天天看點

Kendo UI Grid 使用總結

Kendo UI Grid控件的功能強大,這裡将常用的一些功能總結一下。

Kendo UI Grid 固定列

在使用Gird控件顯示資料時,如果資料列過多,會出現橫向滾動條,很多情況下,我們希望某些列固定,這些列固定顯示,不随滾動條發生變化。這時,可以在資料列上使用locked屬性,比如,下面是使用mvvm定義grid的示例,編輯按鈕被設定為固定列:

<div id="fieldgrid" class="grid"
                     data-role="grid"
                     data-sortable="true"
                     data-height="580"
                     data-toolbar="['create']"
                     data-bind="source: fieldSource"
                     data-editable='{"mode": "popup" }'
                     data-columns='[
                                  {"field":"Name","title":"字段名稱",  "width": "120px"},
                                  {"field":"Title","title":"字段說明",  "width": "120px"},
                                  {"field":"DataType","title":"字段類型","values":dsDataType,  "width": "120px"},
                                 {"field":"ControlType","title":"控件類型", "values":dsControlType,  "width": "120px"},
                                 {"field":"DefaultValue","title":"預設值",  "width": "120px"},
                                 {"field":"Editable","title":"是否可編輯",  "width": "80px"},
                                 {"field":"Visible","title":"是否可見",  "width": "80px"},
                                 {"field":"DisplayOrder","title":"顯示順序", editor: numberEditor,  "width": "80px"},
                                         {"field":"IsCascade","title":"是否級聯",  "width": "80px"},
                                         {"field":"CascadeSubField","title":"級聯下級",  "width": "120px"},
                                         {"field":"CascadeParentField","title":"級聯上級",  "width": "120px"},
                                     {"command": [ "edit", "destroy" ],  "width": "180px","locked":"true"}
                                     ]'
                     data-scrollable="true">
           

需要注意的是,1)固定列總是顯示在最左邊,2)帶有固定列網格在初始化過程時,必須是可見的。如果網格在初始化時不可以見,會出現不可預知的問題。比如這種的場景,如果網格在分頁中,初始化時是不可見的,那麼,界面可能是這樣的:

Kendo UI Grid 使用總結

Grid控件建立自定義彈出編輯窗

Kendo UI Grid控件自帶彈出窗編輯,隻要在資料源中定義schema,就可以自動生成編輯界面,代碼如下:

<div class="form container" id="divForm">
        <div id="divGrid">
            <div id="mygrid" class="grid"
                 data-role="grid"
                 data-sortable="true"
                 data-toolbar="['create']"
                 data-bind="source: dataSource"
                 data-editable='{"mode": "popup" }'
                 data-columns='[
             {"field":"Id","title":"ID"},
             {"field":"Name","title":"姓名"},
             {"field":"Age","title":"年齡"},
             {"field":"JoinDate","title":"入職日期","format": "{0:yyyy-MM-dd}"},
             {"field":"Sex","title":"性别","template": "#if (Sex==1){# 女 #}else{# 男 #}# "},
             {"field":"Married","title":"婚姻狀況","template": "#if (Married){# 已婚 #}else{# 未婚 #}# "},
             {"command": [ "edit", "destroy" ], "filterable": false, "sortable": false, "width:": "240px"}
             ]'
                 data-scrollable="false">
            </div>
        </div>
    </div>
    <script>
      
        $(document).ready(function () {
            var viewModel = kendo.observable({
                dsSex: [{ value: 0, text: '男' }, { value: 1, text: '女' }],
                dataSource: new kendo.data.DataSource(
                    {
                        data: [],
                        schema: {
                            model: {
                                id: "Id",
                                fields: {
                                    Id: { editable: true, nullable: false },
                                    Name: { validation: { required: true } },
                                    Age: { type: "number" },
                                    Sex: { editable: true },
                                    JoinDate: { type: "date", editable: true },
                                    Married: { type: "boolean", editable: true }
                                }
                            }
                        }

                    })
             
            });
           
            kendo.bind($("#divForm"), viewModel);

        });

    </script>
           

自動生成的編輯界面對于基本資料類型的字段夠用了,但在實際中,會有更複雜的要求,比如,某些字段需要使用下拉框或者更複雜的控件,或者我們希望字段多列排列,這時,需要用到自定義的模闆,上面的網格的自定義編輯模闆如下:

