Custom Field Renderer - one or the other (depending on field mode)

  • 1
  • Question
  • Updated 4 years ago
  • Answered
I have 2 fields for weight/capacity in a model. One is for kilos (kgs), the other is for pounds (lbs). As this is part of a managed package, some users will work in kgs, others will work in lbs. I would prefer not to use conditional rendering of the fields (depending on user location) as sometimes they need to work in both.

I'd also prefer not to use formula fields to do the conversions as it would be great if these conversions could be done in real time, rather than with each save operation.

I've started on a snippet, but am stuck with getting it to work depending on the field mode. What I'd like to do is:

IF Cargo__kgs__c is in edit mode, then update Cargo__lbs__c (which is in read mode) with the converted lbs value, 

otherwise

IF Cargo__lbs__c is in edit mode, then update Cargo__kgs__c (which is in read mode) with the converted kgs value.



is this possible? My hacked-together snippet below...

var field = arguments[0],        value = arguments[1];
//runs on the kgs field    
    $ = skuid.$,
    dt = field.metadata.displaytype;

if (field.mode == 'edit') {
    skuid.ui.fieldRenderers[dt][field.mode](field,value);
} else {
    skuid.ui.fieldRenderers[dt].read(field,value);
    
    var m = skuid.model.getModel('CharterOpParent'); 
    var row = m.getFirstRow(); 
    //reference the fields by thier API name
    var lbs = row.stack__Cargo_lbs__c;
    //var kgs = row.stack__Cargo_kgs__c;
    //add all the fields together
    var convert = function() {
    value = (Number(lbs) * 2.2);
    skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
    };
    
    convert();
    
    var listener = new skuid.ui.Field(field.row,field.model,null,{fieldId: 'stack__Cargo_kgs__c'});
    listener.handleChange = function(){
        convert();
    };
    
    field.model.registerField(listener,'stack__Cargo_kgs__c');
    
}
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb

Posted 4 years ago

  • 1
Photo of Ben Hubbard

Ben Hubbard, Employee

  • 12,490 Points 10k badge 2x thumb
Hi Greg,

I would approach this in a totally different way.  I think a lot of times we jump to the field renderer route when we don't really need to.  (This also has a lot to do with limitations of prior versions of Skuid).  But since we can put action snippets on model events now, and our fields will truly listen and update when a model event happens, we can greatly simplify use cases like yours.  

In my opinion, what you're trying to do has nothing to do with how your fields render.  Here's what I would do.

1. Create a new model action on your model that runs a snippet when a row in the model has been updated.

2. Create a snippet like this...


var params = arguments[0],	$ = skuid.$,
updates = params.updates,
convertedWeight;
if ('skuid__Account_Weight_lbs__c' in updates) {
    convertedWeight = params.row.skuid__Account_Weight_lbs__c / 2.2;
    
    if (convertedWeight) {
        params.model.updateRow(params.row,'skuid__Account_Weight_kg__c',convertedWeight);    
    }
} else if ('skuid__Account_Weight_kg__c' in updates) {
    convertedWeight = params.row.skuid__Account_Weight_kg__c * 2.2;
    if (convertedWeight) {
        params.model.updateRow(params.row,'skuid__Account_Weight_lbs__c',convertedWeight);    
    }
}

Obviously, you'll have to change your fields from skuid__Account_Weight_kg__c to your actual fields.  But this should do the trick.
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
Thanks Ben, this is definitely a much simpler approach! Its working, but only in one direction (ie lbs to kgs or kgs to lbs). When I had it going both ways, Chrome blocks the page and I get the 'aw snap' message.

I can only think that as the converted field is being updated, it then goes back and updates the other field, which then goes back and updates the converted field again, and so it keeps going.

Once I commented out the 2nd conversion, the first conversion works fine. See below:

var params = arguments[0],	
$ = skuid.$,
updates = params.updates,
convertedWeight;
//kgs to lbs conversion
if ('stack__Cargo_kgs__c' in updates) {
    convertedWeight = params.row.stack__Cargo_kgs__c * 2.2;
    
    if (convertedWeight) {
        params.model.updateRow(params.row,'stack__Cargo_lbs__c',convertedWeight);    
    }

/*
//lbs to kgs conversion
else if ('stack__Cargo_lbs__c' in updates) {
    convertedWeight = params.row.stack__Cargo_lbs__c / 2.2;
    if (convertedWeight) {
        params.model.updateRow(params.row,'stack__Cargo_kgs__c',convertedWeight);    
    }
}
*/
Would the trick be to make it dependent on field mode? (My field editor component is set to read with inline edit). So if lbs.mode = edit, then update kgs, else if kgs.mode = edit, then update lbs
Photo of Ben Hubbard

Ben Hubbard, Employee

  • 12,490 Points 10k badge 2x thumb
Hi Greg,

What version of Skuid are you running?  This should work right in newer versions of Skuid 5.  Older versions will get you stuck in an infinite update loop.
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
Ahhhh. 5.10 in this org. I will have to get my customer to upgrade to the latest release before I could push this out to them. I'll test with a newer version first.
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
Yep that's working really well in 5.21.4   Thanks Ben