Our blazing fast Grid component built with pure JavaScript


Post by kamranmushtaq »

Please see the attached video the show dirty behaviour is not goining after save if we remove the record before that. The store commit function is present in save button click only.
Remove is working separately (select the row and press delete button no need to save btn click) and add and modify save on single save button click.
Code/ Grid Instance:

    class StoreModel extends Model {
        static get fields() {
            return [
                'name',
                { name : 'quantity', type : 'int' }
            ];
        }
    }


const grid = new Grid({
    appendTo : 'grid',
    store : {
        modelClass : StoreModel,
        listeners : { 
            update : (data) => {	
                toggleSaveButton();		

                if (data.changes.language){
                    var languageName = data.record.data.language,
                        languageId = [...languages].filter((x)=>{
                            return x.name === languageName
                    });
                    data.record.data.language_id = languageId[0].id;
                }

                if (data.changes.status_name){
                    var statusName = data.record.data.status_name;

                    let statusId = [...statuses].filter((x)=>{
                        return x.status === statusName
                    })
                    data.record.data.status_id = statusId[0].id; 
                }
                
                var jobId = $("#job_id").val();	
                data.record.data.jobId  = jobId;
            },
            add : (data) => {	
                toggleSaveButton();
            },
            remove : (data) => {	
                setTimeout (() => {
                    var postUrl = "/_removeSubJob",	
                        removedRecorsCount = data.records.length,	
                        jobSourceIds = [],
                        removeDataSet = {},
                        getData = {},
                        pattern = /_generatedr/,
                        result;

                    for(var i=0; i<removedRecorsCount; i++) {
                        jobSourceIds.push(data.records[i].data.id); 	
                    }
                    result = pattern.test(jobSourceIds);
                    removeDataSet = {	
                        record_id: $("#ParentContainer").val(),	
                        source_id: jobSourceIds.toString(),
                        "jobId" : $("#job_id").val(),
                    };	

                    if (!result) {
                        getData = omg.dataDelivery.doPost(removeDataSet, postUrl, "", false);	
                        $("#totalQty").html(getData.parentQuantity);	
                        WidgetHelper.toast('Record has been removed successfully');
                    }
                }, 500);
            },
            exception : (data) => {
                onStoreException();
            },
            beforeRequest : () => toggleButtons(true),
            afterRequest : () => toggleButtons(false)
        }
    },        
    features : {
        cellEdit : true,
        sort : 'name',
        stripe : true,
        filterBar : {
            compactMode : true
        },
        quickFind : true
    },
    showDirty : true, // Show changed cells
    columns : [
        { type : 'rownumber' },
        { text : 'Title', field : 'creative_name', flex : 1 },
        {
            text : 'Status',
            field : 'status_name',
            renderer({ value }) {
                return {
                    class : 'badge',
                    style : {
                        backgroundColor : status_colours[status_names.indexOf(value)]
                    },
                    text : value
                };
            },
            width : '13em',
            editor : { type : 'combo', items : statuses, displayField : 'status', valueField : 'status' },
        },
        {
            text : 'Language',            
            field : 'language',
            width : '14em',
            editor : { type : 'combo', items : languages, displayField : 'name', valueField : 'name' }
        },
        { text: 'Details', field: 'job_description', width  : '16em' },
        { 
            text: 'Quantity', 
            field: 'quantity',
                type : 'number',
                editor : {
                    min : 1
                }
        },
    ],
    data : source.localdata,
    listeners : {
        selectionChange({ selection }) {
            removeButton.disabled = !selection.length;
        }
    },
    tbar : [     
    <% IF !job.is_locked %>  
        {
            type : 'button',
            ref : 'removeButton',
            icon : 'fa-thin fa-trash',
            tooltip : 'Removes selected record(s)',
            disabled : true,
            onAction : async({ source }) => {
                const selected = grid.selectedRecords;
                if (selected && selected.length) {
                    const store = grid.store,
                        nextRecord = store.getNext(selected[selected.length - 1]),
                        prevRecord = store.getPrev(selected[0]);

                    store.remove(selected);
                    // grid.selectedRecord = nextRecord || prevRecord;
                }
            }
        },
        {
            type : 'button',
            ref : 'addButton',
            icon : 'fa-thin fa-plus-large',
            tooltip : 'Adds a new row (at bottom)',
            onAction : () => {
                const counter = ++newOutputCount,
                    added = grid.store.add({
                        creative_name : `New Output ${counter}`,
                        status_name : '',
                        language : '',
                        job_description : '',
                        quantity : 1,
                        cls : `new_output_${counter}`
                    });
                    grid.features.cellEdit.startEditing({
                        record : added[0].data,
                        field : 'creative_name'
                    });

                grid.selectedRecord = added[0];
            }
        },
        {
            type : 'button',
            ref : 'saveButton',
            icon : 'fa-thin fa-floppy-disk',
            text : 'Save',
            disabled : true,
            tooltip : 'Saves changes (added, modified and removed rows)',
            onAction : async(data) => {
                var changes = await grid.store.commit(),	
                    modifiedRowsCount = changes.modified.length,	
                    addedRowsCount = changes.added.length;	

                if (modifiedRowsCount > 0) {
                    for(var i = 0; i < modifiedRowsCount ; i++) {	
                        grid_job_output.setRowData(changes.modified[i].data);        	
                    }	
                }	
                    
                if (addedRowsCount > 0) {	
                    for(var i = 0; i < addedRowsCount ; i++) {	
                        grid_job_output.setRowData(changes.added[i].data);      	
                    }	
                }

                var updateModifiedRowsReturn = grid_job_output.updateModifiedRows(grid_job_output.getUpdatedObjectsArray()),	
                    countStart = updateModifiedRowsReturn[0].row_id;

                if (addedRowsCount > 0) {	
                    for(var i = countStart, j = 0; i < grid.data.length; i++, j++) {     
                        grid.store.getAt(i).set("id", updateModifiedRowsReturn[j].sub_job_id);
                    }
                }
                
                grid_job_output.clearUpdatedObjectsArray();
                WidgetHelper.toast('Changes are updated Successfully');	
                    
                toggleSaveButton();	
                removeButton.disabled = true;
            }
        }
    <% END %>
    ]
});
Attachments
Britvic (2).mp4
(1.64 MiB) Downloaded 23 times

Post by kamranmushtaq »

Waiting for the reply can anyone please solve this issue.


Post by kamranmushtaq »

Hi Bryntum Team hope you guys are fine can you please answer this one ?


Post by johan.isaksson »

Hi,

Sorry for the delayed response. Took a quick look at your code, some suggestions:

  • Never set (or access) record.data.xx. record.data is a private object holding the raw data object. Setting it directly means the store and the UI won't know about it. Instead set record.xx or use record.set()

  • If you are managing saving yourself, call grid.store.commit() when you have saved to reset change tracking (removing those dirty marks).

When you post code, please make sure it is runable, which greatly helps us help you.

Best regards,
Johan Isaksson

Post Reply