jqGrid 實用技巧 (十六) 關於日期

[anti-both]

用 得 jqGrid,九 成 九 都 有 用 Database。用 得 Database,就 無 法 避 免 會 使 用 到 「日 期 」這 種 資 料 形 態 。今 天 筆 者 就 把 關 於 日 期 的 幾 個 jqGrid 技 巧 介 紹 給 各 讀 者 吧 。

1
2
3
4
5
6
7
...
colModel :[
 ....
 {name:'po_date',index:'po_date',editable:true,edittype:'text'},
 ....
],
...

假 設 我 們 的 jqGrid 裡 面 有 一 個 叫 po_date 的 column,對 應 Mysql 裡 面 一 個 date 形 態 的 field。Mysql 用 的 日 期 標 準 是 yyyy-mm-dd,所 以 本 篇 亦 全 部 用 這 個 格 式 為 標 準 。上 面 的 colModel 是 完 全 空 白 ,什 麼 也 沒 有 。我 們 看 看 如 何 一 步 步 去 完 善 它 。

jqGrid 的 ColModel 其 實 就 有 一 個 property 叫 datefmt,是 指 明 日 期 格 式 的 。預 設 值 就 是 ISO Date (Y-m-d),剛 好 乎 合 我 這 個 例 子 的 需 要 ,於 是 我 就 不 用 特 意 去 改 變 它 。不 過 這 個 datefmt 其 實 很 重 要 ,因 為 column sorting 和 validation 都 是 靠 它 。所 以 如 果 你 不 是 用 預 設 值 的 話 ,你 必 須 要 去 設 定 好 它 。

日 期 資 料 ,一 般 多 數 會 用 text input 來 做 輸 入 ,所 以 上 面 的 edittype 就 設 定 為 text。由 於 我 們 使 用 特 定 的 日 期 格 式 ,那 個 長 度 是 固 定 的 ( 10位 文 字 ),所 以 我 們 可 以 加 入 相 關 的 控 制 。

1
2
3
4
5
6
7
...
colModel :[
 ....
 {name:'po_date',index:'po_date',editable:true,edittype:'text',editable:true, editoptions:{size:10,maxlength:10}},
 ....
],
...

在 這 個 例 子 ,因 為 從 Mysql 拿 出 來 的 日 期 就 很 完 整 ,所 以 是 不 需 要 用 formatter 的 。不 過 有 時 候 ,資 料 庫 的 資 料 並 不 整 齊 ,例 如 沒 有 輸 入 日 期 的 value 全 是 0000-00-00,那 我 們 就 可 以 用 簡 單 的 custom formatter 去 整 理 一 下 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
colModel :[
 ....
 {name:'po_date',index:'po_date',editable:true,edittype:'text',editable:true, editoptions:{size:10,maxlength:10},formatter:fixDate},
 ....
],
...
function fixDate(cellvalue, options, rowObject){
 if (cellvalue!='0000-00-00') {
  return cellvalue;
 } else {
  return "";
 }
}
...

 當 然 ,我 們 也 可 以 用 jqGrid 內 建 的 formatter: ‘date’。但 要 注 意 的 是 formatoptions 裡 面 的 預 設 值 適 不 適 用 。簡 單 的 說 ,我 們 至 少 要 看 看 srcformat 和 newformat,預 設 值 是 “Y-m-d” 和 “d/m/Y”。所 以 如 果 我 們 什 麼 都 不 設 定 的 話 ,在 我 上 面 的 例 子 中 ,日 期 就 會 由 2014-12-31 自 動 變 成 31/12/2014。

1
2
3
4
5
6
7
...
colModel :[
 ....
 {name:'po_date',index:'po_date',editable:true,edittype:'text',editable:true, editoptions:{size:10,maxlength:10},formatter:'date',formatoptions:{srcformat:'Y-m-d',newformat:'Y-m-d'}},
 ....
],
...

 

