Appian Community and Appian Academy are being upgraded. From July 24–August 3, the Appian Community will be in read-only mode. During this time, the site will be read-only and user registration will be disabled. We apologize for any inconvenience this may cause, but a more secure, stable, and performant Community experience is coming soon!
The new Appian Community launches August 3, followed by Appian Academy on August 7. During the migration, Appian Community Edition, Appian Academy, Documentation, Certifications, Instructor-led Customer Training, Partner Sales Training & Accreditation, and Forum (for Appian Partners and Customers only) will remain available.
HI guys
I'm chasing my tail here.
We are assessing software against 4 criteria per software title.
For each criterion we have a different assessor group.
The software titles are kept in a list of map since they are not yet approved for our Allow List and we don't want to keep the data if they are not approved.
We have a custom comments record type which has a many-to-one relationship with the software table.
Issue:
For each software title we need to keep 4 comments, but I find I am only able to overwrite the comments value, not append.Here's the code for my approval details interface:
a!localVariables( local!softwareCategoryList: rule!getSoftwareCategoryList( includeDisabled: false, includedSoftwareCategoryID: if( a!isNullOrEmpty( ri!mappedValue.software[Global Software.fields.id'] ), null, ri!mappedValue.software['recordType!Global Software.fields.softwareCategoryID'] ) ), a!gridLayout( label: "Approve Software", labelPosition: "COLLAPSED", headerCells: { a!gridLayoutHeaderCell(label: "Software Name"), a!gridLayoutHeaderCell(label: "Category Name"), a!gridLayoutHeaderCell(label: "Vendor Name"), a!gridLayoutHeaderCell( label: "", showWhen: and(not(ri!readOnly), not(ri!edit)) ), a!gridLayoutHeaderCell( label: "Comment", showWhen: rule!APP_isTrue(ri!mappedValue.decision), align: "LEFT" ), a!gridLayoutHeaderCell( label: "Status", showWhen: and(ri!readOnly, not(ri!edit)) ) }, columnConfigs: { a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3), a!gridLayoutColumnConfig(width: "NARROW", weight: null), a!gridLayoutColumnConfig(width: "MEDIUM"), a!gridLayoutColumnConfig(width: "DISTRIBUTE") }, rows: a!forEach( items: ri!mappedValue, expression: { a!gridRowLayout( id: fv!index, contents: { a!textField( label: "Software Name", labelPosition: "COLLAPSED", value: fv!item.software['recordType!Global Software.fields.name'], saveInto: fv!item.software['recordType!Global Software.fields.name'], readOnly: or(ri!readOnly, not(ri!edit)) ), a!richTextDisplayField( label: "Category Name", labelPosition: "ADJACENT", value: { a!richTextItem( text: fv!item.software['recordType! Global Software.relationships.softwareCategory.fields.name'] ), char(32), a!richTextIcon( icon: "question-circle-o", caption: fv!item.software['recordType!Global Software.relationships.softwareCategory.fields.description'], showWhen: a!isNotNullOrEmpty( fv!item.software['recordType!Global Software.relationships.softwareCategory.fields.description'] ), color: "#b3d1e6", size: "MEDIUM" ) }, showWhen: or(ri!readOnly, not(ri!edit)) ), a!dropdownField( choiceLabels: local!softwareCategoryList['recordType!Software Category.fields.name'], choiceValues: local!softwareCategoryList['recordType!Software Category.fields.id'], label: "Software Category", labelPosition: "ADJACENT", placeholder: "--- Select a software category ---", value: fv!item.software['recordType!Global Software.fields.softwareCategoryID'], saveInto: { fv!item.software['recordType!Global Software.fields.softwareCategoryID'], a!save( fv!item.software['recordType! Global Software.relationships.softwareCategory'], index( local!softwareCategoryList, wherecontains( save!value, local!softwareCategoryList['recordType!Software Category.fields.id'] ), null ) ) }, showWhen: and(not(ri!readOnly), (ri!edit)), required: true ), a!textField( label: "Vendor Name", labelPosition: "COLLAPSED", value: fv!item.software['recordType!Global Software.fields.vendorName'], saveInto: fv!item.software['recordType!Global Software.fields.vendorName'], readOnly: or(ri!readOnly, not(ri!edit)) ), a!radioButtonField( choiceLabels: { "Approve", "Rejected" }, choiceValues: { true, false }, label: "Approve", labelPosition: "COLLAPSED", value: fv!item.decision, saveInto: { fv!item.decision }, showWhen: and(not(ri!readOnly), not(ri!edit)), required: true, choiceLayout: "COMPACT", choiceStyle: "CARDS" ), a!paragraphField( label: "Comments", labelPosition: "ABOVE", placeholder: "Please add any comments you may have", value: ri!mappedValue.software['recordType!Global Software.relationships.comments.fields.comment'], saveInto: { ri!mappedValue.software['recordType!Global Software.relationships.comments.fields.comment'] }, refreshAfter: "UNFOCUS", height: "MEDIUM", showWhen: rule!APP_isTrue(ri!mappedValue.decision), readOnly: rule!APP_isTrue(ri!readOnly), disabled: false ), a!tagField( labelPosition: "COLLAPSED", tags: { a!match( value: true, equals: fv!item.decision, then: a!tagItem( text: "APPROVED", backgroundColor: "#0c9aba" ), default: a!tagItem( text: "NOT APPROVED", backgroundColor: "#FF9B78" ) ) }, showWhen: and(ri!readOnly, not(ri!edit)) ) }, selectionDisabled: false ) } ), selectionSaveInto: {}, allowRowReordering: false, validations: {}, shadeAlternateRows: false, borderStyle: "LIGHT" ) )
I know there's probably a simple answer but I am drowning in a lake of overthink!Any help will be gratefully accepted
Blessings
Stephen
Discussion posts and replies are publicly visible
Keep in mind that grids aren't a great UX to edit a 1:many relationship within a given row directly. You'll probably want a drilldown UX pattern. The grid would simply show the comments with the link to edit the list of comments in a sidebar (or similar).
To demonstrate this, try the following:
This line:saveInto: { ri!mappedValue.software['recordType!Global Software.relationships.comments.fields.comment'] },
saveInto: { ri!mappedValue.software['recordType!Global Software.relationships.comments.fields.comment'] },
Would turn into something like:
saveInto: { a!save( ri!mappedValue.software['recordType!Global Software.relationships.comments'], append( ri!mappedValue.software['recordType!Global Software.relationships.comments'], recordType!Comment(comment: save!value) ) ) },
There's probably a bit more needed to handle null values, but that's the gist.