easyui Datagrid Editing Experience

Keywords: Attribute JQuery



Editable Form Use Experience Sharing (Continuous Update)

For Easyui editable form, the individual is relatively unfamiliar, although the operation may be more convenient than the use of form modification, but editable form code quality requirements are often higher, if not skilled, prone to such or other problems, this article summarizes the experience of their own use.

Relevant Interface Method

Name Parameter Description
Method:
beginEdit index Make rows editable
endEdit index End the editable state of the line, and the changes will be temporarily saved
cancelEdit index Cancel the edit status and the changes will be restored.
getChanges type Get the changed row data, return an object array, and each element of the array contains the field key values that correspond to the modified rows; it is important to note that after using the acceptChanges method, all the changed data will be cleared, and then getChanges can not get the data. Input is type, which contains the following three values:
Insert: Get only the inserted row data;
Deleted: Get only deleted row data;
Update: Get only fields with updated row data;
If no type is set, all the changed row data will be retrieved
acceptChanges null Submit all the changed rows, and after submitting, you can't use rejectChanges to roll back the changes you made.
rejectChanges none Roll back all operations, restore to the original data of the table, and after acceptChanges, you can't roll back any more.
validateRow index The row data is checked, and all fields are checked before returning true, which is included in the index of the row.
getEditors index Get all the editors for a row. Note that the method must be executed after the beginEdit method, and before the endEdit method executes, the editor can only be obtained from the line in the editing state. Return to the object array, each element contains the following information:
actions: the actions that the editor can do, same as the editor definition.
target: The editor corresponds to the jQuery object of the DOM.
Field: The field of a field.
type: Editor types, such as'text','combobox','datebox', etc.
getEditor options Obtain an editor for a row or column. Note that the method must be executed after the beginEdit method, and before the endEdit method executes, the editor can be obtained only for the line in the editing state. The return value is an object, and the object information is the same as getEditors. Participation includes:
Index: row index.
Field: The field of a field.
addEditor params Adding a column editor, params is an object, including field attribute and editor attribute, where editor object contains type and editor options attribute; params can also be an array for simultaneous operation of multiple columns.
removeEditor params Delete the editor for a column. params can be a field for a column or an array containing multiple fields.
Event:
onClickRow rowIndex, rowData A row click event, which usually triggers the editable state of the row within the event so that the current row can be edited.
onBeforeEdit rowIndex, rowData This event is triggered when the line enters an editable state.
onAfterEdit rowIndex, rowData, changes When the editable state is terminated, the event is triggered, and changes are the object, recording the changed fields and their corresponding values.
onCancelEdit rowIndex, rowData Call this event when line editing is cancelled.

Column attribute formatter

Formatter attributes are very important for editable tables. For editors like combobox and checkbox, if formatter is not used for formatting, the final datagrid will display our key instead of desc we want, so formatter attributes are very important.

Editor type

According to the design of Easyui datagrid, each column can correspond to an editor type, such as checkbox, drop-down box, etc. The framework comes with the following editors:
text,textarea,checkbox,numberbox,validatebox,datebox,combobox,combotree

In addition to the editor that comes with the framework, datagrid also provides a flexible extension interface that allows users to easily extend the editor themselves, such as the official example mentioned:

  1. $.extend($.fn.datagrid.defaults.editors, {
  2.     text: {
  3.         init: function(container, options){
  4.             var input = $('<input type="text" class="datagrid-editable-input">').appendTo(container);
  5.             return input;
  6.         },
  7.         getValue: function(target){
  8.             return $(target).val();
  9.         },
  10.         setValue: function(target, value){
  11.             $(target).val(value);
  12.         },
  13.         resize: function(target, width){
  14.             var input = $(target);
  15.             if ($.boxModel == true){
  16.                 input.width(width - (input.outerWidth() - input.width()));
  17.             } else {
  18.                 input.width(width);
  19.             }
  20.         }
  21.     }
  22. });
Editor based on my97

Let's not mention the method of integrating My97 date control into editable tables, as long as the type of editor is extended. Of course, the web page should first introduce the WdatePicker.js file of my97, and then copy the text editor to write My97 date editor:

  1. $.extend($.fn.datagrid.defaults.editors, {
  2.     my97 : {
  3.         init : function(container, options) {
  4.             var input = $('<input class="Wdate" type="text" onclick="WdatePicker({dateFmt:\'yyyy-MM-dd HH:mm:ss\',readOnly:true});"  />')
  5.                     .appendTo(container);
  6.             return input;
  7.         },
  8.         getValue : function(target) {
  9.             return $(target).val();
  10.         },
  11.         setValue : function(target, value) {
  12.             $(target).val(value);
  13.         },
  14.         resize : function(target, width) {
  15.             var input = $(target);
  16.             if ($.boxModel == true) {
  17.                 input.width(width - (input.outerWidth() - input.width()));
  18.             } else {
  19.                 input.width(width);
  20.             }
  21.         }
  22.     }
  23. });

