ログインユーザーの権限をJavaScriptでチェックする

ひさびさの更新になってしまいましたがちゃんと生きてますよ!!
というわけで、生きている証を立てたいと思います。

ログインユーザの権限に応じて、サイトのUIの一部を非表示にしたいといった要望は多いですよね。
そこで、今回はClient Object Modelを使ってユーザー権限をチェックするコードをJavaScriptで実装してみたいと思います。

Client Object Modelでユーザー権限を取得するには、SP.Web.effectiveBasePermissions propertyを使います。
これで、ユーザーがサイトに対して持っている権限の一覧が取れるので、そこからユーザー権限を判断します。
たとえば、「Webサイトの管理」権限を持っていればフルコントロール権限があるだろう、とか。

では、ログインユーザーが「Web サイトの管理」権限を持っているかチェックするサンプルコードを書いてみます。jQueryも使ってます。

$(function(){
    ExecuteOrDelayUntilScriptLoaded(CheckPermissionOnWeb, "sp.js");
});

function CheckPermissionOnWeb() {
    var ctx = new SP.ClientContext.get_current();
    var web = ctx.get_web();

    var currentUser = web.get_currentUser();
    ctx.load(currentUser);
    ctx.load(web,'EffectiveBasePermissions');
    ctx.executeQueryAsync(Function.createDelegate(this, onSuccessMethod), Function.createDelegate(this, onFailureMethod));        

    function onSuccessMethod(sender, args) {
        if (web.get_effectiveBasePermissions().has(SP.PermissionKind.manageWeb)) {
            console.log('You are Site Admin.');
        }
    }

    function onFailureMethod(sender, args) {
        console.log('Error:' + args.get_message());
    }
}

上記で「SP.PermissionKind.manageWeb」の「manageWeb」のところを変えれば、別の権限を持っているかもチェックできます。
たとえば、「manageLists」ならリストの管理権限があることになります。
具体的には、以下をご参考に。
https://msdn.microsoft.com/en-us/library/ee556747.aspx

対象ユーザーを使って、ビューのアクセス制御っぽいことを実現する

小ネタ、というかメモとして書いておきます。

ご存じのように、SharePointではビューに固有のアクセス権をつけることはできません。
が、ちょっとした工夫でアクセス制御っぽい機能を実現することができます(「ぽい」です、あくまで)。

SharePointのwebパーツには、「対象ユーザー」を設定することができますよね。
リストのビューもwebパーツではあるので、対象ユーザーを設定して特定のユーザーにしか見せないようにできます。

【設定手順】
※以下、画面は2010ですが、2013でも同様にできることを確認しています。

①アクセス制限をかけたいビューを表示した状態で、「サイトの操作」→「ページの編集」を選択します。
②リストビューwebパーツのドロップダウンから、「webパーツの編集」を選択します。
20150114-1
③webパーツの設定画面の「詳細設定」セクションの「対象ユーザー」に、ビューにアクセスさせたいSharePointグループを指定し、「OK」をクリックします。
20150114-2
④リボンで「編集の終了」を押して保存します。
以上です!

これで、指定したグループに登録されていないユーザーは、ページにはアクセスできるもののビューが表示されません。
20150114-3
リボンにも「参照」タブしか表示されず、いい感じです。

厳密にいえば、隠してるだけでほんとのセキュリティではないのですが、こんなやり方もあるよ、ということで。

SharePointのwikiページにページビューカウンタをつけてみた

気が付いたら、今年も残すところあと数日・・・早いものですね。
私らしくどうでもいいネタで今年を締めくくりたいと思います。

もうすっかり前世紀の遺物となってしまった感のあるアクセスカウンターですが、サイトのトップページやお知らせページなんかの場合てっとりばやくどのくらいアクセスがあるのか知りたいって時もあるんじゃないかと思います。

実装するやり方はいろいろあるかと思いますが、ここではアクセスカウントを格納しておくカスタムリストを一つつくっておいて、ページロードの時にJavaScriptでカウンタをインクリメントするようにしてみました。
試した環境はSharePoint2010ですが、2013でもたぶんいけると思います。

下準備:
①サイト内にカスタムリストを作成し、countという一行テキスト列を追加しておきます。
今回は「test」という名前でカスタムリストを作成しました。
②作成したリストに新規アイテムを一つ作成し、countには「0」を入れておきます。

以上で準備は終わりです。
次に、カウンタをつけたいページにコンテンツエディタwebパーツを追加し、そのHTMLソースに以下のコードを記述します。

