When I upload my files, they disappear!!!
Here is the code:
a!fileUploadField( label: "Please upload any pictures, brochures or other documents describing the Project", labelPosition: "ABOVE", target: cons!PMSO_ApplicationDocuments, value: ri!volunteerDocuments, saveInto: ri!volunteerDocuments, showWhen: if( a!isNullOrEmpty( local!applicationDocSubmissionSuccessful ), true, not( local!applicationDocSubmissionSuccessful ) ), validations: {} ),
I checked to make sure that the accounts have Editor access to the folder and the Constant is pointing to the correct folder.
The Rule Input, volunteerDocuments never gets updated.
The funny thing is that this used to work. I tested it many times, and now it doesn't work. The only change to the system was the security patches that were installed.
Discussion posts and replies are publicly visible
Echoing Stefan's answer, but simplifying somewhat: if you're seeing this error in a live task, 99% of the time it means you haven't assigned your form inputs (the interface's rule inputs) into an ACP variable, which is the only way to get user changes made on a form to populate when you want them to be passed back out into the process (like you will for uploaded files).
In the interface editor it will work because you have the component set to save into the RI. But in a running process, the form wants to save from the component, to the RI, then to the ACP (aka "input variable" aka "ac!variable" etc), and when it doesn't get saved into an ACP, it doesn't save anywhere, then the rule input value resolves back to a blank one, thus the component resolves back to being blank. This caveat is sadly just one you need to learn from experience, but after you know about it, it's pretty simple to handle luckily.
Thanks for the feedback. This is a portal, so there is no start form. Sorry, I failed to mention that. I have to call the process model. However, I never get to that point.
First I use the a!fileUploadField function to upload the document and saveInto the ri!volunteerDocuments.
Then I use a!buttonWidget to create a button "Save Files" that uses the function a!submitUploadedFiles. The button displays when the ri!volunteerDocuments are not null or empty. The button never shows up.
Here is the complete JSON.
a!fileUploadField( label: "Please upload any pictures, brochures or other documents describing the Project", labelPosition: "ABOVE", target: cons!PMSO_ApplicationDocuments, value: ri!volunteerDocuments, saveInto: ri!volunteerDocuments, showWhen: if( a!isNullOrEmpty( local!applicationDocSubmissionSuccessful ), true, not( local!applicationDocSubmissionSuccessful ) ), validations: {} ), a!buttonArrayLayout( buttons: { a!buttonWidget( label: "Save Files", saveInto: { a!submitUploadedFiles( documents: ri!volunteerDocuments, onSuccess: a!save( local!applicationDocSubmissionSuccessful, true ), onError: { a!save( local!applicationDocSubmissionSuccessful = false ), a!save(local!applicationDocError = fv!error) } ) }, submit: false, style: "GHOST", color: "ACCENT", showWhen: if( a!isNotNullOrEmpty(ri!volunteerDocuments), if( a!isnotNullOrEmpty( local!applicationDocSubmissionSuccessful ), not( local!applicationDocSubmissionSuccessful ), true ), false ) ) }, align: "CENTER", marginBelow: "NONE" ),
There are no rule inputs in portals. At least not of type "Document". Use local variables.
I suggest to check the examples around the a!submitUploadedFiles() function.
yeah, Rule Inputs in Portal forms are a more recent addition, and they're for input only, not output (as you're trying to do here). Again echoing Stefan's advice to merely use local variables - you can "submitUploadedFiles()" directly from a local variable (though only in portals and sites).
Thank you for both Stefan and Mike, but it is still not working. I changed the rule input to a local variable. I initialize the local variable volunteerDocuments with Null.
local!volunteerDocuments: null,
Here is the code now with using the local variable instead of the rule input.
a!fileUploadField( label: "Please upload any pictures, brochures or other documents describing the Project", labelPosition: "ABOVE", target: cons!PMSO_ApplicationDocuments, value: local!volunteerDocuments, saveInto: local!volunteerDocuments, showWhen: if( a!isNullOrEmpty( local!applicationDocSubmissionSuccessful ), true, not( local!applicationDocSubmissionSuccessful ) ), validations: {} ), a!buttonArrayLayout( buttons: { a!buttonWidget( label: "Save Files", saveInto: { a!submitUploadedFiles( documents: local!volunteerDocuments, onSuccess: a!save( local!applicationDocSubmissionSuccessful, true ), onError: { a!save( local!applicationDocSubmissionSuccessful = false ), a!save(local!applicationDocError = fv!error) } ) }, submit: false, style: "GHOST", color: "ACCENT", showWhen: if( a!isNotNullOrEmpty(local!volunteerDocuments), if( a!isnotNullOrEmpty( local!applicationDocSubmissionSuccessful ), not( local!applicationDocSubmissionSuccessful ), true ), false ) ) }, align: "CENTER", marginBelow: "NONE" ),
Chris.Gillespie said:it is still not working
As in they're still disappearing from the file upload field immediately, or something else?
I fixed the syntax issue that Stefan pointed out, but the documents just disappear just like the video I posted.
In that video, do you just click somewhere else, or on any other component?
This just works
I am not clicking on anything else; I just move the cursor out of the way. I use this same logic in other interfaces in the application that work just fine, but this is in the portal.
The video is not recorded in the portal, correct?
I published that exact interface as a portal. After I added the required service account, things just work.
I recorded the video from the portal. I cropped it down so I could embed the video in the discussion. Here I created another video just now.
I suggest to create a small test UI to understand how to make this work. Isolating specific pieces of code helps a lot when trying to find root causes.
Hard to say much without seeing the full code.
This video was record on the portal. As I said, I use the exact same code in other areas and it works just fine.
thanks for that newer video. I have to admit I'm a little stumped. I had built myself a small file upload field demo in my CE portal back when we could still do personal CEs, and I never ran into this particular issue.
A few more things you could verify, just in case:
Also: as a side note, would you be wiliing to share the name of the utility you used for your video screenshot? I love my still screenshotting tool (greenshot), particularly because it's quick and lightweight (and i was able to install it on my company laptop in spite of otherwise-draconian level lockdowns on software), but it ONLY does still images and i am at a loss whenever i need to produce a video snippet like you've done here.
So i created a test application called Portal File Upload Test. I added a page and copied over my code from the other application using the same local variables. I only changed one thing and that was the constant that pointed to the folder. I then created a Portal and gave the Service Account administrator access. It all works. You can check it out here: https://diocese-dev.appianportals.com/abe5dec1-7b4f-41b2-bea9-92565863815e-fileuploadtest
Here is the code for the interface. What could the difference be?!?!?
a!localVariables( local!volunteerDocuments: null, local!applicationDocSubmissionSuccessful: null, local!applicationDocError: null, a!formLayout( label: "Form", contents: { a!sectionLayout( contents: {} ), a!sectionLayout( label: "Section", contents: { a!fileUploadField( label: "Please upload any pictures, brochures or other documents describing the Project", labelPosition: "ABOVE", target: cons!PFUT_ApplicationDoc, value: local!volunteerDocuments, saveInto: local!volunteerDocuments, showWhen: if( a!isNullOrEmpty( local!applicationDocSubmissionSuccessful ), true, not( local!applicationDocSubmissionSuccessful ) ), validations: {} ), a!buttonArrayLayout( buttons: { a!buttonWidget( label: "Save Files", saveInto: { a!submitUploadedFiles( documents: local!volunteerDocuments, onSuccess: a!save( local!applicationDocSubmissionSuccessful, true ), onError: { a!save( local!applicationDocSubmissionSuccessful ,false ), a!save(local!applicationDocError , fv!error) } ) }, submit: false, style: "GHOST", color: "ACCENT", showWhen: if( a!isNotNullOrEmpty(local!volunteerDocuments), if( a!isnotNullOrEmpty( local!applicationDocSubmissionSuccessful ), not( local!applicationDocSubmissionSuccessful ), true ), false ) ) }, align: "CENTER", marginBelow: "NONE" ), if( a!isNullOrEmpty( local!applicationDocSubmissionSuccessful ), {}, if( local!applicationDocSubmissionSuccessful = true, a!richTextDisplayField( labelPosition: "COLLAPSED", value: { a!richTextIcon(icon: "check-circle", color: "POSITIVE"), " ", a!richTextItem( text: "File uploaded successfully", style: "STRONG" ) }, align: "CENTER" ), a!richTextDisplayField( labelPosition: "COLLAPSED", value: { a!richTextIcon(icon: "times-circle", color: "NEGATIVE"), " ", a!richTextItem( text: concat( "File not uploaded. ", local!applicationDocError ), color: "NEGATIVE", style: "STRONG" ) }, align: "CENTER" ) ) ), a!forEach( items: local!volunteerDocuments, expression: if( a!isNullOrEmpty(local!volunteerDocuments), a!richTextDisplayField( value: a!richTextItem(text: "No Image Uploaded.") ), a!cardLayout( contents: { a!documentViewerField( labelPosition: "COLLAPSED", document: fv!item, height: "SHORT" ) }, showWhen: a!isNotNullOrEmpty(local!applicationDocSubmissionSuccessful) ) ) ) } ) }, buttons: a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Submit", submit: true, style: "SOLID" ) }, secondaryButtons: { a!buttonWidget( label: "Cancel", value: true, saveInto: ri!cancel, submit: true, style: "OUTLINE", validate: false ) } ) ) )
Mike, I use Camtasia. I use it to create user videos. You can check out one here: https://youtu.be/G9JSUh_VPZc
It isn't too expensive and you can do quite a lot with it