2014/07/17

20140717-程式-針對jqGrid的應用-客製Inline Edit的編輯內容

這一功能還是練習記錄一下:

結果畫面:

這是基本的操作設定:


選了權限類別後,可以顯示資料 & 在頁上直接編輯 儲存。

=======



這是同一個頁面,同一個jqGird ,查詢後,特別處理設定值的部份,
讓它可以選擇「單位」/「人員」資訊。
(而單位/人員是 共用的元件資訊~~~)

==========================================
(當初在處理:新增時可以讓[帳號/設定值]可以改;而異動時只可以改[設定值],這段也花了不少功夫)


一開始的想法,是要試看看jqGrid 的 custom cell 可以到什麼什麼地步?

參考了這些文章:
 Custom template column:http://goo.gl/LFG42L
    jqgrid edittype:http://goo.gl/yzdVge
                    http://goo.gl/2HsWW8

而這定了了jqgrid 的colModel:
  colModel: [
            { name: "", hidden: true },@*指定它是unique row no*@
            { name: "ConfigType", hidden: true },
            { name: "iaccount", hidden: true },
                { name: "PersonalAccessConfigTypeDisplay", index: "PersonalAccessConfigTypeDisplay", width: 100 },
                { name: "iaccountDisplay", index: "iaccountDisplay", width: 100, editable: true, editrules: { required: true } },
                {
                    name: "fvalue", index: "fvalue",
                    formatter: jqGridFormatter,
                    unformat: jqGridUnFormatter,
                    editable: true, edittype: 'custom',
                    editoptions: { custom_element: jqGridEditElement, custom_value: jqGridEditValue }
                }
                ],

