Issue with grid selection when storing objects

Certified Senior Developer

Hi,

I'm trying this tutorial... 

docs.appian.com/.../Grid_Tutorial.html

I'm interesting about the two code lines that enables to store the Object selected items :

selectionSaveInto {

  a!save(local!selectedVehicles, append(local!selectedVehicles, fv!selectedRows)),
  a!save(local!selectedVehicles, difference(local!selectedVehicles, fv!deselectedRows))

  All works fine, but could you explain me why when I'm try to set  local!selectedVehicles into a Rule Input. I obtain this error below please ?

I've just addied 2 lines of code :

a!localVariables (

   local!selectedVehicles : ri!selectedVehicles, /* that is the same type used for the grid data, CDT type with array values */

  ...

selectionSaveInto {

  a!save(...),
  a!save(...),

  a!save(ri!selectedVehicles, local!selectedVehicles)

  Discussion posts and replies are publicly visible

Parents
  • problem occurs because of typecasting.  you can typecast a map to cdt using typecast function and then saved it will not result in error. 

    or it can be avoided simply by doing this way also.

    a!save(ri!selectedVehicles, difference(ri!selectedVehicles, fv!deselectedRows))

  • 0
    Certified Senior Developer
    in reply to Praful Singhal

    Thank you Praful.
    Do you mean the "cast" function?  I have tried this :

    a!save(local!selectedVehicles, difference(
       cast('type!{urn:com:appian:types:cjt2}CJT2_Vehicles',local!selectedVehicles),
       cast('type!{urn:com:appian:types:cjt2}CJT2_Vehicles', fv!deselectedRows))),

    but even if the error is not throwed anymore, the selection objects list are wrong and does not reflect the real selection.

    Could you just be more precise with an example please ? 

    Your 2nd suggestion does not correct the problem, you are just storing the result of the Difference function in the rule input but the error still occurs.

  • Yes i am talking about the cast fuction with this saving issue is fixed.  please print local!selectedVehicles, and fv!deselectedRows, then compare both. I think most probably you have issue of wrong fv!deselectedRows. Please try with one more logic a!save(local!selectedVehicles,difference({local!selectedVehicles},{fv!deselectedRows}))

  • 0
    Certified Senior Developer
    in reply to Praful Singhal

    I'm sorry, I don't understand the logic of your reply.

    If I remove the cast functions, and I delete the rule input of my interface, all works perfectly (as my example is from the tutorial).

    So I do not understand how using a rule input in place of the initial local var is a problem.

    as I've mentionned before, I've just adding 2 code lines.

  • rule input is of type CDT CJT2_Vehicles when you assign it to local!selectedVehicles then the local!selectedVehicles also become of same type and while fv!deselectedRows is not of type CDT CJT2_Vehicles, type for fv!deselectedRows  is a map(String, Object). so thats why you are facing this issue. You don`t need to cast local!selectedVehicles you just need to cast fv!deselectedRows to CDT type i.e 

    a!save(
    local!selectedVehicles,
    difference(
    local!selectedVehicles,
    {
    a!flatten(
    a!foreach(
    items: fv!deselectedRows,
    expression: cast(
    'type!{urn:com:appian:types:cjt2}CJT2_Vehicles',
    fv!item
    )
    )
    )
    }
    )
    )

    or  second option convert CDT to map using  but i am not sure the line of code which i right below will change the cdt to map. But i think its worth to try 

    a!save(local!selectedVehicles,difference({local!selectedVehicles},{fv!deselectedRows}))

Reply
  • rule input is of type CDT CJT2_Vehicles when you assign it to local!selectedVehicles then the local!selectedVehicles also become of same type and while fv!deselectedRows is not of type CDT CJT2_Vehicles, type for fv!deselectedRows  is a map(String, Object). so thats why you are facing this issue. You don`t need to cast local!selectedVehicles you just need to cast fv!deselectedRows to CDT type i.e 

    a!save(
    local!selectedVehicles,
    difference(
    local!selectedVehicles,
    {
    a!flatten(
    a!foreach(
    items: fv!deselectedRows,
    expression: cast(
    'type!{urn:com:appian:types:cjt2}CJT2_Vehicles',
    fv!item
    )
    )
    )
    }
    )
    )

    or  second option convert CDT to map using  but i am not sure the line of code which i right below will change the cdt to map. But i think its worth to try 

    a!save(local!selectedVehicles,difference({local!selectedVehicles},{fv!deselectedRows}))

Children
  • difference fuction works on same data type so you need to take care about it.

  • 0
    Certified Senior Developer
    in reply to Praful Singhal

    I've tried all the combinations but it does not work.
    I've tried with others CDT to be sure of my tests, but it still the same.

    Here is a full test that works well (not setting the rule input as source). But if you try to uncomment the first comment (3rd line), or replace local!selectedVehicles by ri!selectedVehicles in the whole code, Appian throws an error.

    a!localVariables(
      local!selection,
      local!selectedVehicles, /* : ri!selectedVehicles, */
      /* cast(
        'type!{urn:com:appian:types:cjt2}CJT2_Vehicles', ri!selectedVehicles),
      */  
      a!sectionLayout(
        contents: {
          a!columnsLayout(
            columns: {
              a!columnLayout(
                contents: {
                  a!cardLayout(
                    contents: {
                      a!gridField(
                        label: "Read-only Grid",
                        labelPosition: "ABOVE",
                        data: ri!vehicles,
                        columns: {
                          a!gridColumn(
                            label: "Make",
                            value: fv!row.make
                          ),
                          a!gridColumn(
                            label: "Model",
                            value: fv!row.model
                          ),
                        },
                        selectable: true,
                        selectionStyle: "CHECKBOX",
                        selectionValue: local!selection,
                        selectionSaveInto: {
                          local!selection,
                          a!save(local!selectedVehicles, append(local!selectedVehicles, fv!selectedRows)),
                          a!save(local!selectedVehicles, difference(local!selectedVehicles, fv!deselectedRows)),
                          
                          a!save(ri!selectedVehicles, local!selectedVehicles),
                        },
                        validations: {}
                      )
                    },
                    height: "AUTO",
                    style: "NONE",
                    marginBelow: "STANDARD"
                  ),
    
                }
              ),
              a!columnLayout(
                contents: {}
              )
            }
          )
    
        },
        showWhen: true
      )
    )

  • 0
    A Score Level 1
    in reply to cedric01

    Line 3:  local!selectedVehicles : ri!selectedVehicles,  Any specific reason for doing that ? Are you passing value of this local variable from somewhere? Because in line 37 , you're saving local!selectedVehicle to RI selectedVehicle. Just define the local variable as local!selectedVehicles. The type mismatch issue is coming because of different type as mentioned by Praful. 

    Also , what is the value of Ri!vehicles(data part in grid ). Is your grid populated ?

  • 0
    Certified Senior Developer
    in reply to Shikha

    My Grid is inside a sub interface.
    So from my parent interface form, I need to pass this RI to the sub interface.

    I would need this to reinitialize this RI in some conditions.

    I need also to pass a RI with the CDT data to this sub interface.

    (this CDT data is dynamically filtered, and then this impact the grid, but the selection has to be reset, when the data filter is changed)

    Yes, the grid works fine and is well populated :

  • 0
    A Score Level 1
    in reply to cedric01

    Hi , 

    Try saving local!selectedVehicle to a new Rule input of type CJT2_vehicles( array type) instead of ri!selectedVehicle. You can use that new RI to pass further.   Please check that your RI vehicle is of same type as that of RI!selectedVehicle. (in this case CJT2_vehicles( array type) this type ). Try with that once. Also , include a paragraph field in the end for debugging. (you can see local!selectedVehicle values in that ).

  • 0
    Certified Senior Developer
    in reply to Shikha

    Thank you Shikha, but I still have this error.

    Finally, I've gave up (as a colleague just confirmed me, that he has exactly the same error few months ago)...

    I've decided to deal with the selectedIds selection ony (array of identifiers)... and then, all I need to do works like a charm now :-)

    I will wait for the next Appian versions and will re-test in the future (as I have a good workaround)...

  • 0
    A Score Level 1
    in reply to cedric01

    I tried the same code , except using one of the CDT's  that I have . It works fine for me . I am able to select/deselect the rows. 

  • 0
    Certified Senior Developer
    in reply to Shikha

    may I see the whole code please (the saveinto part) ?

  • 0
    A Score Level 1
    in reply to cedric01

    a!localVariables(
      local!selection,
      local!selectedVehicles: ri!selectedVehicles,
      /* cast(
        'type!{urn:com:appian:types:cjt2}CJT2_Vehicles', ri!selectedVehicles),
      */
      a!sectionLayout(
        contents: {
          a!columnsLayout(
            columns: {
              a!columnLayout(
                contents: {
                  a!cardLayout(
                    contents: {
                      a!gridField(
                        label: "Read-only Grid",
                        labelPosition: "ABOVE",
                        data: ri!projectDetails,
                        columns: {
                          a!gridColumn(
                            label: "Name",
                            value: fv!row.name
                          ),
                          a!gridColumn(
                            label: "Manager",
                            value: fv!row.manager
                          ),
                          
                        },
                        selectable: true,
                        selectionStyle: "CHECKBOX",
                        selectionValue: local!selection,
                        selectionSaveInto: {
                          local!selection,
                          a!save(
                            local!selectedVehicles,
                            append(
                              local!selectedVehicles,
                              fv!selectedRows
                            )
                          ),
                          a!save(
                            local!selectedVehicles,
                            difference(
                              /*cast(typeof('type!{urn:com:appian:types:AMT}projectDetails?list'),local!selectedVehicles),*/
                             local!selectedVehicles, fv!deselectedRows
                            )
                          ),
                          a!save(
                          ri!test,
                            local!selectedVehicles
                          ),
                          
                        },
                        validations: {}
                      )
                    },
                    height: "AUTO",
                    style: "NONE",
                    marginBelow: "STANDARD"
                  ),
                  
                }
              ),
              a!columnLayout(
                contents: {}
              )
            }
          ),
          a!paragraphField(
            label:"local!selectedVehicle",
            value: local!selectedVehicles
          )
        },
        showWhen: true
      )
    )

    I created Ri test of same table type (Array type). Giving some dummy values to Ri!projectDetails. 

  • 0
    Certified Senior Developer
    in reply to Shikha

    Yes, it works because your ri!test can not be used from a parent interface as an input.

    (your ri!test shows the current Objects selection only but it can not be set)

    With this code if I set the ri!test to null from my parent interface, it does not apply any modification in the selected objects of the grid. It just set the ri!test in the parent interface.