« 2008年03月09日 - 2008年03月15日 | メイン | 2008年03月23日 - 2008年03月29日 »



2008年03月16日 - 2008年03月22日 アーカイブ

2008年03月16日

つくろう!逆転裁判でガチで吹いたスレタイ集つくったよ!

逆転裁判は一時期かなり嵌ったのですが、この「つくろう!逆転裁判」にあてはめるネタは何が面白いかなーと思って、とりあえずガチで吹いたスレタイ集を使ってみました。最後は結構カオスです。あはは。
via : つくろう!逆転裁判

[ 最近のエントリーとその関連エントリー ]


[ スポンサードリンク ]

2008年03月21日

SharePointとExtJSでSharePointグループを一覧で表現してみたよ

sharePointGroup.PNG 任意のサイトのSharePointグループを引っこ抜いてリスト表示して、クリップボードにも挿入しちゃうスクリプトを組みました。ExtJSで表現する上ではサイトヒエラルキーと、所属するグループをExt.treeで表現するのがいいかなと思いましたが、gridで表現しました。そのうちtreeでもポストしたいと思います。

表現はさておきSharePointのほうの解説をします。
  1. SiteData.asmxのGetSiteでサイトURLを引っ張ってきます。
  2. GetSiteで引っ張ってきたサイトヒエラルキーのUserGroup.asmxでGetGroupCollectionFromWebを使います。これでそのサイトのグループ一覧を得ます。
  3. 最後に2.で引っ張ったグループUserGroup.asmxのGetUserCollectionFromGroupに与えて所属するユーザを引っ張ります。
  4. ExtJSのgridでレンダリングするという流れです。
ここんとこ技術のエントリばっかりだったので、明日は手作り肉まんを作る予定なのでそれをポストします。皮からこねちゃうよー。こねー!(ビールで酔ってます)
<link rel="stylesheet" type="text/css" href="<yourSitePath>/ext/resources/css/ext-all.css" />
<script type="text/javascript" src="<yourSitePath>/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="<yourSitePath>/ext/ext-all.js"></script>
<script type="text/javascript">
_spBodyOnLoadFunctionNames.push( "getSiteUrlList" );
function getHttpReq(){
    return window.XMLHttpRequest ? new XMLHttpRequest() : ( function() {
        try        { return new ActiveXObject( "Msxml2.XMLHTTP" );    }
        catch( e ) { return new ActiveXObject( "Microsoft.XMLHTTP" ); }
    }());
}

function getSiteUrlList() {
    var httpInst = getHttpReq();
    var renderItem = '';
    httpInst.open( "POST", "/_vti_bin/SiteData.asmx", false );
    httpInst.setRequestHeader( 'Content-Type','text/xml; charset=utf-8' );
    httpInst.setRequestHeader( 'SOAPAction','http://schemas.microsoft.com/sharepoint/soap/GetSite' );
    var postBody = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetSite xmlns="http://schemas.microsoft.com/sharepoint/soap/" /></soap:Body></soap:Envelope>';

    httpInst.onreadystatechange = function () 
    {
        if ( httpInst.readyState == 4 ){
            var xmlData  = httpInst.responseXML;
            var urlList  = xmlData.getElementsByTagName( "Url" );
            var listSize = urlList.length;
            var tempStr  = '';
            for( idx = 0; idx < listSize; idx++ ){
                tempStr = tempStr + '<option value="' + urlList[ idx ].childNodes[ 0 ].nodeValue + '">' + urlList[ idx ].childNodes[ 0 ].nodeValue + '</option>';
            }
            renderItem =  '<select id="choseSite" onchange="getSiteGroup()"><option value="">▼サイトを選んでください</option>' + tempStr + '</select>';
        }
    }
    httpInst.send( postBody );
    document.getElementById( 'siteUrlList' ).innerHTML = renderItem;
}

