jqGrid 實用技巧 (八) 在 grid 裡面自定義按鈕

很 多 時 候 ,我 們 都 會 在 grid 裡 面 加 一 些 按 鈕 (button),方 便 使 用 者 快 速 地 做 一 些 修 改 。這 一 回 ,筆 者 就 在 jqGrid 上 面 實 作 一 個 自 定 義 按 鈕 給 大 家 參 考 。

這 一 次 的 例 子 ,是 在 jqGrid 加 入 「上 移 」和 「下 移 」按 鈕 ,以 方 便 使 用 者 快 速 地 更 改 jqGrid 上 面 的 資 料 的 次 序 。

jqGrid custom button

為 了 實 現 使 用 者 自 由 更 改 次 序 的 目 的 ,所 以 筆 者 在 資 料 庫 增 加 了 顯 示 次 序 的 欄 位 (displayorder)。當 使 用 者 在 displayorder=4 的 那 一 行 資 料 按 「上 移 」時 ,該 行 資 料 的 displayorder 就 會 變 為 3,而 原 來 displayorder=3 的 那 一 行 資 料 ,其 displayorder 就 會 相 應 的 變 為 4。即 是 每 當 使 用 者 按 下 自 定 義 按 鈕 時 ,相 鄰 兩 行 資 料 的 displayorder 就 會 互 換 。

...
colModel :[
....
{name:'displayorder',index:'displayorder',width:30,search:false,editable:false,viewable:false,formatter:moveButton}
],
...

再 一 次 回 到 colModel,自 定 義 按 鈕 當 然 可 以 用 edittype:’button’,但 自 由 度 就 遠 遠 不 如 自 己 用 formatter 了 。這 一 次 我 們 用 一 條 自 定 義 function,moveButton。

function moveButton(cellvalue, options, rowObject){
return "<input class='movingup' type='button' name='" + cellvalue + "' value='上 移 ' />";
}

首 先 來 簡 單 一 點 的 ,只 加 一 個 button。我 們 為 button 加 了 一 個 class 叫 movingup,然 後 name 就 定 義 為 cellvalue,即 是 displayorder 的 值 。

有 「上 移 」,當 然 也 要 有 「下 移 」吧 。為 了 節 省 一 點 欄 寬 ,而 且 行 高 也 夠 位 ,所 以 就 用
做 一 個 分 行 分 開 兩 個 button。

function moveButton(cellvalue, options, rowObject){
return "<input type='button' value='上 移 ' class='movingup' name='" + cellvalue + "'><br><input type='button' value='下 移 ' class='movingdown' name='" + cellvalue + "'>";
}

「下 移 」的 name 同 樣 是 cellvalue,就 只 是 class 改 為 movingdown。

有 了 button 之 後 ,我 們 就 要 用 jquery 加 入 按 「按 鈕 」的 動 作 了 。

$("#list").delegate("input.movingup","click",function(){
 var displayorder = $(this).attr('name');
 $.ajax({
  type:"post",
  url:"movingposition.php",
  data:{displayorder:displayorder,direction:'up'}
  }).done(function(){
   $("#list").jqGrid().trigger("reloadGrid");
 });
});

