SharePoint集計値列を応用したHTMLがエスケープされる

2017.07.07
SharePoint集計値列を応用したHTMLがエスケープされる

MS開発部の 永田 です。

SharePointでよく使う応用テクニックとして
集計列にIF文等を書いて、値に応じてHTMLで文字色を変更した文字列を出力したり
画像アイコンを表示する技がありました。

しかし、残念ながらSharePoint Onlineは2017年6月13日から仕様変更があり上記の技が使えなくなりました。
2017年9月10日まで延長は可能ですが、それ以降は強制的にエスケープされて表示されます。
SharePoint の計算フィールドの HTML マークアップを処理します。

また、SharePoint2013、SharePoint2016でも同様に2017年6月のアップデートPUに
「CustomMarkupInCalculatedFieldDisabled」という新しいWebアプリケーション設定が増え
管理者による設定によってHTMLをエスケープするかどうかを変更可能となります。

ですが、SharePointOnlineで使えなくなるのは困る方も沢山居ると思いますので、
暫定的ですが回避策を。

1.カスタムワークフローにてリッチテキストに出力するように設定
2.WepパーツにJSリンクを設定
3.ページまたはマスターページにJSを記述

この中で2,3についてサンプルを作成しましたので、参考にして頂けたらと思います。
2.WepパーツにJSリンクを設定
・サンプルの2行目の"unescape.js"はサンプルのJS名を記述してください。
・9行目"FieldName”は対象となる列の内部列名を記述してください。
 複数列設定する必要がある場合は下記のように記述します。

overrideCtx.Templates.Fields = { "FieldName1": { "View" : SetView } "FieldName2": { "View" : SetView } };"

・JSリンク設定時にはjqueryも読み込んでください。
 例:https://siteurl/SiteAssets/js/jquery-2.2.4.min.js | https://siteurl/SiteAssets/js/unescape.js

(function(){
	RegisterModuleInit("unescape.js", ViewIni);
	ExecuteOrDelayUntilScriptLoaded(ViewIni, "init.js");
})();
function ViewIni()
{
	var overrideCtx = {};
	overrideCtx.Templates = {};
	overrideCtx.Templates.Fields = { "FieldName": { "View" : SetView }  };
	SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
}
function SetView(ctx)
{
	var retVal = "";
	try
	{
		retVal = ctx.CurrentItem[ ctx.CurrentFieldSchema.Name ];
		textholder = $(this).text();
		$(this).html(textholder);
	} 
	catch(e)
	{
	}
	return retVal;
}

3.ページまたはマスターページにJSを記述
・1行目の"jquery"のパスを指定してください。
・このJSは列名を設定しなくても良いように作成していますのでそのままコンテンツエディタ等で読み込んでください。

<script language="javascript" src="/SiteAssets/js/jquery-2.2.4.min.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
if ($('div[fieldtype="Calculated"]').length != 0) {
    $('div[fieldtype="Calculated"]').each(function () {
        var thElement = $(this).parent();
        var indexOfThElement = thElement.parent().find('th').index(thElement);
        indexOfThElement++;
        thElement.closest('table').find('tr td:nth-child(' + indexOfThElement + ')').each(function () {
            var thisText = $(this).text();
            $(this).html(thisText);
        });
    });
}
});
</script>

どちらでも同様の結果になります。

以上、最後までご愛読いただき
ありがとうございました。

お問い合わせは、
以下のフォームへご連絡ください。

お問い合わせ

PAGETOP