function getSiteGroup() {

    if( document.getElementById( 'choseSite' ).value == "" ){
        document.getElementById( 'groupList' ).innerHTML = "";
        exit();
    }
    var httpInst = getHttpReq();
    var renderItem = "";

    httpInst.open( "POST", document.getElementById( 'choseSite' ).value + "/_vti_bin/UserGroup.asmx", false );
    httpInst.setRequestHeader( 'Content-Type','text/xml; charset=utf-8' );
    httpInst.setRequestHeader( 'SOAPAction','http://schemas.microsoft.com/sharepoint/soap/directory/GetGroupCollectionFromWeb' );
    var postBody = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetGroupCollectionFromWeb xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/" /></soap:Body></soap:Envelope>';

    httpInst.onreadystatechange = function() 
    {
        if ( httpInst.readyState == 4 ){

            xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" );
            xmlDoc.async = false;
            xmlDoc.loadXML( httpInst.responseText );
            rowsItem = xmlDoc.selectNodes( '/soap:Envelope/soap:Body/GetGroupCollectionFromWebResponse/GetGroupCollectionFromWebResult/GetGroupCollectionFromWeb/Groups/Group' );
            var tempStr = "";
            for( idx = 0; idx < rowsItem.length; idx++ ){
                tempStr = tempStr + '<option value="' + rowsItem[ idx ].getAttribute( "Name" ) + '">' + rowsItem[ idx ].getAttribute( "Name" ) + '</option>';
            }
            renderItem = '<select id="choseGroup" onchange="getGroupUser()"><option value="">▼グループを選んでください</option>' + tempStr + '</select>';
        }
    }

    httpInst.send( postBody );
    document.getElementById( 'groupList' ).innerHTML = renderItem;
}


function getGroupUser() {

    document.getElementById( 'groupUserList' ).innerHTML = "";
    if( document.getElementById( 'choseGroup' ).value == "" ){
        document.getElementById( 'groupUserList' ).innerHTML = "";
        return;
    }
    var httpInst = getHttpReq();
    var renderItem = document.getElementById( 'choseGroup' ).value;
    var dataAry = new Array();
    httpInst.open( "POST", document.getElementById( 'choseSite' ).value + "/_vti_bin/UserGroup.asmx", false );
    httpInst.setRequestHeader( 'Content-Type','text/xml; charset=utf-8' );
    httpInst.setRequestHeader( 'SOAPAction','http://schemas.microsoft.com/sharepoint/soap/directory/GetUserCollectionFromGroup' );
    var postBody = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetUserCollectionFromGroup xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/"><groupName>' + renderItem + '</groupName></GetUserCollectionFromGroup></soap:Body></soap:Envelope>';

    httpInst.onreadystatechange = function() 
    {
        if ( httpInst.readyState == 4 ){

            xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" );
            xmlDoc.async = false;
            xmlDoc.loadXML( httpInst.responseText );
            rowsItem = xmlDoc.selectNodes( '/soap:Envelope/soap:Body/GetUserCollectionFromGroupResponse/GetUserCollectionFromGroupResult/GetUserCollectionFromGroup/Users/User' );
            var copytext = renderItem + "\n名前\tメール\tアカウント\n";
            for( idx = 0; idx < rowsItem.length; idx++ ){
                var fieldDataList = new Array();
                var nameValue = "";
                var emailValue = "";
                var loginNameValue = "";
                
                fieldDataList.push( ( nameValue = rowsItem[ idx ].getAttribute( "Name" ) ) );
                fieldDataList.push( ( emailValue = rowsItem[ idx ].getAttribute( "Email" ) ) );
                fieldDataList.push( ( loginNameValue = rowsItem[ idx ].getAttribute( "LoginName" ) ) );
                dataAry.push( fieldDataList );
                copytext = copytext + nameValue + "\t"+ emailValue + "\t" + loginNameValue + "\n";
            }

            document.getElementById( 'cparea' ).value = copytext;

            Ext.onReady( function(){
                var reader = new Ext.data.ArrayReader( {}, [ 
                    { name: "Name" },
                    { name: "Email" },
                    { name: "LoginName" }
                ]);
                var store = new Ext.data.Store({
                    reader: reader,
                    data: dataAry
                });

                var grid = new Ext.grid.GridPanel({
                    store: store,
                    columns: [
                        { header: "名前", width: 120, sortable: true, dataIndex: "Name" },
                        { header: "メール", width: 240, sortable: true, dataIndex: "Email" },
                        { header: "アカウント", width: 180, sortable: true, dataIndex: "LoginName" } 
                    ],
                    width: 600,
                    height: 400,
                    stripeRows: true,
                    title:renderItem,
                    viewConfig: { forceFit:true },
                    frame:true,
                    collapsible: true,
                    animCollapse: true
                });
                grid.render( 'groupUserList' );
                grid.getSelectionModel().selectFirstRow();
            });
        }
    }
    httpInst.send( postBody );
}
function CopyText( arg ){ 
    var obj = document.all && document.all( arg ) || document.getElementById && document.getElementById( arg ); 
    if ( obj.value ) { 
        var doc = document.body.createTextRange();
        doc.moveToElementText( obj ); 
        doc.execCommand( "copy" ); 
        alert( 'クリップボードにコピーしました。' );
    } else { 
        alert( 'コピーするデータがありません。' );
    } 
}

