« 2008年02月24日 - 2008年03月01日 | メイン | 2008年03月09日 - 2008年03月15日 »



2008年03月02日 - 2008年03月08日 アーカイブ

2008年03月04日

ExtJSのフォームウィジェットとサブミットの方法

extjsform2.PNG 以前のエントリにExtJSのサブミットの方法を試行錯誤してやってみたというものがありましたが、完全に的をはずしていたので改めてポストします。
ページからページへ情報を渡すためにフォームタグにテキストエリアとか、ボタンとか色々配置して表現したりしますが、ExtJSのウィジェットでフォームパネル( Ext.form.FormPanel )というものを持っていますので、こいつを使ってみます。 examples\form にサブミット(アクション)のサンプルが無いってのはどうよ?とは思いますが、ちゃんと隅から隅まで見てません。誰かに「あるよー」なんて言われたら恥の上塗りなので、ごちゃごちゃ言わずに説明してみます。
前回説明したのは、リッチテキストのサブミットですが、フィールドをどう表現するのかは xtype で決まっているみたいだと書きました。以下は xtype のリストです。Form components を見ていただくとフォームフィールドとして簡単に表現できるコンポーネントがたくさんあります。頑張れば grid (の中身)もポストできるってのはすごいですよね。エクセルシートみたいなフォームをポスト出来たりしたらウェブのフォームと言うかほとんどデスクトップアプリケーションですね。
xtype            Class
-------------    ------------------
box              Ext.BoxComponent
button           Ext.Button
colorpalette     Ext.ColorPalette
component        Ext.Component
container        Ext.Container
cycle            Ext.CycleButton
dataview         Ext.DataView
datepicker       Ext.DatePicker
editor           Ext.Editor
editorgrid       Ext.grid.EditorGridPanel
grid             Ext.grid.GridPanel
paging           Ext.PagingToolbar
panel            Ext.Panel
progress         Ext.ProgressBar
splitbutton      Ext.SplitButton
tabpanel         Ext.TabPanel
treepanel        Ext.tree.TreePanel
viewport         Ext.ViewPort
window           Ext.Window

Toolbar components
---------------------------------------
toolbar          Ext.Toolbar
tbbutton         Ext.Toolbar.Button
tbfill           Ext.Toolbar.Fill
tbitem           Ext.Toolbar.Item
tbseparator      Ext.Toolbar.Separator
tbspacer         Ext.Toolbar.Spacer
tbsplit          Ext.Toolbar.SplitButton
tbtext           Ext.Toolbar.TextItem

Form components
---------------------------------------
form             Ext.FormPanel
checkbox         Ext.form.Checkbox
combo            Ext.form.ComboBox
datefield        Ext.form.DateField
field            Ext.form.Field
fieldset         Ext.form.FieldSet
hidden           Ext.form.Hidden
htmleditor       Ext.form.HtmlEditor
numberfield      Ext.form.NumberField
radio            Ext.form.Radio
textarea         Ext.form.TextArea
textfield        Ext.form.TextField
timefield        Ext.form.TimeField
trigger          Ext.form.TriggerField
サブミットするときに必要になるのは、送信先の URL と送信するフィールド(名)とボタンになります。(実装に依存します)この3つをソースで見ていきたいと思います。
まず、フォームは Ext.FormPanel で作って、

送信先URLは
url:'hoge.php'で指定してあげます。

フィールド名は
name:'field1'で決まります。ポスト先はこのフィールド名で値をもらうことになります。
PHPだと$_POST[ "field1" ];こんな感じです。

