datatable.editor中 Editor.prototype._submit方法:
/** * Submit a form to the server for processing. This is the private method that is used * by the 'submit' API method, which should always be called in preference to calling * this method directly. * * @param {function} [successCallback] Callback function that is executed once the * form has been successfully submitted to the server and no errors occurred. * @param {function} [errorCallback] Callback function that is executed if the * server reports an error due to the submission (this includes a JSON formatting * error should the error return invalid JSON). * @param {function} [formatdata] Callback function that is passed in the data * that will be submitted to the server, allowing pre-formatting of the data, * removal of data or adding of extra fields. * @param {boolean} [hide=true] When the form is successfully submitted, by default * the form display will be hidden - this option allows that to be overridden. * @private */Editor.prototype._submit = function ( successCallback, errorCallback, formatdata, hide ){ var that = this; var i, iLen, eventRet, errorNodes; var changed = false, allData = {}, changedData = {}; var setBuilder = DataTable.ext.oApi._fnSetObjectDataFn; var dataSource = this.s.dataSource; var fields = this.s.fields; var editCount = this.s.editCount; var modifier = this.s.modifier; var editFields = this.s.editFields; var editData = this.s.editData; var opts = this.s.editOpts; var changedSubmit = opts.submit; var submitParamsLocal; // After initSubmit to allow `mode()` to be used as a setter var action = this.s.action; var submitParams = { "action": action, "data": {} }; // For backwards compatibility if ( this.s.dbTable ) { submitParams.table = this.s.dbTable; } // Gather the data that is to be submitted if ( action === "create" || action === "edit" ) { $.each( editFields, function ( idSrc, edit ) { var allRowData = {}; var changedRowData = {}; $.each( fields, function (name, field) { if ( edit.fields[ name ] && field.submittable() ) { var multiGet = field.multiGet(); var builder = setBuilder( name ); // If it wasn't an edit field, we still need to get the original // data, so we can submit it if `all` or `allIfChanged` if ( multiGet[ idSrc ] === undefined ) { var originalVal = field.valFromData( edit.data ); builder( allRowData, originalVal );//此处调用,是从datatable.js中的获取的方法 return; } var value = multiGet[ idSrc ]; var manyBuilder = $.isArray( value ) && name.indexOf('[]') !== -1 ? setBuilder( name.replace(/\[.*$/,'')+'-many-count' ) : null; builder( allRowData, value ); // We need to tell the server-side if an array submission // actually has no elements so it knows if the array was // being submitted or not (since otherwise it doesn't know // if the array was empty, or just not being submitted) if ( manyBuilder ) { manyBuilder( allRowData, value.length ); } // Build a changed object for if that is the selected data // type if ( action === 'edit' && (!editData[ name ] || ! field.compare( value, editData[ name ][ idSrc ]) ) ) { builder( changedRowData, value ); changed = true; if ( manyBuilder ) { manyBuilder( changedRowData, value.length ); } } } } ); if ( ! $.isEmptyObject( allRowData ) ) { allData[ idSrc ] = allRowData; } if ( ! $.isEmptyObject( changedRowData ) ) { changedData[ idSrc ] = changedRowData; } } ); // Decide what data to submit to the server for edit (create is all, always) if ( action === 'create' || changedSubmit === 'all' || (changedSubmit === 'allIfChanged' && changed) ) { submitParams.data = allData; } else if ( changedSubmit === 'changed' && changed ) { submitParams.data = changedData; } else { // Nothing to submit this.s.action = null; if ( opts.onComplete === 'close' && (hide === undefined || hide) ) { this._close( false ); } else if ( typeof opts.onComplete === 'function' ) { opts.onComplete( this ); } if ( successCallback ) { successCallback.call( this ); } this._processing( false ); this._event( 'submitComplete' ); return; } } else if ( action === "remove" ) { $.each( editFields, function ( idSrc, edit ) { submitParams.data[ idSrc ] = edit.data; } ); } this._legacyAjax( 'send', action, submitParams ); // Local copy of the submit parameters, needed for the data lib prep since // the preSubmit can modify the format and we need to know what the format is submitParamsLocal = $.extend( true, {}, submitParams ); // Allow the data to be submitted to the server to be preprocessed by callback // and event functions if ( formatdata ) { formatdata( submitParams ); } if ( this._event( 'preSubmit', [submitParams, action] ) === false ) { this._processing( false ); return; } // Submit to the server (or whatever method is defined in the settings) var submitWire = this.s.ajax || this.s.ajaxUrl ? this._ajax : this._submitTable; submitWire.call( this, submitParams, function (json, notGood, xhr) { that._submitSuccess( json, notGood, submitParams, submitParamsLocal, that.s.action, editCount, hide, successCallback, errorCallback, xhr ); }, function (xhr, err, thrown) { that._submitError( xhr, err, thrown, errorCallback, submitParams, that.s.action ); }, submitParams );};
返回的方法是:
/* Array or flat object mapping */ return function (data, val) { // meta is also passed in, but not used data[mSource] = val; };
主要作用是根据 mSource 构建data (传入的allRowData).
null值的select 不提交配置
{ label: "Office:", name: "office", type: "select", options: [{ label: "Tokyo", value: 1 }, { label: "北京", value: 2 }, { label: "上海", value: 3 }, { label: "广州", value: 4 }, { label: "厦门", value: 5 } ], placeholderValue:false, placeholder:'-' }
获取不到editor实例
_mouseup: function ( e ) { $(document.body).off( '.autoFill' ); var that = this; var dt = this.s.dt; var select = this.dom.select; select.top.remove(); select.left.remove(); select.right.remove(); select.bottom.remove(); this.dom.handle.css( 'display', 'block' ); // Display complete - now do something useful with the selection! var start = this.s.start; var end = this.s.end; // Haven't selected multiple cells, so nothing to do if ( start.row === end.row && start.column === end.column ) { return; } var startDt = dt.cell( ':eq('+start.row+')', start.column+':visible', {page:'current'} ); // If Editor is active inside this cell (inline editing) we need to wait for Editor to // submit and then we can loop back and trigger the fill. if ( $('div.DTE', startDt.node()).length ) { var editor = dt.editor();//此处报错获取不到实例 editor .on( 'submitSuccess.dtaf', function () { editor.off( '.dtaf'); setTimeout( function () { that._mouseup( e ); }, 100 ); } ) .on( 'submitComplete.dtaf preSubmitCancelled.dtaf', function () { editor.off( '.dtaf'); } ); // Make the current input submit editor.submit(); return; }.......
原因:Editor.prototype._constructor中验证table的代码问题
$(document) .on('init.dt.dte' + this.s.unique, function(e, settings, json) { // console.log(that.s.table) //选择器 // Attempt to attach to a DataTable automatically when the table is // initialised //settings.nTable === $(that.s.table).get(0)这句报错误没有进入分支 if (that.s.table && settings.nTable === $(that.s.table).get(0)) { settings._editor = that; } }) .on('xhr.dt.dte' + this.s.unique, function(e, settings, json) { // Automatically update fields which have a field name defined in // the returned json - saves an `initComplete` for the user if (json && that.s.table && settings.nTable === $(that.s.table).get(0)) { that._optionsUpdate(json); } });
导致的原因是:
"scrollX": true,
开启滚动项会复制一个table作为表头,而通过通过class类名选择器配置editor,在上方校验时通不过,无法赋值settings._editor实例。
改用ID初始化就好。