Search code examples
extjsstoreextjs4.2

How to prevent a store from updating a record, if another record has the same property?


I am currently working on a grid that uses the RowEditing plugin, when I click the 'add' button linked to the grid a new empty record is added to the store to which the grid is bound to. When I add a new row, I can check for the the values the user is trying to add, if this 'user_id' value is empty or duplicate, I alert the user about his duplicate entry and wipe it from the store.

I have an edge case that I cant figure out- This edge case occurs when the user wants to update an existing row and change the 'user_id' to an existing one or an empty one. I don't want to wipe this record, I just want to assume the user made a mistake and not update this record, I want to undo his/her update it.

here is my store's update method:

update : function(com, record, successful, eOpts){
        var store = Ext.data.StoreManager.lookup('EpaymentKioskOptStores');
        var table_id = record.data.kiosk_user_id;
        var _try = false;
        var _wipe = false;
        //if the record is empty handle it
        if(table_id.trim() == null || table_id.trim() == undefined || table_id.trim() == ''){
            if(record.dirty){
                //restore to original value, and cancel update
                record.data.kiosk_user_id = record.modified.kiosk_user_id;
                _try = true;
            }else{
                store.remove(record);
                _wipe = true;
            }
        }
        //if the record's kiosk_user_id is not empty
        else{
            store.each(function(r){
                var temp = r.data.kiosk_user_id;
                //the record we are trying to enter is a new record
                if(record.phantom){
                    //make sure the record is new and if we find another with the same key we can wipe record
                    if(!r.phantom && (temp == table_id)){
                        store.remove(record);
                        _wipe = true;
                    }
                }
                else{
                    //somehow have to make sure the record and r arent the same
                    if((r.internalId != record.internalId) && (temp == table_id)){
                        record.data.kiosk_user_id = record.modified.kiosk_user_id;
                        _try = true;
                    }
                }
            });
        }
        if(_try){
            Ext.Msg.alert('Warning', 'Your change was reverted');
            store.commitChanges();
        }
        if(_wipe){
            Ext.Msg.alert('Alert', 'Your changes were discarded');
            store.commitChanges();
        }
    }

Edit: This is the fix I implemented to solve my problem, its a little bit hacky


Solution

  • Instead of the store's update method, you can add this validation in the grid's (Row Editor's) validateedit; See http://docs.sencha.com/extjs/5.1/5.1.0-apidocs/#!/api/Ext.grid.plugin.RowEditing-event-validateedit

    listeners: {
      validateedit: function(editor, context) {
        var newId = context.newValues.userId;
        if (!newId) {
          editor.editor.getForm().findField('userId').markInvalid('User ID is required');
          return false;
        }
        // Now iterate through the store and check all userIds against newId and return false 
        // if you see a duplicate
      }
    }