最後にボタンに割り当てるのがハンドラです。以前はアクションを割り当てたらできたよーみたいなことを書きました。もちろんアクションでも出来ますが、非同期で値を渡したい場合は以下のようなハンドラをボタンに割り当てるといいみたいです。
handler:function() {
    myForm.getForm().submit({ 
        success:function( form, action ) {},
        failure:function( form, action ) {}
    });
}
myForm は FormPanel のインスタンスです。 getForm() で BasicForm を返すのでそいつの submit() を使うことになります。このハンドラをボタンに割り当ててあげます。
buttons: [{
    text: '送信', handler:function() {
        myForm.getForm().submit({
            success:function(form, action) {},
            failure:function(form, action) {}
        });
    }
}]
フォームとサブミットのサンプルソースは以下になります。
Ext.onReady( function(){
    var myForm = new Ext.FormPanel({
        url:'hoge.php',
        labelWidth: 75,
        frame:true,
        title: 'テストフォーム',
        bodyStyle:'padding:5px 5px 0',
        width: 350,
        defaults: { width: 230 },

        // デフォルトのフィールドを textfield とします
        defaultType: 'textfield',

        items: [{
                fieldLabel: 'First Name',
                name: 'first',
                allowBlank:true
            },{
                fieldLabel: 'Last Name',
                name: 'last'
            },{
                fieldLabel: 'Company',
                name: 'company'
            },{
                fieldLabel: 'Email',
                name: 'email',
                // vtype:'email'でメールのバリデーションチェックがかかるようです。
                vtype:'email'
            }
        ],

        buttons: [{
            text: '送信',handler:function() {
                myForm.getForm().submit({
                    success:function( form, action ) {
                        // echo print_r($_POST, 1); on hoge.php
                        // ポストしたパラメータと値を見れます。
                        alert( action.response.responseText );
                    },
                    failure:function( form, action ) {
                        // emailのバリデーションチェックで送信できない場合
                        // hostに送信できない場合なんかはこっちにきます
                        alert( action.failureType );
                    }
                });
            }
        }]
    });
    myForm.render( document.body );

});

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


[ スポンサードリンク ]

第4回国際ニコニコ映画祭の受付が開始されているようです。

