Hello,
There is a requirement in my project where I want to upload the image in an editable grid for every device and give a preview before submitting
a!localVariables( local!counter: 0, local!deleteDeviceIds, local!device: a!refreshVariable( value: rule!SABOT_GetAllDeviceSku(), refreshOnVarChange: local!counter ), local!deviceCount: length(local!device), local!result: null, local!showButton: false, local!tableName: "SABOT_DEVICE_SKU", local!DEV_ID: rule!SABOT_GetSABOT_REFR_FLDByColumn(local!tableName, "DEV_ID"), local!SKU: rule!SABOT_GetSABOT_REFR_FLDByColumn(local!tableName, "SKU"), local!DEV_NME: rule!SABOT_GetSABOT_REFR_FLDByColumn(local!tableName, "DEV_NME"), local!DEV_IMAG_NBR: rule!SABOT_GetSABOT_REFR_FLDByColumn(local!tableName, "DEV_IMAG_NBR"), local!DSPL_ORDR_NBR: rule!SABOT_GetSABOT_REFR_FLDByColumn(local!tableName, "DSPL_ORDR_NBR"), local!ACTV_CD: rule!SABOT_GetSABOT_REFR_FLDByColumn(local!tableName, "ACTV_CD"), a!boxLayout( label: "Spectrum Barter Account Devices", /*isCollapsible: true(),*/ /*accessibilityText: "Spectrum Barter Account Device list",*/ contents: { a!gridLayout( label: "", labelPosition: "ABOVE", totalCount: local!deviceCount, emptyGridMessage: "No Device SKUs found, use the Add Device SKU link to create one", headerCells: { a!gridLayoutHeaderCell(label: local!DEV_ID.FLD_LABEL_TXT), a!gridLayoutHeaderCell(label: local!SKU.FLD_LABEL_TXT), a!gridLayoutHeaderCell(label: local!DEV_NME.FLD_LABEL_TXT), a!gridLayoutHeaderCell(label: local!DEV_IMAG_NBR.FLD_LABEL_TXT), a!gridLayoutHeaderCell(label: "Upload Device Image"), a!gridLayoutHeaderCell( label: local!DSPL_ORDR_NBR.FLD_LABEL_TXT ), a!gridLayoutHeaderCell(label: local!ACTV_CD.FLD_LABEL_TXT), a!gridLayoutHeaderCell(label: "") }, columnConfigs: { a!gridLayoutColumnConfig( width: "NARROW", showWhen: isusermemberofgroup_21r2(loggedInUser(), cons!SABOT_ADMIN_GROUP) ), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 2), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 4), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 2), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1), a!gridLayoutColumnConfig(width: "ICON"), a!gridLayoutColumnConfig(width: "ICON") }, rows: { a!forEach( items: local!device, expression: a!gridRowLayout( id: fv!index, contents: { a!integerField( /*value: fv!item.DEV_ID,*/ /*readOnly: true*/ labelPosition: if(ri!readOnly, "ADJACENT", "ABOVE"), instructions: local!DEV_ID.INSTRTN_TXT, helpTooltip: local!DEV_ID.HELP_TOOLTIP_TXT, value: fv!item.DEV_ID, saveInto: fv!item.DEV_ID, required: local!DEV_ID.REQR_CD, requiredMessage: local!DEV_ID.REQR_MSG_TXT, /* NOTE this is the only time we override the ri!readOnly input */ readOnly: true, validations: if( isnull(local!DEV_ID.MAX_LGTH_QTY), "", if( len(fv!item.DEV_ID) > local!DEV_ID.MAX_LGTH_QTY, "The data entered is " & len(fv!item.DEV_ID) & " characters long, but the maximum characters allowed is " & local!DEV_ID.MAX_LGTH_QTY, {} ) ), accessibilityText: local!DEV_ID.ACCESSIBILITY_TXT ), a!textField( /*value: fv!item.SKU,*/ /*saveInto: fv!item.SKU*/ /*label: "SKU " & fv!index,*/ labelPosition: if(ri!readOnly, "ADJACENT", "ABOVE"), instructions: local!SKU.INSTRTN_TXT, helpTooltip: local!SKU.HELP_TOOLTIP_TXT, placeholder: local!SKU.PLACEHOLDER_LABEL_TXT, value: fv!item.SKU, saveInto: { fv!item.SKU, a!save(local!showButton, true) }, required: local!SKU.REQR_CD, requiredMessage: local!SKU.REQR_MSG_TXT, readOnly: ri!readOnly, disabled: ri!readOnly, validations: if( isnull(local!SKU.MAX_LGTH_QTY), "", if( len(fv!item.SKU) > local!SKU.MAX_LGTH_QTY, "The data entered is " & len(fv!item.SKU) & " characters long, but the maximum characters allowed is " & local!SKU.MAX_LGTH_QTY, {} ) ), accessibilityText: local!SKU.ACCESSIBILITY_TXT ), a!textField( /*value: fv!item.DEV_NME,*/ /*saveInto: fv!item.DEV_NME*/ label: "DEV_NME " & fv!index, labelPosition: if(ri!readOnly, "ADJACENT", "ABOVE"), instructions: local!DEV_NME.INSTRTN_TXT, helpTooltip: local!DEV_NME.HELP_TOOLTIP_TXT, value: fv!item.DEV_NME, saveInto: fv!item.DEV_NME, required: local!DEV_NME.REQR_CD, requiredMessage: local!DEV_NME.REQR_MSG_TXT, readOnly: ri!readOnly, disabled: ri!readOnly, validations: if( isnull(local!DEV_NME.MAX_LGTH_QTY), "", if( len(fv!item.DEV_NME) > local!DEV_NME.MAX_LGTH_QTY, "The data entered is " & len(fv!item.SKU) & " characters long, but the maximum characters allowed is " & local!DEV_NME.MAX_LGTH_QTY, {} ) ), accessibilityText: local!DEV_NME.ACCESSIBILITY_TXT ), a!imageField( size: "MEDIUM", images: if(isnull(ri!file), {}, a!documentImage( document: ri!file, /*altText: fv!item.DEV_IMAG_NBR*/ ) ) ), a!fileUploadField( /*label: "Image Upload",*/ /*labelPosition: "",*/ required: "", buttonStyle: "", buttonSize: "SMALL", maxSelections: 1, target: cons!SABOT_SAVING_DEVICE_IMAGE, value: fv!item.DEV_IMAG_NBR, saveInto: { fv!item.DEV_IMAG_NBR, a!save(ri!file,fv!item.DEV_IMAG_NBR) }, validations: a!localVariables( local!invalidExtensions: difference(upper(fv!files.extension), { "PNG", "JPG" }), if( length(local!invalidExtensions) > 0, "Attachments must be images. Remove: " & index(fv!files, "name", wherecontains(local!invalidExtensions, upper(fv!files.extension)), {}), "" ) ) ), a!integerField( /*value: fv!item.DSPL_ORDR_NBR,*/ /*saveInto: fv!item.DSPL_ORDR_NBR*/ labelPosition: if(ri!readOnly, "ADJACENT", "ABOVE"), instructions: local!DSPL_ORDR_NBR.INSTRTN_TXT, helpTooltip: local!DSPL_ORDR_NBR.HELP_TOOLTIP_TXT, value: fv!item.DSPL_ORDR_NBR, saveInto: fv!item.DSPL_ORDR_NBR, required: local!DSPL_ORDR_NBR.REQR_CD, requiredMessage: local!DSPL_ORDR_NBR.REQR_MSG_TXT, readOnly: ri!readOnly, disabled: ri!readOnly, validations: if( isnull(local!DSPL_ORDR_NBR.MAX_LGTH_QTY), "", if( len(fv!item.DSPL_ORDR_NBR) > local!DSPL_ORDR_NBR.MAX_LGTH_QTY, "The data entered is " & len(fv!item.DSPL_ORDR_NBR) & " characters long, but the maximum characters allowed is " & local!DSPL_ORDR_NBR.MAX_LGTH_QTY, {} ) ), accessibilityText: local!DSPL_ORDR_NBR.ACCESSIBILITY_TXT ), a!radioButtonField( /*choiceLabels: {"Yes", "No"},*/ /*choiceValues: {true,false},*/ /*value: fv!item.ACTV_CD,*/ /*saveInto: fv!item.ACTV_CD,*/ /*choiceLayout: "COMPACT"*/ labelPosition: if(ri!readOnly, "ADJACENT", "ABOVE"), instructions: local!ACTV_CD.INSTRTN_TXT, helpTooltip: local!ACTV_CD.HELP_TOOLTIP_TXT, choiceLabels: { "Yes", "No" }, choiceValues: { true, false }, value: fv!item.ACTV_CD, saveInto: { fv!item.ACTV_CD, a!save(local!showButton, true) }, required: local!ACTV_CD.REQR_CD, requiredMessage: local!ACTV_CD.REQR_MSG_TXT, /*readOnly: ri!readOnly,*/ disabled: ri!readOnly, choiceLayout: "COMPACT", validations: if( isnull(local!ACTV_CD.MAX_LGTH_QTY), "", if( len(fv!item.ACTV_CD) > local!ACTV_CD.MAX_LGTH_QTY, "The data entered is " & len(fv!item.ACTV_CD) & " characters long, but the maximum characters allowed is " & local!ACTV_CD.MAX_LGTH_QTY, {} ) ), accessibilityText: local!ACTV_CD.ACCESSIBILITY_TXT ), a!imageField( label: "delete " & fv!index, images: a!documentImage( document: a!iconIndicator("REMOVE"), altText: "Remove Device", caption: "Remove " & fv!item.SKU, link: a!dynamicLink( value: fv!index, saveInto: { if( isnull(fv!item.DEV_ID), {}, a!save( local!deleteDeviceIds, append(local!deleteDeviceIds, fv!item.DEV_ID) ) ), a!save( local!device, remove(local!device, save!value) ), a!save(local!showButton, true) } ) ), size: "ICON" ) } ) ) }, selectionSaveInto: {}, addRowLink: a!dynamicLink( label: "Add Device SKU", value: { DEV_NME: "new device type", DSPL_ORDR_NBR: 999, ACTV_CD: true }, saveInto: { a!save( local!device, append(local!device, save!value) ), a!save(local!deviceCount, local!deviceCount + 1) } ), validations: {}, shadeAlternateRows: true ), /*},*/ a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Submit", submit: true, style: "PRIMARY", saveInto: { a!startProcess( processModel: cons!SABOT_DEVICE_SKU_CREATE_UPDATE_PM, processParameters: { deviceSku: local!device, deleteDeviceIds: local!deleteDeviceIds, /*cancel: local!cancel,*/ /*readOnly: ri!readOnly,*/ onSuccess: a!save(local!result, "Yee ha!"), onError: a!save(local!result, "Uh Oh") } ), a!save(local!counter, local!counter + 1), a!save(local!showButton, false) }, disabled: local!showButton<>true ) }, secondaryButtons: { a!buttonWidget( label: "Back", value: null, /*saveInto: local!cancel,*/ saveInto: ri!category, submit: true, style: "DESTRUCTIVE", validate: false, ) }, showWhen: or(isnull(ri!readOnly), not(ri!readOnly)) ) } ) )
I am adding the UI, Interface, and code with this discussion. You will find the image and upload field column in code at lines 134 and 144.
Kindly reply if you find something wrong or want to understand something. I will be quick.
Thanks
Discussion posts and replies are publicly visible
Quick question, by any chance are you using it in the record view or report? because as per documentation it will not work
Hi gayathris0003 I checked the rule inputs there is no any rule input created using record type. Thanks
gayathris0003 - I think calling an interface directly in the site is an alternate that can be used instead of creating a report and using it there. Directly calling the interface might not work for file upload.
As you've suggested, the interface can be embedded into a process model and it can be configured as an action in the site.
,
You can save the fields(text values) by using functions such as writetoDataStoreEntity in a button save into. But for documents, Appian expects a form to be submitted. Only on form submit, the file will generate an Id and store the document in Appian. Hence the file-upload field alone is disabled in reports. Hope this helps you!
Good question, other fields can be used for filters like date search, free text search and etc. but file using file upload search is not common.
ok if the interface is inside the reports. Then what are the possible ways to upload an image for a particular row? gayathris0003Selvakumar Kumarasamy
A start process link. Create a simple process with a start form for just uploading that image.
Once that process is completed, you can refresh your data to include the image.
Ok I want that the start form to come up as a dialog box on the same screen? How to do that?
You can create a record action and configure the action in the interface.
docs.appian.com/.../Record_Action_Component.html
Ok, everything is added and uploading is working. One issue, I have to reload the page to see the change. Like I open the interface using the record action and upload image and submit. Then process model runs and adds the data into the database. After submit I come out the record action interface and I have to reload the page to see the image. Any solutions on that ?
Unknown said: Then process model runs and adds the data into the database. After submit I come out the record action interface and I have to reload the page to see the image.
Make sure your process model has Activity Chaining enabled on all flow lines between the Task and the WTDS node. If chaining is broken earlier than this, the old data will be seen upon leaving the process, as you described.
Activity chaining was not there before. But it didn't resolve that reload the page. Is there any way I submit the record action and a certain interface gets refreshed ?
Yes, you can use the function a!refreshVariable() to refresh the local variables after the record action(by configuring the refreshAfter parameter). This will make sure that the specified variables will refresh after you complete the action.docs.appian.com/.../fnc_evaluation_a_refreshvariable.html