我 們 用 delegate 方 法 ,為 jqGrid(#list)裡 面 的 所 有 class=movingup 的 input 的 click 事 件 ,加 入 一 條 function,去 實 行 我 們 的 動 作 。

然 後 我 們 就 用 ajax 方 法 ,把 變 數 傳 遞 到 movingposition.php。php 檔 就 會 取 得 變 數 (displayorder 和 direction),和 在 資 料 庫 做 相 應 的 變 動 (就 只 是 交 換 兩 筆 資 料 的 displayorder 而 已 )。

當 ajax 完 成 之 後 ,callback function 就 會 對 jqGrid 進 行 一 次 reload,於 是 displayorder 的 變 動 就 會 馬 上 反 映 出 來 了 。

我 們 在 上 面 只 處 理 了 「上 移 」按 鈕 ,其 實 「下 移 」也 是 同 樣 的 。

$("#list").delegate("input.movingdown","click",function(){
 var displayorder = $(this).attr('name');
 $.ajax({
  type:"post",
  url:"movingposition.php",
  data:{displayorder:displayorder,direction:'down'}
  }).done(function(){
   $("#list").jqGrid().trigger("reloadGrid");
 });
});

我 們 再 增 加 一 個 delegate 方 法 ,但 這 次 的 對 象 是 input.movingdown。另 外 ,ajax 的 data 裡 面 的 direction 也 相 應 的 修 改 為 down。

輕 輕 鬆 鬆 的 ,我 們 就 做 好 了 我 們 的 custom button 了 。至 於 那 個 php,沒 什 麼 難 度 的 ,就 留 給 諸 君 自 由 發 揮 了 。

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

15 Responses to jqGrid 實用技巧 (八) 在 grid 裡面自定義按鈕

  1. compileerrors says:

    版主,不好意思我想問一下:

    function moveButton(callvalue, options, rowOject)的callvalue

    為什麼都是undefined您有遇過這樣的問題嗎??

    • compileerrors says:

      版主不好意思,我解開了,打擾您了!!

      • C.T. Leung says:

        不打擾,不打擾。我自己沒遇到過這種情況,但我也多說兩句,留給其他可能遇到這種情況的朋友吧。你可別嫌我煩啊。

        其實為什麼 moveButton function 會有那幾個 parameters 呢?其實就是 jqGrid 裡面 define 的。jqGrid 的 custom_formatter 就會有這幾個 parameters,以方便大家傳遞參數。

        其中一個可能性,如果我們不是在 custom_formatter 的情況下引用,就會出現 undefine 的情況了。

        而那幾個 parameters 代表什麼呢?我們可以看 jqGrid 裡面的定義。

        cellvalue – is the value to be formatted

        options – is an object containing the following element
        options : { rowId: rid, colModel: cm} where rowId – is the id of the row colModel is the object of the properties for this column getted from colModel array of jqGrid

        rowObject – is a row data represented in the format determined from datatype option. If we have datatype: xml/xmlstring – the rowObject is xml node,provided according to the rules from xmlReader If we have datatype: json/jsonstring – the rowObject is array, provided according to the rules from jsonReader

        雖然我上面的簡單例子只用了 cellvalue,但其實甚至是一整行資料的 rowObject 都已經傳回了給你,你想做什麼運算都可以的。

        • compileerrors says:

          版主不好意思我又來了,這次我想問的是,

          目前我遇到一個問題,目前我的情況是塞checkbox進去

          那我發現function mailCheck(callvalue, options, rowOject) 的rowOject

          在第一頁的時候都會有值,但要換到下一頁的時候,就變成undefine,

          不曉得版主是否有遇過這樣的問題?

          • C.T. Leung says:

            一行程式碼也沒看到,實在是不太好判斷…. ( 但請你千萬別貼出來 )

            盲估:loadonce set to true ???

  2. compileerrors says:

    沒錯,我loadonce: true,但是我set false他的頁數只會只有1共1頁,正常來說應該是兩頁才對,不曉得版主是否知道這個問題呢?

    • C.T. Leung says:

      為了減少每次從資料庫取出的資料量,以增加顯示的速度,多數的 Grid 都是每次只取出一頁資料,到翻頁的時候才取得下一頁的資料。如果 loadonce: true 的話,grid 就會一次過取出所有資料,再把那些資料變為 local data。除非有特殊需要,否則 loadonce: true 只應用在資料筆數非常少的情況,所以是一般情況都是 loadonce: false 的,這亦是 default value。

      因為 loadonce: true ,在完成首次連線之後,grid 就會把所有資料變成 local data,所以會造成很多影響,尤其是在翻頁的時候,會引出更多問題。個人是不太建議使用 loadonce: true 的。( 是非常不建議才對,哈哈,其實 loadonce: false 才是基本,loadonce: true 是進階玩法 )

      至於你用 loadonce: false 時所遇到的問題,應該是你的 server side script ( 用我一向的例子就是 server 上面運行的 php ,也就是 url 參數的 data_json.php ) 出問題所至。

      按 jqGrid 的要求,這個 script 要接收和處理 page、rows、sidx、sord 這幾個參數,以及要傳回 page、total、records 等幾個參數。如果這些部分都處理好了,你的 loadonce: false 就不會有問題了。

      在 jqGrid demo 的 loading data 裡面,會有這個 script 的例子,去看看吧。

  3. miny says:

    版主,想請教您
    是否可能依據data的內容,而對不同row顯示不同的button?

    例如 row1 可編輯,就顯示客製化編輯按鈕
       row2 不可編輯,則不顯示按鈕

    • C.T. Leung says:

      呵呵,當然可以喇。請看我上例中的 moveButton() function,那其實是 custom formatter,本身是有 rowObject 的。rowObject 就是一整個 row 的所有 data 了。

      function moveButton (cellvalue, options, rowObject){
      if (rowObject[3] >= 5) {
      return "your custom button 1";
      } elseif (rowObject[2] == "banana" ) {
      return "your custom button 2";
      } else {
      // 不顯示就可以 return empty string
      return "";
      }
      }

      以上是依據 data 的值而顯示不同按鈕。至於要判斷該 row 是不是可以編輯,由於資料不足,就留給你自己做吧。

  4. miny says:

    圖片如下

    • C.T. Leung says:

      你好意思啊,把 code 都貼出來要人家幫你 debug…. 你是學生吧(還是大的那種!!)?學校的老師工資多高啊,他們收了錢,你又不去問他們,卻來問我這麼一個無產階級….. (嘿嘿嘿)

      你的問題跟一樓看來相似,卻絕不相同。他是因為設定了 loadonce: true 而又不知道在這情況下 json 會自動變成 local data (於是那個 rowObject 就跟著變了)。而你呢,你自己一開始就是 datatype: “local”,根本就沒變過。這是你主動去設定的,不能說你不知道啊。

      其實 jqGrid 的說明文件就寫得很清楚 (大概你沒看,而我也知道大家都不會去看,所以還苦口婆心的在上面貼過出來)。這個 rowObject,顧名思義,原本就是一個 object。只有在 datatype 有別,它才會變成其他東西。用現在流行的 json 做例子,它就會成了一個 array 了。我示範給你看的例子是依照本系列文章一向使用 json 的習慣,所以才會用 array 的方法來處理 rowObject。

      你的情況是 local data,那 rowObject 就只可能是一個 object 了。你用 rowObject.name 就能得到該 field 的值了。

      別怪老人長氣,東西要自己學來才是自己的。發問的時候你應該要先搞清楚自己的問題(不要連問題出在那裡都不知道,就把一堆 code 貼出來要人家去找錯處),然後針對那個問題去問解決之法。你再有問題就去問你的老師吧,他們收了錢,你是他們的責任。哈哈哈。

      • miny says:

        抱歉造成您的困擾,也十分感謝您還是回答了我的問題。

        我是自學jqgrid的新手,努力在一邊debug一邊尋求google的幫助,對jqgrid的觀念還不甚清楚,以至於問出了令人貽笑大方的問題。

        貼出code的原因,是看了許多外國網站都要求人家貼code,不然無法幫他找問題,令我誤以為這是一般的模式,絕對沒有抱持不付錢又要求人家debug的心態,讓您感到不適真的十分抱歉。

        不過還是非常感謝版主回答問題,並且寫了很棒的網誌們讓我受益良多!!(解決了我很多的問題)

        我就繼續來慢慢google跟研究了~

        • C.T. Leung says:

          還外國我呀你,哼哼哼。我從小就是在 stackoverflow ( 基本上你 google 任何 programming 的問題都鐵定會找到它 ) 裡爬文長大的,人家在裡面說 jqGrid 的 rowObject undefined 都不知說過幾千百次了。你這位看了許多外國網站的朋友怎麼不去 stackoverflow 問,而會問到我這種一天也沒有幾十人來逛的蚊型小站呀?我實在是忍不住要套用一句本地某位垃圾作家的話:真是天下之奇,莫過於此。

          你既自學、又新手的,我就不能不慎重地再一次重複我在這系列文章第一篇的觀點。第一,要先閱讀所有 jqGrid Wiki 裡面的 documentation;第二,jqGrid Demo Page 裡面所有範例也要看一次。缺少了以上任何一樣,都會令你對 jqGrid 的了解不甚完整(例外情況是你已經讀完 jqGrid 的 source code,但我個人不太建議)。你不了解你的工具,又怎麼會懂得如果去用它?

          我學東西純粹是因為我喜歡,看遍那些東西雖然花時間,卻不是苦事。我智商很弱,能力很低,讀書成績一向包尾,所以我知道學習沒有捷徑。哈哈哈。

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>