在 我 的 例 子 中 ,資 料 庫 的 日 期 格 式 ,和 我 想 顯 示 出 來 的 日 期 格 式 ,都 是 ‘Y-m-d’。但 大 家 不 要 把 這 個 formatoptions 裡 面 的 newformat,和 colModel 裡 面 的   datefmt 搞 亂 了 。datefmt 是 指 定 資 料 庫 拿 回 來 的 日 期 格 式 ( 就 像 srcformat ),newformat 則 是 在 Grid 裡 面 顯 示 的 日 期 格 式 。

然 後 就 是 data validation,這 當 然 就 是 在 editrules 裡 面 設 定 。首 先 當 然 是 {date:true},它 會 依 據 colModel 裡 面 的 datefmt 來 檢 查 你 輸 入 的 日 期 格 式 。另 外 ,{required:true/false} 就 是 允 不 允 許 輸 入 空 白 。

1
2
3
4
5
6
7
...
colModel :[
 ....
 {name:'po_date',index:'po_date',editable:true,edittype:'text',editable:true, editoptions:{size:10,maxlength:10},editrules:{date:true,required:true},formatter:'date',formatoptions:{srcformat:'Y-m-d',newformat:'Y-m-d'}},
 ....
],
...

如 果 單 是 要 validate 輸 入 的 是 不 是 日 期 ,內 建 的 editrules 就 很 夠 了 。不 過 如 果 你 想 控 制 可 以 輸 入 日 期 的 範 圍 ,就 要 自 己 寫 條 custom_func 了 。( 內 建 的 minValue / maxValue 只 是 針 對 數 值 的 )

講 到 日 期 輸 入 ,當 然 不 得 不 提 jQuery UI 的 Datepicker。要 在 jqGrid 裡 面 使 用 Datepicker 實 在 是 太 簡 單 不 過 ,只 要 在 editoptions 的 dataInit 設 定 一 條 custom Function。

1
2
3
4
5
6
7
8
9
10
11
...
colModel :[
 ....
 {name:'po_date',index:'po_date',editable:true,edittype:'text',editable:true, editoptions:{size:10,maxlength:10,dataInit:getDate},editrules:{date:true,required:true},formatter:'date',formatoptions:{srcformat:'Y-m-d',newformat:'Y-m-d'}},
 ....
],
...
function getDate(el) {
 $(el).datepicker({dateFormat:"yy-mm-dd"});
}
...

以 前 jqGrid 的 documentation 還 有 使 用 datepicker 要 加 setTimeout 的 一 說 ,但 現 在 應 該 沒 有 這 個 需 要 了 。

 

1
2
3
4
5
6
7
...
function getDate(el) {
 setTimeout(function() {
  $(el).datepicker({dateFormat:"yy-mm-dd"});
 }, 200);
}
...

大 家 要 注 意 ,datepicker 的 預 設 格 式 是 ‘mm/dd/yy’,所 以 在 我 的 例 子 中 要 把 日 期 格 式 轉 為 ‘yy-mm-dd’。

jqGrid Datepicker

jqGrid Datepicker

如 果 我 們 想 要 在 form editing 的 add new 裡 面 設 定 日 期 的 預 設 值 ,我 們 可 以 在 afterShowForm event 裡 面 設 定 。下 面 看 看 navGrid method。

1
2
3
4
5
6
7
8
9
10
...
$("#grid_id").jqGrid('navGrid','#grid_pager',
 {parameters},
 {}, // prmEdit
 {}, // prmAdd
 {}, // prmDel
 {}, // prmSearch
 {}  // prmView
);
...

一 般 所 謂 的 預 設 值 只 會 在 Add New 時 才 有 ,所 以 我 們 要 只 要 修 改 prmAdd 裡 面 的 parameters。

1
2
3
4
5
6
7
8
9
10
11
12
...
$("#grid_id").jqGrid('navGrid','#grid_pager',
 {parameters},
 {}, // prmEdit
 {afterShowForm: function(formid) {
  $('#po_date').val($.datepicker.formatDate('yy-mm-dd', new Date()));
 }}, // prmAdd
 {}, // prmDel
 {}, // prmSearch
 {}  // prmView
);
...

