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初始化就好。