Row Action, Action Type = Custom, using inline snippet as below:
skuid.snippet.registerSnippet('orderLineItem.CalculateCost', function(params) {
var price = params.item.row.Price__c;
var quantity = params.item.row.Quantity__c;
var cost = price * quantity;
params.model.updateRow(params.item.row, 'Cost', cost);
params.model.save();
};
Also, is it possible to just update the value when in edit mode, and let the user initiate the save. I commented out the "params.model.save()", but nothing is updated in the UI?
-
90 Points
Posted 6 years ago
Zach McElrath, Employee
-
54,246 Points
The reason you're getting the Remoting Exception is that you're trying to update a Field that does not exist --- "Cost" should be "Cost__c", I believe.
As far as getting the Cost__c column in your Table to automatically update whenever Price and Quantity are updated by the user, this is a very good use case for a Custom Field Renderer. Basically, go to your "Cost" column in your table, and change the "Field Renderer" to be "Custom", then for "Render Snippet", enter "CostRenderer". Then, go to your JavaScript Resources, and create a new "Inline (Snippet)" resource, named CostRenderer, with the following Body:
var field = arguments[0],
value = arguments[1],
$ = skuid.$,
dt = field.metadata.displaytype;
if (field.mode != 'edit') {
skuid.ui.fieldRenderers[dt][field.mode](field,value);
} else {
skuid.ui.fieldRenderers[dt].edit(field,value);
}
var calculateCost = function(){
value = (field.model.getFieldValue(field.row,'Quantity__c',true) || 0)
* (field.model.getFieldValue(field.row,'Price__c',true) || 0);
value = Math.round(value * 100) / 100;
field.model.updateRow(
field.row,
'Cost__c',
value
);
if (field.mode == 'edit') {
field.element.find('input').val(value);
}
};
calculateCost();
var listener = new skuid.ui.Field(field.row,field.model,null,{fieldId: 'Cost__c'});
listener.handleChange = function(){
calculateCost();
};
field.model.registerField(listener,'Price__c');
field.model.registerField(listener,'Quantity__c');
The result should be that whenever you change the Price or Quantity fields in your table, your Cost field will be updated.

Glenn Elliott, Champion
-
7,788 Points
Rob Hatch, Official Rep
-
44,968 Points
You can create a custom renderer on another field (Which you use just as a dummy placeholder) and in that renderer call the fields and do your calculations in Javascript. I'm thinking the dummy field could be set to read only so that a save is not attempted on that field when you save the other fields in the table.
Zach McElrath, Employee
-
54,246 Points
var field = arguments[0],
value = arguments[1],
$ = skuid.$;
field.metadata = {
displaytype: 'CURRENCY',
accessible: true,
precision: 8,
scale: 2,
required: false,
nameField: false,
label: 'Cost'
};
field.required = false;
var calculateCost = function(){
value = (field.model.getFieldValue(field.row,'Quantity__c',true) || 0)
* (field.model.getFieldValue(field.row,'Price__c',true) || 0);
value = Math.round(value * 100) / 100;
field.element.empty();
skuid.ui.fieldRenderers.CURRENCY.readonly(field,value);
};
calculateCost();
var listener = new skuid.ui.Field(field.row,field.model,null,{fieldId: 'Quantity__c',register:true});
listener.handleChange = function(val){
calculateCost();
};
field.model.registerField(listener,'Price__c');
Glenn Elliott, Champion
-
7,788 Points
Glenn Elliott, Champion
-
7,788 Points
Now, for bonus points ...
My actual use case is to calculate a Budget Amount and an Actual Amount, which I do using the above technique, but then also calculate a Variance which is simply Budget Amount minus Actual Amount. In the Variance custom renderer, I don't really want to have to repeat the calcs for budget and actual, I want to refer to those values already calculated in the other two fields. Is that possible? I suspect not, given that Budget, Actual and Variance all render simultaneously.
Rob Hatch, Official Rep
-
44,908 Points
Another idea that might not meet you stringent UI standards would be to combine all three items in a single field. You have well used the "stacked field" model in your tables. This would allow a single snippet to be do your calculations and then display the three values effectively.
Jack Sanford, Champion
-
10,100 Points
I've got a table of FCCA's and here's my row action snippet, in its entirety:
skuid.snippet.registerSnippet('updateMERS', function(params) { var caMERS = params.item.row.CustomerAccount__r.MERSSearchCompleted__c; params.model.updateRow(params.item.row, 'Foreclosure__r.MERSSearchComplete__c', caMERS); params.model.save(); });I'm very new here so I may be missing something.
Ideally this would be a Mass Action, and happen to all the selected rows, is that possible?
Here's the error I'm getting:
The line referred to in the error is var caMERS = params.item.row...
I may be missing something very basic here.
Zach McElrath, Employee
-
54,246 Points
That being said, this is doable, it will just take a bit more work, you would need to create another Model on whatever object Foreclosure__r is pointing to. This Model should not load any records by default, but it should have a Filterable (Default Off) Condition on the Id field of the object. Then in your Snippet (thinking here about using it for Row or Mass Action) you would need to assemble a list of all the Foreclosure Ids that you need to query for, and then perform a query on the Model to get those records. Then you would do your updates in much the same way as you're doing right now, only you'd be updating the Foreclosure records you queried for. Then you save the Foreclosures Model. Finally to update the field values on your original Model, re-query it.
So assuming that you have a Model called "SelectedForeclosures" or something like that on your "Foreclosure" object, whatever its name is, and that you have a Filterable Condition on the Id field of that object called "SelectedIds" or something like that, you could do something like this:
skuid.snippet.registerSnippet('updateMERS', function(params) {
var $ = skuid.$;
var errorHandler = function(message){
$.blockUI({
message: 'There was an error updating MERS' + (message ? ': ' + message : '.'),
// Show the message for 2 seconds
timeout: 2000
});
};
// Block the UI
$.blockUI({
message: 'Updating MERS...'
});
// Get our Foreclosures Model and Condition
var foreclosuresModel = skuid.$M('SelectedForeclosures');
var selectedIdsCondition = foreclosuresModel.getConditionByName('SelectedIds');
// get a mapping of Foreclosure records we want to update
var foreclosureUpdates = {};
// Is this a Row Action? If so we should have an item and a row
if (params.item && params.item.row) {
foreclosureUpdates[params.item.row.Id] = params.item.row.CustomerAccount__r.MERSSearchCompleted__c;
}
// Is this a Mass Action? If so we should have selected items
else if (params.list && params.list.getSelectedItems().length) {
$.each(params.list.getSelectedItems(),function(i,item){
foreclosureUpdates[item.row.Id] = item.row.CustomerAccount__r.MERSSearchCompleted__c;
});
}
// Set the value of our SelectedIds condition to the Ids of the rows we want to update
foreclosuresModel.setCondition(selectedIdsCondition,Object.keys(foreclosureUpdates));
// Now query for foreclosures
foreclosuresModel.updateData()
.done(function(){
var updatesToMake = {};
// Loop over our Foreclosure rows and apply our updates
$.each(foreclosuresModel.getRows(),function(i,row){
updatesToMake[row.Id] = {
'MERSSearchComplete__c': foreclosureUpdates[row.Id]
};
});
// Perform an en-masse update
foreclosuresModel.updateRows(updatesToMake);
// Now save our foreclosures Model
foreclosuresModel.save()
.done(function(result){
// If our result was a success,
// then re-query our principal model
if (result.totalsuccess) {
params.model.updateData()
.done(function(){
// Success!
$.unblockUI();
})
.fail(errorHandler);
} else {
errorHandler();
}
})
.fail(errorHandler);
})
.fail(errorHandler);
});
Jack Sanford, Champion
-
10,100 Points
The two fields I'm trying to work with are both Date fields, that's probably what's causing an error.
Here's the error I'm getting, "Illegal Value for Primitive":
The line in VFRemote.js that's referenced is:
$VFRM.Util={log:function(a,b){if(!("undefined"===typeof console||!console.groupCollapsed||!console.log||!console.groupEnd))if("undefined"!==typeof b&&null!==b)try{console.groupCollapsed(a),console.log(b),console.groupEnd()}catch(c){}else try{console.log(a)}catch(d){}},warn:function(a){if("undefined"!==typeof console&&console.warn&&a)try{console.warn(a)}catch(b){}},error:function(a,b){if("undefined"!==typeof console&&console.error&&a)if(b)try{console.error(a,b)}catch(c){}else try{console.error(a)}catch(d){}},
Zach McElrath, Employee
-
54,246 Points
skuid.snippet.registerSnippet('updateMERS', function(params) {
var $ = skuid.$;
var errorHandler = function(message){
$.blockUI({
message: 'There was an error updating MERS' + (message ? ': ' + message : '.'),
// Show the message for 2 seconds
timeout: 2000
});
};
// Block the UI
$.blockUI({
message: 'Updating MERS...'
});
// Get our Foreclosures Model and Condition
var foreclosuresModel = skuid.$M('SelectedForeclosures');
var selectedIdsCondition = foreclosuresModel.getConditionByName('SelectedIds');
// get a mapping of Foreclosure records we want to update
var foreclosureUpdates = {};
// Is this a Row Action? If so we should have an item and a row
if (params.item && params.item.row) {
foreclosureUpdates[params.item.row.Foreclosure__c] = params.item.row.CustomerAccount__r.MERSSearchCompleted__c;
}
// Is this a Mass Action? If so we should have selected items
else if (params.list && params.list.getSelectedItems().length) {
$.each(params.list.getSelectedItems(),function(i,item){
foreclosureUpdates[item.row.Foreclosure__c] = item.row.CustomerAccount__r.MERSSearchCompleted__c;
});
}
// Set the value of our SelectedIds condition to the Ids of the rows we want to update
foreclosuresModel.setCondition(selectedIdsCondition,Object.keys(foreclosureUpdates));
// Now query for foreclosures
foreclosuresModel.updateData()
.done(function(){
var updatesToMake = {};
// Loop over our Foreclosure rows and apply our updates
$.each(foreclosuresModel.getRows(),function(i,row){
updatesToMake[row.Id] = {
'MERSSearchComplete__c': foreclosureUpdates[row.Id]
};
});
// Perform an en-masse update
foreclosuresModel.updateRows(updatesToMake);
// Now save our foreclosures Model
foreclosuresModel.save()
.done(function(result){
// If our result was a success,
// then re-query our principal model
if (result.totalsuccess) {
params.model.updateData()
.done(function(){
// Success!
$.unblockUI();
})
.fail(errorHandler);
} else {
errorHandler();
}
})
.fail(errorHandler);
})
.fail(errorHandler);
});
Jack Sanford, Champion
-
10,100 Points
I'm not sure I made it clear before, my table is full of rows of the 'FCCA' model which is a join object with the API name of FCCAAssociations__c. It looks like it shouldn't matter what the table's model is since the code it just pulling the row, but just in case.
Here's VFRemote.js:117
$VFRM.Util={log:function(a,b){if(!("undefined"===typeof console||!console.groupCollapsed||!console.log||!console.groupEnd))if("undefined"!==typeof b&&null!==b)try{console.groupCollapsed(a),console.log(b),console.groupEnd()}catch(c){}else try{console.log(a)}catch(d){}},warn:function(a){if("undefined"!==typeof console&&console.warn&&a)try{console.warn(a)}catch(b){}},error:function(a,b){if("undefined"!==typeof console&&console.error&&a)if(b)try{console.error(a,b)}catch(c){}else try{console.error(a)}catch(d){}},
Zach McElrath, Employee
-
54,246 Points
Jack Sanford, Champion
-
10,100 Points
Thanks for all your help so far. Maybe it's something I can work out in the Chicago training in a couple weeks.
Zach McElrath, Employee
-
54,246 Points
Jack Sanford, Champion
-
10,100 Points
It may be that it would work better to have a table of CustomerAccounts, then look up the Foreclosure__c WHERE Id IN Foreclosure__c [field] FROM FCCAAssociations__c WHERE CustomerAccount__c [field] =: {{{Id}}} [Id of row]
Hmm, starting to seem like maybe I can just do an Apex Class and a standard SF button...
-
140 Points
I just want to convert the business account to person account on skuid, using button.
Can you please help me to provide me the code to update the recordtypeId on Account ?
Thanks
Related Categories
-
Fields and Custom Renderers
- 61 Conversations
- 136 Followers