jQuery學習筆記–jqGrid的使用方法(編輯,刪除,更新,新增) – Javascript教程_JS教程_技術文章 – 程式設計聯盟

 

早上無意中發現,jqGrid發佈瞭3.6.2版本。查看瞭一下chang log,居然讓我看到瞭中文包的發佈。

前幾天正為這事兒頭痛,要不要根據grid.local-en.js來漢化一下,沒想到居然直接就出中文包瞭。官方的一般來說比自己做的要好吧。

下載地址:http://www.trirand.com/blog/?page_id=6

下載之後修改自己寫的jsp文件中的引用語句

<script src="../js/i18n/grid.locale-en.js" type="text/javascript"></script>

修改為

<script src="../js/i18n/grid.locale-cn.js" type="text/javascript"></script>

再打開運行tomcat來看,果然變成中文的瞭。哈哈!爽!

不過有一點需要註意,如果你是狂熱愛好者,在jsp中直接引用src目錄下的原始包(這樣可以調試jqGrid的源代碼),那麼除瞭上面我們說的jsp文件中需要修改之外,還有一個js文件需要修改,那就是:src/grid.loader.js中

var modules = [ { include: true, incfile:'i18n/grid.locale-en.js'}, // jqGrid translation

需要修改為

var modules = [ { include: true, incfile:'i18n/grid.locale-cn.js'}, // jqGrid translation

這樣就好瞭!

使用jqGrid修改數據

jqGrid可以有三種方式,讓我們來修改顯示在jqGrid中的數據。這三種方式分別是:
Cell Editing——隻允許修改某一個單元格內容.(所有圖片均來自jqGrid的wiki或者jqGrid的Demo截圖)


Inline Editing——允許在jqGrid中直接修改某一行的數據


Form Editing——彈出一個新的編輯窗口進行編輯和新增


暫時先不管這三種方式,我們來看看如何讓一個jqGrid的數據能夠進行編輯呢?
其實很簡單,就是在jqGrid的colModel屬性中,設置幾個屬性:
editable
    可選值是true或者false,默認是false。用來說明這個列的數據是否可編輯。特別要註意的是,jqGrid的隱藏字段就算設置瞭這個屬性為true,一樣不能被編輯。在Cell Editing以及Inline Editing模式下,隻能通過把這些字段設置為可見來修改。在Form Editing模式下,可以通過editoptions參數來設置是否可以修改隱藏列。
edittype
    可選的值是'text', 'textarea', 'select', 'checkbox', 'password', 'button', 'image', 'file'以及'custom'。默認值是text。
    根據名字就可以看出來,這個屬性是設置編輯框的HTML樣式的。比如,設置為text值,並且可以在editoptions中設置size以及maxlength等屬性。這樣生成的HTML樣式有點類似<input type="text" size="10" maxlength="15"/>這樣。
    其中有幾個要註意:
    設置checkbox的時候,需要在editoptions中指定value值,第一個值應該是checked的時候的值。比如editoptions:{value:"Yes:No"}會設定這個checkbox編輯框,選中的時候,值是Yes,沒選中的時候值是No。建議最好都設定一下這個值。
    設置select的時候,editoptions中需要設定select下拉框的值。
        一種方式是用字符串設置editoptions的value屬性,像這樣editoption: { value: “FE:FedEx; IN:InTime; TN:TNT” },這就為下拉框設置瞭三個可選值。註意,冒號前面的代表的是值,冒號後面代表的是顯示值。
        第二種方式是用對象來設置editoptions的value屬性,這個時候,value值要用{}包括起來,像這樣: editoptions:{value:{1:'One',2:'Two'}}。
        第三種方式,是為editoptions設置dataUrl參數。意思就是select的值,是通過一個URL來獲取的,比如一個Ajax請求的返回值。特別需要註意的是,在這種情況下,URL的返回值必須是包括select以及option這些HTML標簽的。就像這樣:<select><option value="1">One</option><option value="2">Two</option></select>.這種情況下,還可以在editoptions中設置是否允許多選,size等等。
    設置image的時候,editoptions的src屬性用來指定圖片的地址。
    custom類型就是通過一個函數來指定需要編輯的元素,並返回需要提交的值。
        函數的定義在editoptions中說明,分別是custom_element用來指定哪一個函數用來創建編輯框,註意這裡函數必須返回一個新的DOM元素,函數的參數一個是值Value,另外一個是colModel的editoptions值。
        另外一個是custom_value,這個函數用來在編輯完成之後返回本編輯框的值,這個函數的參數是元素對象。大概的調用格式如下:
        <script>
            //創建一個input輸入框
            function myelem (value, options) {
              var el = document.createElement("input");
              el.type="text";
              el.value = value;
              return el;
            }
             
            //獲取值
            function myvalue(elem) {
              return $(elem).val();
            }
            jQuery("#grid_id").jqGrid({
            …
               colModel: [ 
                  … 
                  {name:'price', …, editable:true, edittype:'custom', editoptions:{custom_element: myelem, custom_value:myvalue} },
                  …
               ]
            …
            });
        </script>

editoptions
    除瞭上面介紹的editoptions選項外,我們還可以設置defaultValue等等,更復雜的東西,比如dataEvents就不介紹瞭。
editrules
    editrules是用來設置一些可用於可編輯列的colModel的額外屬性的。大多數的時候是用來在提交到服務器之前驗證用戶的輸入合法性的。比如editrules:{edithidden:true, required:true….}。
    可選的屬性包括:
    edithidden:隻在Form Editing模式下有效,設置為true,就可以讓隱藏字段也可以修改。
    required:設置編輯的時候是否可以為空(是否是必須的)。
    number:設置為true,如果輸入值不是數字或者為空,則會報錯。
    integer:
    minValue:
    maxValue:
    email:
    url:檢查是不是合法的URL地址。
    date:
    time:
    custom:設置為true,則會通過一個自定義的js函數來驗證。函數定義在custom_func中。
    custom_func:傳遞給函數的值一個是需要驗證value,另一個是定義在colModel中的name屬性值。函數必須返回一個數組,一個是驗證的結果,true或者false,另外一個是驗證錯誤時候的提示字符串。形如[false,”Please enter valid value”]這樣。
    自定義驗證的例子:
    <script>
        function mypricecheck(value, colname) {
        if (value < 0 && value >20) 
           return [false,"Please enter value between 0 and 20"];
        else 
           return [true,""];
        }

        jQuery("#grid_id").jqGrid({
        …
           colModel: [ 
              … 
              {name:'price', …, editrules:{custom:true, custom_func:mypricecheck….}, editable:true },
              …
           ]
        …
        });
    </script>    <         function mypricecheck(value, colname) {         if (value < 0 && value >20)             return [false,"Please enter value between 0 and 20"];         else             return [true,""];         }          jQuery("#grid_id").jqGrid({         …            colModel: [                …                {name:'price', …, editrules:{custom:true, custom_func:mypricecheck….}, editable:true },               …            ]         …         });      // >

formoptions(隻在Form Editing方式下有效),他的主要作用是用來重新排序Form中的編輯元素,同時可以在編輯元素前或者編輯元素後增加一些信息(比如,一些提示信息,或者一個紅色的*表示必須要填寫等等)。
    可選的屬性如下:
    elmprefix:字符串值,如果設置瞭,則會在編輯框之後出現一些內容(可能是HTML的內容)
    elmsuffix:字符串值,如果設置瞭,則會在編輯框之前出現一些內容(可能是HTML的內容)
    label:字符串值,如果設置瞭,則這個值會替換掉colNames中的值出現作為該編輯框的標簽顯示
    rowpos:數字值,決定元素行在Form中的位置(相對於文本標簽again with the text-label)
    colpos:數字值,決定元素列在Form中的位置(相對於標簽again with the label)
    兩個編輯框可以有相同的rowpos值,但是colpos值不同,這會把這兩個編輯框放到Form的同一行中。
    特別註意:如果設置瞭rowpos以及colpos的值,強烈推薦為所有的其他編輯元素都設置這些值。

 

—-本文隻是doc文檔的解釋,沒有太多自己的東西。接下來我會做一個Form Editing的例子,肉戲即將登場……

 

我們講瞭一下jqGrid編輯的基礎知識。下面我們基於Form Editing的編輯模式詳細舉例講解一下。

Form Editing編輯模式主要的方法有幾個,分別是editGridRow——用來修改記錄,editGridRow函數,傳遞一個'new'的參數就表示新增記錄;viewGridRow查看記錄詳情;delGridRow刪除記錄。

這幾個方法的調用方式,和jqGrid的其它函數調用方式一樣。(可以采用new API的調用方式,把函數名稱作為第一個參數來調用)需要註意的地方是,各個函數調用內容的options參數有一些差異,具體可以參考文檔;另外就是,各個函數提交到服務端的數據和格式有所差異。這裡以editGridRow為例來說明一下。

editGridRow的調用方式如下:

jQuery("#grid_id").editGridRow( rowid, properties ); 或者是如下的方式 jQuery("#grid_id").jqGrid('editGridRow', rowid, properties );

其中rowid指定是編輯那一行,properties是一個包含各種屬性以及事件的數組。(具體的屬性和事件,請參考文檔,這裡就不翻譯瞭。)調用之後,提交到服務器上去的數據都是一些什麼數據呢?

提交的數據主要包括:

1.各個編輯"字段:值"的對。這個不好理解,其實的意思就是,相當於用POST的方式提交一些數據,數據的名稱就是我們定義在colModel中的name屬性,值就是我們在彈出窗口錄入的值。(當然,這就要求我們在Server端的Action定義這些變量並封裝到Pojo對象中去進行處理。)

2.包含一個"id:rowid"的值,用來表明是哪一個id關鍵字的記錄被修改(新增記錄的時候,id=_empty);

3.包含一個"oper:edit"的值,用來指示是編輯還是新增記錄(新增記錄的時候,oper=add)

4.其它高級情況,比如使用瞭editData對象或者實現瞭onclickSubmit事件之後的處理。比較復雜,暫時沒有詳細研究這種情況下提交數據的格式。

如果是要新增記錄,那麼editGridRow的調用方式如下:

jQuery("#grid_id").editGridRow( "new", properties );

 

好瞭,接下來我們來看看我們在jsp文件中是如何實現的吧。

首先說明一下,這個例子和前一篇文章中的例子有很多變化。主要包括,在jqGrid中新增瞭一個列,用來作為操作列,同時增加瞭兩個操作:編輯和刪除。增加瞭一個導出查詢結果為csv的按鈕(自定義按鈕),但是具體的後臺服務器功能沒有實現;把查詢和新增功能單獨作為一個按鈕顯示在jqGrid的後面。具體的差異,大傢可以看看本人另外一篇文章《jqGrid的多字段查詢》中的例子。

    $().ready(function(){
        $("#grid").jqGrid({        
            url:'queryAllBrand.action',
            datatype: "json",
            mtype: 'POST',
            colNames:['操作','品牌ID','品牌代碼', '品牌名稱', '是否可用','最後修改時間'],
            colModel:[
                {name:'act',index:'act',width:110,search:false,sortable:false,editable:false},
                {name:'brandId',index:'brandId', width:90,editable:false},
                {name:'code',index:'code', width:110,
                    editable:true,
                    edittype:'text',
                    editoptions:{size:10,maxlength:15},
                    editrules:{required:true},
                    formoptions:{elmprefix:'(*)'}
                },
                {name:'brandName',index:'brandName', width:100,
                    editable:true,
                    edittype:'text',
                    editoptions:{size:10,maxlength:15},
                    editrules:{required:true},
                    formoptions:{elmprefix:'(*)'}
                },
                {name:'status',index:'status', width:80,
                    editable:true,
                    edittype:'checkbox',
                    editoptions:{value:"1:0"},
                    editrules:{required:true},
                    formoptions:{elmprefix:'(*)'}
                },
                {name:'lastModifiedDatetime',index:'lastModifiedDatetime', width:100,editable:false}
            ],
            rowNum:3

 

在實際的修改、新增保存中,會看到如下的錯誤提示:error Status:"OK".Error code: 900。實際上,修改(新增)的記錄已經正確的保存到數據庫中瞭。見下圖:

這是為什麼呢?一直為這個問題頭痛苦惱瞭好幾天。仔細閱讀瞭jqGrid wiki上的文檔,也google瞭許多的文章,仍然找不到相應的說明或者解決辦法。

後來研究瞭一下jqGrid的源代碼。src/grid.formedit.js文件,發現其中有一個函數postIt,其中有如下的代碼:

if(Status != "success") { ret[0] = false; if ($.isFunction(rp_ge.errorTextFormat)) { ret[1] = rp_ge.errorTextFormat(data); } else { ret[1] = Status + " Status: '" + data.statusText + "'. Error code: " + data.status; } } else { // data is posted successful // execute aftersubmit with the returned data from server if( $.isFunction(rp_ge.afterSubmit) ) { ret = rp_ge.afterSubmit(data,postdata); } }

看來問題是在這個地方。由此猜想jqGrid的增刪改操作是要求服務器返回內容的。

我猜測,jqGrid要求服務器返回包含成功與否的status內容。所以我修改瞭一下Action的類方法的返回值:如下:

public String modifyBrand() { String result = "success"; try { MProductBrand mpb = new MProductBrand(); mpb.setBrandName(brandName); mpb.setCode(code); mpb.setStatus(status); mpb.setLastModifiedDatetime(new Timestamp(System.currentTimeMillis())); if(oper != null && oper.equals("edit")){ //編輯 mpb.setBrandId(new Integer(id)); this.brandService.modifyBrand(mpb); } else if (oper != null && oper.equals("add")){ //新增 MProductBrand mproductbrand1 = this.brandService.locateByBrandcode(mpb .getCode().toString().trim().toUpperCase()); MProductBrand mproductbrand2 = this.brandService.locateByBrandName(mpb .getBrandName().toString().trim()); if (mproductbrand1.getBrandId() == null && mproductbrand2.getBrandId() == null) //檢查是否存在 { this.brandService.addBrand(mpb); } else { log.warn("品牌代碼或品牌名稱已經存在"); result = "error"; } } } catch (Exception ex) { ex.printStackTrace(); log.warn("修改失敗"); result = "error"; } HttpServletResponse response = ServletActionContext.getResponse(); response.setContentType("text/json; charset=UTF-8"); try{ PrintWriter out = response.getWriter(); JSONObject json = new JSONObject(); json.put("status", result); out.print(json.toString()); } catch(Exception e){ e.printStackTrace(); log.error("Error:Cannot create PrintWriter Object !"); } return null; }

再次執行,發現保存成功之後,編輯窗口自動關閉,頁面自動重新加載。很好!

不過我一直在疑惑,到底服務器要怎麼返回呢???仔細看瞭看jqGrid的Demo,想通過研究php文件來看看例子中是如何做的,也沒有找到。並且,jqGrid Demo的編輯例子,是不實際向服務器提交修改內容的。說是為瞭安全原因……

 

摘自 Hurry的專欄

發佈留言