Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

commented Jun 10, 2016

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

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

image

@sankaran1984

This comment has been minimized.

Copy link

commented Feb 12, 2017

HI Zachel,

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

image

@zachelrath

This comment has been minimized.

Copy link
Owner Author

commented Feb 13, 2017

@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

This comment has been minimized.

Copy link
Owner Author

commented Mar 7, 2017

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

@hasanthaera

This comment has been minimized.

Copy link

commented Aug 28, 2017

Thanks @zachelrath this works now

@hasanthaera

This comment has been minimized.

Copy link

commented Aug 28, 2017

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
You can’t perform that action at this time.