<script id="popup_editor" type="text/x-kendo-template">
        <div class="form container">
            <div class="form-group row">
                 <label class="col-sm-2 control-label" for="Id">ID</label>
                 <div class="col-sm-4">
                    <input type='number' class='k-textbox' data-bind="value: Id" />
                    <span class="k-invalid-msg" data-for="Id"></span>
                </div>
            <!--</div>
            <div class="form-group row">-->
                
                <label class="col-sm-2" for="Name">姓名</label>
               
                
                <div class="col-sm-4 ">
                    <input type='text' name="Name" class='k-input k-textbox k-valid' data-bind="value: Name" required="required" />
                    <span class="k-invalid-msg" data-for="Name"></span>
                </div>
            </div>
            <div class="form-group row">
                <label class="col-sm-2 control-label" for="Age">年齡</label>
                <div class="col-sm-4">
                    <input type='number' style="" data-role="numerictextbox" class='form-control' data-bind="value: Age" />
                    <span class="k-invalid-msg" data-for="Age"></span>
                </div>
            </div>
            <div class="form-group row">
                <label class="col-sm-2 control-label" for="val_JoinDate">參加日期</label>
                <div class="col-sm-4">
                    <input data-role="datepicker" data-culture="zh-CN" style="" class='form-control' data-bind="value: JoinDate," />
                    <span class="k-invalid-msg" data-for="JoinDate"></span>
                </div>
            </div>
            <div class="form-group row">
                <label class="col-sm-2 control-label" for="val_Married">已婚</label>
                <div class="col-sm-4">
                    <input type="checkbox" style="" data-bind="checked: Married," />
                    <span class="k-invalid-msg" data-for="Married"></span>
                </div>
            </div>
            <div class="form-group row">
             
                <label class="col-sm-2 control-label" for="val_Sex">性别</label>
                <div class="col-sm-4">
                    <select data-role="dropdownlist" class='form-control' data-text-field="text"
                            data-value-field="value" data-bind="source:dsSex,value: Sex">
                    </select>
                    <span class="k-invalid-msg" data-for="Sex"></span>
                </div>
            </div>

        </div>
    </script>
           

模闆使用script标記,類型為text/x-kendo-template,說明是kendo的模闆。模闆語言就是html,其中的data标記與kendo MVVM一緻。模闆中有幾點需要注意:

  • 模闆中需要驗證的字段,需要定義name屬性,如果不定義,驗證資訊無法顯示
  • 需要定義 用于顯示驗證資訊
  • 如果需要多列顯示,需要在頁面中定義自定義的樣式:
<style>
        .k-edit-form-container {
            width: 700px;
        }

            .k-edit-form-container div {
                box-sizing: border-box;
            }
            .k-edit-form-container label {
                box-sizing: border-box;
            }
       
    </style>
           

需要将相關元素的box-sizing 設定為border-box

為Grid建立詳細顯示資訊

KendoUI Grid支援在網格行中顯示該行資料的詳細資訊,示例界面如下:

Kendo UI Grid 使用總結

詳細資訊部分是在Grid控件的detailInit事件中建立的,如果采用mvvm方式定義,示例代碼如下:

<div id="functiongrid" class="grid"
                             data-role="grid"
                             data-sortable="true"
                             data-toolbar="['create']"
                             data-bind="source: functionSource, events: { dataBound: fn_dataBound }"
                             data-editable='{"mode": "popup" }'
                             data-detail-init="viewModel.functiongrid_detailInit"
                             data-detail-template='functiongridsubtemp'
                             data-columns='[
                                 {"field":"FunctionName","title":"名稱"},
                                 {"field":"Desc","title":"說明"},
                                 {"field":"ExecuteUrl","title":"位址"},
                                 {"field":"ViewName","title":"函數類型名"},
                                 {"command": [ "edit", "destroy" ], "filterable": false, "sortable": false, "width:": "240px"}
                                 ]'
                             data-scrollable="false"
                             >

                        </div>
           

上面的代碼中,detailInit事件需要寫為mvvm的方式,也就是需要用data開頭,不同的單詞中間用“-”分隔,全部為小寫,這樣,detailInit就需要寫為data-detail-init。這個事件定義的函數在視圖模型中,還有一個需要定義的屬性是detailTemplate,用于定義顯示模闆,相關部分的代碼如下:

