ColdFusion 10 + jqGridを使ってみる(その3)

2012.09.13

前回に引き続き第3回目はjqGridのリロードを使ってみます。form要素も出てきますのでここはBootstrap.jsを使ってform要素を配置してみたいと思います。

ColdFusionで提供されているお手軽なautosuggest機能を使ってD/Bから取得したデータをプルダウン項目に設定するようにしましたが、どうやら2バイト入力には対応していないようです。(イベントが走らない)で、input項目に『サンプル』を入力した状態でカーソルを左にずらすとイベントが走って候補が出来てきますが、、、cfajax.jsのバグですかね???と言う事でautosuggest機能を使う場合は対象が半角英数の場合をお勧めします。

cf10_cfgrid.cfmのサンプルソース

<cfsetting enablecfoutputonly="true">
<cfcontent type="text/html; charset=utf-8">
<cfprocessingdirective pageEncoding="utf-8" suppressWhitespace="true">
<cfoutput>
<!DOCTYPE html>
<html lang="ja">
<head>
      <meta charset="utf-8">
      <title>ColdFusion 10 + jqGrid サンプル</title>
      <link rel="stylesheet" type="text/css" media="screen" href="css/jquery-ui-1.8.19.custom.css" />
      <link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" />
      <link href="css/bootstrap.css" rel="stylesheet">
      <link href="css/bootstrap-responsive.min.css" rel="stylesheet">

      <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
      <script type="text/javascript" src="js/jquery-ui-1.8.19.custom.min.js" ></script>
      <script type="text/javascript" src="js/jquery.jqGrid.min.js" ></script>
      <script type="text/javascript" src="js/i18n/grid.locale-ja.js" ></script>

      <!--- ページロード時にjqGridを生成する --->
      <script type="text/javascript">
      $(document).ready(function(){
      $(".jgrid").jqGrid({
      url:'GetData_sample.cfc?method=getinfo',
      datatype: 'json',
      formatter : {
      integer : {thousandsSeparator: " ", defaultValue: '0'},
      number : {decimalSeparator:".", thousandsSeparator: " ", decimalPlaces: 2, defaultValue: '0.00'},
      currency : {decimalSeparator:".", thousandsSeparator: " ", decimalPlaces: 2, prefix: "", suffix:"$", defaultValue: '0.00'}
      },
      colModel :[
      {name:'ID',index:'ID'},
      {name:'Remark',index:'Remark'},
      {name:'RealName',index:'RealName', editable:true},
      {name:'ProjectName',index:'ProjectName', align:"left", editable:true},
      {name:'CustomerName',index:'CustomerName', align:"left", editable:true},
      {name:'Resale',index:'Resale', formatter:'number', formatoptions:{decimalSeparator:".", thousandsSeparator: ",", decimalPlaces: 2},align:"right", editable:true}
      ],
      pager: $(".jgpager"),
      //cellEdit: true,
      rowNum:10,
      rowList:[10,20,30],
      sortorder: "desc",
      viewrecords: true,
      height: 180,
      caption: 'jqGridサンプル',
      jsonReader: {
      root: "ROWS",
      page: "PAGE",
      total: "TOTAL",
      records: "RECORDS",
      id: "ID",
      cell: "CELL"
      }
      });

      });
      </script>

</head>
<body>

      <div class="row-fluid" style="background-color:mintcream;">

            <div class="span12" style="padding-top : 5px;">
                  <div>
                        <cfform name="inclimental_search" class="form-inline">
                              <cfinput type="text" class="input-small" placeholder="ProjectName" name="ProjectName" id="ProjectName" autosuggest="cfc:brogsample.get_mk_code({cfautosuggestvalue})" />
                              <cfinput type="text" class="input-large" placeholder="CustomerName" name="CustomerName" id="CustomerName" autosuggest="cfc:brogsample.get_mk_name({cfautosuggestvalue})" />
                              <label class="control-label" style="padding-top : 5px;">※cfinput autosuggest機能は2バイト入力時にはイベントが飛ばない?</label>
                              <!--- 検索ボタンクリックでjqGRIDを呼び出す --->
                              <input type="button" value="検索" class="btn btn-info button_1">
                        </cfform>
                  </div>
            </div>

            <div class="span12" style="padding-top:5px;">
                  <!--- jqGrid表示 --->
                  <div class="row-fluid" style="background-color:mintcream;">
                        <div id="d_grid1" style="padding-top:5px;">
                              <table id="list" class="jgrid"></table>
                              <div id="pager" class="jgpager">
                              </div>
                        </div>
                  </div>
            </div>
      </div>

</body>
</html>
</cfoutput>
</cfprocessingdirective>      
<cfsetting enablecfoutputonly="false">

cfinputタグ autosuggest機能用のサンプルコード(brogsample.cfc)