niconicofes4th.PNG 国際ニコニコ映画祭第4回が3月1日からエントリを開始しているようです。第3回で咲と五月女を応募したもののカスリもしなかったので泣きぬれていたのですが、第4回と聞いて飛んで行って見てきました。ふむ。もう一回エントリするお!
        ノ L____
       ⌒ \ / \
      / (○) (○)\
     /    (__人__)   \
     |       |::::::|     |
     \       l;;;;;;l    /l!| !
     /     `ー'    \ |i
   /          ヽ !l ヽi
   (   丶- 、       しE |そ 今度こそノミネートされるはずだお!
    `ー、_ノ       ∑ l、E ノ <
               レY^V^ヽl 


       ______
      /  \    /\
    /  し (>)  (<)\
    | ∪    (__人__)  J | ________
    \  u   `⌒´   / | |          |
    ノ           \ | |          |


         ____
      /  \    ─\   チラッ
    /  し (>)  (●)\
    | ∪    (__人__)  J | ________
    \  u   `⌒´   / | |          |
    ノ           \ | |          |


         ____
      /::::::─三三─\
    /:::::::: ( ○)三(○)\
    |::::::::::::::::::::(__人__)::::  | ________
     \:::::::::   |r┬-|  / | |          |
    ノ::::::::::::  `ー'´   \ | |          | 
やる夫が最近すきなのですが、それはそれでいいとして今度は咲と五月女じゃないのでエントリしようかと思います。ニコニコテイストってどんなだろうね。確かにyoutubeポイやつとか、ニコニコぽいやつといわれればあるような気がしますね。突っ込みどころ満載にしておけばいいのかな。あははー。

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


SharePointのGetListItemsを使ってみました

SharePointのListsウェブサービスのGetListItems(http://<Site>/_vti_bin/Lists.asmx?op=GetListItems)を使ってみました。
C#やVBなどの使い方はサンプルソースつきでmsdnに載っているのですが、クライアントからスクリプトでサービスを呼びたかったので結構苦労しましたよ。

http://<Site>/_vti_bin/Lists.asmx?op=GetListItems
を見てみるとsoapの要求と応答のサンプルが載っています。リスト名(listName)、ビュー名(viewName)を与えるらしいです。ほかにもクエリ(query)と結果(viewFields)、取得件数(rowLimit)クエリオプション(queryOptions)とウェブID(webID)を渡すようですね。
<listName>string</listName>
<viewName>string</viewName>
<query>
  <xsd:schema>schema</xsd:schema>xml</query>
<viewFields>
  <xsd:schema>schema</xsd:schema>xml</viewFields>
<rowLimit>string</rowLimit>
<queryOptions>
  <xsd:schema>schema</xsd:schema>xml</queryOptions>
<webID>string</webID>
ふむふむり。このカタチで渡せってことみたいです。
listNameはGUIDでもリスト名を直打ちでもいいらしいくて、viewNameは省略可のようです。
queryは
<query><Query><Where><Eq><FieldRef Name="ID" /><Value Type="Counter">1</Value></Eq></Where></Query></query>
こんな感じで組み立てたら出来ました。
<query><Query/></query>っていう発想はなかったです。これが出来るまでsoapのエラーを何度見たことか。msdnにちゃんと書いてあるんだけど、ちょっと紛らわしいですね。全文サンプル載せて欲しいです。で、このクエリのWhere句のつくり方を以下に記してみます
  • FieldRef
    • FieldRefタグはそのままフィールド名です。[リストの設定ページ]→[ビューの編集ページ]のHTMLソースを見ればどんな値がNameに入ってくるか判ります。スクリプトのg_FieldsというArrayに設定されている文字列がそれです。
    • Name属性の例として、Title / ID / ContentType / Modified / Created / Author / Editorなどがあります。デフォルトでリストが持っているものから、追加したフィールドもg_Fieldsに全て載っています。
  • Value
    • ValueタグのType要素も同様、HTMLのソースを見れば判ります。今度はg_FieldTypeというArrayに設定されている文字列になります。
    • Type属性の例として、Attachments / Boolean / Choice / Counter / DateTime / Lookup / RichText / Text / WorkflowStatusなどがあります
  • Eq / Lt / Gt
    • Eqタグはクエリで得られるアイテムそのものを返してくれるようにする要求で、他にもLtタグ、Gtタグが使えます。Ltタグはクエリ以下のもの、Gtはクエリ以上のものです。例えば、上記のクエリに5を与えていた場合、Ltで要求すると、1から4が返ってきます。
      <Lt><FieldRef Name="ID" /><Value Type="Counter">5</Value></Lt>
      Ltタグを使うとrowLimitタグにしたがって、要求数分1~4のIDを持つアイテムが返ってきます。

      <Gt><FieldRef Name="ID" /><Value Type="Counter">5</Value></Gt>
      Gtタグを使うと、6~のIDを持つアイテムがrowLimitにしたがって返ってきます。
これがQueryタグのWhere句タグ?の作り方になります。

viewFieldsは
<viewFields><ViewFields><FieldRef Name="ID" /><FieldRef Name="Title" /></ViewFields></viewFields>
上記のように組み立てます。特に設定が無いと、デフォルトとして戻り値を得ることが出来るのですが、全てのフィールドが返ってくる訳ではないようですので、欲しいフィールドは明示的にこの要求から設定する必要があるようです。順番も上記設定どおりに返ってきます。
クライアントで戻ってきたxmlをパースすることになるので、ある程度欲しい情報は絞ったほうがいいかもしれませんね。
queryOptionはちゃんと使ってないので判りませんが、戻り値の日付フォーマットをUTCにしたり、ページングの情報を返してくれたりすることが出来るようです。
最後のwebIDはどうやら省略可能のようですが、http://<Site>/_vti_bin/SiteData.asmx?op=GetWebの戻り値の
<WebID>string</WebID>
に入ってくる値です。

最終的にGetListItemsでやりたかったのは、リストのビューを作らないでクエリを投げて必要なアイテムを返してもらってExtJSのGridを使ってレンダリングするということなのですが、GetListItemsで投げるクエリは完全一致したものを戻してくるのでちょっと目論見が外れました。でもリストフィールドがフリーテキストではなくて、ステータスを保持しているものであれば、意外と使えそうですね。

以下にサンプルスクリプトを載せておきます。環境に合わせて試してみてください。
<script language="JavaScript">
<!--
var httpInst = window.XMLHttpRequest ? new XMLHttpRequest() : ( function() {
    try        { return new ActiveXObject( "Msxml2.XMLHTTP" );    }
    catch( e ) { return new ActiveXObject( "Microsoft.XMLHTTP" ); }
})();

function GetListItems() {

    var renderData = '';
    var qry = document.getElementById( "value_id" ).value;
    httpInst.open( "POST", "http://<Site>/_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>{********-****-****-*****************}</listName>' + 
    '<viewName>{********-****-****-*****************}</viewName>' + 
    '<query><Query><Where><Eq><FieldRef Name="ID" /><Value Type="Counter">' + qry + '</Value></Eq></Where></Query></query>' + 
    '<viewFields><ViewFields><FieldRef Name="ID" /><FieldRef Name="Title" /></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 );

            // IDで取っているので1個だけ返るはずだけど。
            rowsItem = xmlDoc.selectNodes( '/soap:Envelope/soap:Body/GetListItemsResponse/GetListItemsResult/listitems/rs:data/z:row' );

            for( idx = 0; idx < rowsItem.length; idx++ ){
                alert( rowsItem[ idx ].getAttribute( "ows_Title" ) );
            }
        }
    }
    httpInst.send( postBody );
    document.getElementById( "printField" ).innerHTML = renderItem;
}

//-->
</script>
</head>
<body>
    <div>
        <input type="button" value="ID検索" onclick="GetListItems()"/>
        <input type="text" id="value_id" size="40" />
        <div id="printField"></div>
    </div>
</body>

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


IEのキャッシュハンドリングについて調べてみました。

お仕事のほうで、こんな依頼がありました。
「イントラのポータルサイトに毎日社員全員がアクセスして欲しい。ただ、PC起動時(スタートアップ)にブラウザを起動してポータルを見せようとすると、社員の出社時間帯にアクセスが集中してサーバに負荷がかかる。ので、とある時間帯にアプリケーションがIEのキャッシュを調べ、ポータルにアクセスしていないようだったらメッセージをポップしてポータルの閲覧を促したい」
というものです。
             ____
           /      \
          / ─    ─ \  ないない
        /   (●)  (●)  \
        |      (__人__)     |
         \     ` ⌒´    ,/
 r、     r、/          ヘ
 ヽヾ 三 |:l1             ヽ
  \>ヽ/ |` }            | |
   ヘ lノ `'ソ             | |
    /´  /             |. |
    \. ィ                |  |
        |                |  | 