functiongrid_detailInit: function (e) {
                    e.detailRow.find(".functionTab").kendoTabStrip(
                        {
                            animation: {
                                open: {
                                    effects: "fadeIn"
                                }
                            }
                        }
                    );
                    if (!e.data.InParas) e.data.InParas = [];
                    if (!e.data.OutParas) e.data.OutParas = [];
                    if (!e.data.ExProps) e.data.ExProps = [];
                    var dsIn = new kendo.data.DataSource({
                        data: e.data.InParas,
                        schema: {
                            model: {
                                id: "FieldName",
                                fields: {
                                    FieldName: { editable: true, validation: { required: true } },
                                    ParaName: { editable: true, validation: { required: true } }
                                }
                            }
                        }
                    });
                    e.detailRow.find(".inparagrid").kendoGrid({
                        dataSource: dsIn,
                        editable: "popup",
                        toolbar: ['create'],
                        columns: [{
                            title: "字段名稱",
                            field: "FieldName"
                        }, {
                            title: "Api參數名",
                                field: "ParaName"
                        }, {
                            command: ["edit", "destroy"]
                        }
                        ]
                    });
                    var dsOut = new kendo.data.DataSource({
                        data: e.data.OutParas,
                        schema: {
                            model: {
                                id: "FieldName",
                                fields: {
                                    FieldName: { editable: true, validation: { required: true } },
                                    ParaName: { editable: true, validation: { required: true } }
                                }
                            }
                        }
                    });
                    e.detailRow.find(".outparagrid").kendoGrid({
                        dataSource: dsOut,
                        editable: "popup",
                        toolbar: ['create'],
                        columns: [{
                            title: "字段名稱",
                            field: "FieldName"
                        }, {
                            title: "Api參數名",
                            field: "ParaName"
                        }, {
                            command: ["edit", "destroy"]
                        }
                        ]
                    });
                    var dsEx = new kendo.data.DataSource({
                        data: e.data.ExProps,
                        schema: {
                            model: {
                                id: "PropName",
                                fields: {
                                    PropName: { editable: true, validation: { required: true } },
                                    PropValue: { editable: true, validation: { required: true } }
                                }
                            }
                        }
                    });
                    e.detailRow.find(".expropgrid").kendoGrid({
                        dataSource: dsEx,
                        editable: "popup",
                        toolbar: ['create'],
                        columns: [{
                            title: "屬性名稱",
                            field: "PropName"
                        }, {
                            title: "屬性值",
                                field: "PropValue"
                        }, {
                            command: ["edit", "destroy"]
                        }
                        ]
                    });
                },
           

還要定義綁定函數如下:

fn_dataBound: function (e) {
                   e.sender.expandRow(e.sender.tbody.find("tr.k-master-row").first());
                }
           

模闆的定義如下:

<script id="functiongridsubtemp" type="text/x-kendo-template">
        <div class="functionTab">
            <ul>
                <li >輸入參數</li>
                <li>輸出參數</li>
                <li>附加屬性</li>
            </ul>
            <div>
                <div class='inparagrid'></div>
            </div>
            <div>
                <div class='outparagrid'></div>
            </div>
            <div>
                <div class='expropgrid'></div>
            </div>
        </div>
        
    </script>
           

這個模闆相對複雜,在一個分頁控件中顯示三個網格,用于顯示函數的輸入參數、輸出參數和附加參數。需要注意的是,模闆中不能用id進行标記,因為在頁面中,每一行都需要使用模闆建立一組元素,在模闆中定義id,不能保證id唯一。是以在函數中,需要使用class來擷取相關的元素。

Grid彈出編輯窗下拉框控件

如果在Grid彈出窗中有下拉框控件,可以使用values屬性直接綁定到數組,在彈出編輯窗中自動生成下拉框,示例代碼如下:

<div id="fieldgrid" class="grid"
                             data-role="grid"
                             data-sortable="true"
                             data-toolbar="['create']"
                             data-bind="source: fieldSource"
                             data-editable='{"mode": "popup" }'
                             data-columns='[
                                  {"field":"Name","title":"字段名稱"},
                                  {"field":"Title","title":"字段說明"},
                                  {"field":"DataType","title":"字段類型","values":dsDataType},
                                 {"field":"ControlType","title":"控件類型", "values":dsControlType},
                                 {"field":"DefaultValue","title":"預設值"},
                                 {"field":"Editable","title":"是否可編輯"},
                                 {"field":"Visible","title":"是否可見"},
                                 {"field":"DisplayOrder","title":"顯示順序", editor: numberEditor},
                                         {"field":"IsCascade","title":"是否級聯"},
                                         {"field":"CascadeSubField","title":"級聯下級"},
                                         {"field":"CascadeParentField","title":"級聯上級"},

                                     {"command": [ "edit", "destroy" ], "filterable": false, "sortable": false, "width:": "240px"}
                                     ]'
                             data-scrollable="false">
           

上面的代碼使用了mvvm的定義模式,其中DataType和ControlType字段的values綁定到數組,數組定義示例如下:

