Field Not Refreshing on Page

  • 1
  • Question
  • Updated 4 years ago
  • (Edited)
The following page is not behaving the way I understand it.

I thought that after I updated the First_Name__c field in the UI that the 'Name' field should update as well. However, that is not happening. Instead its only updating when the page loads, or when I click on Save or even cancel. When I inspect the element, I want to see the Snippet running but it is not. I don't see any of the Console.log() messages I added in the scripts.

Please help!!! What am I doing wrong?

<!--
<skuidpage unsavedchangeswarning="yes" showsidebar="true" showheader="true" tabtooverride="Related_Person__c">
<models>
<model id="RelatedPerson" limit="1" query="false" createrowifnonefound="true" sobject="Related_Person__c">
<fields>
<field id="Name"/>
<field id="CreatedDate"/>
<field id="First_Name__c"/>
<field id="Last_Name__c"/>
<field id="Patient_Name__c"/>
</fields>
<conditions/>
<actions/>
</model>
</models>
<components>
<pagetitle model="RelatedPerson">
<maintitle>
<template>{{Name}}</template>
</maintitle>
<subtitle>
<template>{{Model.label}}</template>
</subtitle>
<actions>
<action type="delete"/>
<action type="clone"/>
<action type="share"/>
<action type="savecancel" window="self"/>
</actions>
</pagetitle>
<basicfieldeditor showsavecancel="false" showheader="true" model="RelatedPerson" mode="edit" layout="above">
<columns>
<column width="50%">
<sections>
<section title="Basics" collapsible="no">
<fields>
<field id="Name" type="CUSTOM" snippet="nameConcat">
<renderconditions/>
</field>
<field id="First_Name__c" type="CUSTOM" snippet="nameConcat"/>
<field id="Last_Name__c" type="CUSTOM" snippet="nameConcat"/>
</fields>
</section>
</sections>
</column>
<column width="50%">
<sections>
<section title="System Info">
<fields>
<field id="CreatedDate"/>
</fields>
</section>
</sections>
</column>
</columns>
<renderconditions/>
</basicfieldeditor>
</components>
<resources>
<labels/>
<css/>
<javascript>
<jsitem location="inlinesnippet" name="nameConcat" cachelocation="false">var field = arguments[0],
value = arguments[1],
$ = skuid.$,
dt = field.metadata.displaytype;

console.log('==============================');
console.log('In Field Field' + field);
console.log('Field Mode: ' + field.mode);
console.log('Field Value: ' + value);
console.log('Field Display Type: ' + dt);
console.log('==============================');

if (field.mode != 'edit') {
skuid.ui.fieldRenderers[dt][field.mode](field, value);
} else {
skuid.ui.fieldRenderers[dt].edit(field, value);
}

var firstname = field.model.getFieldValue(field.row, "First_Name__c");
var lastname = field.model.getFieldValue(field.row, "Last_Name__c");
var middlename = field.model.getFieldValue(field.row, "Middle_Name__c");
console.log("Extracting First Name: " + firstname);
console.log("Extracting Middle Name: " + middlename);
console.log("Extracting Last Name: " + lastname);
value = firstname + ' ' + middlename + ' ' + lastname;
console.log("Concotanated Value: " + value);

field.model.updateRow(
field.row,
field.id,
value,
{ initiatorId : field._GUID}
);
</jsitem>
</javascript>
</resources>
</skuidpage>

-->
Photo of Sofware Developer Guy

Sofware Developer Guy

  • 1,354 Points 1k badge 2x thumb

Posted 4 years ago

  • 1
Photo of JD Bell

JD Bell, Senior Product Engineer

  • 2,996 Points 2k badge 2x thumb
Hi Software Developer Guy (is that you real name?!? ;) ),

This is actually the expected behavior. Let me try to explain what's going on.

On a Skuid Model, pretty much anything that references a particular field on a particular record will be updated when any change is made to that field. So if you had a Table and a Field Editor which both reference the same Model and you edit a field with the Table, then you'll see the change to that field immediately reflected in the Field Editor. This all happens on the client (your browser) without any need to go back and forth between the server (saving you a lot of time waiting for server responses).

