Editor - Bug if edit a select2 or selectsize field with less options update

Editor - Bug if edit a select2 or selectsize field with less options update

chrisLabchrisLab Posts: 2Questions: 0Answers: 0
edited June 2017 in Free community support

There is a bug with selectize plugin when you want edit field with less selected options than orginal state.

In datables.js :

/**
 * Save submitted data without an Ajax request. This will write to a local
 * table only - not saving it permanently, but rather using the DataTable itself
 * as a data store.
 *
 * @param  {object} data Data to submit
 * @param  {function} success Success callback
 * @param  {function} error Error callback
 * @param  {object} submitParams Submitted data
 * @private
 */
Editor.prototype._submitTable = function ( data, success, error, submitParams )
{
    var that = this;
    var action = data.action;
    var out = { data: [] };
    var idGet = DataTable.ext.oApi._fnGetObjectDataFn( this.s.idSrc );
    var idSet = DataTable.ext.oApi._fnSetObjectDataFn( this.s.idSrc );

    // Nothing required for remove - create and edit get a copy of the data
    if ( action !== 'remove' ) {
        var originalData = this._dataSource( 'fields', this.modifier() );

        $.each( data.data, function ( key, vals ) {
            var toSave;

            // Get the original row's data, so we can modify it with new values.
            // This allows Editor to not need to submit all fields
            if ( action === 'edit' ) {
                var rowData = originalData[ key ].data;
                toSave = $.extend(true, {}, rowData, vals );
            }
            else {
                toSave = $.extend( true, {}, vals );
            }
            // If create and there isn't an id for the new row, create
            // one. An id could be creased by `preSubmit`
            if ( action === 'create' && idGet( toSave ) === undefined ) {
                idSet( toSave, +new Date() +''+ key );
            }
            else {
                idSet( toSave, key );
            }

            out.data.push( toSave );
        } );
    }

    success( out );
};

Edit action "toSave = $.extend(true, {}, rowData, vals );" , but $extend(true) will deep copy object.
When we edit a selectzise (or select2) field new data it's a array

examples :

N° 1 :

Before edit : ["foo","bar"]
New Value : ["foo","lop"]

Result : ["foo","lop"]

It's Work

But

N° 2 :

Before edit: ["foo","bar"]
New Value : ["foo"]

Result : ["foo","bar"]

It's the effect of extends with "true" param.

I have patched like that and now edit selectize or select2 works fine.
But i think it's not the best solution.

Thanks

Patch :

if ( action === 'edit' ) {
        var rowData = originalData[ key ].data;
                - toSave = $.extend(true, {}, rowData, vals ); // old
                + toSave = $.extend({}, rowData, vals ); // new
}

Replies

  • allanallan Posts: 63,893Questions: 1Answers: 10,531 Site admin

    Thanks for this and your insights into it! This is a tricky one, as it is valid to have nested objects of data in the table, where the true parameter to deep copy would be required.

    I'll need to think about this one a bit more. I don't have an immediate solution I'm afraid!

    Allan

  • chrisLabchrisLab Posts: 2Questions: 0Answers: 0

    Thanks for reply.
    For moment for not hardcode datables.js I use this ""ugly patch"" where my tables needs select2 or selectize :

    var editor = new $.fn.dataTable.Editor({ ..})
    
    // Overwrite Methods Datables for select2 bug
    editor._submitTable = function ( data, success, error, submitParams )
    {
        var that = this;
        var action = data.action;
        var out = { data: [] };
        var idGet = $.fn.dataTable.ext.oApi._fnGetObjectDataFn( this.s.idSrc );
        var idSet = $.fn.dataTable.ext.oApi._fnSetObjectDataFn( this.s.idSrc );
    
        // Nothing required for remove - create and edit get a copy of the data
        if ( action !== 'remove' ) {
            var originalData = this._dataSource( 'fields', this.modifier() );
    
            $.each( data.data, function ( key, vals ) {
                var toSave;
    
                // Get the original row's data, so we can modify it with new values.
                // This allows Editor to not need to submit all fields
                if ( action === 'edit' ) {
                    var rowData = originalData[ key ].data;
                    toSave = $.extend({}, rowData, vals );
                }
                else {
                    toSave = $.extend( true, {}, vals );
                }
                // If create and there isn't an id for the new row, create
                // one. An id could be creased by `preSubmit`
                if ( action === 'create' && idGet( toSave ) === undefined ) {
                    idSet( toSave, +new Date() +''+ key );
                }
                else {
                    idSet( toSave, key );
                }
    
                out.data.push( toSave );
            } );
        }
    
        success( out );
    };
    
This discussion has been closed.