在 form editing 裡 面 ,每 一 個 column 會 自 動 生 成 一 個 和 column name 相 同 的 input,所 以 直 接 用 #po_date 就 可 以 選 擇 我 們 要 的 input。然 後 我 們 再 用 datepicker 來 取 得 一 個 已 經 format 好 的 日 期 。上 例 中 的 預 設 日 期 就 是 「今 天 」。

最 後 ,我 們 也 來 說 一 點 點 search 吧 。日 期 field,多 數 情 況 只 需 要 equal,less than and equal to,greater than and equal to 三 個 就 夠 了 。Searchoptions 也 一 樣 可 以 設 定 dataInit 來 使 用 datepicker 幫 助 輸 入 。Searchrules 也 一 樣 可 以 {date:true} 之 類 的 。

最 後 把 search 也 加 入 colModel 之 後 ,整 體 看 起 來 就 像 如 下 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
$("#grid_id").jqGrid({
 ...
 colModel :[
  ....
  {name:'po_date',index:'po_date',editable:true,edittype:'text',editable:true, editoptions:{size:10,maxlength:10,dataInit:getDate},editrules:{date:true,required:true},formatter:'date',formatoptions:{srcformat:'Y-m-d',newformat:'Y-m-d'},search:true, stype:'text',searchoptions:{sopt:['eq','le','ge'],dataInit:getDate},searchrules:{date:true,required:true},align:'center'},
  ....
 ],
 ...
});
...
$("#grid_id").jqGrid('navGrid','#grid_pager',
 {add:true},
 {}, // prmEdit
 {afterShowForm: function(formid) {
  $('#po_date').val($.datepicker.formatDate('yy-mm-dd', new Date()));
 }}, // prmAdd
 {}, // prmDel
 {}, // prmSearch
 {}  // prmView
);
...
function getDate(el) {
 $(el).datepicker({dateFormat:"yy-mm-dd"});
}
...

 

ctleung張先生,男性,肖龍。
職業:I.T. Consultant
簡介:不好好讀書;七尺差五寸,手長過膝,雙耳垂肩;性寬和,寡言語,喜怒不形於色。據說少時曾斬白蛇於鳳凰山下……

This entry was posted in jqGrid and tagged , , , , . Bookmark the permalink.

2 Responses to jqGrid 實用技巧 (十六) 關於日期

  1. 李小龍 says:

    把您的JQGRID系列看完,真是很棒, 希望能再繼續造福網友! 請問若要做到keyboard only, 讓專業使用者盲打, 用inline edit會不會比form edit及cell edit好用又可以很有效率的輸入? 如果能夠, 希望了解您在JQGRID的keyboard only設計心得。

    • C.T. Leung says:

      在 Web Application 做 Keyboard only 好像有點…吃力不討好的樣子,所以我自己沒有嘗試過。很不好意思實在談不上有心得。

      不過,自從 jqGrid 4.0 就加入了 bindKeys method,只要加入一句

      jQuery(“#list”).jqGrid(‘bindKeys’);

      就自動增加了用上下鍵選取一行 row 的功能。你還可以在 bindKeys 裡面自定義 onEnter / onSpace / onLeftKey / onRightKey 等四個事件。例如我想像可以是 onEnter 就開始 edit 一筆記錄,Left / Right Key 就用來翻頁,諸如此類的。

      當然,在 edit 的時候,你可能要另外自己去綁定每個 input 的 keypress 事件來作進一步的控制。例如直接用 enter / arrow 跳去下一個 input 之類的。( 可以參考我 inline edit 那篇在 input 裡 delegate 一個 keypress event,又或者用 jqGrid editoptions 裡面就有的 dataEvents )

      在 jqGrid demo page 的 functionality 裡面有一個 keyboard navigation 的例子,功能不多 ( 其實是沒有功能 ),但可以參考看看。也可以去 google 一下 “jqGrid excel like editing”、”jqgrid arrow key navigation”之類的,參考參考別人的作法。

Leave a Reply to C.T. Leung Cancel reply

Your email address will not be published. Required fields are marked *