Getting a list of Salesforce Files
This post details how you can access Salesforce Files in a Skuid page. I'm using Millau 11.0.3 in this post.
My requirement was to display a list of files (via a Deck) related to an opportunity. Here's how I did it.
Firstly I created a model based on the ContentDocumentLink object. Querying this object retrieves the file ids related to the opportunity. I created a condition based on the field LinkedEntityId, which I filled with Opportunity Id.
Then I created a second model based on the ContentDocument object. This model then fed the Deck component with the fields I wanted to display (Title, Size, Type etc). The model had a condition set against the Id field (set to multiple specified values as there may be multiple files per opportunity).
I populated the condition's values and querying of the models in the required sequence via a series of actions (against an opportunity list in a table, which shows a popup containing further details of the opportunity along with related objects such as the files).
One other thing, because my model based on the ContentDocument object had a multiple specified values condition, I created a JS snippet to grab the Ids from the model based on the ContentDocumentLink object and pass these into the condition. The snippet can be found below.
Hope this helps.
Matt
var params = arguments[0],
$ = skuid.$;
var SourceModel = skuid.$M('DocumentLinking');
var selectedIds = [];
//Build the array of linked document Ids, based on the values from the DocumentLinking model
$.each(SourceModel.data,function(i,row){
selectedIds.push(row.ContentDocumentId);
});
//Filter the ContentDocument model to get the files, but only if there are links
if (selectedIds.length >= 1)
{
var TargetModel = skuid.$M('ContentDocument');
var ConIdsCondition = TargetModel.getConditionByName('DocIds');
TargetModel.setCondition(ConIdsCondition,selectedIds);
TargetModel.updateData();
}
My requirement was to display a list of files (via a Deck) related to an opportunity. Here's how I did it.
Firstly I created a model based on the ContentDocumentLink object. Querying this object retrieves the file ids related to the opportunity. I created a condition based on the field LinkedEntityId, which I filled with Opportunity Id.
Then I created a second model based on the ContentDocument object. This model then fed the Deck component with the fields I wanted to display (Title, Size, Type etc). The model had a condition set against the Id field (set to multiple specified values as there may be multiple files per opportunity).
I populated the condition's values and querying of the models in the required sequence via a series of actions (against an opportunity list in a table, which shows a popup containing further details of the opportunity along with related objects such as the files).
One other thing, because my model based on the ContentDocument object had a multiple specified values condition, I created a JS snippet to grab the Ids from the model based on the ContentDocumentLink object and pass these into the condition. The snippet can be found below.
Hope this helps.
Matt
var params = arguments[0],
$ = skuid.$;
var SourceModel = skuid.$M('DocumentLinking');
var selectedIds = [];
//Build the array of linked document Ids, based on the values from the DocumentLinking model
$.each(SourceModel.data,function(i,row){
selectedIds.push(row.ContentDocumentId);
});
//Filter the ContentDocument model to get the files, but only if there are links
if (selectedIds.length >= 1)
{
var TargetModel = skuid.$M('ContentDocument');
var ConIdsCondition = TargetModel.getConditionByName('DocIds');
TargetModel.setCondition(ConIdsCondition,selectedIds);
TargetModel.updateData();
}
Tagged:
3
Categories
- 7.9K Questions
- 926 Ideas
- 220 Discussion Categories
- 178 General
- 9 Community Feedback
- 3 Community Info
- 18 Knowledge Base
Comments
Thanks for putting this together!
<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="false" useviewportmeta="true" showheader="false" theme="Lightning Design">
<models>
<model id="Opportunities" limit="20" query="true" createrowifnonefound="false" datasource="salesforce" type="" sobject="Opportunity">
<fields>
<field id="Name"/>
<field id="StageName"/>
<field id="OwnerId"/>
<field id="Owner.Name"/>
<field id="Id"/>
<field id="Amount"/>
<field id="Description"/>
</fields>
<conditions/>
<actions/>
</model>
<model id="SelectedOpportunity" limit="1" query="false" createrowifnonefound="false" datasource="salesforce" type="" sobject="Opportunity">
<fields>
<field id="Name"/>
<field id="StageName"/>
<field id="OwnerId"/>
<field id="Owner.Name"/>
<field id="Id"/>
<field id="Amount"/>
<field id="Description"/>
</fields>
<conditions>
<condition type="fieldvalue" value="" field="Id" operator="=" state="filterableoff" inactive="true" name="Id" enclosevalueinquotes="true"/>
</conditions>
<actions/>
</model>
<model id="ContentDocument" limit="20" query="false" createrowifnonefound="false" datasource="salesforce" type="" sobject="ContentDocument">
<fields>
<field id="Title"/>
<field id="FileType"/>
<field id="ContentSize"/>
<field id="Id"/>
</fields>
<conditions>
<condition type="multiple" value="" field="Id" state="filterableoff" inactive="true" name="DocIds" operator="in" enclosevalueinquotes="true">
<values>
<value/>
</values>
</condition>
</conditions>
<actions/>
</model>
<model id="DocumentLinking" limit="20" query="false" createrowifnonefound="false" datasource="salesforce" type="" sobject="ContentDocumentLink">
<fields>
<field id="ShareType"/>
<field id="ContentDocumentId"/>
<field id="ContentDocument.Title"/>
<field id="LinkedEntityId"/>
</fields>
<conditions>
<condition type="fieldvalue" value="" enclosevalueinquotes="true" field="LinkedEntityId" fieldtargetobjects="LinkedEntityId" state="filterableoff" inactive="true" name="LinkedEntityId"/>
</conditions>
<actions/>
</model>
</models>
<components>
<skootable showconditions="true" showsavecancel="false" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" alwaysresetpagination="false" createrecords="false" model="Opportunities" buttonposition="" mode="readonly" allowcolumnreordering="true" responsive="true" uniqueid="sk-3RboX8-660">
<fields>
<field id="Name" hideable="true" uniqueid="sk-3RboX8-661" valuehalign="" type="" allowordering="true"/>
<field id="StageName" hideable="true" uniqueid="sk-3RboX8-662" valuehalign="" type="" allowordering="true"/>
<field id="OwnerId" hideable="true" uniqueid="sk-3RboX8-665" valuehalign="" type=""/>
</fields>
<rowactions>
<action type="multi" label="View Details" icon="sk-icon-listview">
<actions>
<action type="action-sequence" action-sequence-id="24519ed6-ef57-466d-bb1a-97a2e653fd99"/>
</actions>
</action>
</rowactions>
<massactions usefirstitemasdefault="true"/>
<views>
<view type="standard"/>
</views>
</skootable>
</components>
<resources>
<labels/>
<javascript>
<jsitem location="inlinesnippet" name="getFiles" cachelocation="false">var params = arguments[0],
$ = skuid.$;
var SourceModel = skuid.$M('DocumentLinking');
var selectedIds = [];
//Build the array of linked document Ids, based on the values from the DocumentLinking model
$.each(SourceModel.data,function(i,row){
selectedIds.push(row.ContentDocumentId);
});
//Filter the ContentDocument model to get the files, but only if there are links
if (selectedIds.length >= 1)
{
var TargetModel = skuid.$M('ContentDocument');
var ConIdsCondition = TargetModel.getConditionByName('DocIds');
TargetModel.setCondition(ConIdsCondition,selectedIds);
TargetModel.updateData();
}</jsitem>
</javascript>
<css>
<cssitem location="inline" name="pageCSS" cachelocation="false">.hidetablefooter .nx-list-footer {
display: none;
}</cssitem>
<cssitem location="inline" name="stepIndicatorCSS" cachelocation="false">.progress-indicator .progress-chunk.current .progress-text .step-label {
color: #30ad60;
}
.progress-indicator .progress-chunk.current .progress-text .text-content {
background-color: #30ad61;
color: white;
}
.progress-indicator .progress-chunk.done .progress-text .text-content {
background-color: #ddd;
color: white;
}
.progress-indicator .progress-chunk.done .progress-text .step-label {
color: #dddddd;
}
.progress-indicator .progress-chunk.done .progress-text .indicator-line {
background: #30ad60;
}</cssitem>
</css>
<actionsequences uniqueid="sk-3QZynU-261">
<actionsequence id="24519ed6-ef57-466d-bb1a-97a2e653fd99" label="ViewOppDetails" type="reusable" uniqueid="sk-3WRMkW-306">
<actions>
<action type="setCondition" model="DocumentLinking" condition="LinkedEntityId" value="{{Id}}"/>
<action type="requeryModels" behavior="standard">
<models>
<model>DocumentLinking</model>
</models>
</action>
<action type="setCondition" model="SelectedOpportunity" condition="Id" value="{{Id}}"/>
<action type="requeryModels" behavior="standard">
<models>
<model>SelectedOpportunity</model>
</models>
</action>
<action type="custom" snippet="getFiles"/>
<action type="showPopup">
<popup title="View Grant Details" width="95%">
<components>
<wrapper uniqueid="sk-3aQ8E--1234">
<components>
<wrapper uniqueid="sk-3aQExf-1271">
<components>
<wrapper uniqueid="sk-3cMHtY-2457">
<components>
<pagetitle model="SelectedOpportunity" uniqueid="sk-3RboX8-666">
<maintitle>{{{Name}}}</maintitle>
<actions>
<action type="multi" label="Save" uniqueid="sk-3RboX8-667">
<actions>
<action type="save">
<models>
<model>SelectedOpportunity</model>
</models>
</action>
</actions>
<renderconditions logictype="and">
<rendercondition type="fieldvalue" enclosevalueinquotes="false" fieldmodel="SelectedOpportunity" sourcetype="modelproperty" sourceproperty="hasChanged" value="true" operator="="/>
</renderconditions>
<enableconditions/>
</action>
<action type="multi" label="Cancel" uniqueid="sk-3RboX8-668">
<actions>
<action type="cancel">
<models>
<model>SelectedOpportunity</model>
</models>
</action>
</actions>
<renderconditions logictype="and">
<rendercondition type="fieldvalue" enclosevalueinquotes="false" fieldmodel="SelectedOpportunity" sourcetype="modelproperty" sourceproperty="hasChanged" value="true" operator="="/>
</renderconditions>
<enableconditions/>
</action>
</actions>
<conditions/>
<renderconditions logictype="and"/>
</pagetitle>
</components>
<styles>
<styleitem type="background"/>
<styleitem type="border"/>
<styleitem type="size"/>
</styles>
</wrapper>
<wrapper uniqueid="sk-3aPJYG-1061">
<components>
<basicfieldeditor showheader="true" showsavecancel="false" showerrorsinline="true" model="SelectedOpportunity" buttonposition="" uniqueid="sk-3RboX8-669" mode="read">
<columns>
<column width="100%">
<sections>
<section title="Details" collapsible="no">
<fields>
<field uniqueid="sk-3RboX8-671" id="StageName"/>
<field uniqueid="sk-3RboX8-672" id="Amount" showhelp="true" decimalplaces="" valuehalign="" type=""/>
</fields>
</section>
</sections>
</column>
</columns>
<conditions/>
</basicfieldeditor>
</components>
<styles>
<styleitem type="background"/>
<styleitem type="border" borders="all" padding="bottom,left,top,">
<styles>
<styleitem property="border" value="1px solid #f2f2f2"/>
<styleitem property="padding-left" value="25px"/>
<styleitem property="padding-top" value="5px"/>
<styleitem property="padding-bottom" value="5px"/>
<styleitem property="box-sizing" value="border-box"/>
</styles>
</styleitem>
<styleitem type="size"/>
</styles>
</wrapper>
</components>
<styles>
<styleitem type="background" bgtype="none"/>
<styl
/sfc/servlet.shepherd/version/download/{{{ContentDocumentLink.ContentDocument.LatestPublishedVersionId}}}
Also, with models, you can declaratively use a set of record Ids (or other fields) from a prior model to use in a secondary models' filters. You just load your first model to get the records of interest and then in your next model, setup your filter like so: