Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    [Bug] ListGrid.autoSaveEdits=false; do not work on fields with `dataPath` attribute.

    Hi,

    After couple of hours of debugging I finally concluded that all fields which contains `dataPath` attribute will modify a ResultSet field immediately instead of placing edited values inside ListGrid._editSessions, and that`s why I cannot call ListGrid.saveAllEdits() it won`t recognize any changes, even in UI I can clearly see that edited item is in regular color (instead of blue).

    Preconditions:

    ListGrid.canEdit=true;
    ListGrid.autoSaveEdits=false;

    Example:

    Code:
    ListGrid.create({
                    fields: [
                        {
                            title: 'Total Price',
                            name: 'price',
                            dataPath: 'total_price/amount',
                            type: "float"
                        }
                    ]
    });
    Actions:

    1) click on the row and begin inline editing
    2) change to some value '123456'
    3) click ENTER

    Postcondition:

    value should be in blue color. But actually is in black color as before.

    Reasoning:

    I think FormItem component immediately changes a value reflected by `dataPath` and we cannot observe any value changes in ListGrid._storeEditValue(), because oldValue === newValue immediately.

    Stack trace:
    >>>> Here <<< field value with `dataPath` is now changed. And on fields without `dataPath` values is still not changed in this step (correct behavior).

    Object.isc.ListGrid.addMethods.storeUpdatedEditorValue (http://demo.dev/isomorphic/system/modules-debug/ISC_Grids.js:50741:5)
    at Object.isc.ListGrid.addMethods.getEditValue (http://demo.dev/isomorphic/system/modules-debug/ISC_Grids.js:49434:14)
    at Object.isc.ListGrid.addMethods._saveAndHideEditor (http://demo.dev/isomorphic/system/modules-debug/ISC_Grids.js:51211:25)
    at Object.isc.ListGrid.addMethods.cellEditEnd (http://demo.dev/isomorphic/system/modules-debug/ISC_Grids.js:50684:14)
    at Object.isc.ListGrid.addProperties.editorKeyPress (http://demo.dev/isomorphic/system/modules-debug/ISC_Grids.js:28155:18)
    at Object.isc.ListGrid.addProperties.editFormDefaults.itemKeyPress (http://demo.dev/isomorphic/system/modules-debug/ISC_Grids.js:27988:30)

    Further ListGrid._storeEditValue() won't detect (return: false) that any fields that had changed so no values are stored in `_editSessions` .

    I hope you'll figure out what I just had written, ask me if you need a more details about this situation.

    Thank you.


    Affected: all versions including SmartClient_v100p_2015-03-10_LGPL

    #2
    First off, do not use the "dataPath" feature unless you are compensating for a legacy architecture, for example, a legacy server system that returns all data as compound documents with multiple record types instead of supporting individual fetch/add/update/remove operations on individual record types (the modern architecture).

    Most likely you will realize you don't need to use this feature at all. But if you think it may still make sense for you, you need to fix several things to make your test case runnable: there's no DataSource, the settings are incomplete, and there's no sample data.

    Comment


      #3
      Where is no need for data source to work.
      Here is non working code:

      Code:
      ListGrid.create({
                      canEdit:true,
                      autoSaveEdits:false,
                      fields: [
                          {
                              title: 'Total Price',
                              name: 'price',
                              dataPath: 'total_price/amount',
                              type: "float"
                          }
                      ],
                      data: [
                             { total_price: {amount:100, currency: 'EUR'} }
                       ]
      });
      I thought that I could access nested structures using dataPath, but is it deprecated today?
      If I use simple data structures for example data: [ {total_price: 100}] and field: [{name:'total_price'}] when autoSaveEdits=false;
      will work as defined. all pre-commited values will be changed to "blue" color and I can retrieve all changed data. or call saveAllEdits()
      to commit all changed to that data array.

      That`s why I`m showing you example with a "dataPath" is because I was using name="total_price.amount", for example:

      Code:
      ListGrid.create({
                      canEdit:true,
                      autoSaveEdits:false,
                      fields: [
                          {
                              title: 'Total Price',
                              name: 'total_price.amount',
                              type: "float"
                          }
                      ],
                      data: [
                             { total_price: {amount:100, currency: 'EUR'} }
                       ]
      });
      It will display value correctly in ListGrid so is it unexpected behavior? (Actually also debugged with this and it looks even worse in debug session, as with "dataPath" )

      Actually is doesn't matter whether is with DataSource or without a DataSource I've tested it also.

      Everything works expect transactional commits (with autoSaveEdits=false) (changes are saved immediately)

      Please clarify about that name: "total_price.amount", why it works at all? It would be good that such cases would throw exceptions immediately about incorrect usages because it`s impossible to find out what is good and what is bad, btw why is it bad? because ListGrid DynamicForm's will recognize that name: "{field}.{field2}.{field3}" naming and can use deep nested objects.

      It`s nice that is possible to return JSON response as full object on a field. My example field "total_price": {amount:100, currency: 'EUR'} and I can access that values by using "total_price.amount" (I just translated it to "dataPath" as thought is more correct approach)

      So by your response as I understood there is a system restriction that any DataSource fields must be flattened? we cannot contain any nested variables? But why it works?

      Thanks.
      Last edited by antanas.arvasevicius; 26 Mar 2015, 11:18.

      Comment


        #4
        "dataPath" not deprecated, but as we explained before, the "dataPath" feature is designed to enable integration with legacy systems. If you do not have a legacy system, you should either flatten your data or represent it as related DataSource records. Otherwise, if you use dataPath, you get into an area where there is a lot of extra complexity and lots of limitations, which only make sense to tackle if you are forced to use dataPath due to integration with a legacy system.

        On your other question: DataSource and ListGrid field names may not contain non-identifier characters (such as "."), and you can discover this by just reading the docs. Anything that results when you use an invalid field name is unspecified and unsupported behavior.

        Comment


          #5
          Thank you for your fast response!

          I was suspicious about that "{field}.{field}" naming at first, but saw that SmartClient on add operations will make an nested objects from these fields and also then receives nested objects will recognize using "{field}.{field}" notation on FormItems. But it`s unintentional behavior which simplify ValueObjects implementation, as Money type, Quantity type {value: 100, unit: 'Meters'}
          so now this must be implemented as separate fields {"brutto_amount", "brutto_currency", "netto_amount", "netto_currency"} instead of elegant solution. with "field.field" it`s possible to implement CurrentyItem form item which represets amount and currency on the same component.
          Using separate datasources for such Value Objects I think would be overkill.

          From now I'll use flattened fields for my features.

          Could be added fast defensive checks on field names as some /^[\w\d_-]+$/ regexp or similar? You know programmers do not read a docs line by line :-)

          Comment


            #6
            When you have a numeric value and unit field, you still need two field definitions, because your "currency" value is still going to need a field definition in order to allow it to be displayed and edited.

            Once you realize that you need two field definitions regardless, the fact that the structure is nested in a particular way is not "elegant", it's just a nuisance that requires all kinds of processing to be more complicated (recursive traversal required for copying, change detection, etc) and introduces a variety of new edge cases and error conditions.

            About defensive checks: we do have such checks in the SmartGWT product line, where there is a distinct mode used for debugging. Defensive checks of this kind are too slow for production use, and if we added them and had a flag to turn them off, we would just get complaints from people who didn't read the docs telling them to turn the defensive checks off!

            Comment

            Working...
            X