關鍵在:
edittype: 'custom',editoptions: { custom_element: jqGridEditElement, custom_value: jqGridEditValue

而這邊,先從試試,怎麼取到cell 的原始資料,
而我的JSON格式為:
{
        units: ["120102", "620110","220100"],
        members: ["910129", "910370"]

}

先試怎麼拿這資料,再一步步來處理這些呈現資訊。

=================================

先拿最基本的格式來處理:(即原本的:點選後可以文字編輯[設定值])

 //fvalue顯示格式處理
        function jqGridFormatter(cellvalue, options, rowObject) {
            return GetExecuteObj().DisplayFmt(cellvalue, options, rowObject);
        }
        //fvalue顯示格式Un處理
        function jqGridUnFormatter(cellvalue, options, cell) {
            return GetExecuteObj().DisplayUnFmt(cellvalue, options, cell);
        }
        //fvalue編輯時的呈現
        function jqGridEditElement(value, options) {
            return GetExecuteObj().EditFmt(value, options);
        }
        //fvalue編輯時的取值
        function jqGridEditValue(elem, operation, value) {
            return GetExecuteObj().EditValueFmt(elem, operation, value);
        }


這是試到最後的jqgrid 的 function :
1. 當你 呈現時有 format 過,一定要做[UnFormat] 的動作。
2. 因為要做成之後可以「共用」的地步,所以我用 GetExecuteObj() 來決定我要用什麼方式呈現。

定義Obj 的class (示意的javascript 版)

//預設的物件定義
        var DefaultObj = {
            //fvalue顯示格式處理
            DisplayFmt: function (cellvalue, options, rowObject) {
                var value = rowObject["fvalue"];
                return value != null ? value : "";//Access row data:http://goo.gl/r3aw7q
            },
            //fvalue顯示格式Un處理
            DisplayUnFmt: function (cellvalue, options, cell) {
                return cellvalue;//.replace("my", "");
            },
            //fvalue編輯時的呈現
            EditFmt: function (value, options) {
                var div = $("#template_input").clone();
                div.show();
                var myinput = $(div).find("#fvalue");
                myinput.val(value);
                return div;
            },
            //fvalue編輯時的取值
            EditValueFmt: function (elem, operation, value) {
                var div = $(elem);
                var myinput = $(div).find("#fvalue");
                alert(myinput.val());
                if (operation === 'get') {
                    return myinput.val();
                } else if (operation === 'set') {
                    myinput.val(value);
                }
            }
        }


所以我最後定義出:
//預設的物件定義  =>呈現 基本的 textbox 處理
        var DefaultObj = { ...}

 //組織人員物件   =>呈現組織&人員 檢視/編輯 的處理
        var MemberUnitObj = {...}

======================================

而其中,也試試如何 load template 資料到 cell 裡,一樣用基本的試驗。
若可以 把tempate 內的textbox 做呈現的話,那就可以試著載入其它不同的common controller

在這段程式裡就可以看出:
//我的template

    


//我的js 處理:
 EditFmt: function (value, options) {
                var div = $("#template_input").clone();
                div.show();
                var myinput = $(div).find("#fvalue");
                myinput.val(value);
                return div;
            },

我可以設定 html 內的元件完成後,再把它放到grid 裡,
至於為何要用「clone()」,因為若只用同一個,他操作過一次後就會不見了~~~~


而在更復雜的「單位人員」元件裡,除了 clone()後,我還要給html內的元件 unique ID
而在編輯時,我 單從它event 的參數,我無法直覺的知道 unique ID
所以 unique ID 就存在全域變數裡以便處理。


================================
在 jqgrid colModel下的設定,關鍵在這些:
formatter: jqGridFormatter,   //jqgrid 的display處理
unformat: jqGridUnFormatter, //要再把它unformat 拿到原始資料才可以。
edittype: 'custom',
editoptions: { custom_element: jqGridEditElement, custom_value: jqGridEditValue }

formatter/unformat:
一開始就用簡單的測試,在formatter時,在data 前面加個符號
就因為一開始沒有處理 unformat ,所以呈現時會越加越多~~~~~


custom_element://你要在edit mode 時要呈現什麼樣子
custom_value:   //這個要定義這個cell 的"值"要如何取得~~~這個function 不知為何,沒有event觸發它 ,所以我在儲存時,要自已想辦法 call 此 function .

=================================
之間有一個主題:我要預設勾選 它選擇的 tree 資料:



在設定單位值時,要等到它tree load 完後才可以做設定,
因一開始,資料有時有勾選到,有時又沒有帶到資料,本想放棄的~~但還是要找出原因來

.fn.set_selUnits_by_unitGUIDs = function (unitGUIDs) {
    var ucID = $(this).attr("id");
    $(this).value(unitGUIDs);
    //如果有設定值則預設checked
    var unitguids = $("#" + ucID).value();
    if (unitguids != null && unitguids != "") {
        var guidarray = unitguids.split(",");
        //判斷是否已載入,若未載入則reload
        if ($("#" + ucID + "_dynatree").dynatree("getRoot")._isLoading) {
            setTimeout(function () { $("#" + ucID).set_selUnits_by_unitGUIDs(unitGUIDs) }, 100);
            return;
        }
        var rootNode = $("#" + ucID + "_dynatree").dynatree("getRoot");
        rootNode.visit(function (node) {
            if ($.inArray(node.data.key, guidarray) >= 0) {
                node.select(true);
            }
        });
        $("#" + ucID).selUnitsDialog_confirmClick("", "", null, 1);
    }
    //如果有設定值則預設checked END
}


關鍵值:
$("#" + ucID + "_dynatree").dynatree("getRoot")._isLoading //判斷tree load完成了沒?
而我用 recall 的方式,來達到「一定要」設定到的功能。
用 setTimeout () 再一次呼叫自已~~
好在解決這問題,讓操作起來較順手~~~~
===============================================
結論:
程式一陣子沒寫,對於相關的jquery 寫法都陌生了,而透過 google 來找一些資料處理。
這次這樣一步步的實驗,將大方向切成一個個小目標達成。

也透過這樣的評估,來判斷「這條路」的可行性!

在當我完成心裡所想的這架構時,那種感覺,也算是程式開發人員的「小確幸」吧!

我喜歡這樣開發程式完成後所帶來的感覺!

所以,這份記錄,是記錄下這次的歷程,詳細的code ,以後要看再來翻翻。
而且盡量保留住那份心情。

(THE END)

















0 意見 :

張貼留言