Preface: When I introduced the bootstrapTable component before, I mentioned its in-line editing function, but for the purpose of displaying the function, I have taken this over and said it is a sin! Recently, I still plan to use the in-line editing in the project, so I studied the x-editable component again. I have encountered some pitfalls, so let’s record the pits here! Friends who want to know about bootstrapTable can move to the JS component series - table component artifact: bootstrap table.
1. Introduction to x-editable component
The x-editable component is a plug-in for creating editable pop-up boxes. It supports three styles: bootstrap, Jquery UI, and Jquery. The general effect is as follows:
According to the blogger's usual style, the first one must be chosen here. First, give the open source address.
x-editable open source address: https://github.com/vitalets/x-editable
x-editable document address: http://vitalets.github.io/x-editable/docs.html
x-editable online Demo: http://vitalets.github.io/x-editable/demo-bs3.html
1. First experience of x-editable
First download the source code based on bootstrap to the local area. References to relevant files.
<link href="/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" /><link href="~/Content/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet" /><script src="/Scripts/jquery-1.9.1.min.js"></script><script src="/Content/bootstrap/js/bootstrap.min.js"></script><script src="~/Content/bootstrap3-editable/js/bootstrap-editable.js"></script>
Page elements
Copy the code as follows: <a href="#" id="username" data-type="text" data-title="username">username</a>
js initialization
$(function () { $('#username').editable(); });Effect display
The above is to set the x-editable parameters through the html data attribute. Of course, I can also set the parameters during initialization. For example, I just give an empty a tag: <a href="#" id="username">username</a>
js initialization
$(function () { $('#username').editable({ type: "text", //The type of the edit box. Support text|textarea|select|date|checklist and other titles: "Username", //The title of the edit box was disabled: false, //Doess edit emptytext: "empty text", //Default text mode of empty value: "inline", //The mode of edit box: supports popup and inline mode, the default is popup validate: function (value) { // Field verification if (!$.trim(value)) { return 'can't be empty'; } } }); });View the effect
Let's have a slightly more complicated one
<a href="#" id="department">Select department</a>
$(function () { $('#department').editable({ type: "select", //The type of editing box. Support text|textarea|select|date|checklist and other sources: [{ value: 1, text: "Development Department" }, { value: 2, text: "Sales Department" }, { value: 2, text: "Sales Department" }, { value: 3, text: "Administrative Department"}], title: "Select Department", //The title of the editing box disabled: false, //Do not disable editing emptytext: "empty text", //The default text mode of empty value: "popup", //The mode of editing box: supports popup and inline mode, the default is popup validate: function (value) { //field verification if (!$.trim(value)) { return 'can't be empty'; } } }); });View the effect
The above article only gives some commonly used fields. Of course, the x-editable component has many other functional parameters. If you are interested, you can check the documentation. The official documentation has detailed descriptions for each parameter.
2. BootstrapTable initial plan for editing in-line
After talking for a long time, the above is just a prelude. We ultimately hope to implement in-line editing in bootstrapTable. According to the above rules, if we want to use x-editable to implement in-line editing, there must be an a tag in the cell of the table, and then the a tag is initialized. With this idea, let’s try this way first.
Quote related files
<link href="/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" /><link href="~/Content/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet" /><link href="/Content/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" /><script src="/Scripts/jquery-1.9.1.min.js"></script><script src="/Content/bootstrap/js/bootstrap.min.js"></script><script src="~/Content/bootstrap3-editable/js/bootstrap-editable.js"></script><script src="~/Content/bootstrap-table/bootstrap-table.js"></script><script src="/Content/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
Related initialization of bootstrapTable
<script type="text/javascript"> var curRow = {}; $(function () { $("#tb_user").bootstrapTable({ toolbar: "#toolbar", idField: "Id", pagination: true, showRefresh: true, search: true, clickToSelect: true, queryParams: function (param) { return {}; }, url: "/Editable/GetUsers", columns: [{ checkbox: true }, { field: "UserName", title: "Username", formatter: function (value, row, index) { return "<a href=/"#/" name=/"UserName/" data-type=/"text/" data-pk=/"+row.Id+"/" data-title=/"Username/">" + value + "</a>"; } }, { field: "Age", title: "Age", }, { field: "Birthday", title: "Birthday", formatter: function (value, row, index) { var date = eval('new ' + eval(value).source) return date.format("yyyyy MM month ddd day"); } }, { field: "DeptName", title: "Department" }, { field: "Hodd", title: "Host" }], onClickRow: function (row, $element) { curRow = row; }, onLoadSuccess: function (aa, bb, cc) { $("#tb_user a").editable({ url: function (params) { var sName = $(this).attr("name"); curRow[sName] = params.value; $.ajax({ type: 'POST', url: "/Editable/Edit", data: curRow, dataType: 'JSON', success: function (data, textStatus, jqXHR) { alert('Save successfully!'); }, error: function () { alert("error");} }); }, type: 'text' }); }, }); }); }); });Backend method
Background testing method
public JsonResult GetUsers() { var lstRes = new List<User>(); lstRes.Add(new User() { Id = "1", UserName = "Zhang San", Age = 22, Birthday = Convert.ToDateTime("1994-12-21"), DeptId = "1", DeptName = "R&D Department" }); lstRes.Add(new User() { Id = "2", UserName = "Li Si", Age = 28, Birthday = Convert.ToDateTime("1988-09-09"), DeptId = "2", DeptName = "Sales Department" }); lstRes.Add(new User() { Id = "3", UserName = "Wrestle Coat Uncle", Age = 40, Birthday = Convert.ToDateTime("1976-09-01"), DeptId = "2", DeptName = "Sales Department" }); lstRes.Add(new User() { Id = "4", UserName = "Lightning Prawn", Age = 37, Birthday = Convert.ToDateTime("1979-03-12"), DeptId = "4", DeptName = "Creative Department" }); lstRes.Add(new User() { Id = "5", UserName = "Han Meimei", Age = 29, Birthday = Convert.ToDateTime("1987-05-01"), DeptId = "5", DeptName = "Business Department" }); return Json(lstRes, JsonRequestBehavior.AllowGet); } public JsonResult Edit(User user) { //Update the return after deserialization Json(new { }, JsonRequestBehavior.AllowGet); }This can indeed achieve the desired effect, and it seems that it can also be edited within the row, but if there are no columns that require editing within the row and there are many columns, then does it take for each column to format the same way? And this kind of writing is obviously rigid, which is really hard for bloggers to accept. So I looked for an example and found that the js bootstrap-table-editable.js exists in the extension of bootstrapTable.
3. BootstrapTable editing final plan
Well, the blogger admits that the above is still a prelude, because the blogger thinks this may be a general idea to solve the problem, so the length of these preludes may be a bit too much. First, let’s take a look at the bootstrap-table-editable.js file:
/** * @author zhixin wen <[email protected]> * extensions: https://github.com/vitalets/x-editable */!function ($) { 'use strict'; $.extend($.fn.bootstrapTable.defaults, { editable: true, onEditableInit: function () { return false; }, onEditableSave: function (field, row, oldValue, $el) { return false; }, onEditableShown: function (field, row, $el, editable) { return false; }, onEditableHidden: function (field, row, $el, reason) { return false; } }); $.extend($.fn.bootstrapTable.Constructor.EVENTS, { 'editable-init.bs.table': 'onEditableInit', 'editable-save.bs.table': 'onEditableSave', 'editable-shown.bs.table': 'onEditableShown', 'editable-hidden.bs.table': 'onEditableHidden' }); var BootstrapTable = $.fn.bootstrapTable.Constructor, _initTable = BootstrapTable.prototype.initTable, _initBody = BootstrapTable.prototype.initBody; BootstrapTable.prototype.initTable = function () { var that = this; _initTable.apply(this, Array.prototype.slice.apply(arguments)); if (!this.options.editable) { return; } $.each(this.columns, function (i, column) { if (!column.editable) { return; } var _formatter = column.formatter; column.formatter = function (value, row, index) { var result = _formatter ? _formatter(value, row, index) : value; return ['<a href="javascript:void(0)"', ' data-name="' + column.field + '"', ' data-pk="' + row[that.options.idField] + '"', ' data-value="' + result + '"', '>' + '</a>' ].join(''); }; }); }; BootstrapTable.prototype.initBody = function () { var that = this; _initBody.apply(this, Array.prototype.slice.apply(arguments)); if (!this.options.editable) { return; } $.each(this.columns, function (i, column) { if (!column.editable) { return; } that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable) .off('save').on('save', function (e, params) { var data = that.getData(), index = $(this).parents('tr[data-index]').data('index'), row = data[index], oldValue = row[column.field]; row[column.field] = params.submitValue; that.trigger('editable-save', column.field, row, oldValue, $(this)); }); that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable) .off('shown').on('shown', function (e, editable) { var data = that.getData(), index = $(this).parents('tr[data-index]').data('index'), row = data[index]; that.trigger('editable-shown', column.field, row, $(this), editable); }); that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable) .off('hidden').on('hidden', function (e, reason) { var data = that.getData(), index = $(this).parents('tr[data-index]').data('index'), row = data[index]; that.trigger('editable-hidden', column.field, row, $(this), reason); }); }); this.trigger('editable-init'); };}(jQuery);
This js actually makes a simple encapsulation of x-editable, adding editable attributes of columns and editing and saving some events. With this as the basis, the code we edited in the industry became like this.
The files that need to be referenced are as follows:
<link href="/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" /><link href="~/Content/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet" /><link href="/Content/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" /><script src="/Scripts/jquery-1.9.1.min.js"></script><script src="/Content/bootstrap/js/bootstrap.min.js"></script><script src="~/Content/bootstrap3-editable/js/bootstrap-editable.js"></script><script src="~/Content/bootstrap-table/bootstrap-table.js"></script><script src="/Content/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script><script src="/Content/bootstrap-table/ src="~/Content/bootstrap-table/extensions/editable/bootstrap-table-editable.js"></script>
1. Text box
$(function () { $("#tb_user").bootstrapTable({ toolbar: "#toolbar", idField: "Id", pagination: true, showRefresh: true, search: true, clickToSelect: true, queryParams: function (param) { return {}; }, url: "/Editable/GetUsers", columns: [{ checkbox: true }, { field: "UserName", title: "Username", editable: { type: 'text', title: 'username', validate: function (v) { if (!v) return 'Username cannot be empty'; } } } }, { field: "Age", title: "Age", }, { field: "Birthday", title: "Birthday", formatter: function (value, row, index) { var date = eval('new ' + eval(value).source) return date.format("yyyy-MM-dd"); } }, { field: "DeptName", title: "Department" }, { field: "Hobby", title: "Hobby" }], onEditableSave: function (field, row, oldValue, $el) { $.ajax({ type: "post", url: "/Editable/Edit", data: row, dataType: 'JSON', success: function (data, status) { if (status == "success") { alert('Successful submission of data'); } }, error: function () { alert('Edit failed'); }, complete: function () { } }); } });The corresponding update method of the background
public JsonResult Edit(User user) { //Update entity return Json(new { }, JsonRequestBehavior.AllowGet); }After testing, the username column can be edited freely. Similarly, the age column can also be changed to this
{ field: "Age", title: "Age", editable: { type: 'text', title: 'age', validate: function (v) { if (isNaN(v)) return 'Age must be a number'; var age = parseInt(v); if (age <= 0) return 'Age must be a positive integer'; } } }No modification is required for the rest.
Code explanation: The editable parameters are configured in the initial columns attribute above. Note that the Json object corresponding to the editable attribute of each column here is the initialized Json object in x-editable. That is to say, what attributes can be configured when we initialize x-editable, and the same can be configured in the editable attribute of the column, so it will be much more enjoyable to use. The edited submission method is uniformly placed in the onEditableSave event to handle it uniformly.
2. Time selection box
With the above knowledge as a basis, let's initialize the birthday column:
{ field: "Birthday", title: "Birthday", formatter: function (value, row, index) { var date = eval('new ' + eval(value).source) return date.format("yyyy-MM-dd"); }, editable: { type: 'date', title: 'birthday' } }No modifications are required elsewhere to get the effect:
This is the default style of x-editable. If you don't feel happy, you can configure it yourself. x-editable provides many parameters for configuring date boxes, as follows:
Of course, if the time is accurate to the time, minutes and seconds, you can use an edit box of datetime type. The following is the official time frame editing effect, which looks pretty good.
3. Pull down box
There is another important tag in form editing, which is select. As mentioned above, we know that x-editable provides us with a drop-down box editing mode, for example, the editing of this column in our department can be written like this:
{ field: "DeptId", title: "Department", editable: { type: 'select', title: 'Department', source:[{value:"1",text:"R&D Department"},{value:"2",text:"Sales Department"},{value:"3",text:"Administrative Department"}] } }Get the effect
Of course, this method of setting data sources locally cannot meet our needs, because in many cases the options in the drop-down box are obtained remotely from the database. Of course, x-editable has also been considered for us, for example, we can write this:
{ field: "DeptId", title: "Department", editable: { type: 'select', title: 'Department', source: function () { var result = []; $.ajax({ url: '/Editable/GetDepartments', async: false, type: "get", data: {}, success: function (data, status) { $.each(data, function (key, value) { result.push({ value: value.ID, text: value.Name }); }); } }); return result; } } } }We configure a method in the background
public JsonResult GetDepartments() { var lstRes = new List<Department>(); lstRes.Add(new Department() { ID = "1", Name = "R&D Department" }); lstRes.Add(new Department() { ID = "2", Name = "Sales Department" }); lstRes.Add(new Department() { ID = "3", Name = "Administrative Department" }); lstRes.Add(new Department() { ID = "4", Name = "Creative Department" }); lstRes.Add(new Department() { ID = "5", Name = "Business Unit" }); return Json(lstRes, JsonRequestBehavior.AllowGet); }It can also achieve the results we want.
Code Question: Here is one thing that needs to be explained. Careful gardeners may have discovered that our field: "DeptId" here, why should we configure DeptId instead of DeptName? It's very simple, because we need to correspond to the value value in the data source.
4. Check box
In addition to the common editing boxes mentioned above, x-editable also provides us with editing of checkbox groups. for example:
{ field: "Hobby", title: "Host", editable: { type: "checklist", separator:",", source: [{ value: 'bsb', text: 'basketball' }, { value: 'ftb', text: 'football' }, { value: 'wsm', text: 'swimming' }], } }Get the effect:
Of course, if you have remote data, you can also use a method similar to the above to retrieve it.
5. The "ghosts never fade" select2
Speaking of the checkbox above, the blogger couldn't help but think of things like Multiselect, so he searched for the x-editable document, and found that it does not support Multiselect, but supports select2, and I don't know if this is good news. Based on the blogger's own usage experience and the chat experience in the technical communication group, I found that many people have encountered various style problems when using select2, and it is not easy to solve.
Since x-editable supports select2, let's try it. Anyway, the official demo is pretty good. Here is an example of using the official demo:
With a nervous mood, the blogger tried it himself.
Reference select2 file
<link href="~/Content/select2-bootstrap.css" rel="stylesheet" /><link href="~/Content/select2-master/dist/css/select2.min.css" rel="stylesheet" /><script src="~/Content/select2-master/dist/js/select2.full.min.js"></script>
Code Try
{ field: "Hobby", title: "Hobby", editable: { type: 'select2', title: 'hobby', name: 'Hobby', placement: 'top', success: function (response, newValue) { debugger; }, error: function(response, newValue) { debugger; }, url: function(params) { debugger; }, source: [{ id: 'bsb', text: 'basketball' }, { id: 'ftb', text: 'football' }, { id: 'wsm', text: 'Swimming' }], inputclass: 'input-large', select2: { allowClear: true, multiple: true, } } }Get the result:
It turns out that the selected value of select2 cannot be passed to the background normally. Anyway, the blogger has tried various parameters and according to the official demo, and they all ended in failure. I don't know how the official demo was successful. This question is first thrown out. If there are any gardeners who use it, please correct and answer it. If the blogger solves this problem in the future, it will also be updated here.
4. Summary
Another problem is that after the editing and submission is completed, the blogger encountered a problem in the project: if there is too much text content after submission, the width of the th in the head of the table and the width of the td in the tbody is not right, which looks quite disgusting. But I didn't encounter this problem when writing demos. Here is the solution.
Solve your troubles in just one sentence!
This article introduces the use of bootstrapTable combined with x-editable to implement in-line editing. Many of the questions in the article are explained based on the blogger's experience of using it. If you plan to use it, you can also try it.
If you still want to study in depth, you can click here to study and attach 3 exciting topics to you:
Bootstrap learning tutorial
Bootstrap practical tutorial
Bootstrap plug-in usage tutorial
The above is all about this article. I hope it can help you better learn the JS table component artifact bootstrap table.