a!localVariables( local!lineOfBusiness: rule!LCM_getLineOfBusinesses(lobkey: null(), lobcode: null()), local!attorneys: rule!LCM_getAttorneys(soeid: null(), attorneykey: null()), local!selectedAttorney, local!selectedAttorneyLOB, local!attorneyLOB: { a!map(attorneykey: null(), lobkey: null()) }, a!formLayout( label: "Form", contents: { a!boxLayout( label: "Attorney - Line of Businesses", contents: { a!gridLayout( label: "", labelPosition: "ABOVE", totalCount: count(local!attorneyLOB), headerCells: { a!gridLayoutHeaderCell(label: "Attorney(s)"), a!gridLayoutHeaderCell(label: "Line of Business"), a!gridLayoutHeaderCell(label: "") }, columnConfigs: { a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1), a!gridLayoutColumnConfig(width: "ICON") }, rows: { a!forEach( items: local!attorneyLOB, expression: a!gridRowLayout( contents: { a!dropdownField( label: "Attorney(s)" & fv!index, labelPosition: "ABOVE", helpTooltip: "Attorney(s)", placeholder: "Select a Attorney", choiceLabels: index(local!attorneys, "name", ""), choiceValues: index(local!attorneys, "attorneykey", ""), value: fv!item.attorneykey, saveInto: { fv!item.attorneykey, a!save( target: ri!intakeattorneys, value: a!forEach( items: local!attorneyLOB, expression: {AttorneyKey: fv!item.attorneykey} ) ) }, required: true ), a!multipleDropdownField( label: "LOB" & fv!index, labelPosition: "ABOVE", placeholder: "Select a Line of Business", choiceLabels: index(local!lineOfBusiness, "lobname", ""), choiceValues: index(local!lineOfBusiness, "lobkey", ""), value: fv!item.lobkey, saveInto: {fv!item.lobkey, a!save( ri!attorneyLineOfBusiness, value: a!forEach( items: local!attorneyLOB, expression: {attorneykey: fv!item.attorneykey, lobkey: a!forEach( items: fv!item.lobkey, expression: {lobkey: fv!item} ) } ) ) }, required: true ), a!imageField( label: "delete " & fv!index, images: a!documentImage( document: a!iconIndicator("REMOVE"), altText: "Remove", caption: "Remove ", link: a!dynamicLink( value: fv!index, saveInto: { a!save( local!attorneyLOB, remove(local!attorneyLOB, save!value) ) }, ), showWhen: fv!index > 1 ), size: "ICON" ) } ) ) }, selectionSaveInto: {}, validations: {}, shadeAlternateRows: true, addRowLink: a!dynamicLink( label: "Add", saveInto: { a!save( local!attorneyLOB, append(local!attorneyLOB, save!value) ) } ), rowHeader: 1 ) }, style: "STANDARD", marginBelow: "STANDARD" ) }, buttons: a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Submit", submit: true, style: "PRIMARY" ) }, secondaryButtons: { a!buttonWidget( label: "Cancel", value: true, saveInto: ri!cancel, submit: true, style: "NORMAL", validate: false ) } ) ) )
I have a user input with editable grid where each row will have 2 dropdowns.
The first dropdown "Attorney(s)" is a single selection where as "Line of Business" is a multiselection.
I have able to save the attorneykey to the rule input (black arrow in the image), where as I was unable to save/pass lobkey (multiple values) into the rule input.
Can someone give an idea who can I fix this. Thanks in advance.
Discussion posts and replies are publicly visible
What is the CDT definition for the "attourneyLineOfBusiness" rule input? Is the "lobkey" property single or multiple?
It looks like every time the multiple dropdown is changed (regardless of the row) you're attempting to overwrite the value of "ri!attourneyLineOfBusiness" with a copy stored in the local!attourneyLOB dictionary where the "lobkey" property is actually multiple values. If your CDT doesn't have that field defined as an array, then it simply won't work. I'd also caution that this might not be the best approach for storing multiple row-related values, though i suppose it could work with some fixes to your existing code (i'd suggest fixing the indentation in your a!forEach loops in your saveInto and consider whether you need to list the "lobkey" property name quite so many times, for one...)
When I try to create lobkey as an array, appian is trying to create one more new table.
Do I need to create another new ruleInput with referring to newly crated table?
If the child CDT is nested in the parent CDT, you can save directly into its value(s) in the parent row of the editable grid by saving into "fv!item.childCdtPropertyName". That would require one and only one a!forEach level in the saveInto of the multiple dropdown field - looping over every value currently in the "save!value" of the dropdown, and initializing a child CDT entry for it. In this manner you should be able to base the Editable Grid rows directly on the Rule Input CDT and skip the local dictionary stage.
Here's a 100% generic form relying on a generic, relatively-freshly-created parent/child CDT pair, which handles the "rows of child CDT per parent row based on multi dropdown value" concept.
a!formLayout( label: "Simple Submit form", contents: { a!gridLayout( label: "test grid", headerCells: { a!gridLayoutHeaderCell(label: "label"), a!gridLayoutHeaderCell(label: "multiple") }, rows: a!forEach( ri!parentCdt, a!gridRowLayout( contents: { a!textField( value: fv!item.parentText1, saveInto: fv!item.parentText1 ), a!multipleDropdownField( value: property(fv!item.nestedElement1, "int1", {}), saveInto: { a!save( fv!item.nestedElement1, a!forEach( save!value, { int1: fv!item, text1: "active" } ) ) }, choiceValues: {1, 2, 3}, choiceLabels: {1, 2, 3} ) } ) ), addRowLink: a!dynamicLink( label: "Add", saveInto: a!save( ri!parentCdt, append( ri!parentCdt, { parentText1: "", nestedElement1: {} } ) ) ) ) }, buttons: a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Submit", submit: true() ) } ) )
Hi,
Thanks for providing details explanation.
Is there any way we can get a default row in this editable grid. If we try to use ruleInput "ri!parentCdt" for the gird rows, we are not getting default row until we click "New Field" link.
Any idea on this.
You would need to populate it in-process prior to your user input task. Though I don't think it should really be necessary to have a "default row" - just validate that the users add at least one.
Thanks for your reply.
I don't user input task. I am attaching the SAIL form to the process start node.
Not sure how I can achieve.
You can always off-shift your editable grid rows into a local variable instead of directly reading/writing to the Rule Input - in that case you'd declare a "blank" one initially in the local variable definition, then in the "submit" button you'd add an a!save() statemen that mirrors the value of the local variable into the rule input.
Thank you so much for all your explanations. I really appreciate.
Hi Mike,
One strange issue which I am facing is, the RecordType which I am using to refer Child CDT is not getting synced once the data is saved through Parent CDT.
If I ran DataSync, manually then I was able to see in the front-end.
Any tips please.
Thanks.
If you're in Appian 22.2 already, you could try using the "Sync Records" smart service node to force syncing of the child element. Otherwise I'm unsure - my assumption so far was that the Write to DSE Node caused syncing to happen, but I'm unsure how nested CDTs are handled there.
We are currently using 21.4.