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

2012.09.18

第5回の記事ではセルの入力値を数値以外はエラーにし、数値の場合にデータベースへアップデートするところまでを動かしてみました。

次に下段グリッドでソートができるようにしたいと思います。下段jqGridの列タイトルをクリックした際にURLパラメータとして sidx と sord が渡されてcfcomponentが呼び出されます。なのでそのURL変数をcfcomponentのgetinfo_bottom内で処理します。変更後のcfcomponent(GetData_sample.cfc)は以下のようにしました。

	<cffunction name="getinfo_bottom" access="remote" output="false" returnformat="json">

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

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

	    <!--- ソート対象カラムが渡せれてきた場合にsqlにorder byを追加する --->
	    <cfif IsDefined("url.sidx") and #url.sidx# is not "">
	    	<cfset sql = #sql# & " order by " & #url.sidx#>
	    <cfelse>
	    	<cfset sql = #sql# & " order by ID">
	    </cfif>

	    <!--- 昇順か降順の指定を取得する --->
	    <cfif IsDefined("url.sord") and #url.sord# is not "">
	    	<cfset sql = #sql# & " " & #url.sord#>
	    </cfif>

		<cfquery datasource="sample" name="q">
			SELECT ID,F_TIME,Q1,Q2,Q3,Q4,F_TOTAL FROM sample_bottom
           		#preserveSingleQuotes(sql)#
		</cfquery>

		<cfloop query="q">
			<cfset f_cast[currentrow] = { id=#ID#,cell=[#ID#, '#F_TIME#', '#Q1#', '#Q2#', '#Q3#', '#Q4#', '#F_TOTAL#'] }>
		</cfloop>
		<cfset str = {total=1, page=1, records=#q.recordcount#, rows=f_cast}>
        <cfreturn str />
	</cffunction>

このcfcomponentの変更により、タイトル列をクリックする毎に昇順/降順でグリッドの表示が並び替えられます。
次に下段グリッドにF_TOTALのカラムがあって、セル編集したらそれに合わせて合計金額を自動計算させたいと思います。
自動計算というよりセル編集を行ってデータベースへのアップデートが終わった後、そのIDを持つ行を再度selectしてQ1,Q2,Q3,Q4のsumを取得し、合計金額をアップデートさせると言う半ば強引なやり方です。もっといいやり方があると思いますが、、、

以下に強引な手法のcfcomponent(SetData_sample.cfc)をサンプルとして載せておきます。

<cfcomponent displayname="SetInfoMgr" output="false">
	<cffunction name="setinfo_bottom" access="remote" output="true" returnType="boolean">
		<cfset str = "">

		<!--- POSTされてきた値が数値でない場合はupdateせずに未処理で抜ける --->
		<cfif isDefined("form.Q1") and #IsNumeric(form.Q1)#>
			<cfset str = " set Q1=" & #form.Q1#>
		</cfif>

		<cfif isDefined("form.Q2") and #IsNumeric(form.Q2)#>
			<cfset str = " set Q2=" & #form.Q2#>
		</cfif>

		<cfif isDefined("form.Q3") and #IsNumeric(form.Q3)#>
			<cfset str = " set Q3=" & #form.Q3#>
		</cfif>

		<cfif isDefined("form.Q4") and #IsNumeric(form.Q4)#>
			<cfset str = " set Q4=" & #form.Q4#>
		</cfif>

		<cfset sqlstring = #str# & " where ID=" & #form.id#>

		<cfif #form.oper# is "edit">
			<cfquery name="upd_bottom" datasource="sample">
				update sample_bottom #preserveSingleQuotes(sqlstring)#
			</cfquery>

			<!--- アップデート後にトータル金額を求めて合計値を再度アップデートする --->
			<cfquery name="sel_money" datasource="sample">
				select sum(IFNULL(Q1,0)+IFNULL(Q2,0)+IFNULL(Q3,0)+IFNULL(Q4,0)) as total_sum from sample_bottom where ID=#form.id#
			</cfquery>

			<cfquery name="upd_total" datasource="sample">
				update sample_bottom set F_TOTAL = #sel_money.total_sum# where ID=#form.id#
			</cfquery>

			<cfreturn true />
		<cfelse>
			<cfreturn false />
		</cfif>
	</cffunction>

</cfcomponent>

下記は下段グリッドのサンプルソースです。

$(".jgrid_bottom").jqGrid({
      url:'GetData_sample.cfc?method=getinfo_bottom',
      datatype: 'json',
      mtype: "GET",
      formatter : {
      number : {decimalSeparator:".", thousandsSeparator: ",", decimalPlaces: 2, defaultValue: '0.00'}
      },
      colModel :[
      {name:'ID',index:'ID', hidden:true},
      {name:'F_TIME',index:'F_TIME', align:"left", editable:false},
      {name:'Q1',index:'Q1', align:"right", formatter:'number', editable:true, editrules:{number:true}},
      {name:'Q2',index:'Q2', align:"right", formatter:'number', editable:true, editrules:{number:true}},
      {name:'Q3',index:'Q3', align:"right", formatter:'number', editable:true, editrules:{number:true}},
      {name:'Q4',index:'Q4', align:"right", formatter:'number', editable:true, editrules:{number:true}},
      {name:'F_TOTAL',index:'F_TOTAL', align:"right", formatter:'number', editable:false}
      ],
      pager: $(".jgpager_bottom"),
      cellEdit: true,
      cellsubmit: "remote",
      cellurl: "SetData_sample.cfc?method=setinfo_bottom",
      afterSaveCell: save_after_reload, //今回追加した行
      rowNum:10,
      rowList:[10,20,30],
      sortorder: "desc",
      viewrecords: true,
      imgpath: 'themes/basic/images',
      height: 180,
      caption: 'jqGridサンプル Bottom',
      jsonReader: {
      root: "ROWS",
      page: "PAGE",
      total: "TOTAL",
      records: "RECORDS",
      id: "ID",
      cell: "CELL"
      }
      });

      //CELL編集された後に呼び出されるjavascript関数
      function save_after_reload(rowid, cellname, value, iRow, iCol)  { 
            $(".jgrid_bottom").trigger("reloadGrid");
      }

セル編集が終わったら save_after_reload が実行されて、下段グリッドのリロードが行われ、トータル金額の部分もアップデートされた値で表示されるようになります。