<div id="pageView"></div>
<script src="http://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/2014.01/jquery.SPServices.min.js" type="text/javascript"></script>
<script type="text/javascript">
(function (){

    var itemId;
    var count;

    $().SPServices({
        operation: "GetListItems",
        async: false,
        listName: 'test',
        completefunc: function (xData, Status) {
            $(xData.responseXML).SPFilterNode("z:row").each(function () {
                itemId= $(this).attr("ows_ID");
                count = Number($(this).attr("ows_count"));
            });
        }
    });

    count++;
    count = String(count);

    $().SPServices({
        operation: "UpdateListItems",
        async: false,
        batchCmd: "Update",
        listName: "test",
        valuepairs: [["count", count]],
        ID: itemId,
        completefunc: function(xData, Status) {
          //
        }
    });

    $('#pageView').empty();
    $('#pageView').append('<p>' + count + ' views</p>' );

})();
</script>

以上でOKです!
こんな感じで控え目にページビューが表示されます。
20141226

ちなみに、上記サンプルコードは、多数アクセスがあったときの排他制御とか、複数ビューカウンタをつけたい場合とか、自分のアクセスや編集モードにしたときのページロードを排除するとかは一切考慮しておりません。
何かのヒントになればうれしいです。

それではみなさま、よいお年を!

SharePoint2010にコンテンツエリア拡大ボタンをつけてみた

SharePointのヘッダー部分や、サイドリンクバーって意外と場所をとりますよね。
なんで、コンテンツがもりだくさんのページの場合、もっと大きな画面で見せたい時があると思います。

そういうニーズを受けてかなのか、SharePoint2013なら、コンテンツエリアを拡大して見せるボタン(*)が標準であるのですが、残念ながら2010にはありません。

* コレ↓です
20141128

というわけで、自前で作ってみました。
動作イメージはこんな感じです。画面右下、「全画面」ボタンを押すとコンテンツエリアがぐぐっとひろがります。
20141128

ソースコードです。これをコンテンツエディタwebパーツでページにぺたっと貼ればOKです。

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js"></script>
<style type="text/css">
  .screen-change
  {
      position: fixed;
      bottom: 20px;
      right: 80px;
  }

  .screen-change a
  {
      background: #666;
      text-decoration: none;
      color: #fff;
      width: 120px;
      padding: 8px 0;
      text-align: center;
      display: block;
      border-radius: 3px;
      -webkit-border-radius: 3px;
      -moz-border-radius: 3px;
      opacity: 0.8;
      filter: alpha(opacity=80); /* IE lt 8 */
      -ms-filter: "alpha(opacity=80)"; /* IE 8 */
  }

  .screen-change a:hover
  {
      text-decoration: none;
      background: #222;
  }
</style>
<script>
  $(function(){
    $(document.body).append('<p id="only-content-area" class="screen-change"><a href="#">全画面表示</a></p><p id="default-screen" class="screen-change"><a href="#">元に戻す</a></p>');
    $("#default-screen").hide();
    $(".screen-change").click(function() {
      $('#s4-titlerow, #s4-leftpanel, #RibbonContainer-TabRowLeft, .ms-cui-tts').toggle('slide', '', 500);
      var hide = $('#default-screen').css('display');
      if(hide == 'none'){
        $('.s4-ca').css('margin-left', '0px');
      } else {
        $('.s4-ca').css('margin-left', '155px');
      };
      $("#only-content-area, #default-screen" ).toggle();
    });
  });
</script>

リボンメニューが表示されている状態で拡大するとあやしい動きになってしまうので、リボンメニューを表示させられるツールバーのボタンやタブも軒並み隠してますが、それならいっそツールバー自体を隠しちゃってもよかったかも。
そのへんはお好みで調整してください。

ふと、思ったのですが、これ応用したら印刷用画面としても使えるかも・・・?

ドキュメントライブラリのファイルがPDFだったら別窓で開く

ひさびさの更新になってしまいました。気が付けば、今年も残すところあと2か月、巷には早くもクリスマスのイルミが・・・という季節になってしまいました。早すぎるだろ。

さて、SharePoint2010のお話です。

ドキュメントライブラリでPDFを入れている場合、該当のファイル名をクリックするとブラウザの同じウィンドウ内で開いてしまいます。
(ブラウザでPDFを開く設定にしていれば、ですが。)
その時、うっかりタブを閉じたりすると元のライブラリに戻れなくなっちゃったりします。
地味に不便ですよね。

で、PDFファイルの場合だけ選択的に別窓で開かせるスクリプトを書いてみました。jQuery使ってます。

// これだとグルーピングしたビューではダメ
$('a[href$=".pdf"]').each(function(){
	$(this).removeAttr('onclick');
});
//無理やりだけど・・・
$(document).on('mouseover', 'a[href$=".pdf"]',
	function(eo) {
		$(eo.target).removeAttr('onclick');
	}
);
//クリックイベントを設定
$(document).on('click', 'a[href$=".pdf"]',
	function(eo) {
		window.open(eo.target.href, '_blank');
		return false;
   	}
);