var dsDataType = [
    { value: 'number', text: '數值' },
    { value: 'string', text: '字元串' }, 
    { value: 'date', text: '日期' },  
    { value: 'boolean', text: '布爾' }];
var dsControlType = [
   { value: 'InputNumber', text: '數字輸入' },
   { value: 'InputText', text: '文本輸入' },
   { value: 'DatePicker', text: '日期輸入' },
   { value: 'Checkbox', text: '單選框' },
   { value: 'Selection', text: '下拉框' },
   { value: 'ComboBox', text: '級聯下拉框' }
        ];
           

數組定義時值字段名為value,顯示字段名為text。在彈出編輯窗中,會自動建立為下拉框,顯示結果如下:

Kendo UI Grid 使用總結

使用這種方法,就不需要為下拉框定制顯示控件了。

為Grid控件建立自定義彈出編輯窗

Kendo UI Grid控件自帶彈出窗編輯,隻要在資料源中定義schema,就可以自動生成編輯界面,代碼如下:

<div class="form container" id="divForm">
        <div id="divGrid">
            <div id="mygrid" class="grid"
                 data-role="grid"
                 data-sortable="true"
                 data-toolbar="['create']"
                 data-bind="source: dataSource"
                 data-editable='{"mode": "popup" }'
                 data-columns='[
             {"field":"Id","title":"ID"},
             {"field":"Name","title":"姓名"},
             {"field":"Age","title":"年齡"},
             {"field":"JoinDate","title":"入職日期","format": "{0:yyyy-MM-dd}"},
             {"field":"Sex","title":"性别","template": "#if (Sex==1){# 女 #}else{# 男 #}# "},
             {"field":"Married","title":"婚姻狀況","template": "#if (Married){# 已婚 #}else{# 未婚 #}# "},
             {"command": [ "edit", "destroy" ], "filterable": false, "sortable": false, "width:": "240px"}
             ]'
                 data-scrollable="false">
            </div>
        </div>
    </div>
    <script>
      
        $(document).ready(function () {
            var viewModel = kendo.observable({
                dsSex: [{ value: 0, text: '男' }, { value: 1, text: '女' }],
                dataSource: new kendo.data.DataSource(
                    {
                        data: [],
                        schema: {
                            model: {
                                id: "Id",
                                fields: {
                                    Id: { editable: true, nullable: false },
                                    Name: { validation: { required: true } },
                                    Age: { type: "number" },
                                    Sex: { editable: true },
                                    JoinDate: { type: "date", editable: true },
                                    Married: { type: "boolean", editable: true }
                                }
                            }
                        }

                    })
             
            });
           
            kendo.bind($("#divForm"), viewModel);

        });

    </script>
           

自動生成的編輯界面對于基本資料類型的字段夠用了,但在實際中,會有更複雜的要求,比如,某些字段需要使用下拉框或者更複雜的控件,或者我們希望字段多列排列,這時,需要用到自定義的模闆,上面的網格的自定義編輯模闆如下:

<script id="popup_editor" type="text/x-kendo-template">
        <div class="form container">
            <div class="form-group row">
                 <label class="col-sm-2 control-label" for="Id">ID</label>
                 <div class="col-sm-4">
                    <input type='number' class='k-textbox' data-bind="value: Id" />
                    <span class="k-invalid-msg" data-for="Id"></span>
                </div>
            <!--</div>
            <div class="form-group row">-->
                
                <label class="col-sm-2" for="Name">姓名</label>
               
                
                <div class="col-sm-4 ">
                    <input type='text' name="Name" class='k-input k-textbox k-valid' data-bind="value: Name" required="required" />
                    <span class="k-invalid-msg" data-for="Name"></span>
                </div>
            </div>
            <div class="form-group row">
                <label class="col-sm-2 control-label" for="Age">年齡</label>
                <div class="col-sm-4">
                    <input type='number' style="" data-role="numerictextbox" class='form-control' data-bind="value: Age" />
                    <span class="k-invalid-msg" data-for="Age"></span>
                </div>
            </div>
            <div class="form-group row">
                <label class="col-sm-2 control-label" for="val_JoinDate">參加日期</label>
                <div class="col-sm-4">
                    <input data-role="datepicker" data-culture="zh-CN" style="" class='form-control' data-bind="value: JoinDate," />
                    <span class="k-invalid-msg" data-for="JoinDate"></span>
                </div>
            </div>
            <div class="form-group row">
                <label class="col-sm-2 control-label" for="val_Married">已婚</label>
                <div class="col-sm-4">
                    <input type="checkbox" style="" data-bind="checked: Married," />
                    <span class="k-invalid-msg" data-for="Married"></span>
                </div>
            </div>
            <div class="form-group row">
             
                <label class="col-sm-2 control-label" for="val_Sex">性别</label>
                <div class="col-sm-4">
                    <select data-role="dropdownlist" class='form-control' data-text-field="text"
                            data-value-field="value" data-bind="source:dsSex,value: Sex">
                    </select>
                    <span class="k-invalid-msg" data-for="Sex"></span>
                </div>
            </div>

        </div>
    </script>
           

