How to tell if a file has been uploaded

I have a file upload component on a wizard and have a couple questions:

1. How can I tell if a file has been uploaded so that I can not enable the “Next Step” button until one has been uploaded?

I am saving to the attachments on the Record. I want them to be able to upload one or more files.

2. I would like to display the names of the files immediately after they have been uploaded to give them some feedback that it has succeeded. The file upload does not seem to trigger a re-query of the record and there does not appear to be an action framework.

Any ideas?

Thanks,
Tony


Tony,

Make a model on the Attachments sObject (with a condition linking the ParentId to the record you’re attaching to. Make a table on that attachments model and place it just below your file upload component.

That should get you started.

You can then create an enable condition on your next step button for the number of rows in your attachments model.

Hi Matt,

Thanks for the idea.

I tried something similar but the Attachments Model did not automatically re-query when the file was uploaded and I don’t see a way to re-trigger  that query (file upload does not have an action framework).

Is it your sense that the Attachment model would somehow refresh?

Tony

I believe this the the behavior you’re looking for?

Here’s the XML:

<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" showheader="true" tabtooverride="Account">   <models>
      <model id="Account" limit="1" query="true" createrowifnonefound="false" sobject="Account" adapter="" type="">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
         </fields>
         <conditions>
            <condition type="param" enclosevalueinquotes="true" operator="=" field="Id" value="id"/>
         </conditions>
         <actions/>
      </model>
      <model id="Attachment" limit="20" query="true" createrowifnonefound="false" adapter="" type="" sobject="Attachment">
         <fields>
            <field id="Description"/>
            <field id="Name"/>
            <field id="CreatedById"/>
            <field id="CreatedBy.Name"/>
            <field id="CreatedDate"/>
            <field id="LastModifiedDate"/>
            <field id="LastModifiedById"/>
            <field id="LastModifiedBy.Name"/>
         </fields>
         <conditions>
            <condition type="modelmerge" value="" field="ParentId" operator="=" model="Account" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="deactivate"/>
         </conditions>
         <actions/>
      </model>
   </models>
   <components>
      <pagetitle model="Account" uniqueid="sk-2LwnYg-72">
         <maintitle>
            <template>{{Name}}</template>
         </maintitle>
         <subtitle>
            <template>{{Model.label}}</template>
         </subtitle>
         <actions>
            <action type="delete"/>
            <action type="clone"/>
            <action type="share"/>
            <action type="savecancel" window="self"/>
         </actions>
      </pagetitle>
      <basicfieldeditor showsavecancel="false" showheader="true" model="Account" mode="read" uniqueid="sk-2LwnYg-73">
         <columns>
            <column width="50%">
               <sections>
                  <section title="Basics">
                     <fields>
                        <field id="Name"/>
                     </fields>
                  </section>
               </sections>
            </column>
            <column width="50%">
               <sections>
                  <section title="System Info">
                     <fields>
                        <field id="CreatedDate"/>
                     </fields>
                  </section>
               </sections>
            </column>
         </columns>
      </basicfieldeditor>
      <file storeas="record" displayas="filename" uniqueid="sk-2Lx1K8-127" model="Account"/>
      <skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="Attachment" buttonposition="" mode="read" uniqueid="sk-2Lx7qx-140">
         <fields>
            <field id="Name"/>
            <field id="Description"/>
            <field id="CreatedDate"/>
            <field id="CreatedById"/>
            <field id="LastModifiedDate"/>
            <field id="LastModifiedById"/>
         </fields>
         <rowactions>
            <action type="edit"/>
            <action type="delete"/>
         </rowactions>
         <massactions usefirstitemasdefault="true">
            <action type="massupdate"/>
            <action type="massdelete"/>
         </massactions>
         <views>
            <view type="standard"/>
         </views>
      </skootable>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript/>
   </resources>
   <styles>
      <styleitem type="background" bgtype="none"/>
   </styles>
</skuidpage>

Hi Matt,

Looks great in your version but I am having trouble getting this to work with a new object that I have just created. Basically I have a pop-up to create an Account and then immediately want to add attachments to it. When I click the upload button the file is successfully attached but my corresponding attachments model is not updated. Perhaps I am missing something in terms of how to properly connect the Attachments model to the Account model in the case of a new record.

I’ve included XML below.

<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" showheader="true" tabtooverride="Account"> <models>
 <model id="Account" limit="1" query="true" createrowifnonefound="false" sobject="Account" adapter="" type="">
 <fields>
 <field id="Name"/>
 <field id="CreatedDate"/>
 </fields>
 <conditions>
 <condition type="param" enclosevalueinquotes="true" operator="=" field="Id" value="id"/>
 </conditions>
 <actions/>
 </model>
 <model id="Attachment" limit="20" query="true" createrowifnonefound="false" adapter="" type="" sobject="Attachment">
 <fields>
 <field id="Description"/>
 <field id="Name"/>
 <field id="CreatedById"/>
 <field id="CreatedBy&#46;Name"/>
 <field id="CreatedDate"/>
 <field id="LastModifiedDate"/>
 <field id="LastModifiedById"/>
 <field id="LastModifiedBy&#46;Name"/>
 </fields>
 <conditions>
 <condition type="modelmerge" value="" field="ParentId" operator="=" model="Account" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="deactivate"/>
 </conditions>
 <actions/>
 </model>
 <model id="NewAccount" limit="1" query="false" createrowifnonefound="true" adapter="" type="" sobject="Account">
<fields>
 <field id="Id"/>
 <field id="Name"/>
</fields>
<conditions/>
<actions/>
</model>
<model id="NewAccountAttachment" limit="20" query="true" createrowifnonefound="false" adapter="" type="" sobject="Attachment">
 <fields>
 <field id="Description"/>
 <field id="Name"/>
 <field id="CreatedById"/>
 <field id="CreatedBy&#46;Name"/>
 <field id="CreatedDate"/>
 <field id="LastModifiedDate"/>
 <field id="LastModifiedById"/>
 <field id="LastModifiedBy&#46;Name"/>
 </fields>
 <conditions>
 <condition type="modelmerge" value="" field="ParentId" operator="=" model="NewAccount" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="noquery"/>
 </conditions>
 <actions/>
 </model>
</models>
 <components>
 <pagetitle model="Account" uniqueid="sk-2LwnYg-72">
 <maintitle>
 <template>{{Name}}</template>
 </maintitle>
 <subtitle>
 <template>{{Model&#46;label}}</template>
 </subtitle>
 <actions>
 <action type="delete"/>
 <action type="clone"/>
 <action type="share"/>
 <action type="savecancel" window="self"/>
 <action type="multi" label="New Account">
<actions>
 <action type="showPopup">
 <popup title="New Popup" width="90%">
 <components>
 <pagetitle model="NewAccount" uniqueid="sk-2Mf3Br-154">
 <maintitle>
 <template>{{Name}}</template>
 </maintitle>
 <subtitle>
 <template>{{Model&#46;label}}</template>
 </subtitle>
 <actions/>
 </pagetitle>
 <basicfieldeditor showheader="true" showsavecancel="true" showerrorsinline="true" model="NewAccount" buttonposition="" uniqueid="sk-2Mf4Lk-157" mode="edit">
 <columns>
 <column width="50%">
 <sections>
 <section title="Section A" collapsible="no">
 <fields>
 <field id="Id"/>
 </fields>
 </section>
 </sections>
 </column>
 <column width="50%">
 <sections>
 <section title="Section B">
 <fields>
 <field id="Name" valuehalign="" type=""/>
 </fields>
 </section>
 </sections>
 </column>
 </columns>
 </basicfieldeditor>
 <file storeas="record" displayas="filename" uniqueid="sk-2Mf6mt-167" model="NewAccount"/>
 <skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="NewAccountAttachment" buttonposition="" mode="read" uniqueid="sk-2MfRDd-222">
 <fields>
 <field id="CreatedById"/>
 <field id="CreatedDate"/>
 <field id="Description"/>
 <field id="Name"/>
 <field id="LastModifiedById"/>
 <field id="LastModifiedDate"/>
 </fields>
 <rowactions>
 <action type="edit"/>
 <action type="delete"/>
 </rowactions>
 <massactions usefirstitemasdefault="true">
 <action type="massupdate"/>
 <action type="massdelete"/>
 </massactions>
 <views>
 <view type="standard"/>
 </views>
 </skootable>
 </components>
 </popup>
 </action>
</actions>
</action>
</actions>
 </pagetitle>
 <basicfieldeditor showsavecancel="false" showheader="true" model="Account" mode="read" uniqueid="sk-2LwnYg-73">
 <columns>
 <column width="50%">
 <sections>
 <section title="Basics">
 <fields>
 <field id="Name"/>
 </fields>
 </section>
 </sections>
 </column>
 <column width="50%">
 <sections>
 <section title="System Info">
 <fields>
 <field id="CreatedDate"/>
 </fields>
 </section>
 </sections>
 </column>
 </columns>
 </basicfieldeditor>
 <file storeas="record" displayas="filename" uniqueid="sk-2Lx1K8-127" model="Account"/>
 <skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="Attachment" buttonposition="" mode="read" uniqueid="sk-2Lx7qx-140">
 <fields>
 <field id="Name"/>
 <field id="Description"/>
 <field id="CreatedDate"/>
 <field id="CreatedById"/>
 <field id="LastModifiedDate"/>
 <field id="LastModifiedById"/>
 </fields>
 <rowactions>
 <action type="edit"/>
 <action type="delete"/>
 </rowactions>
 <massactions usefirstitemasdefault="true">
 <action type="massupdate"/>
 <action type="massdelete"/>
 </massactions>
 <views>
 <view type="standard"/>
 </views>
 </skootable>
 </components>
 <resources>
 <labels/>
 <css/>
 <javascript/>
 </resources>
 <styles>
 <styleitem type="background" bgtype="none"/>
 </styles>
</skuidpage>


Tony.  I’m not going to read through your full XML here.  But quickly wanted to point out that the File component Requires an existing record in order to function correctly.  You have to create a two step process of some sort,  where first the record data is defined – AND SAVED – before the file upload feature is exposed.  There are number of ways to do this,  muliple pages, wizards,  conditional rendering.  But I think that’s whats tripping you up. 

Hi Rob,

Thanks for jumping in, and on a Saturday no less.

I am successfully saving the new object first. And I am successfully uploading the attachment. I just don’t seem to be getting the NewAccountAttachment model to update when the file is uploaded.

See video below.

Tony, A few things to check: Is your table on the attachment model? Does the attachment model have a condition that us correctly linking it to the new account (you’ll have to query the model after you save the account)? After your file is uploaded, use the console to check the attachment model data… Is there anything there? skuid.$M(‘AttachmentModel’).getRows()

Hi Matt,

Thanks for the help. I added an action on the NewAccount model so that when it is saved it resets the Condition on the NewAccountAttachment model and then requeries it, and now it works.

I’ll paste the XML below in case anyone else ever runs into this same problem.

<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" showheader="true" tabtooverride="Account"> <models>
 <model id="Account" limit="1" query="true" createrowifnonefound="false" sobject="Account" adapter="" type="">
 <fields>
 <field id="Name"/>
 <field id="CreatedDate"/>
 </fields>
 <conditions>
 <condition type="param" enclosevalueinquotes="true" operator="=" field="Id" value="id"/>
 </conditions>
 <actions/>
 </model>
 <model id="Attachment" limit="20" query="true" createrowifnonefound="false" adapter="" type="" sobject="Attachment">
 <fields>
 <field id="Description"/>
 <field id="Name"/>
 <field id="CreatedById"/>
 <field id="CreatedBy.Name"/>
 <field id="CreatedDate"/>
 <field id="LastModifiedDate"/>
 <field id="LastModifiedById"/>
 <field id="LastModifiedBy.Name"/>
 </fields>
 <conditions>
 <condition type="modelmerge" value="" field="ParentId" operator="=" model="Account" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="deactivate"/>
 </conditions>
 <actions/>
 </model>
 <model id="NewAccount" limit="1" query="false" createrowifnonefound="true" adapter="" type="" sobject="Account">
<fields>
 <field id="Id"/>
 <field id="Name"/>
</fields>
<conditions/>
<actions>
 <action>
 <actions>
 <action type="setCondition" model="NewAccountAttachment" condition="ParentId" value="{{$Model.NewAccount.data.0.Id}}"/>
 <action type="requeryModel" model="NewAccountAttachment" behavior="standard"/>
 </actions>
 <events>
 <event>models.saved</event>
 </events>
 </action>
</actions>
</model>
<model id="NewAccountAttachment" limit="20" query="true" createrowifnonefound="false" adapter="" type="" sobject="Attachment">
 <fields>
 <field id="Description"/>
 <field id="Name"/>
 <field id="CreatedById"/>
 <field id="CreatedBy.Name"/>
 <field id="CreatedDate"/>
 <field id="LastModifiedDate"/>
 <field id="LastModifiedById"/>
 <field id="LastModifiedBy.Name"/>
 </fields>
 <conditions>
 <condition type="modelmerge" value="" field="ParentId" operator="=" model="NewAccount" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="noquery" state="filterableon" inactive="false" name="ParentId"/>
 </conditions>
 <actions/>
 </model>
</models>
 <components>
 <pagetitle model="Account" uniqueid="sk-2LwnYg-72">
 <maintitle>
 <template>{{Name}}</template>
 </maintitle>
 <subtitle>
 <template>{{Model.label}}</template>
 </subtitle>
 <actions>
 <action type="delete"/>
 <action type="clone"/>
 <action type="share"/>
 <action type="savecancel" window="self"/>
 <action type="multi" label="New Account">
<actions>
 <action type="showPopup">
 <popup title="New Popup" width="90%">
 <components>
 <pagetitle model="NewAccount" uniqueid="sk-2Mf3Br-154">
 <maintitle>
 <template>{{Name}}</template>
 </maintitle>
 <subtitle>
 <template>{{Model.label}}</template>
 </subtitle>
 <actions/>
 </pagetitle>
 <basicfieldeditor showheader="true" showsavecancel="true" showerrorsinline="true" model="NewAccount" buttonposition="" uniqueid="sk-2Mf4Lk-157" mode="edit">
 <columns>
 <column width="50%">
 <sections>
 <section title="Section A" collapsible="no">
 <fields>
 <field id="Id"/>
 </fields>
 </section>
 </sections>
 </column>
 <column width="50%">
 <sections>
 <section title="Section B">
 <fields>
 <field id="Name" valuehalign="" type=""/>
 </fields>
 </section>
 </sections>
 </column>
 </columns>
 </basicfieldeditor>
 <file storeas="record" displayas="filename" uniqueid="sk-2Mf6mt-167" model="NewAccount"/>
 <skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="NewAccountAttachment" buttonposition="" mode="read" uniqueid="sk-2MfRDd-222">
 <fields>
 <field id="CreatedById"/>
 <field id="CreatedDate"/>
 <field id="Description"/>
 <field id="Name"/>
 <field id="LastModifiedById"/>
 <field id="LastModifiedDate"/>
 </fields>
 <rowactions>
 <action type="edit"/>
 <action type="delete"/>
 </rowactions>
 <massactions usefirstitemasdefault="true">
 <action type="massupdate"/>
 <action type="massdelete"/>
 </massactions>
 <views>
 <view type="standard"/>
 </views>
 </skootable>
 </components>
 </popup>
 </action>
</actions>
</action>
</actions>
 </pagetitle>
 <basicfieldeditor showsavecancel="false" showheader="true" model="Account" mode="read" uniqueid="sk-2LwnYg-73">
 <columns>
 <column width="50%">
 <sections>
 <section title="Basics">
 <fields>
 <field id="Name"/>
 </fields>
 </section>
 </sections>
 </column>
 <column width="50%">
 <sections>
 <section title="System Info">
 <fields>
 <field id="CreatedDate"/>
 </fields>
 </section>
 </sections>
 </column>
 </columns>
 </basicfieldeditor>
 <file storeas="record" displayas="filename" uniqueid="sk-2Lx1K8-127" model="Account"/>
 <skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="Attachment" buttonposition="" mode="read" uniqueid="sk-2Lx7qx-140">
 <fields>
 <field id="Name"/>
 <field id="Description"/>
 <field id="CreatedDate"/>
 <field id="CreatedById"/>
 <field id="LastModifiedDate"/>
 <field id="LastModifiedById"/>
 </fields>
 <rowactions>
 <action type="edit"/>
 <action type="delete"/>
 </rowactions>
 <massactions usefirstitemasdefault="true">
 <action type="massupdate"/>
 <action type="massdelete"/>
 </massactions>
 <views>
 <view type="standard"/>
 </views>
 </skootable>
 </components>
 <resources>
 <labels/>
 <css/>
 <javascript/>
 </resources>
 <styles>
 <styleitem type="background" bgtype="none"/>
 </styles>
</skuidpage>


Glad you got that working,  but the file component is supposed to do that for you - auto requerying the attachments model so that the saved attachment shows up in the list on the save event.  Thanks for posting the XML.  I’ll explore. 

Rob,

The problem wasn’t that the attachments model doesn’t requery after the attachment is loaded, the problem was that the attachments model wasn’t properly connected to the record, so it didn’t know to requery when the file was uploaded. What Tony is doing is setting the condition to link the models when the account record is saved… which seems to make sense? Perhaps the query is not needed? before the upload?

Yes I see that now.  After saving the new record,  you do need reset the condition on the new attachments model so that they are correctly bound together.  A model action sequence could do this,  or a set of actions on a wizard step,  or “save” button…