UNPKG

free-jqgrid

Version:

grid as jQuery plugin - fork of jqGrid before licensing change

1,243 lines (1,226 loc) 99.1 kB
/** * jqGrid extension for form editing Grid Data * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com, http://trirand.com/blog/ * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl-2.0.html **/ /*jshint eqeqeq:false, eqnull:true, devel:true */ /*jslint browser: true, eqeq: true, plusplus: true, unparam: true, vars: true, nomen: true, continue: true, white: true, todo: true */ /*global jQuery, define, exports, module, require */ (function (global, factory) { "use strict"; if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module. //console.log("grid.formedit AMD"); define([ "jquery", "./grid.base", "./jquery.fmatter", "./grid.common", "./grid.filter" ], function ($) { //console.log("grid.formedit AMD: define callback"); return factory($, global, global.document); }); } else if (typeof module === "object" && module.exports) { // Node/CommonJS //console.log("grid.formedit CommonJS, typeof define=" + typeof define + ", define=" + define); module.exports = function (root, $) { //console.log("grid.formedit CommonJS: in module.exports"); if (!root) { root = window; } //console.log("grid.formedit CommonJS: before require('jquery')"); if ($ === undefined) { // require("jquery") returns a factory that requires window to // build a jQuery instance, we normalize how we use modules // that require this pattern but the window provided is a noop // if it's defined (how jquery works) $ = typeof window !== "undefined" ? require("jquery") : require("jquery")(root); } //console.log("grid.formedit CommonJS: before require('./grid.base')"); require("./grid.base"); //console.log("grid.formedit CommonJS: before require('./jquery.fmatter')"); require("./jquery.fmatter"); //console.log("grid.formedit CommonJS: before require('./grid.common')"); require("./grid.common"); //console.log("grid.formedit CommonJS: before require('./grid.filter')"); require("./grid.filter"); //console.log("grid.formedit CommonJS: before factory"); factory($, root, root.document); return $; }; } else { // Browser globals //console.log("grid.formedit Browser: before factory"); factory(jQuery, global, global.document); } }(typeof window !== "undefined" ? window : this, function ($, window, document) { "use strict"; var jgrid = $.jgrid, jqID = jgrid.jqID, base = $.fn.jqGrid, getGuiStyles = base.getGuiStyles, mergeCssClasses = jgrid.mergeCssClasses, hasOneFromClasses = jgrid.hasOneFromClasses; // begin module grid.formedit var jgridFeedback = jgrid.feedback, fullBoolFeedback = jgrid.fullBoolFeedback, builderFmButon = jgrid.builderFmButon, addFormIcon = function ($fmButton, iconInfos, commonIcon) { var iconspan; if (iconInfos[0] === true) { iconspan = "<span class='" + mergeCssClasses("fm-button-icon", commonIcon, iconInfos[2]) + "'></span>"; if (iconInfos[1] === "right") { $fmButton.addClass("fm-button-icon-right").append(iconspan); } else { $fmButton.addClass("fm-button-icon-left").prepend(iconspan); } } }, getGuiStateStyles = function (path) { return getGuiStyles.call(this, "states." + path); }, hideRowsWithoutVissibleCells = function ($tb) { $tb.find("tr[data-rowpos]").each(function () { var vissible = 0; $(this).children("td").each(function () { if ($(this).css("visibility") !== "hidden") { vissible++; } }); if (!vissible) { $(this).hide(); } }); }, isEmptyString = function (htmlStr) { return htmlStr === "&nbsp;" || htmlStr === "&#160;" || (htmlStr.length === 1 && htmlStr.charCodeAt(0) === 160); }; jgrid.extend({ searchGrid: function (oMuligrid) { // if one uses jQuery wrapper with multiple grids, then oMuligrid specify the object with common options return this.each(function () { var $t = this, $self = $($t), p = $t.p; if (!$t.grid || p == null) { return; } // make new copy of the options and use it for ONE specific grid. // p.searching can contains grid specific options // we will don't modify the input options oMuligrid var o = $.extend(true, { drag: true, sField: "searchField", sValue: "searchString", sOper: "searchOper", sFilter: p.prmNames.filters, loadDefaults: true, // this options activates loading of default filters from grid's postData for Multipe Search only. beforeShowSearch: null, afterShowSearch: null, onInitializeSearch: null, afterRedraw: null, afterChange: null, closeAfterSearch: false, closeAfterReset: false, closeOnEscape: false, searchOnEnter: false, multipleSearch: false, multipleGroup: false, // we can't use srort names like resetIcon because of conflict with existing "x" of filterToolbar top: 0, left: 0, removemodal: true, //jqModal : true, //modal: false, resize: true, width: 450, height: "auto", dataheight: "auto", showQuery: false, errorcheck: true, sopt: null, stringResult: undefined, onClose: null, onSearch: null, onReset: null, //toTop : false, //overlay : 30, columns: [], tmplNames: null, tmplFilters: null, tmplLabel: " Template: ", showOnLoad: false, layer: null, operands: { eq: "=", ne: "<>", lt: "<", le: "<=", gt: ">", ge: ">=", bw: "LIKE", bn: "NOT LIKE", "in": "IN", ni: "NOT IN", ew: "LIKE", en: "NOT LIKE", cn: "LIKE", nc: "NOT LIKE", nu: "IS NULL", nn: "IS NOT NULL" } }, base.getGridRes.call($self, "search"), jgrid.search || {}, p.searching || {}, oMuligrid || {}); var fid = "fbox_" + p.id, commonIconClass = o.commonIconClass, ids = { themodal: "searchmod" + fid, modalhead: "searchhd" + fid, modalcontent: "searchcnt" + fid, resizeAlso: fid }, themodalSelector = "#" + jqID(ids.themodal), gboxSelector = p.gBox, gviewSelector = p.gView, each = $.each, defaultFilters = p.postData[o.sFilter], searchFeedback = function () { var args = $.makeArray(arguments); args.unshift("Search"); args.unshift("Filter"); args.unshift(o); return jgridFeedback.apply($t, args); }, hideModel = function () { jgrid.hideModal(themodalSelector, { gb: gboxSelector, jqm: o.jqModal, onClose: o.onClose, removemodal: o.removemodal }); }; if (typeof defaultFilters === "string") { defaultFilters = $.trim(defaultFilters) !== "" ? $.parseJSON(defaultFilters) : undefined; } $(themodalSelector).remove(); function showFilter($filter) { if (searchFeedback("beforeShow", $filter)) { $(themodalSelector).data("onClose", o.onClose); jgrid.viewModal.call($t, themodalSelector, { gbox: gboxSelector, jqm: o.jqModal, overlay: o.overlay, modal: o.modal, overlayClass: o.overlayClass, toTop: o.toTop, onHide: function (h) { h.w.remove(); if (h.o) { h.o.remove(); } } }); searchFeedback("afterShow", $filter); } } if ($(themodalSelector)[0] !== undefined) { showFilter($("#fbox_" + jqID(p.id))); } else { var fil = $("<div><div id='" + fid + "' class='" + getGuiStyles.call($t, "dialog.body", "searchFilter") + "' style='overflow:auto'></div></div>").insertBefore(gviewSelector); if (p.direction === "rtl") { fil.attr("dir", "rtl"); } var bQ = "", tmpl = "", colnm, found = false, bt, cmi = -1, columns = $.extend([], p.colModel), bS = builderFmButon.call($t, fid + "_search", o.Find, mergeCssClasses(commonIconClass, o.findDialogIcon), "right"), bC = builderFmButon.call($t, fid + "_reset", o.Reset, mergeCssClasses(commonIconClass, o.resetDialogIcon), "left"); if (o.showQuery) { bQ = builderFmButon.call($t, fid + "_query", "Query", mergeCssClasses(commonIconClass, o.queryDialogIcon), "left") + "&#160;"; } if (o.searchForAdditionalProperties) { each(p.additionalProperties, function () { var cm = typeof this === "string" ? { name: this } : this; if (!cm.label) { cm.label = cm.name; } cm.isAddProp = true, columns.push(cm); }); } if (!o.columns.length) { each(columns, function (i, n) { if (!n.label) { n.label = n.isAddProp ? n.name : p.colNames[i]; } // find first searchable column and set it if no default filter if (!found) { var searchable = (n.search === undefined) ? true : n.search, hidden = (n.hidden === true), ignoreHiding = (n.searchoptions && n.searchoptions.searchhidden === true); if ((ignoreHiding && searchable) || (searchable && !hidden)) { found = true; colnm = n.index || n.name; cmi = i; } } }); } else { columns = o.columns; cmi = 0; colnm = columns[0].index || columns[0].name; } // old behaviour if ((!defaultFilters && colnm) || o.multipleSearch === false) { var cmop = "eq"; if (cmi >= 0 && columns[cmi].searchoptions && columns[cmi].searchoptions.sopt) { cmop = columns[cmi].searchoptions.sopt[0]; } else if (o.sopt && o.sopt.length) { cmop = o.sopt[0]; } defaultFilters = { groupOp: "AND", rules: [{ field: colnm, op: cmop, data: "" }] }; } found = false; if (o.tmplNames && o.tmplNames.length) { found = true; tmpl = o.tmplLabel; tmpl += "<select class='ui-template'>"; tmpl += "<option value='default'>Default</option>"; each(o.tmplNames, function (i, n) { tmpl += "<option value='" + i + "'>" + n + "</option>"; }); tmpl += "</select>"; } bt = "<div class='" + getGuiStyles.call($t, "dialog.footer") + "'><table class='EditTable' style='border:0px none;margin-top:5px' id='" + fid + "_2'><tbody><tr><td colspan='2'><hr class='" + getGuiStyles.call($t, "dialog.hr") + "' style='margin:1px'/></td></tr><tr><td class='EditButton EditButton-" + p.direction + "' style='float:" + (p.direction === "rtl" ? "right" : "left") + ";'>" + bC + tmpl + "</td><td class='EditButton EditButton-" + p.direction + "'>" + bQ + bS + "</td></tr></tbody></table></div>"; fid = jqID(fid); o.gbox = gboxSelector; //"#gbox_" + fid; o.height = "auto"; fid = "#" + fid; $(fid).jqFilter({ columns: columns, filter: o.loadDefaults ? defaultFilters : null, showQuery: o.showQuery, errorcheck: o.errorcheck, sopt: o.sopt, groupButton: o.multipleGroup, ruleButtons: o.multipleSearch, afterRedraw: o.afterRedraw, ops: o.odata, cops: p.customSortOperations, operands: o.operands, ajaxSelectOptions: p.ajaxSelectOptions, groupOps: o.groupOps, onChange: function (filterOptions, filterDiv) { if (filterOptions.showQuery) { $(".query", filterDiv).text(filterDiv.toUserFriendlyString()); } fullBoolFeedback.call($t, o.afterChange, "jqGridFilterAfterChange", $(fid), o, filterOptions, filterDiv); }, direction: p.direction, id: p.id }); fil.append(bt); if (found && o.tmplFilters && o.tmplFilters.length) { $(".ui-template", fil).on("change", function () { var curtempl = $(this).val(); if (curtempl === "default") { $(fid).jqFilter("addFilter", defaultFilters); } else { $(fid).jqFilter("addFilter", o.tmplFilters[parseInt(curtempl, 10)]); } return false; }); } if (o.multipleGroup === true) { o.multipleSearch = true; } searchFeedback("onInitialize", $(fid)); if (o.layer) { jgrid.createModal.call($t, ids, fil, o, gviewSelector, $(gboxSelector)[0], "#" + jqID(o.layer), { position: "relative" }); } else { jgrid.createModal.call($t, ids, fil, o, gviewSelector, $(gboxSelector)[0]); } if (o.searchOnEnter || o.closeOnEscape) { $(themodalSelector).keydown(function (e) { var $target = $(e.target); if (o.searchOnEnter && e.which === 13 && // 13 === $.ui.keyCode.ENTER !$target.hasClass("add-group") && !$target.hasClass("add-rule") && !$target.hasClass("delete-group") && !$target.hasClass("delete-rule") && (!$target.hasClass("fm-button") || !$target.is("[id$=_query]"))) { $(fid + "_search").click(); return false; } if (o.closeOnEscape && e.which === 27) { // 27 === $.ui.keyCode.ESCAPE $("#" + jqID(ids.modalhead)).find(".ui-jqdialog-titlebar-close").click(); return false; } }); } if (bQ) { $(fid + "_query").on("click", function () { $(".queryresult", fil).toggle(); return false; }); } if (o.stringResult === undefined) { // to provide backward compatibility, inferring stringResult value from multipleSearch o.stringResult = o.multipleSearch; } $(fid + "_search").on("click", function () { var sdata = {}, res = "", filters, fl = $(fid), $inputs = fl.find(".input-elm"); if ($inputs.filter(":focus")) { $inputs = $inputs.filter(":focus"); } $inputs.change(); filters = fl.jqFilter("filterData"); if (o.errorcheck) { fl[0].hideError(); if (!o.showQuery) { fl.jqFilter("toSQLString"); } if (fl[0].p.error) { fl[0].showError(); return false; } } if (o.stringResult || p.datatype === "local") { try { res = JSON.stringify(filters); } catch (ignore) { } if (typeof res === "string") { sdata[o.sFilter] = res; each([o.sField, o.sValue, o.sOper], function () { sdata[this] = ""; }); } } else { if (o.multipleSearch) { sdata[o.sFilter] = filters; each([o.sField, o.sValue, o.sOper], function () { sdata[this] = ""; }); } else { sdata[o.sField] = filters.rules[0].field; sdata[o.sValue] = filters.rules[0].data; sdata[o.sOper] = filters.rules[0].op; sdata[o.sFilter] = ""; } } $.extend(p.postData, sdata); if (fullBoolFeedback.call($t, o.onSearch, "jqGridFilterSearch", p.filters)) { p.search = true; $self.trigger("reloadGrid", [$.extend({ page: 1 }, o.reloadGridSearchOptions || {})]); } if (o.closeAfterSearch) { hideModel(); } return false; }); $(fid + "_reset").on("click", function () { var sdata = {}, fl1 = $(fid); p.search = false; p.resetsearch = true; if (o.multipleSearch === false) { sdata[o.sField] = sdata[o.sValue] = sdata[o.sOper] = ""; } else { sdata[o.sFilter] = ""; } fl1[0].resetFilter(); if (found) { $(".ui-template", fil).val("default"); } $.extend(p.postData, sdata); if (fullBoolFeedback.call($t, o.onReset, "jqGridFilterReset")) { $self.trigger("reloadGrid", [$.extend({ page: 1 }, o.reloadGridResetOptions || {})]); } if (o.closeAfterReset) { hideModel(); } return false; }); showFilter($(fid)); var hoverClasses = getGuiStateStyles.call($t, "hover"); // !!! The next row will not work if "states.disabled" is defined using more as one CSS class $(".fm-button:not(." + getGuiStateStyles.call($t, "disabled").split(" ").join(".") + ")", fil).hover( function () { $(this).addClass(hoverClasses); }, function () { $(this).removeClass(hoverClasses); } ); } }); }, editGridRow: function (rowid, oMuligrid) { // if one uses jQuery wrapper with multiple grids, then oMultiple specify the object with common options return this.each(function () { var $t = this, $self = $($t), p = $t.p; if (!$t.grid || p == null || !rowid) { return; } // make new copy of the options oMuligrid and use it for ONE specific grid. // p.formEditing can contains grid specific options // we will don't modify the input options oMuligrid var gridId = p.id, getGridRes = base.getGridRes, setSelection = base.setSelection, o = $.extend(true, { top: 0, left: 0, width: 300, datawidth: "auto", height: "auto", dataheight: "auto", //modal: false, //toTop : false, //overlay : 30, drag: true, resize: true, url: null, mtype: "POST", clearAfterAdd: true, closeAfterEdit: false, reloadAfterSubmit: true, onInitializeForm: null, beforeInitData: null, beforeShowForm: null, afterShowForm: null, beforeSubmit: null, afterSubmit: null, onclickSubmit: null, afterComplete: null, onclickPgButtons: null, afterclickPgButtons: null, editData: {}, //jqModal : true, closeOnEscape: false, addedrow: "first", topinfo: "", bottominfo: "", labelswidth: "", savekey: [false, 13], navkeys: [false, 38, 40], checkOnSubmit: false, checkOnUpdate: false, _savedData: {}, processing: false, onClose: null, ajaxEditOptions: {}, serializeEditData: null, viewPagerButtons: true, overlayClass: getGuiStyles.call(this, "overlay"), removemodal: true, skipPostTypes: ["image", "file"], saveui: "enable", savetext: getGridRes.call($self, "defaults.savetext") || "Saving..." }, getGridRes.call($self, "edit"), jgrid.edit, p.formEditing || {}, oMuligrid || {}); var frmgr = "FrmGrid_" + gridId, frmgrId = frmgr, frmtborg = "TblGrid_" + gridId, frmtb = "#" + jqID(frmtborg), frmtb2 = frmtb + "_2", ids = { themodal: "editmod" + gridId, modalhead: "edithd" + gridId, modalcontent: "editcnt" + gridId, resizeAlso: frmgr }, themodalSelector = "#" + jqID(ids.themodal), gboxSelector = p.gBox, colModel = p.colModel, iColByName = p.iColByName, maxCols = 1, maxRows = 0, postdata, diff, editOrAdd, commonIconClass = o.commonIconClass, hideModal = function () { jgrid.hideModal(themodalSelector, { gb: gboxSelector, jqm: o.jqModal, onClose: o.onClose, removemodal: o.removemodal }); }, errcap = getGridRes.call($self, "errors.errcap"), editFeedback = function () { var args = $.makeArray(arguments); args.unshift(""); args.unshift("AddEdit"); args.unshift(o); return jgridFeedback.apply($t, args); }, hoverClasses = getGuiStateStyles.call($t, "hover"), disabledClass = getGuiStateStyles.call($t, "disabled"), highlightClass = getGuiStateStyles.call($t, "select"), activeClass = getGuiStateStyles.call($t, "active"), errorClass = getGuiStateStyles.call($t, "error"); $(themodalSelector).remove(); frmgr = "#" + jqID(frmgr); if (rowid === "new") { rowid = "_empty"; editOrAdd = "add"; o.caption = o.addCaption; } else { o.caption = o.editCaption; editOrAdd = "edit"; } var closeovrl = true; if (o.checkOnUpdate && (o.jqModal === true || o.jqModal === undefined) && !o.modal) { closeovrl = false; } function getFormData() { $(frmtb + " > tbody > tr > td .FormElement").each(function () { var $celm = $(".customelement", this), nm = $celm.length ? $celm.attr("name") : this.name, iCol = iColByName[nm], cm = iCol !== undefined ? colModel[iCol] || {} : {}, editoptions = cm.editoptions || {}, formatoptions, newformat, type; if ($celm.length && $.isFunction(editoptions.custom_value)) { try { postdata[nm] = editoptions.custom_value.call($t, $("#" + jqID(nm), frmtb), "get"); if (postdata[nm] === undefined) { throw "e1"; } } catch (e) { if (e === "e1") { jgrid.info_dialog.call($t, errcap, "function 'custom_value' " + o.msg.novalue, o.bClose); } else { jgrid.info_dialog.call($t, errcap, e.message, o.bClose); } } return true; } else { type = $(this)[0].type; switch (type) { case "checkbox": var checkBoxValues = typeof editoptions.value === "string" ? editoptions.value.split(":") : ["Yes", "No"]; postdata[nm] = $(this).is(":checked") ? checkBoxValues[0] : checkBoxValues[1]; break; case "select-one": postdata[nm] = $("option:selected", this).val(); break; case "select-multiple": postdata[nm] = $(this).val(); postdata[nm] = postdata[nm] ? postdata[nm].join(",") : ""; var selectedText = []; $("option:selected", this).each( function (i, selected) { selectedText[i] = $(selected).text(); } ); break; case "date": postdata[nm] = $(this).val(); if (String(postdata[nm]).split("-").length === 3) { formatoptions = cm.formatoptions || {}; newformat = formatoptions.newformat || getGridRes.call($self, "formatter.date.newformat"); postdata[nm] = jgrid.parseDate.call($self[0], "Y-m-d", postdata[nm], newformat); } break; default: if (type !== undefined && $.inArray(type, o.skipPostTypes) < 0) { postdata[nm] = $(this).val(); } break; } } }); return true; } function createData(rowid1, tb, maxcols) { var cnt = 0, retpos = [], ind = false, $tb = $(tb), labelsWidth = String(o.labelswidth) + (!o.labelswidth || isNaN(o.labelswidth) ? "" : "px"), tdtmpl = "<td class='CaptionTD" + (labelsWidth ? "' style='width:" + labelsWidth + ";" : "") + "'>&#160;</td><td class='DataTD'>&#160;</td>", tmpl = "", i; //*2 for (i = 1; i <= maxcols; i++) { tmpl += tdtmpl; } if (rowid1 !== "_empty") { ind = base.getInd.call($self, rowid1); } $(colModel).each(function (iCol) { var cm = this, nm = cm.name, $td, hc, trdata, tmp, elc, editable = cm.editable, disabled = false, readonly = false, mode = rowid1 === "_empty" ? "addForm" : "editForm"; if ($.isFunction(editable)) { editable = editable.call($t, { rowid: rowid1, iCol: iCol, iRow: ind, // can be false for Add operation cmName: nm, cm: cm, mode: mode }); } // hidden fields are included in the form if (cm.editrules && cm.editrules.edithidden === true) { hc = false; } else { hc = cm.hidden === true || editable === "hidden" ? true : false; } switch (String(editable).toLowerCase()) { case "hidden": editable = true; break; case "disabled": editable = true; disabled = true; break; case "readonly": editable = true; readonly = true; break; } if (nm !== "cb" && nm !== "subgrid" && editable === true && nm !== "rn") { if (ind === false) { tmp = ""; } else { $td = $($t.rows[ind].cells[iCol]); // $("td[role=gridcell]:eq(" + i + ")", $t.rows[ind]) try { tmp = $.unformat.call($t, $td, { rowId: rowid1, colModel: cm }, iCol); } catch (_) { tmp = (cm.edittype && cm.edittype === "textarea") ? $td.text() : $td.html(); } if (isEmptyString(tmp)) { tmp = ""; } } var opt = $.extend({}, cm.editoptions || {}, { id: nm, name: nm, rowId: rowid1, mode: mode, cm: cm, iCol: iCol }), frmopt = $.extend({}, { elmprefix: "", elmsuffix: "", rowabove: false, rowcontent: "" }, cm.formoptions || {}), rp = parseInt(frmopt.rowpos, 10) || cnt + 1, cp = parseInt((parseInt(frmopt.colpos, 10) || 1) * 2, 10); if (rowid1 === "_empty" && opt.defaultValue) { tmp = $.isFunction(opt.defaultValue) ? opt.defaultValue.call($t) : opt.defaultValue; } if (!cm.edittype) { cm.edittype = "text"; } if (p.autoEncodeOnEdit) { tmp = jgrid.oldDecodePostedData(tmp); } elc = jgrid.createEl.call($t, cm.edittype, opt, tmp, false, $.extend({}, jgrid.ajaxOptions, p.ajaxSelectOptions || {})); //if(tmp === "" && cm.edittype == "checkbox") {tmp = $(elc).data("offval");} //if(tmp === "" && cm.edittype == "select") {tmp = $("option:eq(0)",elc).text();} if (o.checkOnSubmit || o.checkOnUpdate) { o._savedData[nm] = tmp; } $(elc).addClass("FormElement"); if ($.inArray(cm.edittype, ["text", "textarea", "checkbox", "password", "select"]) > -1) { $(elc).addClass(getGuiStyles.call($t, "dialog.dataField")); } trdata = $tb.find("tr[data-rowpos=" + rp + "]"); if (frmopt.rowabove) { var newdata = $("<tr><td class='contentinfo' colspan='" + (maxcols * 2) + "'>" + frmopt.rowcontent + "</td></tr>"); $tb.append(newdata); newdata[0].rp = rp; } if (trdata.length === 0) { trdata = $("<tr data-rowpos='" + rp + "'></tr>").addClass("FormData").attr("id", "tr_" + nm); $(trdata).append(tmpl); $tb.append(trdata); trdata[0].rp = rp; } var $label = $("td:eq(" + (cp - 2) + ")", trdata[0]), $data = $("td:eq(" + (cp - 1) + ")", trdata[0]); $label.html(frmopt.label === undefined ? p.colNames[iCol] : frmopt.label || "&#160;"); var $dataCell = $data[isEmptyString($data.html()) ? "html" : "append"](frmopt.elmprefix); $dataCell.append(elc).append(frmopt.elmsuffix); if (elc.tagName.toUpperCase() === "INPUT" && cm.createColumnIndex && opt.generateDatalist) { var $datalist = $self.jqGrid("generateDatalistFromColumnIndex", cm.name); if ($datalist != null && $datalist.length > 0) { $(elc).attr("list", "dl_" + elc.id); $dataCell.append($datalist.attr("id", "dl_" + elc.id)); } } if (disabled) { $label.addClass(disabledClass); $data.addClass(disabledClass); $(elc).prop("readonly", true); $(elc).prop("disabled", true); } else if (readonly) { $(elc).prop("readonly", true); } if (cm.edittype === "custom" && $.isFunction(opt.custom_value)) { opt.custom_value.call($t, $("#" + jqID(nm), frmgr), "set", tmp); } jgrid.bindEv.call($t, elc, opt); if (hc) { $label.add($data).css("visibility", "hidden"); } retpos[cnt] = iCol; cnt++; } }); hideRowsWithoutVissibleCells($tb); if (cnt > 0) { var idrow = $("<tr class='FormData' style='display:none'><td class='CaptionTD'>&#160;</td><td colspan='" + (maxcols * 2 - 1) + "' class='DataTD'><input class='FormElement' id='id_g' type='text' name='" + gridId + "_id' value='" + rowid1 + "'/></td></tr>"); idrow[0].rp = cnt + 999; $tb.append(idrow); if (o.checkOnSubmit || o.checkOnUpdate) { o._savedData[gridId + "_id"] = rowid1; } } return retpos; } function fillData(rowid1, fmid) { var nm, cnt = 0, fld, opt, vl, vlc; if (o.checkOnSubmit || o.checkOnUpdate) { o._savedData = {}; o._savedData[gridId + "_id"] = rowid1; } var cm = p.colModel; if (rowid1 === "_empty") { $(cm).each(function () { nm = this.name; opt = $.extend({}, this.editoptions || {}); fld = $("#" + jqID(nm), fmid); if (fld && fld.length && fld[0] !== null) { vl = ""; if (this.edittype === "custom" && $.isFunction(opt.custom_value)) { opt.custom_value.call($t, fld, "set", vl); } else if (opt.defaultValue) { vl = $.isFunction(opt.defaultValue) ? opt.defaultValue.call($t) : opt.defaultValue; if (fld[0].type === "checkbox") { vlc = vl.toLowerCase(); if (vlc.search(/(false|f|0|no|n|off|undefined)/i) < 0 && vlc !== "") { fld[0].checked = true; fld[0].defaultChecked = true; fld[0].value = vl; } else { fld[0].checked = false; fld[0].defaultChecked = false; } } else { fld.val(vl); } } else { if (fld[0].type === "checkbox") { fld[0].checked = false; fld[0].defaultChecked = false; vl = $(fld).data("offval"); } else if (fld[0].type && fld[0].type.substr(0, 6) === "select") { fld[0].selectedIndex = 0; } else { fld.val(vl); } } if (o.checkOnSubmit === true || o.checkOnUpdate) { o._savedData[nm] = vl; } } }); $("#id_g", fmid).val(rowid1); return; } var tre = base.getInd.call($self, rowid1, true); if (!tre) { return; } //$("td[role=gridcell]", tre) $(tre.cells).filter("td[role=gridcell]").each(function (i) { var tmp; nm = cm[i].name; // hidden fields are included in the form if (nm !== "cb" && nm !== "subgrid" && nm !== "rn" && cm[i].editable === true) { try { tmp = $.unformat.call($t, $(this), { rowId: rowid1, colModel: cm[i] }, i); } catch (_) { tmp = cm[i].edittype === "textarea" ? $(this).text() : $(this).html(); } if (p.autoEncodeOnEdit) { tmp = jgrid.oldDecodePostedData(tmp); } if (o.checkOnSubmit === true || o.checkOnUpdate) { o._savedData[nm] = tmp; } nm = "#" + jqID(nm); switch (cm[i].edittype) { case "password": case "text": case "button": case "image": case "textarea": if (isEmptyString(tmp)) { tmp = ""; } $(nm, fmid).val(tmp); break; case "select": var valuesToSelect = tmp.split(","); valuesToSelect = $.map(valuesToSelect, function (n) { return $.trim(n); }); // first of all we try to select options testing the valuesToSelect, // we will remove the values from valuesToSelect, which will be found by value // In the next step we go through all options once more time and select the options // testing there by text. In other words selection by text will be used only for // values from valuesToSelect, which not exist as option by value $(nm + " option", fmid).each(function () { var selOpt = this, $selOpt = $(selOpt), optVal = $.trim($selOpt.val()), iVal; if (!cm[i].editoptions.multiple && valuesToSelect[0] === optVal) { valuesToSelect.splice(0, 1); selOpt.selected = true; } else if (cm[i].editoptions.multiple) { iVal = $.inArray(optVal, valuesToSelect); if (iVal > -1) { valuesToSelect.splice(iVal, 1); selOpt.selected = true; } else { selOpt.selected = false; } } else { selOpt.selected = false; } if (valuesToSelect.length === 0) { return false; } }); if (valuesToSelect.length > 0) { $(nm + " option", fmid).each(function () { var selOpt = this, $selOpt = $(selOpt), optText = $.trim($selOpt.text()), iVal; if (!cm[i].editoptions.multiple && ($.trim(tmp) === optText || valuesToSelect[0] === optText)) { valuesToSelect.splice(0, 1); selOpt.selected = true; } else if (cm[i].editoptions.multiple) { iVal = $.inArray(optText, valuesToSelect); if (iVal > -1) { valuesToSelect.splice(iVal, 1); selOpt.selected = true; } } if (valuesToSelect.length === 0) { return false; } }); } break; case "checkbox": tmp = String(tmp); // tmp will be set below (in the if-else) to Boolean true or false if (cm[i].editoptions && cm[i].editoptions.value) { tmp = cm[i].editoptions.value.split(":")[0] === tmp; } else { tmp = tmp.toLowerCase(); tmp = tmp.search(/(false|f|0|no|n|off|undefined)/i) < 0 && tmp !== ""; } $(nm, fmid).prop({ checked: tmp, defaultChecked: tmp }); break; case "custom": try { if (cm[i].editoptions && $.isFunction(cm[i].editoptions.custom_value)) { cm[i].editoptions.custom_value.call($t, $(nm, fmid), "set", tmp); } else { throw "e1"; } } catch (e) { if (e === "e1") { jgrid.info_dialog.call($t, errcap, "function 'custom_value' " + o.msg.nodefined, o.bClose); } else { jgrid.info_dialog.call($t, errcap, e.message, o.bClose); } } break; } cnt++; } }); if (cnt > 0) { $("#id_g", frmtb).val(rowid1); } } function setNullsOrUnformat() { var url = o.url || p.editurl; $.each(colModel, function (i, cm) { var cmName = cm.name; if (postdata.hasOwnProperty(cmName)) { if (cm.formatter === "date" && (cm.formatoptions == null || cm.formatoptions.sendFormatted !== true)) { // TODO: call all other predefined formatters!!! Not only formatter: "date" have the problem. // Floating point separator for example postdata[cmName] = $.unformat.date.call($t, postdata[cmName], cm); } if (url !== "clientArray" && cm.editoptions && cm.editoptions.NullIfEmpty === true && postdata[cmName] === "") { postdata[cmName] = "null"; } } }); } function postIt() { var successResult = [true, "", ""], ret = successResult, onClickSubmitResult = {}, opers = p.prmNames, idname, oper, key, selr, i, url, itm, iCol, iRow = base.getInd.call($self, rowid), tr = iRow === false ? null : $t.rows[iRow], retvals = $self.triggerHandler("jqGridAddEditBeforeCheckValues", [postdata, $(frmgr), editOrAdd]); if (retvals && typeof retvals === "object") { postdata = retvals; } iRow = iRow === false ? -1 : iRow; if ($.isFunction(o.beforeCheckValues)) { retvals = o.beforeCheckValues.call($t, postdata, $(frmgr), editOrAdd); if (retvals && typeof retvals === "object") { postdata = retvals; } } for (key in postdata) { if (postdata.hasOwnProperty(key)) { iCol = p.iColByName[key]; ret = jgrid.checkValues.call($t, postdata[key], key, undefined, undefined, { oldValue: rowid === "_empty" ? null : base.getCell.call($self, rowid, iCol), newValue: postdata[key], cmName: key, rowid: rowid, cm: colModel[iCol], iCol: iCol, iRow: iRow, tr: tr, td: tr == null ? null : tr.cells[iCol], mode: rowid === "_empty" ? "addForm" : "editForm" }); if (ret == null || ret === true) { ret = successResult; } if (ret[0] === false) { break; } } } setNullsOrUnformat(); if (ret[0]) { onClickSubmitResult = $self.triggerHandler("jqGridAddEditClickSubmit", [o, postdata, editOrAdd]); if (onClickSubmitResult === undefined && $.isFunction(o.onclickSubmit)) { onClickSubmitResult = o.onclickSubmit.call($t, o, postdata, editOrAdd) || {}; } ret = $self.triggerHandler("jqGridAddEditBeforeSubmit", [postdata, $(frmgr), editOrAdd]); if (ret == null || ret === true) { ret = successResult; } if (ret[0] && $.isFunction(o.beforeSubmit)) { ret = o.beforeSubmit.call($t, postdata, $(frmgr), editOrAdd); if (ret == null || ret === true) { ret = successResult; } } } if (ret[0] && !o.processing) { o.processing = true; $("#sData", frmtb2).addClass(activeClass); url = o.url || p.editurl; oper = opers.oper; idname = url === "clientArray" && p.keyName !== false ? p.keyName : opers.id; // we add to pos data array the action - the name is oper postdata[oper] = ($.trim(postdata[gridId + "_id"]) === "_empty") ? opers.addoper : opers.editoper; if (postdata[oper] !== opers.addoper) { postdata[idname] = postdata[gridId + "_id"]; } else { // check to see if we have allredy this field in the form and if yes lieve it if (postdata[idname] === undefined) { postdata[idname] = postdata[gridId + "_id"]; } } delete postdata[gridId + "_id"]; postdata = $.extend(postdata, o.editData, onClickSubmitResult); if (p.treeGrid === true) { if (postdata[oper] === opers.addoper) { selr = p.selrow; var parentIdField = p.treeGridModel === "adjacency" ? p.treeReader.parent_id_field : "parent_id"; postdata[parentIdField] = selr; } for (i in p.treeReader) { if (p.treeReader.hasOwnProperty(i)) { itm = p.treeReader[i]; if (postdata.hasOwnProperty(itm)) { if (postdata[oper] === opers.addoper && i === "parent_id_field") { continue; } delete postdata[itm]; } } } } postdata[idname] = jgrid.stripPref(p.idPrefix, postdata[idname]); if (p.autoEncodeOnEdit) { $.each(postdata, function (n, v) { if (!$.isFunction(v)) { postdata[n] = jgrid.oldEncodePostedData(v); } }); } var ajaxOptions = $.extend({ url: $.isFunction(url) ? url.call($t, postdata[idname], editOrAdd, postdata, o) : url, type: $.isFunction(o.mtype) ? o.mtype.call($t, editOrAdd, o, postdata[idname], postdata) : o.mtype, //data: $.isFunction(o.serializeEditData) ? o.serializeEditData.call($t,postdata) : postdata, data: jgrid.serializeFeedback.call($t, $.isFunction(o.serializeEditData) ? o.serializeEditData : p.serializeEditData, "jqGridAddEditSerializeEditData", postdata), complete: function (jqXHR, textStatus) { $self.jqGrid("progressBar", { method: "hide", loadtype: o.saveui }); $("#sData", frmtb2).removeClass(activeClass); postdata[idname] = $("#id_g", frmtb).val(); if ((jqXHR.status >= 300 && jqXHR.status !== 304) || (jqXHR.status === 0 && jqXHR.readyState === 4)) { ret[0] = false; ret[1] = $self.triggerHandler("jqGridAddEditErrorTextFormat", [jqXHR, editOrAdd]); if ($.isFunction(o.errorTextFormat)) { ret[1] = o.errorTextFormat.call($t, jqXHR, editOrAdd); } else { ret[1] = textStatus + " Status: '" + jqXHR.statusText + "'. Error code: " + jqXHR.status; } } else { // data is posted successful // execute aftersubmit with the returned data from server ret = $self.triggerHandler("jqGridAddEditAfterSubmit", [jqXHR, postdata, editOrAdd]); if (ret == null || ret === true) { ret = successResult; } if (ret[0] && $.isFunction(o.afterSubmit)) { ret = o.afterSubmit.call($t, jqXHR, postdata, editOrAdd); if (ret == null || ret === true) { ret = successResult; } } } if (ret[0] === false) { $("#FormError>td", frmtb).html(ret[1]); $("#FormError", frmtb).show(); } else { if (p.autoEncodeOnEdit) { $.each(postdata, function (n, v) { postdata[n] = jgrid.oldDecodePostedData(v); }); } //o.reloadAfterSubmit = o.reloadAfterSubmit && $t.o.datatype != "local"; // the action is add var reloadGridOptions = [$.extend({}, o.reloadGridOptions || {})]; if (postdata[oper] === opers.addoper) { //id processing // user not set the id ret[2] if (!ret[2]) { ret[2] = jgrid.randId(); } if (postdata[idname] == null || postdata[idname] === "_empty" || postdata[oper] === opers.addoper) { postdata[idname] = ret[2]; } else { ret[2] = postdata[idname]; } if (o.reloadAfterSubmit) { $self.trigger("reloadGrid", reloadGridOptions); } else { if (p.treeGrid === true) { base.addChildNode.call($self, ret[2], selr, postdata); } else { base.addRowData.call($self, ret[2], postdata, o.addedrow); } } if (o.closeAfterAdd) { if (p.treeGrid !== true) { setSelection.call($self, ret[2]); } hideModal(); } else if (o.clearAfterAdd) { fillData("_empty", frmgr); } } else { // the action is update if (o.reloadAfterSubmit) { $self.trigger("reloadGrid", reloadGridOptions); if (!o.closeAfterEdit) { setTimeout(function () { setSelection.call($self, postdata[idname]); }, 1000); } } else { if (p.treeGrid === true) { base.setTreeRow.call($self, postdata[idname], postdata); } else { base.setRowData.call($self, postdata[idname], postdata); } } if (o.closeAfterEdit) { hideModal(); } } if ($.isFunction(o.afterComplete)) { var copydata = jqXHR; setTimeout(function () { $self.triggerHandler("jqGridAddEditAfterComplete", [copydata, postdata, $(frmgr), editOrAdd]); o.afterComplete.call($t, copydata, postdata, $(frmgr), editOrAdd); copydata = null; }, 50); } if (o.checkOnSubmit || o.checkOnUpdate) { $(frmgr).data("disabled", false); if (o._savedData[gridId + "_id"] !== "_empty") { var key1; for (key1 in o._savedData) { if (o._savedData.hasOwnProperty(key1) && postdata[key1]) { o._savedData[key1] = postdata[key1]; } } } } } o.processing = false; try { $(frmgr).find("input,textarea,select,button,object,*[tabindex]") .filter(":input:visible:not(:disabled)") .first() .focus(); } catch (ignore) { } } }, jgrid.ajaxOptions, o.ajaxEditOptions); if (!ajaxOptions.url && !o.useDataProxy) { if ($.isFunction(p.dataProxy)) { o.useDataProxy = true; } else { ret[0] = false; ret[1] += " " + jgrid.errors.nourl; } } if (ret[0]) { $self.jqGrid("progressBar", { method: "show", loadtype: o.saveui, htmlcontent: o.savetext }); if (o.useDataProxy) { var dpret = p.dataProxy.call($t, ajaxOptions, "set_" + gridId); if (dpret === undefined) { dpret = [true, ""]; } if (dpret[0] === false) { ret[0] = false; ret[1] = dpret[1] || "Error deleting the selected row!"; } else { if (ajaxOptions.data.oper === opers.addoper && o.closeAfterAdd) { hideModal(); } if (ajaxOptions.data.oper === opers.editoper && o.closeAfterEdit) { hideModal(); } } } else { if (ajaxOptions.url === "clientArray") { o.reloadAfterSubmit = false; postdata = ajaxOptions.data; ajaxOptions.complete({ status: 200, statusText: "" }, ""); } else { $.ajax(ajaxOptions); } } } } if (ret[0] === false) { $("#FormError>td", frmtb).html(ret[1]); $("#FormError", frmtb).show(); // return; } } function compareData(nObj, oObj) { var ret = false, key; for (key in nObj) { if (nObj.hasOwnProperty(key) && String(nObj[key]) !== String(oObj[key])) { ret = true; break; } } return ret; } function checkUpdates() { var stat = true; $("#FormError", frmtb).hide(); if (o.checkOnUpdate) { postdata = {}; getFormData(); diff = compareData(postdata, o._savedData); if (diff) { $(frmgr).data("disabled", true); $(".confirm", themodalSelector).show(); stat = false; } } return stat; } function restoreInline() { var editingInfo = jgrid.detectRowEditing.call($t, rowid); if (editingInfo != null) { if (editingInfo.mode === "inlineEditing") { base.restoreRow.call($self, rowid); } else { var savedRowInfo = editingInfo.savedRow, tr = $t.rows[savedRowInfo.id]; base.restoreCell.call($self, savedRowInfo.id, savedRowInfo.ic); // remove highlighting of the cell $(tr.cells[savedRowInfo.ic]).removeClass("edit-cell " + highlightClass); $(tr).addClass(highlightClass).attr({ "aria-selected": "true", "tabindex": "0" }); } } } function updateNav(cr, posarr) { var totr = posarr[1].length - 1; if (cr === 0) { $("#pData", frmtb2).addClass(disabledClass); } else if (posarr[1][cr - 1] !== undefined && hasOneFromClasses($("#" + jqID(posarr[1][cr - 1])), disabledClass)) { $("#pData", frmtb2).addClass(disabledClass); } else { $("#pData", frmtb2).removeClass(disabledClass); } if (cr === totr) { $("#nData", frmtb2).addClass(disabledClass); } else if (posarr[1][cr + 1] !== undefined && hasOneFromClasses($("#" + jqID(posarr[1][cr + 1])), disabledClass)) { $("#nData", frmtb2).addClass(disabledClass); } else { $("#nData", frmtb2).removeClass(disabledClass); } } function getCurrPos() { var rowsInGrid = base.getDataIDs.call($self), selrow = $("#id_g", frmtb).val(), pos = $.inArray(selrow, rowsInGrid); return [pos, rowsInGrid]; } var dh = isNaN(o.dataheight) ? o.dataheight : o.dataheight + "px", dw = isNaN(o.datawidth) ? o.datawidth : o.datawidth + "px", frm = $("<form name='FormPost' id='" + frmgrId + "' class='FormGrid' onSubmit='return false;' style='width:" + dw + ";overflow:auto;position:relative;height:" + dh + ";'></form>").data("disabled", false), tbl = $("<table id='" + frmtborg + "' class='EditTable'><tbody></tbody></table>"); $(colModel).each(function () { var fmto = this.formoptions; maxCols = Math.max(maxCols, fmto ? fmto.colpos || 0 : 0); maxRows = Math.max(maxRows, fmto ? fmto.rowpos || 0 : 0); }); $(frm).append(tbl); var flr = $("<tr id='FormError' style='display:none'><td class='" + errorClass + "' colspan='" + (maxCols * 2) + "'>&#160;</td></tr>"); flr[0].rp = 0; $(tbl).append(flr); //topinfo flr = $("<tr style='display:none' class='tinfo'><td class='topinfo' colspan='" + (maxCols * 2) + "'>" + (o.topinfo || "&#160;") + "</td></tr>"); flr[0].rp = 0; $(tbl).append(flr); if (!editFeedback("beforeInitData", frm, editOrAdd)) { return; } restoreInline(); // set the id. // use carefull only to change here colproperties. // create data var rtlb = p.direction === "rtl" ? true : false, bp = rtlb ? "nData" : "pData", bn = rtlb ? "pData" : "nData"; createData(rowid, tbl, maxCols); // buttons at footer var bP = builderFmButon.call($t, bp, "", mergeCssClasses(commonIconClass, o.prevIcon), "", "left"), bN = builderFmButon.call($t, bn, "", mergeCssClasses(commonIconClass, o.nextIcon), "", "right"), bS = builderFmButon.call($t, "sData", o.bSubmit), bC = builderFmButon.call($t, "cData", o.bCancel), bt = "<div class='" + getGuiStyles.call($t, "dialog.footer") + "'><table class='EditTable' id='" + frmtborg + "_2'><tbody><tr><td colspan='2'><hr class='" + getGuiStyles.call($t, "dialog.hr") + "' style='margin:1px'/></td></tr><tr id='Act_Buttons'><td class='navButton navButton-" + p.direction + "'>" + (rtlb ? bN + bP : bP + bN) + "</td><td class='EditButton EditButton-" + p.direction + "'>" + bS + "&#160;" + bC + "</td></tr>"; bt += "<tr style='display:none' class='binfo'><td class='bottominfo' colspan='2'>" + (o.bottominfo || "&#160;") + "</td></tr>"; bt += "</tbody></table></div>"; if (maxRows > 0) { var sd = []; $.each($(tbl)[0].rows, function (i, r) { sd[i] = r; }); sd.sort(function (a, b) { if (a.rp > b.rp) { return 1; } if (a.rp < b.rp) { return -1; } return 0; }); $.each(sd, function (index, row) { $("tbody", tbl).a