jqGrid 實用技巧 (五) Form Edit

好 不 容 易 ,終 於 寫 到 jqGrid 的 Form Edit。我 們 再 一 次 回 到 功 能 強 大 的 colModel。

...
colModel :[
....
{name:'name',index:'name',editable:true,edittype:'text',editoptions:{size:50,maxlength:100},editrules:{required:true}},
....
],
...

在 colModel 裡 面 ,跟 Form Edit 有 直 接 關 係 的 参 數 有 4 個 – editable、edittype、editoption 和 editrules。

editable,顧 名 思 義 ,就 是 設 定 這 個 欄 位 能 不 能 修 改 。預 設 值 是 false。如 果 是 editable:flase 的 話 ,該 欄 位 是 不 會 出 現 在 Edit Form 裡 面 的 。

edittype,就 是 Edit Form 裡 面 的 <input> Tag 的 種 類 。edittype 的 值 可 以 是  text,textarea,select,checkbox,password,button,image,file 和 custom。就 是 相 應 的 ,<input type=text>,<textarea></textarea>,<select></select> 等 等 在 表 單 裡 面 使 用 的 輸 入 項 。

editoptions,就 是 <input> Tag 裡 面 ,額 外 的  attributes。這 些 attributes 會 跟 據 edittype 而 有 所 不 同 。例 如 上 面 的 例 子 ,edittype 是 text,所 以 就 相 應 的 加 入 size 和 maxlength 參 數 。再 看 下 面 的 另 一 例 。

...
colModel :[
....
{name:'description',index:'description',editable:true,edittype:'textarea',editoptions:{rows:"5",cols:"50"},editrules:{required:true}},
....
],
...

由 於 edittype 是 textarea,所 以 size 和 maxlenght 都 不 會 生 效 。於 是 我 們 相 應 的 加 入 rows 和 cols 這 兩 個 textarea 相 關 的 參 數 。editoptions 也 是 設 定 select 的 option 的 地 方 。

...
colModel :[
....
{name:'enable',index:'enable',editable:true,edittype:'select',editoptions:{value:"0:正 常 ;1:停 用 "}},
....
],
...

另 外 ,editoptions 也 可 以 使 用 dataInit function(就 像 searchoptions 一 樣 ), 加 入 jQuery UI。在 下 例 中 我 就 使 用 了 jQuery UI 的 datepicker。

...
colModel :[
....
{name:'date',index:'date',editable:true,edittype:'text',editoptions:{dataInit:datePick,size:10,maxlength:10},editrules:{required:true,date:true}},
....
],
...
...
...
function datePick(elem){
$(elem).datepicker({ dateFormat: "yy-mm-dd" });
}
...

至 於 最 後 的 editrules,就 是 做 data validation 的 。jqGrid 本 身 已 經 包 含 了 很 多 常 用 的 data validation,令 開 發 者 節 省 了 很 多 時 間 。例 如 上 例 的 的 editrules:{required:true,date:true},意 思 就 是 「不 得 留 空 」和 「必 須 是 日 期 」。jqGrid 的 editrules 還 有  number,integer,minValue,maxValue,email,url,time,custom。

Data Validation

而 其 中 的 custom ,就 是 讓 開 發 者 在 jqGrid 本 來 的 data validation 不 夠 用 的 時 候 ,可 以 簡 易 的 新 增 自 定 義 的 data validation。請 看 下 例 。

...
colModel :[
....
{name:'pass',index:'pass',editable:true,edittype:"password",editrules:{required:true,custom:true, custom_func:checkPassword}},
....
],
...
...
function checkPassword(value, colname){
if (value.length < 8)
return [false,"Password too short"];
else
return [true,""];
}
...

這 是 一 個 使 用 者 密 碼 的 欄 位 ,筆 者 希 望 使 用 者 輸 入 的 密 碼 至 少 要 有 8 個 位 。首 先 ,我 們 在 editrules 加 入 custom:true,然 後 再 加 入 一 條 自 定 義 的 function,custom_func: checkPassword。自 定 義 function 的 參 數 value,就 是 使 用 者 輸 入 的 數 值 了 。value.length 就 是 value 字 串 的 長 度 ,少 於 8 的 話 ,我 們 就 傳 回 false,以 及 錯 誤 訊 息 ,這 個 錯 誤 訊 息 是 會 在 Edit Form 上 面 顯 示 給 使 用 者 的 。如 果 檢 查 之 後 是 正 確 的 話 ,就 傳 回 true。