Why integrate my97 into editable tables? It covets its powerful functions, especially time constraints, convenient formatting definitions and so on. For time constraints, it seems that just expanding the editor is not enough. For example, I have two fields, one is the start date, the other is the end date, and the two fields are constrained by each other. How should we deal with them? This will be followed by a further solution.

Simple password editor

See: http://www.easyui.info/archives/646.html

Dynamic Add/Delete Editors

These two methods were originally written by Xia Jing. http://easyui.btboys.com/post-83.html On this basis, I made a slight modification, mainly to put the method body into the each, so as to support multiple grid s to operate together.

  1. $.extend($.fn.datagrid.methods, {
  2.     addEditor : function(jq, param) {
  3.         return jq.each(function(){
  4.             if (param instanceof Array) {
  5.                 $.each(param, function(index, item) {
  6.                     var e = $(jq).datagrid('getColumnOption', item.field);
  7.                     e.editor = item.editor;
  8.                 });
  9.             } else {
  10.                 var e = $(jq).datagrid('getColumnOption', param.field);
  11.                 e.editor = param.editor;
  12.             }
  13.         });
  14.     },
  15.     removeEditor : function(jq, param) {
  16.         return jq.each(function(){
  17.             if (param instanceof Array) {
  18.                 $.each(param, function(index, item) {
  19.                     var e = $(jq).datagrid('getColumnOption', item);
  20.                     e.editor = {};
  21.                 });
  22.             } else {
  23.                 var e = $(jq).datagrid('getColumnOption', param);
  24.                 e.editor = {};
  25.             }
  26.         });
  27.     }
  28. });

These two extensions are suitable for dynamically controlling whether a column can be edited or not and the editor type of the column, but special attention should be paid when using them: do not use these two methods when the current table is still in the editing state row, which will cause the getEditor method to obtain inaccurate data, so these two extensions are more suitable for single-line editing mode.

Cascade operation of fields

Cascade operation of combobox

For example, there are Jiangning District and Qixia District under Nanjing and Guanyun County under Lianyungang. When we choose different cities, the combobox content of district and county level administrative region should change dynamically, which is cascade.

The way combobox wants to cascade is very simple. It can be easily implemented by using the onSelect and onShowPanel events of combobox. The onSelect event is used for the municipal administrative areas mentioned in our example, while the onShowPanel is used for the district and county administrative areas mentioned in our example. Both of them are designed to dynamically load the contents of county-level areas. For example:

  1. <th rowspan="2" data-options="field:'city',width:100,align:'center',formatter:regionFormatter,
  2.     editor:{
  3.         type:'combobox',
  4.         options:{
  5.             valueField:'id',
  6.             textField:'name',
  7.             data:getRegions(''),
  8.             required:true,
  9.             onSelect:function(record){
  10.                 var target = $('#tt').datagrid('getEditor',{'index':editingIndex,'field':'county'}).target;
  11.                 target.combobox('clear');
  12.                 target.combobox('loadData',getRegions(record.id));
  13.                 target.combobox('setValue',getRegions(record.id)[0].id);
  14.             }
  15.         }
  16. }">City</th>
  17. <th rowspan="2" data-options="field:'county',width:100,align:'center',formatter:regionFormatter,
  18.     editor:{
  19.         type:'combobox',
  20.         options:{
  21.             valueField:'id',
  22.             textField:'name',
  23.             data:regions,
  24.             required:true,
  25.             onShowPanel:function(){
  26.                 var targetCity = $('#tt').datagrid('getEditor',{'index':editingIndex,'field':'city'}).target;
  27.                 var targetCounty = $('#tt').datagrid('getEditor',{'index':editingIndex,'field':'county'}).target;
  28.                 var valueCity = targetCity.combobox('getValue');
  29.                 var valueCounty = targetCounty.combobox('getValue');
  30.                 targetCounty.combobox('clear');
  31.                 targetCounty.combobox('loadData',getRegions(valueCity));
  32.                 targetCounty.combobox('setValue',valueCounty);
  33.             }
  34.         }
  35. }">District and county</th>

It should be noted that we use getEditor method extensively in the code. This method is actually the link of linkage. Through it, we can realize the carrier of interaction between editors. Through it, we can locate any existing editor, and then carry out the necessary operation.

Cascade of Text Type Editors

Similar text type editors are text,textarea,numberbox,validatebox,datebox editors. Here, we take the example mentioned earlier, the date box, and instead use our extended my97 editor, which we use to implement constraints between two dates.