</script>
<table><tr><td>サイトURLを選んでください</td><td>
<div id="siteUrlList"><img src="<yourSitePath>/ext/resources/images/default/shared/blue-loading.gif">loading...</div></td></tr>
<tr><td>サイトに属するグループを選んでください</td><td>
<div id="groupList"><select><option value="">▼グループを選んでください</option></select></div></td></tr>
<tr><td>出力ユーザをコピーします。</td><td><input type="button" name="Copy" value="コピー" onClick='CopyText("cparea")'></td></tr>
</table>
<div id="groupUserList"></div>
<textarea style="display:none" name="cparea"></textarea>

[ 最近のエントリーとその関連エントリー ]


2008年03月17日

SharePointのライブラリをExtJSのgridウィジェットで表現してみました

sharePointWithExtJS.PNG SharePoint(moss2007)ネタが続きます。SharePointといえば、ほぼノンコーディングで何でもできますよーといったMSのグループウェアで、その柔軟性もものすごいものです。ですが、どれだけノンコーディングで色々できるといっても、カスタマイズしなければならない要求はいくらでも出てきます。でてくることは問題ないのですが、
  • どうやって
  • どこに
  • 安全に
カスタマイズする方法を考え始めるといろいろと難しい問題があります。その割には、SharePointではそういった「裏側からこうやったら」色々いじくれるよーといったエントリはまだまだ少ない気もします。ググってみてもほしい情報はなかなか転がっていません。
が、つい最近のことなのですが、山崎 愛さんのSharePoint Technical Noteを発見してから結構お世話になっております。SharePointの開発をやる方にはお勧めのエントリがたくさんありますよ。

今日は、SharePoint Desinger 2007 を使用した ASP.NET コントロールとデータビューの連携というエントリをみて、影響を受けまして、
  • 任意の
  • 複数のライブラリを
  • 同じページに
  • 非同期で
表示させる方法をポストしたいと思います。
これを実装すると上記のスクリーンショットのようになるのですが、静的なHTMLに書いてドキュメントライブラリに放り込んでもよいですし、リンク先のSharePointTechnicalNoteさんにも記述があります、SharePointデザイナから[ファイル]メニューから[新規作成]-[マスタページから作成]で作成したaspxに埋め込むと、見栄えがよいです。

使ったのは、2つのウェブサービスと、ExtJSのgridウィジェットです。このウィジェットは高速でかなり強力ですので、SharePointで持っているビューを時として凌ぐ使いやすさがあります。
スクリプトは以下のタグの直後に差し込んで使ってみてください。HTMLで書く場合はどのように表現してもOKです。
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
ExtJSは以下のスクリプトのソースに合わせて任意のドキュメントライブラリに格納してください。

