Question about custom row ids in local table editing mode

Question about custom row ids in local table editing mode

sliekenssliekens Posts: 97Questions: 17Answers: 2
edited June 2017 in Editor

This one is hard to explain so bear with me.

My table is configured for local editing and I have set idSrc to a custom property. I have a handler for preSubmit where I assign a custom id to new entries.

preSubmit: function( e, data, action ) {
  if (action === 'create') {
    $.each(data, (index, value) => {
        // 'id' is the idSrc
        value.id = "row_" + nextInSequence();
    });
  }
}

The value of data might look something like this (after preSubmit):

{  
  "action":"create",
  "data":{  
    "0":{
      "loginName":"tester",
      "alias":"test user",
      "firstName":"testy",
      "lastName":"mctestface",
      "type":"User"
      // idSrc 
      "id": "row_5000"
    }
  }
}

I don't quite know how to explain my issue but the problem that I have is that the index property is still "0" instead of "row_5000" and I don't know how to rename it. I tried renaming the property inside my preSubmit handler but when the code reaches my postSubmit handler, it's renamed back to "0".

In the example I would like to rename the indexed property to "row_5000", same as the value of idSrc.

{  
  "action":"create",
  "data":{  
    "row_5000":{  
      "id": "row_5000"
      "loginName":"tester",
      "alias":"test user",
      "firstName":"testy",
      "lastName":"mctestface",
      "type":"User"
    }
  }
}

Is it possible to rename the indexed property inside preSubmit and have that change propagate to postSubmit?

My application handles postSubmit events to save data changes in a Redux store instead of talking to an ajax backend.

The reason why I want to use the indexed property instead of the idSrc property is because I use form-options submit type changed everywhere so I can't rely on idSrc to always be present in the data.

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    The data you are seeing in postSubmit is the expected structure for Editor. Actually, I would expect it to be an array rather than an object, but that won't make much difference.

    The examples in the manual show this.

    The id is in the object, so there is no need for it to also be in the parameter key.

    If you want to use the structure else where you'd need to map it to that structure (this is true regardless of it being local table editing or processed on the server-side).

    Allan

  • sliekenssliekens Posts: 97Questions: 17Answers: 2
    edited June 2017

    I'm talking about the other argument to postSubmit that represents the request.

    Given the following signature:

    postSubmit: function( e, json, data, action )

    Here json is the data from the server (or generated in-memory when in local table editing mode) and it looks like an array like you said.

    {
      "data": [
        {
          "user": {
            "loginName": "tester",
            "alias": "test user",
            "firstName": "testy",
            "lastName": "mctestface",
            "type": "User",
            "id": "row_149"
          }
        }
      ]
    }
    

    This is fine but that's not the data that I'm interested in. I'm only interested in what has changed. For that purpose I use the data argument - the object that Editor submits to the server.

    Here are three different examples of what that object looks like with submit form-option set to changed.

    When creating a new row:

    {
      "action": "create",
      "data": {
        // indexed property is the index of the first new item that was submitted to the server
        "0": {
          "user": {
            "loginName": "tester",
            "alias": "test user",
            "firstName": "testy",
            "lastName": "mctestface",
            "type": "User",
            // idSrc set by a preSubmit handler
            "id": "row_149"
          }
        }
      }
    }
    

    When editing the row that was just created:

    {
      "action": "edit",
      "data": {
        // indexed property is the value of idSrc
        "row_149": {
          "user": {
            "type": "Admin"
             // idSrc is missing because Editor is configured to submit only changed values
          }
        }
      }
    }
    

    When deleting the row:

    {
      "action": "remove",
      "data": {
        // indexed property is the value of idSrc
        "row_149": {
          "user": {
            "loginName": "tester",
            "alias": "test user",
            "firstName": "testy",
            "lastName": "mctestface",
            "type": "Admin",
             // idSrc
            "id": "row_149"
          }
        }
      }
    }
    

    Editor conveniently uses the id value for the indexed property of the data object, but only when editing or removing a row. For new rows, I have to write custom code in postSubmit to retrieve the id value from each new entry.

    It's not a huge deal but I would prefer if the data object for new rows is consistent with the other Editor actions once it reaches postSubmit.

    {
      "action": "create",
      "data": {
        // indexed property is the value of idSrc
        "row_149": {
          "user": {
            "loginName": "tester",
            "alias": "test user",
            "firstName": "testy",
            "lastName": "mctestface",
            "type": "User",
             // idSrc
            "id": "row_149"
          }
        }
      }
    }
    

    tldr version

    When I assign a value to idSrc in a preSubmit handler then I don't want to see the "0" index anymore in a postSubmit handler.

    I'll try some more and let you know how it goes.

  • sliekenssliekens Posts: 97Questions: 17Answers: 2

    I was able to get the result that I want and it was actually pretty easy.

    preSubmit: function( e, data, action ) {
      if (action === 'create') {
        $.each(data, (index, value) => {
            // 'id' is the idSrc
            value.user.id = "row_" + nextInSequence();
            
            // create a new index property on 'data'
            data[value.user.id] = value;
            
            // delete the original property
            delete data[index];
        });
      }
    }
    
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    I see what you mean - thanks for the clarification.

    In the case where you are generating the id on the client-side, yes I can see that would be useful. However, that is a relatively unusual use case - the majority of Editor deployments use a primary key value which is generated by a database, so there is nothing to use as the object key in the submitted data structure when submitting to the server. Hence why a simple array index is used.

    Thanks for posting your workaround though. That looks like the perfect way to handle it for this use case.

    Allan

  • sliekenssliekens Posts: 97Questions: 17Answers: 2
    edited June 2017

    the majority of Editor deployments use a primary key value which is generated by a database

    Yes our application is unusual. It's really cool though. We store change events from Editor in memory until a user clicks a save button. Then we submit all those changes as a single array to the server where they are applied to the data source in order of events.

    We implemented it this way to prevent users from making accidental changes to the live database. The way we have it now, a user can make changes and review them before deciding whether to save or discard the data. In the future we might add Undo and Redo buttons since our event sourcing pattern makes it super easy.

    The only trouble with this approach is that you have to have client-generated primary keys or it just doesn't work.

  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395

    We implemented it this way to prevent users from making accidental changes to the live database.

    That's impressive. The best I came up with was hiding the keyboards....

This discussion has been closed.