First, the most important is the getEditor method, which is responsible for the carrier of interaction between different editors; second, for text, we need to bind events ourselves to achieve constraints on other editors, and the best thing to bind is to have its own namespace to prevent conflicts with events that come with datagrid, where we use click.myNameSpace. Looking directly at the code that implements the date frame linkage may be clearer:

  1. onClickRow:function (rowIndex) {
  2.     editingIndex = rowIndex;
  3.     if (lastIndex != rowIndex) {
  4.         if ($(this).datagrid('validateRow', lastIndex)) {
  5.             $(this).datagrid('endEdit', lastIndex);
  6.             $(this).datagrid('beginEdit', rowIndex);
  7.             var startTimeEditor = $('#tt').datagrid('getEditor', {
  8.                         index : rowIndex,
  9.                         field : "startTime"
  10.                     });
  11.             var endTimeEditor = $('#tt').datagrid('getEditor', {
  12.                         index : rowIndex,
  13.                         field : "endTime"
  14.                     });
  15.             if (startTimeEditor) {
  16.                 startTimeEditor.target.attr("onclick""");
  17.                 startTimeEditor.target.unbind("click.myNameSpace").bind(
  18.                         "click.myNameSpace"function(e) {
  19.                             var initObj = {
  20.                                 dateFmt : 'yyyy-MM-dd',
  21.                                 readOnly : false
  22.                             };
  23.                             if (endTimeEditor.target.val() != "")
  24.                                 initObj["maxDate"] = endTimeEditor.target.val();
  25.                             WdatePicker(initObj);
  26.                         });
  27.             }
  28.             if (endTimeEditor) {
  29.                 endTimeEditor.target.attr("onclick""");
  30.                 endTimeEditor.target.unbind("click.myNameSpace").bind(
  31.                         "click.myNameSpace"function(e) {
  32.                             var initObj = {
  33.                                 dateFmt : 'yyyy-MM-dd',
  34.                                 readOnly : false
  35.                             };
  36.                             if (startTimeEditor.target.val() != "")
  37.                                 initObj["minDate"] = startTimeEditor.target
  38.                                         .val();
  39.                             WdatePicker(initObj);
  40.                         });
  41.             }
  42.             lastIndex = rowIndex;
  43.         } else {
  44.             $(this).datagrid('selectRow', lastIndex);
  45.         }
  46.     }
  47. }

We first use startTime Editor. target. attr ("onclick","); delete this binding method, and then use jQuery's event mechanism to bind, you can see that the code is actually a refactoring of the my97 editor, so as to achieve the limit of the optional date range of the my97 date box.

Dependence of edit fields on non-edit fields

Sometimes editable fields also depend on non-editable fields. A typical scenario, such as hotel checkout form, has the fields of "amount receivable (automatic calculation, non-editable)" and "amount receivable (cashier can fill in manually, editable)", in which case, the amount receivable can obviously not be greater than the amount receivable.

In fact, the processing of this situation is simpler than the cascade of two editable fields. Using the "dynamic add/delete editor" extension mentioned above, we only need to dynamically set the editor type of the "paid amount" field in the onClickRow event.

Assuming that the editor type of the paid-in amount field is validatebox, using our extended max maximum rule, we just need to set the maximum dynamically. The following code is for reference only:

  1. onClickRow:function(rowIndex){
  2.     if (lastIndex != rowIndex){
  3.         $('#tt').datagrid('endEdit', lastIndex);
  4.         //Obtaining the value of the current bank's receivables as a new verification rule
  5.         var newMax = 'max[' + $('#tt').datagrid('getSelected').receivable + ']';
  6.         //Change the editor type of the paid-in amount field dynamically (it is safe to change the editor type only if there are no rows in the editing state for the entire table)
  7.         $('#tt').datagrid('addEditor ',{field:'paid',editor:{type:'validatebox',options:{validType:newMax}}});
  8.         $('#tt').datagrid('beginEdit', rowIndex);
  9.     }
  10.     lastIndex = rowIndex;
  11. }

Note: Because changing the editor type dynamically requires that all rows exit the editable state before it is safe, this approach is only suitable for single-line editing mode.

Data submission and recovery

Using loading to Improve User Experience

In this place, we need to temporarily change the loadMsg, because the default prompt is "Loading..." When we submit data, we should change it to "in storage..." After saving successfully, restore the loadMsg attribute, for example:

  1. if ($.isEmptyObject(chanages) == false) {
  2.     var bakMsg = $(this).datagrid('options').loadMsg;
  3.     $(this).datagrid('options').loadMsg = "In storage...";
  4.     $('#tt').datagrid('loading');
  5.     setTimeout(function() {
  6.                 $('#tt').datagrid('loaded');
  7.                 $('#tt').datagrid('options').loadMsg = bakMsg;
  8.             }, 1000);
  9. }
Getting raw data after editing

Before invoking acceptChanges, the original row data of the table can be obtained through the originalRows attribute of the object bound to the DOM, that is:

  1. var originalRows = $('#tt').data('datagrid').originalRows;

After calling acceptChanges, the raw data disappears completely and can never be retrieved.
So much is summarized at present, and will be added later. All the functions mentioned in this article can be found in the demo page.




Posted by coder9 on Mon, 24 Jun 2019 11:26:22 -0700