<cfcomponent> 

    <cffunction name="get_mk_code" access="remote" returntype="array" output="false">

        <cfargument name="suggestvalue" required="true">

        <!--- この関数は選択候補を配列として返します。 --->
        <cfset var namearray = ArrayNew(1)>

        <cfquery name="q" datasource="sample">  
            SELECT Distinct(RealName)
            FROM sample 
            WHERE RealName like '%#suggestvalue#%'
            order by RealName asc
        </cfquery>  

        <!--- クエリーを配列に変換します。 --->
        <cfloop query="q">
            <cfset arrayAppend(namearray, q.RealName)>
        </cfloop>
        <cfreturn namearray>
    </cffunction> 

    <cffunction name="get_mk_name" access="remote" returntype="array" output="false">

        <cfargument name="suggestvalue" required="true">

        <!--- この関数は選択候補を配列として返します。 --->
        <cfset var namearray1 = ArrayNew(1)>

        <cfquery name="q1" datasource="sample">  
            SELECT Distinct(ProjectName)
            FROM sample 
            WHERE ProjectName like '%#suggestvalue#%'
            order by ProjectName asc
        </cfquery>  

        <!--- クエリーを配列に変換します。 --->
        <cfloop query="q1">
            <cfset arrayAppend(namearray1, q1.ProjectName)>
        </cfloop>
        <cfreturn namearray1>
    </cffunction> 

</cfcomponent>

実行した結果は以下の通り。2バイトのautosuggest機能はカーソルを左に動かすとプルダウンが生成されます。CRキー(キャリッジリターンキー)でイベント走ってくれると一番いいんですけどね~残念。隠し機能として一応消さずに置いておきます。

jqGridのpager部分の表示がBootstrap.cssでselect要素に対してpadding: 4px 6px;が効いてしまってプルダウン要素内の文字が欠けてしまってます。見栄えは後で調整するとして、Boostrap.jsは見た目が綺麗になるのでやはりいいですね。

前置きはこれくらいにしておいて、目的であるinput項目で入力された値でjqGridに表示されている内容を更新してみたいと思います。jqGridのリロード時にurlの部分を動的に書き換えてからjqGridを呼び出せばおそらくinput項目で入力された値で絞り込みをして再表示できると思うのでやってみます。

cf10_cfgrid.cfmの56行目に検索ボタンをクリックされた時に実行するjavascriptのコードを追加します。

//検索ボタンをクリックされた場合の処理
      $(".button_1").click(function(){
            var PN = encodeURI(inclimental_search.ProjectName.value);
            var CN = encodeURI(inclimental_search.CustomerName.value);
            //jqGridをリロードする
            $(".jgrid").setGridParam({url:"GetData_sample.cfc?method=getinfo&PN=" + PN + "&CN=" + CN}).trigger("reloadGrid");
      });

3行目、4行目でinputフィールドに入力されている値を取得し、ここでは一応2バイトの文字が入ってくるのでエンコードしています。
6行目でsetGridParamを使ってcfcomponentで呼び出す際にURL変数を付けて呼び出しています。あとはtriggerでjqGridを再読み込みします。

inputフィールドで入力された値をcfcomponent側に渡した際に検索条件となるように変更します。(GetData_sample.cfc)

<cfcomponent displayname="GetInfoMgr" output="false">
	<cffunction name="getinfo" access="remote" output="false" returnformat="json">

        <cfset invoices = ArrayNew(1) />
        <cfset sql = "">

        <cfif IsDefined("url.PN") and #url.PN# is not "">
            <cfset sql = "and ProjectName like '%" & #url.PN# & "%'">
        </cfif>

        <cfif IsDefined("url.CN") and #url.CN# is not "">
            <cfset sql = #sql# & "and CustomerName like '%" & #url.CN# & "%'">
        </cfif>

        <cfif sql is not "">
            <cfset sqllen = len(sql)>
            <cfset sql = "where " & mid(sql,5,sqllen-4)>
        </cfif>

        <cfquery datasource="sample" name="q">
            SELECT ID,Remark,RealName,ProjectName,CustomerName,Resale FROM sample
            <cfif sql is not "">
                #preserveSingleQuotes(sql)#
            </cfif>
        </cfquery>

        <cfloop query="q">
            <cfset invoices[currentrow] = { id=#ID#,cell=[#ID#,'#Remark#', '#RealName#', '#ProjectName#', '#CustomerName#' , '#Resale#'] }>
        </cfloop>
        <cfset str = {total=1, page=1, records=#q.recordcount#, rows=invoices}>
        <cfreturn str />
        </cffunction>
</cfcomponent>

実行した時のスクリーンショットは以下です。期待通り、inputフィールドに入力した値を反映した一覧が表示されました。

次回はjqGridで選択された行(クリックされた行)の値を取得して、その取得した値をもう一つのjqGridに引き渡し、上のグリッドと下のグリッドを連動させるということを試してみたいと思います。