ドキュメントライブラリのリストビューだと、クリック時 onclick属性に設定されてるファンクションが先に動いてしまうので、まずそいつを削除する、しかもmouseoverイベントで・・・という荒ワザをやっております。
こんなことしていいかよくわかりませんけど、よくない気もしますけど、もっといいやり方があったら教えていただけるとうれしいです。

また、グルーピングしたビューの場合アイテムが動的に追加されるため hoge.click(function… みたいな書き方は通用しません。
で、こちらなど参考にしつつ、
外部リンクを別窓で開くJavaScriptを改善した – rakugaki-box.net.
上記コードに落ち着きました。

リンクリストで、外部リンクは別窓で開かせたい!なんて場合にも応用できそうですね。

SharePointのページ内リンクでスムーススクロール

またしてもSharePointの機能とはさして関係のないネタです。当ブログ、こんなんばっかりですがお許しください・・・

以前、こんな記事を書きましたが、
SharePointでスクロールするとトップへ戻るボタンを表示してみた
こちらの姉妹編のエントリです。

最近のwebサイトでは、ページ内リンクへのジャンプはアニメーションでスルスル~っとスクロールしてくのがもう定番ですよね。
これをSharePointのページにも実装してみました。
smoothScroll

スムーススクロールは巷にプラグインなどあふれてますが、余計なものを入れたくなかったのでCSS-Tricksにあったこちらを元ネタにしました。
Smooth Scrolling | CSS-Tricks
jQueryさえあれば動かせます。

ソースコードです。SharePoint2010、2013で動作確認しています。
JavaScript

$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    var def = $('div[id*=titlerow]').offset().top;
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('#s4-workspace').animate({
        	scrollTop: target.offset().top - def
        }, 500);
        return false;
      }
    }
  });
});

HTMLサンプル

<h3>​​​​​​<a href="#section1">Section1</a></h3>
<h3><a href="#section2">Section2​</a></h3>

<h1 id="section1">Section1</h1>
<div>Vivamus suscipit tortor eget felis porttitor volutpat. Pellentesque in ipsum id orci porta dapibus.
 Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. 
Quisque velit nisi, pretium ut lacinia in, elementum id enim. Pellentesque in ipsum id orci porta dapibus. 
Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. 
Pellentesque in ipsum id orci porta dapibus. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. 
Cras ultricies ligula sed magna dictum porta. Proin eget tortor risus.</div>

<h1 id="section2">Section2</h1>
<div>Vivamus suscipit tortor eget felis porttitor volutpat. 
Pellentesque in ipsum id orci porta dapibus. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. 
Quisque velit nisi, pretium ut lacinia in, elementum id enim. 
Pellentesque in ipsum id orci porta dapibus. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. 
Pellentesque in ipsum id orci porta dapibus. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. 
Cras ultricies ligula sed magna dictum porta. Proin eget tortor risus.</div>

SharePointで実装するときの注意点ですが、windowオブジェクトではスクロール位置がとれないので、idが”#s4-workspace”のdiv要素を動かします。
また、リンク元の要素がページの半ばにあることも考慮して、サイトのタイトルエリアがwindowのトップからどれだけ上にふっ飛んでるかでスクロール幅を調整しています。
HTML側は、サンプルのように基本飛ばしたい先の要素にハッシュと同じID名を振ればよいのですが、スクリプト的にはアンカーにも対応してます。

余談ですが、SharePointでページにアンカーをつけたい時は、リンクツールでBookmark欄に任意のアンカー名をいれればつけられます。
20141003

なので、上記コードをパッケージ化(コンテンツエディタwebパーツに仕込んでExportするなど)すれば、HTMLを書けないユーザでもスムーススクロールできるようになりそうですね!

SharePoint 2010のwikiページを2013のosloテーマっぽくするCSS

先日ひさびさにバンドの練習で歌ってきたのですが、背中と脇腹が筋肉痛になりました。普段からまじめにトレーニングしないとだめですね・・・

さて、SharePoint2013になってosloテーマができ、サイドリンクバーなしの中央固定幅のレイアウトが選べるようになりました。
SharePoint2010のチームサイトでもosloっぽいレイアウトにしてみたく、CSSで強引につくってみました。
これを適用したいwikiページにコンテンツエディタ webパーツで埋め込んでください。

CSS

#s4-leftpanel
{
    display : none;
}
.s4-ca
{
    margin-left : 0px !important;
} 

.ms-rtestate-field{
    max-width: 1024px;
    min-width: 768px;
    margin: 0 auto;
    padding: 0;
}

max-width、min-widthはお好みや環境に応じて設定してください。

いちおう、wikiページのテキストレイアウトをいろいろ変更しても中央固定幅になることは確認してますが、そんなにしっかりテストはしてないので、実環境に適用される場合は副作用がないか十分検証してくださいね。