それでは簡単にソースを解説します。
まず、ライブラリ名をフォームから取得してLists.asmxのGetListウェブサービスに渡します。このウェブサービスで取得するのはリスト・ドキュメントライブラリのフィールド名です。
フィールド名はDisplayNameと、StaticNameというアトリビュートで、返ってきたXMLに入ってきます。DisplayNameはそのまま表示されるフィールド名ですが、StaticNameは裏で持っているフィールド名を一意にするidといったところでしょうか。この取得したフィールド名を次のウェブサービスに投げて実際のアイテムを刈り取っていくという作業です。
実際のアイテム取得は以前のエントリでも触れたLists.asmxのGetListItemsです。詳しくはそちらを参照していただければと思いますが、GetListで取得したStaticNameに準じてライブラリのフィールドを制御しています。ですので、基本的にはライブラリやフィールドに依存しないつくりになっています。
ExtJSのgirdはjavascriptのArrayでも表現することができます。gridで表示される値は、属性(type:日付や数値など)も考慮されていますが、今回は属性を意識したつくりにはしていません。というわけで、スクリプトを以下に記します。
<link rel="stylesheet" type="text/css" href="http://<yourSitePath>/ext/resources/css/ext-all.css" />
<script type="text/javascript" src="http://<yourSitePath>/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="http://<yourSitePath>/ext/ext-all.js"></script>
<script type="text/javascript">
// onloadでレンダリングさせたい場合
// _spBodyOnLoadFunctionNames.push( "getList" );
var httpInst = window.XMLHttpRequest ? new XMLHttpRequest() : ( function() {
    try        { return new ActiveXObject( "Msxml2.XMLHTTP" );    }
    catch( e ) { return new ActiveXObject( "Microsoft.XMLHTTP" ); }
})();

function getList() 
{
    var listGuid = "";
    if( ( listGuid = document.getElementById( "listguid" ).value ) == "" ){
        return;
    }

    httpInst.open( "POST", "http://<yourSitePath>/_vti_bin/Lists.asmx", false );
    httpInst.setRequestHeader( 'Content-Type','text/xml; charset=utf-8' );
    httpInst.setRequestHeader( 'SOAPAction','http://schemas.microsoft.com/sharepoint/soap/GetList' );
    var postBody = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetList xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>' + listGuid + '</listName></GetList></soap:Body></soap:Envelope>';

    httpInst.onreadystatechange = function()
    {
        if ( httpInst.readyState == 4 ){
            xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" );
            xmlDoc.async = false;
            xmlDoc.loadXML( httpInst.responseText );
            listInfo = xmlDoc.selectSingleNode( '/soap:Envelope/soap:Body/GetListResponse/GetListResult/List' );
            var urlLink = listInfo.getAttribute( "DefaultViewUrl" );
            urlLink = urlLink.replace( "AllItems.aspx", "" );
            var libTitle = listInfo.getAttribute( "Title" );

            rowsItem = xmlDoc.selectNodes( '/soap:Envelope/soap:Body/GetListResponse/GetListResult/List/Fields/Field' );

            var xmlStaticNm = new Array();
            var xmlDispNm = new Array();
            for( idx = 0; idx < rowsItem.length; idx++ ){
                if( rowsItem[ idx ].getAttribute( "Hidden" ) == null &&
                    rowsItem[ idx ].getAttribute( "StaticName" ) != "LinkTitleNoMenu" &&
                    rowsItem[ idx ].getAttribute( "StaticName" ) != "LinkTitle" )
                {
                    xmlStaticNm.push( rowsItem[ idx ].getAttribute( "StaticName" ));
                    xmlDispNm.push( rowsItem[ idx ].getAttribute( "DisplayName" ));
                }
            }
            getListItems( listGuid, xmlStaticNm, xmlDispNm, urlLink, libTitle );
        }
    }
    httpInst.send( postBody );
}