そんな依頼メールを読んでモニタにウーロン茶噴き付けそうになりましたが、お仕事なので一応キャッシュのハンドリングを調べてみました。すると[HOWTO] Visual C# .NET で WebBrowser コントロールをホストするアプリケーションからキャッシュをクリアする方法というのを発見しました。ソースも載っているのですが、読むと FindFirstUrlCacheEntry という Win32API を使えば、キャッシュファイルの情報を INTERNET_CACHE_ENTRY_INFOA 構造体でもらえるらしいです。なるほど。
IntPtr lpszSourceUrlName;	// で URLなんかを参照して 
FILETIME LastAccessTime;	// でラストアクセスタイムが引けると。
FindFirstUrlCacheEntryを使ったアプリケーションの用途をぐぐってみると大抵キャッシュのクリアなのですが、こんな使い方で実装することになるとは。それにしても、エンドユーザにはこんな常駐アプリ作ったやつ誰だー!なんてすげぇ嫌われそうだなぁ。バグなんか作りこんじゃったら「ポータル見てるって言うのにうざったいメッセージがあがるんだけど」なんて問合せがありそうですね。どうみてもマルウェアです本当にありがとうございました。
代替案考えておこうかなぁ。

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


ExtJSのフォームウィジェットとサブミットの方法

extjsform2.PNG 以前のエントリにExtJSのサブミットの方法を試行錯誤してやってみたというものがありましたが、完全に的をはずしていたので改めてポストします。
ページからページへ情報を渡すためにフォームタグにテキストエリアとか、ボタンとか色々配置して表現したりしますが、ExtJSのウィジェットでフォームパネル( Ext.form.FormPanel )というものを持っていますので、こいつを使ってみます。 examples\form にサブミット(アクション)のサンプルが無いってのはどうよ?とは思いますが、ちゃんと隅から隅まで見てません。誰かに「あるよー」なんて言われたら恥の上塗りなので、ごちゃごちゃ言わずに説明してみます。
前回説明したのは、リッチテキストのサブミットですが、フィールドをどう表現するのかは xtype で決まっているみたいだと書きました。以下は xtype のリストです。Form components を見ていただくとフォームフィールドとして簡単に表現できるコンポーネントがたくさんあります。頑張れば grid (の中身)もポストできるってのはすごいですよね。エクセルシートみたいなフォームをポスト出来たりしたらウェブのフォームと言うかほとんどデスクトップアプリケーションですね。
xtype            Class
-------------    ------------------
box              Ext.BoxComponent
button           Ext.Button
colorpalette     Ext.ColorPalette
component        Ext.Component
container        Ext.Container
cycle            Ext.CycleButton
dataview         Ext.DataView
datepicker       Ext.DatePicker
editor           Ext.Editor
editorgrid       Ext.grid.EditorGridPanel
grid             Ext.grid.GridPanel
paging           Ext.PagingToolbar
panel            Ext.Panel
progress         Ext.ProgressBar
splitbutton      Ext.SplitButton
tabpanel         Ext.TabPanel
treepanel        Ext.tree.TreePanel
viewport         Ext.ViewPort
window           Ext.Window