模闆使用script标記,類型為text/x-kendo-template,說明是kendo的模闆。模闆語言就是html,其中的data标記與kendo MVVM一緻。模闆中有幾點需要注意:

  • 模闆中需要驗證的字段,需要定義name屬性,如果不定義,驗證資訊無法顯示
  • 需要定義 用于顯示驗證資訊
  • 如果需要多列顯示,需要在頁面中定義自定義的樣式:
<style>
        .k-edit-form-container {
            width: 700px;
        }

            .k-edit-form-container div {
                box-sizing: border-box;
            }
            .k-edit-form-container label {
                box-sizing: border-box;
            }
       
    </style>
           

需要将相關元素的box-sizing 設定為border-box

Grid彈出編輯窗自定義編輯控件

上節介紹了建立自定義的彈出編輯窗體,這種方法的好處是可以完全控制編輯窗體中的各個控件,但也有些麻煩,如果隻需要修改其中的幾個控件,完全重寫一個編輯窗體就顯得沒有必要了。這時,可以為單個編輯控件進行定制。示例代碼如下:

<div id="commandgrid" class="grid"
                             data-role="grid"
                             data-sortable="true"
                             data-toolbar="['create']"
                             data-bind="source: commandSource"
                             data-editable='{"mode": "popup" }'
                             data-columns='[
                                 {"field":"Name","title":"名稱"},
                                 {"field":"Title","title":"文本"},
                                 {"field":"FunctionName","title":"函數名稱"},
                                  {"field":"DisplayOrder","title":"顯示順序", editor: numberEditor},
                                 {"command": [ "edit", "destroy" ], "filterable": false, "sortable": false, "width:": "240px"}
                                 ]'
                             data-scrollable="false">
                        </div>
           

上面的代碼使用了mvvm的定義方式,其中DisplayOrder字段使用了自定義的editor,numberEditor是一個自定義的函數,在這個函數裡建立自定義的控件并添加到container中:

function numberEditor(container, options) {
            $('<input name="' + options.field + '"/>')
                .appendTo(container)
                .kendoNumericTextBox({
                    format:"n0"
                });
        }
           

這裡定義了數字輸入的格式,不顯示小數。

根據條件改變行顯示

在網格顯示時,經常需要設定條件,根據網格中的資料,改變網格或者所在行的顯示屬性。比如如果資料超過某個限度,需要顯示報警顔色。這些需求包括當滿足一定條件時:

  • 整行背景顔色改變
  • 字型顔色改變
  • 字型加粗
  • 增加删除線
  • 當網格的第一列時複選框時,自動選中目前行
  • 當網格的第一列時複選框時,不允許選擇

在Kendo Grid的dataBound事件中,可以實作上述功能。 示例代碼如下:

dataBound: function (e) {
                        
                        var rows = e.sender.tbody.children();
                        for (var j = 0; j < rows.length; j++) {
                            var row = $(rows[j]);
                            var dataItem = e.sender.dataItem(row);

                            var age = dataItem.get("AGE");
                            
                            var cells = row.children();
                            if (age > 15) {
                                
                                for (var idx = 0; idx < cells.length; idx++) {
                                    var mytd = cells[idx];
                                    cells[idx].bgColor = "green"; //設定行背景顔色
                                 }
                                
                            }

                            if (age < 15) {
                                for (var idx = 0; idx < cells.length; idx++) {
                                    var mytd = cells[idx];
                                    if (idx == 0) {
                                        var chk = mytd.children[0];
                                        $(chk).prop("checked", true); //設定選擇框
                                    }
                                    
                                    $(mytd).css("font-weight", "bold"); //設定字型
                                    $(mytd).css("color", "red");//設定字型顔色
                                    $(mytd).css("text-decoration", "line-through");//加删除線
                                    $(mytd).height(100);//設定行高
                                }

                            }
                            
                        }
                    }
           

本文來自部落格園,作者:尋找無名的特質,轉載請注明原文連結:https://www.cnblogs.com/zhenl/p/15920798.html