Password too short

好 了 ,現 在 Form View,Form Edit,Form Search 我 們 都 獨 立 的 學 了 一 遍 。下 一 回 ,我 們 就 試 作 一 些 複 雜 一 點 的 欄 位 ,看 看 同 一 個 欄 位 的 colModel 在 夾 雜 了 View ,Edit,Search 等 等 之 後 會 變 成 什 麼 樣 子 。

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

21 Responses to jqGrid 實用技巧 (五) Form Edit

  1. Pippen says:

    你好, 看了你写的jqgrid的文章,有个问题想请教一下。
    我的数据列有一个唯一性约束,unique constraint。比如用户名注册的时候不能重复。
    如何在添加数据的时候验证用户名的唯一性呢?
    我想到的是使用自定义的custom_func来验证,但是并不知道具体怎么来验证。
    比如修改用户名的时候,也需要验证用户名是否已经存在。

    谢谢。

  2. tony says:

    請問一下:
    用form edit 修改資料後, 按submit,會進行存檔, 但是form edit的畫面依然存在,
    請問要如何在按submit後, 該form會關閉,
    謝謝!!

    • C.T. Leung says:

      這個很簡單。在 form editing 裡面有兩個 Properties: closeAfterAdd 和 closeAfterEdit。兩者的預設值都是 false。

      預設值是方便使用者一次過新增多筆資料,又或者修改多筆資料 [ edit 的時候可以用前後箭號移動到不同的 record ]。

      這個你只要在 pager 裡面修改就可以了。

      $("#list").jqGrid('navGrid','#pager',
        {edit:true,add:true,del:false,search:false,view:false},
        {closeAfterEdit:true},
        {closeAfterAdd:true},
        ....
      });
  3. tony says:

    又來請教了,
    請問一下, 我是用 form edit
    若欄位有 數量 . 單價 . 小計
    在 數量 及 單價 change Event 去計算 小計
    到這裡都 ok,
    再來要把 小計的數字 放入 “小計” 就不會了,
    上次 select 的動態選項 是以
    $(“#tr_field select.FormElement”).html(msg);
    的方式, 試了很多種方式, 依然無法
    所以…..
    如果 inline edit 不一樣作法, 也請一併賜教
    謝謝!!

    • C.T. Leung says:

      你能算出「小計」的值,但不會把它放到「小計」的 element 裡面,但怎麼「小計」會是用 select??不太可能吧….

      如果你真係有獨立的不同問題,你可以分開一題一題來問麼?例如:
      1. xxxxxx
      2. xxxxxx
      3. xxxxxx

      • tony says:

        sorry, 我是說上次動態 select 是用
        $(“#tr_field select.FormElement”).html(msg);
        的方式完成, 不是小計要用 select…
        而這次 的問題是要 塞 小計的值,
        我想 作法應該相當, 只是不知道 keyword為何…
        遵照指示:
        1. 在 form edit 中,如何將 100 塞給 total 的欄位?
        2. inline edit 方法一樣嗎?
        謝謝!!

        • C.T. Leung says:

          如果用最常見的 text input 來做例子。

          form editing

          form editing 的話,input 的 id 就是 colModel 裡面的 name。在我的例子中,colModel 的 name 是 remarks,所以 input 的 id 也就一樣是 remarks。

          所以寫法就是:
          $(‘#remarks’).val(subtotal);

          row editing

          至於 row editing 的話,input 的 id 就是 row id 再加上 colModel 裡面的 name。例子中 name 是 invdate,而該行的 row id 是 13,所以加起來就是 13_invdate。

          寫法也是完全一樣:
          $(‘#13_invdate’).val(subtotal);

          我個人覺得重點有兩個吧。

          第一,看來你要用一點點時間來學學 jquery。或許你不知道,但整個 jqGrid 都是用 jquery 寫出來的,沒有 jquery 就不會有 jqGrid。所以 jquery 是鐵定要學的。用 .val() 來設定 input 的值,正是基本中的基本,正常情況是不可能不知道的。而用什麼 id (或是其它方法) 來選取一個 element,更是 jquery 的重中之重。不搞清楚這些東西,jqGrid 是不會用得好的。

          第二,就是在上例中,在 row editing 要如何取得 row id ( 並且把它和 column name 組合成你要的 element id )。不過這亦是 jqGrid 一個十分基本的操作,我就不在此累贅了。

  4. tony says:

    你們真棒,
    .val() 這我知道,
    原先以為 jqgrid 設的 id , 可能會加上某些前碼,
    所以沒有以 name 來試, 東猜西猜…..
    沒想到就是 直接 以 name 為 id,
    不過也多了解了 row_id+_+name 是 inline edit 的 id
    真是受教….
    謝謝!!

  5. gavin says:

    請問,我在edit form或add form畫面時,因欄位多,有只打到一半,滑鼠不小心點了edit form以外的地方,整個edit form就不見了,前面打的字也不見了。
    是否有可以edit form,不會因這樣的情況而消失呢?

    • C.T. Leung says:

      其實這個在 jqGrid 的 documentation 就有講。你需要的是 jqModal plugin 和 jqGrid 的兩個設定。

      1. jqModal plugin :
      http://dev.iceburg.net/jquery/jqModal/
      下載之後當然就是引用啦。
      <script type="text/javascript" src="jqModal.js">

      2. jqGrid 的兩個設定 :
      jqModal:true,
      modal:true,
      它們要放在 form editing 的設定裡面,而不是 jqGrid 的設定裡面。而每一張 Form (add,edit,search,view) 的 modal 都是可以獨立設定的。
      $("#list").jqGrid('navGrid','#pager',
      {edit:true,add:true,del:false,search:true, view:true},
      {jqModal:true,modal:true}, //edit
      {jqModal:true,modal:true}, //add
      {}, //del
      {jqModal:true,modal:true}, //search
      {jqModal:true,modal:true} //view
      );

      設定了 modal 之後,Form 就不會因為你點選了外面的空白地方而 close 的了 ( 一定要 click “close” / “cancel” button 才會 close )。剛好見到網上有一個現成的 example ( 不是我做的!! ),也給你參考吧:
      http://www.ok-soft-gmbh.com/jqGrid/LocalFormEditing.htm

      • tony says:

        日前jqModal有更新, 若下載新版, 就不能用了…
        所以舊的可別丟了

        • C.T. Leung says:

          老兄, 可唔可以詳細些少?例如乜野版本(jqModal)同乜野版本(jqgrid/jquery)唔夾呀?新版講既係幾新?舊版講既又係幾舊呀?謝謝。

  6. janice says:

    若按了編輯後,需要執行一組後端程式產生資料,然後將資料用dialog呈現在另一個畫面
    請問該怎麼做呢?

    • C.T. Leung says:

      你按的「編輯」,應該是指 pager 裡面那個 edit button 吧?但那個 edit 明明就是 form edit 專用的,你的這個改變也太大了吧,嘿嘿。如果是我的話,我會直接 hide 了原來的那個 edit button,然後自己新增一個 custom button ( 當然可以用回原來 edit 的 icon )。

      那個你新增的 custom button,你想用它來幹什麼都可以了吧?哈哈哈 ( 你要的無非就是 ajax + dialog 吧,應該不會有什麼難度… )。

  7. mia says:

    不好意思請問一下,如果我的欄位在編輯時不能修改,我把editable設為false但是新增的時候又想要讓這個欄位可以填寫要怎麼做呢?

    • C.T. Leung says:

      我自己的話,我會使用另一種方法,而不會把 editable 設定為 false。

      editable:true, editoptions:{readonly:'readonly'}

      在 colModel 裡,我會把 editable 設定為 true,然後在 editoption 裡設定 readonly。這樣的話,在 edit form 裡面它仍然會顯示,但會變為 readonly,不能修改。

      然後在 add form 的 afterShowForm event 加入

      $('#column_name').removeAttr('readonly');

      並且在 edit form 的 afterShowForm event 加入

      $('#column_name').attr('readonly','readonly');

      完成之後,那你就可以在 edit 時 readonly,但 add new 時就變回 editable 了。

  8. mia says:

    不好意思又來叨擾您了,想請問一個問題是,
    我在我的jqGrid有寫
    onSelectRow的function,接著我用程式去控制選取其中一列
    jQuery(grid_selector).jqGrid(‘setSelection’,1, true);
    他並沒有觸發onSelectRow的function。
    請問如果想要觸發onSelectRow的function我該怎麼做比較好呢?

    • C.T. Leung says:

      grid.jqGrid('setSelection',rowid,true);

      以上確實是正確的寫法,而且絕對會 trigger onSelectRow event。

      我想很有可能是你程式碼中的其他部分寫錯了。

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>