Toolbar components
---------------------------------------
toolbar          Ext.Toolbar
tbbutton         Ext.Toolbar.Button
tbfill           Ext.Toolbar.Fill
tbitem           Ext.Toolbar.Item
tbseparator      Ext.Toolbar.Separator
tbspacer         Ext.Toolbar.Spacer
tbsplit          Ext.Toolbar.SplitButton
tbtext           Ext.Toolbar.TextItem

Form components
---------------------------------------
form             Ext.FormPanel
checkbox         Ext.form.Checkbox
combo            Ext.form.ComboBox
datefield        Ext.form.DateField
field            Ext.form.Field
fieldset         Ext.form.FieldSet
hidden           Ext.form.Hidden
htmleditor       Ext.form.HtmlEditor
numberfield      Ext.form.NumberField
radio            Ext.form.Radio
textarea         Ext.form.TextArea
textfield        Ext.form.TextField
timefield        Ext.form.TimeField
trigger          Ext.form.TriggerField
サブミットするときに必要になるのは、送信先の URL と送信するフィールド(名)とボタンになります。(実装に依存します)この3つをソースで見ていきたいと思います。
まず、フォームは Ext.FormPanel で作って、

送信先URLは
url:'hoge.php'で指定してあげます。

フィールド名は
name:'field1'で決まります。ポスト先はこのフィールド名で値をもらうことになります。
PHPだと$_POST[ "field1" ];こんな感じです。

最後にボタンに割り当てるのがハンドラです。以前はアクションを割り当てたらできたよーみたいなことを書きました。もちろんアクションでも出来ますが、非同期で値を渡したい場合は以下のようなハンドラをボタンに割り当てるといいみたいです。
handler:function() {
    myForm.getForm().submit({ 
        success:function( form, action ) {},
        failure:function( form, action ) {}
    });
}
myForm は FormPanel のインスタンスです。 getForm() で BasicForm を返すのでそいつの submit() を使うことになります。このハンドラをボタンに割り当ててあげます。
buttons: [{
    text: '送信', handler:function() {
        myForm.getForm().submit({
            success:function(form, action) {},
            failure:function(form, action) {}
        });
    }
}]
フォームとサブミットのサンプルソースは以下になります。
Ext.onReady( function(){
    var myForm = new Ext.FormPanel({
        url:'hoge.php',
        labelWidth: 75,
        frame:true,
        title: 'テストフォーム',
        bodyStyle:'padding:5px 5px 0',
        width: 350,
        defaults: { width: 230 },

        // デフォルトのフィールドを textfield とします
        defaultType: 'textfield',

        items: [{
                fieldLabel: 'First Name',
                name: 'first',
                allowBlank:true
            },{
                fieldLabel: 'Last Name',
                name: 'last'
            },{
                fieldLabel: 'Company',
                name: 'company'
            },{
                fieldLabel: 'Email',
                name: 'email',
                // vtype:'email'でメールのバリデーションチェックがかかるようです。
                vtype:'email'
            }
        ],

        buttons: [{
            text: '送信',handler:function() {
                myForm.getForm().submit({
                    success:function( form, action ) {
                        // echo print_r($_POST, 1); on hoge.php
                        // ポストしたパラメータと値を見れます。
                        alert( action.response.responseText );
                    },
                    failure:function( form, action ) {
                        // emailのバリデーションチェックで送信できない場合
                        // hostに送信できない場合なんかはこっちにきます
                        alert( action.failureType );
                    }
                });
            }
        }]
    });
    myForm.render( document.body );

});

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


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

open all | close all

リファラから検索


サイト内検索