function getListItems( listGuid, xmlStaticNm, xmlDispNm, urlLink, libTitle )
{
    var fieldRefData = '';
    var dataAry = new Array();
    var headAry = new Array();
    var clmnAry = new Array();

    for( idx = 0; idx < xmlStaticNm.length; idx++ ){
        fieldRefData = fieldRefData + '<FieldRef Name="' + xmlStaticNm[ idx ] + '" />';
        headAry.push( { name: xmlStaticNm[ idx ] } );
        clmnAry.push( { header: xmlDispNm[ idx ], width: 90, sortable: true, dataIndex: xmlStaticNm[ idx ] } );
    }
    httpInst.open( "POST", "http://<yourSitePath>/_vti_bin/Lists.asmx", false );
    httpInst.setRequestHeader( 'Content-Type','text/xml; charset=utf-8' );
    httpInst.setRequestHeader( 'SOAPAction','http://schemas.microsoft.com/sharepoint/soap/GetListItems' );
    var postBody = '<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"><soap12:Body><GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">' + 
    '<listName>' + listGuid + '</listName>' + 
    '<viewName></viewName>' + 
    '<query><Query><Where><Gt><FieldRef Name="ID" /><Value Type="Counter">0</Value></Gt></Where></Query></query>' + 
    '<viewFields><ViewFields>' + fieldRefData + '</ViewFields></viewFields>' + 
    '<rowLimit>100</rowLimit>' + 
    '<queryOptions><QueryOptions/></queryOptions>' + 
    '<webID></webID>' + 
    '</GetListItems></soap12:Body></soap12:Envelope>';

    httpInst.onreadystatechange = function()
    {
        if ( httpInst.readyState == 4 ){
            xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" );
            xmlDoc.async = false;
            xmlDoc.loadXML( httpInst.responseText );

            rowsItem = xmlDoc.selectNodes( '/soap:Envelope/soap:Body/GetListItemsResponse/GetListItemsResult/listitems/rs:data/z:row' );

            for( idx = 0; idx < rowsItem.length; idx++ ){
                var fieldDataList = new Array();
                for( sdx = 0; sdx < xmlStaticNm.length; sdx++ ){
                    var curItem = rowsItem[ idx ].getAttribute( "ows_" + xmlStaticNm[ sdx ] );
                    curItem = ( xmlStaticNm[ sdx ] == "ID" ) 
                        ? '<a href="' + urlLink + 'DispForm.aspx?ID=' + curItem + '">' + curItem + '</a>'
                        : rowsItem[ idx ].getAttribute( "ows_" + xmlStaticNm[ sdx ] );
                    fieldDataList.push( curItem );
                }
                dataAry.push( fieldDataList );
            }

            Ext.onReady( function(){

                var reader = new Ext.data.ArrayReader( {}, headAry );
                var store = new Ext.data.Store({
                    reader: reader,
                    data: dataAry
                });

                var grid = new Ext.grid.GridPanel({
                    store: store,
                    columns: clmnAry,
                    width: 540,
                    height: 200,
                    stripeRows: true,
                    title: libTitle
                });

                grid.render( 'grid-example' );
                grid.getSelectionModel().selectFirstRow();

            });
        }
    }
    httpInst.send( postBody );
}
</script>
<input type="text" id="listguid" /><input type="button" value="参照リストの追加" onclick="getList()">
<div id="grid-example"></div>

[ 最近のエントリーとその関連エントリー ]


2008年03月16日

つくろう!逆転裁判でガチで吹いたスレタイ集つくったよ!

逆転裁判は一時期かなり嵌ったのですが、この「つくろう!逆転裁判」にあてはめるネタは何が面白いかなーと思って、とりあえずガチで吹いたスレタイ集を使ってみました。最後は結構カオスです。あはは。
via : つくろう!逆転裁判

[ 最近のエントリーとその関連エントリー ]


ツリータイプ・カテゴリー

open all | close all

リファラから検索


サイト内検索