As I'm sure you know, some fields in Salesforce are formula fields. Their values may be calculated from one or several other fields. That's the case with your Name field - it's calculated by concatenating the First Name and Last Name fields together. But that is occurring on the server, not in your browser. The only way to refresh that value is to send the value of your updated First Name to the server and then get the updated Name value back.

That's exactly what's happening when you click "Save": Skuid is sending First Name to the server. The server then recalculates the value of Name and sends the updated Name field back to Skuid. Skuid detects that the Name field has changed since the last query and automatically updates any components which reference that field.

The good news is that there's a fairly easy work-around. Rather than using FullName, use a Template Field with the following template:

{{FirstName}} {{LastName}}

Both FirstName and LastName will be automatically registered with the Model, allowing Skuid to update the template in real-time without the need to round-trip to the server:

(Edited)
Photo of Sofware Developer Guy

Sofware Developer Guy

  • 1,354 Points 1k badge 2x thumb
Thank you for the response!!!
Sorry for not completely understanding, can you help me understand the following:

I understand the relationship between the Table and Field Editor, I think. They share the same model, correct? if they do then the values will be updated. Is that done through some event? Some Javascript.
Also: My understanding is that you are only updating the model on the machine and not the server. Then when you hit the Save button all of the model is sent to the server to be saved.

I don't understand why a server trip needs to occur for the case of concatenated fields (such as name). With the Javascript I wrote, I was trying to mimic the first scenario. My understanding was that when a model.updateRow() occurred, then the snippet would execute. (Which did not need to go to the server). As the data is changed in the model only.

I can kinda make this work using the console in my browser. if I do a model.updateRow() manually through the console, according to what I've seen and tested, it triggers the Script. However, how do you trigger the script when the user changes something on the First_Name__c box for example?

Hope I made sense and that you can straighten me out.

Software Developer Guy is an alias !!! :)
Photo of JD Bell

JD Bell, Senior Product Engineer

  • 2,996 Points 2k badge 2x thumb
Ah... sorry I didn't notice your custom field renderer before. Basically, the issue is that your field renderer isn't registered with the Model, so Skuid doesn't know that the UI field needs to be re-rendered when the Model field is changed.

Fortunately that's not too hard to fix! All you need to do is register the UI field via the <Model>.registerField( UIField, ModelFieldId ) function. For example:

var $ = skuid.$,
    field = arguments[0],
    value = arguments[1];
field.model.registerField( field, "FirstName" );
field.model.registerField( field, "LastName" );
var firstName = field.model.getFieldValue( field.row, 'FirstName' ),
    lastName = field.model.getFieldValue( field.row, 'LastName' );
skuid.ui.fieldRenderers.STRING.read( field, firstName + ' ' + lastName );
The image below gives you a sense of the difference between using the standard Name renderer, using a Template Field with FirstName and LastName, and using the custom renderer which has been registered with the FirstName and LastName fields (the example code above):



If you can use the Template Field, I'd recommend it. It comes with some awesome extra features, like the ability to edit the individual fields in a popup:

Photo of Sofware Developer Guy

Sofware Developer Guy

  • 1,354 Points 1k badge 2x thumb
Hi,
Thank you so much.
That is what I was missing!!!

I know it works, but there is something I don't understand. I thought that when you dropped a field onto an editor, that field was automatically registered with the model. I guess that is not the case.

Is there some documentation that you can point me to understand more of the squid sequence of events?

Thank you.
Photo of JD Bell

JD Bell, Senior Product Engineer

  • 2,996 Points 2k badge 2x thumb
Yes, the field is registered automatically, but only with one Model field - the "initial" field, if you will.

For example, if you have a custom renderer defined for the Name field, then the UI field will be registered with the Name Model field, but not the First Name or Last Name fields. So, a change to the First Name field will not be reflected in the Name field until you send the Model to the server and get a response back.

By registering the Name UI field with the FirstName and LastName Model fields, the UI field will be re-rendered when there's a change to the any of the three fields: Name, FirstName or LastName.
(Edited)
Photo of Sofware Developer Guy

Sofware Developer Guy

  • 1,354 Points 1k badge 2x thumb
Thank you that makes sense. That was the piece that I could not figure out.