Skip to content

Instantly share code, notes, and snippets.

@zachelrath
Last active January 7, 2021 21:06
Show Gist options
  • Save zachelrath/4eef2eceaa2d56be9cf2 to your computer and use it in GitHub Desktop.
Save zachelrath/4eef2eceaa2d56be9cf2 to your computer and use it in GitHub Desktop.
A Skuid Page with JavaScript code for creating Models and Components dynamically from JavaScript
<skuidpage showsidebar="true" showheader="true">
<models>
<model id="DummyUserModel" datasource="salesforce" sobject="User" limit="1" query="false"/>
</models>
<components>
<custom name="DynamicTableAndModel"/>
</components>
<resources>
<labels/>
<javascript>
<jsitem location="inlinecomponent" name="DynamicTableAndModel" cachelocation="false" url="">var element = arguments[0],
$ = skuid.$,
$xml = skuid.utils.makeXMLDoc;
// Add some content to our area while we are loading it in
element.html('Loading...');
// Define our Model(s)
var allModels = [];
var OppModel = new skuid.model.Model({
dataSourceName: "salesforce",
objectName: "Opportunity",
id: "OpportunityData",
recordsLimit: 20,
fields: [
{ id: 'Name' },
{ id: 'AccountId' },
{ id: 'Account.Name' },
{ id: 'StageName' },
{ id: 'Amount' },
{ id: 'CloseDate' },
{ id: 'OwnerId' },
{ id: 'Owner.Name' },
],
conditions: [
{
type: 'fieldvalue',
field: 'StageName',
operator: '=',
value: '',
state: 'filterableoff',
inactive: true,
name: 'StageName',
encloseValueInQuotes: true
},
],
});
allModels.push(OppModel);
// Initialize each of our Models
// so that they have index maps created
// and other internal guts,
// then register them with Skuid
// so that Skuid officially knows about them
$.each(allModels,function(){
// Register each of our Models with Skuid
this.initialize().register();
});
// Define the XML for the component we want to show in our element,
// which we'll instantiate once our Models are loaded
var xmlDefinition = $xml(
'&lt;skootable showconditions="true" showsavecancel="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="OpportunityData" mode="read"/&gt;'
).append(
$xml('&lt;fields/&gt;').append(
$xml('&lt;field id="Name" allowordering="true"/&gt;'),
$xml('&lt;field id="AccountId"/&gt;'),
$xml('&lt;field id="StageName"/&gt;'),
$xml('&lt;field id="Amount"/&gt;'),
$xml('&lt;field id="CloseDate"/&gt;'),
$xml('&lt;field id="OwnerId"/&gt;')
),
$xml('&lt;rowactions/&gt;').append(
$xml('&lt;action type="edit"/&gt;'),
$xml('&lt;action type="delete"/&gt;')
),
$xml('&lt;massactions usefirstitemasdefault="true"/&gt;').append(
$xml('&lt;action type="massupdate"/&gt;'),
$xml('&lt;action type="massdelete"/&gt;')
),
$xml('&lt;views&gt;&lt;view type="standard"/&gt;&lt;/views&gt;'),
$xml('&lt;filters/&gt;').append(
$xml('&lt;filter type="select" filteroffoptionlabel="Any Stage" createfilteroffoption="true" affectcookies="true" autocompthreshold="25" condition="StageName"/&gt;')
.append(
$xml('&lt;sources&gt;&lt;source type="metadata" effectsbehavior="justdefault"/&gt;&lt;/sources&gt;')
)
)
);
// Load all Models --- this will:
// (a) populate all metadata
// (b) run the queries on the models
// Once the loading is finished,
// we'll build our components from XML
$.when(skuid.model.load(allModels)).then(function(){
element.empty();
skuid.component.factory({
element: element,
xmlDefinition: xmlDefinition
});
});
</jsitem>
</javascript>
<css/>
</resources>
</skuidpage>
@hasanthaera
Copy link

Zach, I get an error while I try to preview this.

skuid__SkuidJS:28 Uncaught TypeError: Cannot read property 'getAdapter' of undefined

image

@sankaran1984
Copy link

HI Zachel,

Do you have any idea why this code is not working in latest Brooklyn release ?

image

@zachelrath
Copy link
Author

@hasanthaera @sankaran1984 The reason that this page does not work in Banzai, Rockaway, or Brooklyn releases by itself is that the page needs a "static" Model associated with the salesforce Data Source on the page in order for the salesforce Data Source to be loaded. Prior to the Banzai release, the salesforce Data Source was always loaded, but this is no longer the case, it is only loaded if a static dependency to the Data Source is encountered. The dynamic Model approach currently does not load in Data Source dependencies if a Model is created against a Data Source that is not already present in the page. So the easy workaround is to have at least one "static" Model on the page.

I will revise this Gist to include a static model.

@zachelrath
Copy link
Author

@hasanthaera @sankaran1984 I have revised the Gist to work with the Brooklyn release.

@hasanthaera
Copy link

Thanks @zachelrath this works now

@hasanthaera
Copy link

Hi @zachelrath,

I'm trying to add a custom filter to the table, but it doesn't show me the filter list. It just shows a button instead.
My CompetitionTeam__u field is a UI field which I'm trying to populate the values from another model.
Heres the snippet;

`var element = arguments[0],
$ = skuid.$,
$xml = skuid.utils.makeXMLDoc;
// Add some content to our area while we are loading it in
element.html('Loading...');
var originalSource = skuid.$M('PlayerStatistics');
var Statisticsdefinition = skuid.$M('Statisticsdefinition');
// Define our Model(s)
var allModels = [];

$.each(allModels, function() {
// Register each of our Models with Skuid
this.initialize().register();
});

// Define the XML for the component we want to show in our element,
// which we'll instantiate once our Models are loaded

//generate the table column headers dynamically, this is the main reason we used a custom table component
var statFields = [];
var statFieldsForModel = [];

// adding default fields
statFields.push('NAME') ;
statFieldsForModel.push({id: 'NAME', label: 'NAME', accessible: true, displaytype: "TEXT", filterable: true});
statFieldsForModel.push({id: 'CompetitionTeam__u', label: 'Competition Team', accessible: true, displaytype: "PICKLIST", filterable: true, snippet : "CompetitionTeamPicklIstRenderer"});

//dunamically adding the fields
$.each(Statisticsdefinition.data, function(i,row){
statFields.push(row.code) ;
statFieldsForModel.push({id: row.code, label: row.code, accessible: true, displaytype: "TEXT", filterable: false});
});

originalSource.fields = statFieldsForModel;

allModels.push(Statisticsdefinition);
allModels.push(originalSource);

var xmlDefinition = $xml(
''
).append(
$xml('').append(
skuid.$.map(statFields,function(statField){
return $xml('').attr('id',statField);
})
),
$xml('').append(
$xml(''),
$xml('')
),
$xml('').append(
$xml(''),
$xml('')
),
$xml('')
,
$xml('').append(
$xml('')
)

);

console.log(xmlDefinition);

// Load all Models --- this will:
// (a) populate all metadata
// (b) run the queries on the models

// Once the loading is finished,
// we'll build our components from XML
$.when(skuid.model.load(allModels)).then(function() {
element.empty();
skuid.component.factory({
element: element,
xmlDefinition: xmlDefinition
});
});`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment