field rendering twice

  • 1
  • Problem
  • Updated 4 years ago
  • Solved
I have a custom field renderer on a datetime field with a snippet that looks like this:

var field = arguments[0],    value = skuid.utils.decodeHTML(arguments[1]),
   $ = skuid.$;
var model = skuid.$M('TempAdder');
if(value == null){
    value = skuid.time.getSFDate(new Date());
    value += 'T04:00:00';
    model.updateRow(model.getFirstRow(),'End_Date__c',value);
    console.log(value);
}
skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
I believe this was working fine before the new release but I might be wrong... Here is how my page looks now:



Any ideas?
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
  • liking the new release

Posted 4 years ago

  • 1
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
If I comment out this line "model.updateRow(model.getFirstRow(),'End_Date__c',value);"everything works fine... can update row cause it to render twice?
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Yes, that's exactly what's happening. We did make a change in Summer 14 that would cause this, and it is intentional. But it is easy to avoid.

There are various ways you can branch your logic so that the renderer is not run twice, but here is one of them:

var field = arguments[0],    
    value = skuid.utils.decodeHTML(arguments[1]),
   $ = skuid.$;
var model = skuid.$M('TempAdder');
if (value == null) {
    value = skuid.time.getSFDate(new Date());
    value += 'T04:00:00';
    model.updateRow(model.getFirstRow(),'End_Date__c',value);
    console.log(value);
} else {
   skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
}
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
OK so just to understand this (because I use field renderers like crazy...) you guys added logic to automatically run the default renderer whenever any update to the model data happens?!
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
That's close: what we did was to officially "register" all skuid.ui.Fields created for each Table and Field Editor field, so that any changes made via updateRow() would be reflected, immediately, in the UI, rather than you having to call save on the Model or list.render() .

This was done to eliminate the need for a lot of JavaScript code whose only purpose was to sync up the UI after Model data changes were made. Skuid now handles this natively.

This shouldn't affect custom field renderers unless you are already doing things like finding all registered Lists and then calling list.render(), or if, like in this situation, you're calling updateRow() within a custom field renderer --- that is, if your Field Renderer has "side effects". 

The biggest tool to be aware of when making Custom Field Renderers that will be helpful here is the initiatorId parameter that can be passed in to updateRow, and the field._GUID property. Another way to have rewritten the above code would be:

var field = arguments[0],    
    value = skuid.utils.decodeHTML(arguments[1]),
   $ = skuid.$;
var model = skuid.$M('TempAdder');
if (value == null) {
    value = skuid.time.getSFDate(new Date());
    value += 'T04:00:00';
    model.updateRow(model.getFirstRow(),'End_Date__c',value, { initiatorId: field._GUID } );
}
skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
This works because when you pass in the initiatorId parameter to updateRow you're letting Skuid know exactly which skuid.ui.Field is responsible for the update --- that way, Skuid knows NOT to tell this Field about the update after it has been processed, because Skuid assumes you already know about it, because you're the initiator, so of course you know about it, you caused it to happen! 

After Skuid Model changes happen, Skuid will call various API methods (see "Overriding and Extending Editors" in this tutorial), but it will only call them on Fields, Items, Lists, Editors that did NOT initiate the data changes.
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
OK sounds great I noticed that updateRow seemed to be working better thanks for the detailed explanation.