Re-render dependent field when another field updated

I’m using a custom renderer to calculate the value for a field based on several other fields (Call them A, B, C). I’d like this field to update dynamically when A B or C is changed.

I put the field in a field editor and gave it a unique id 'avr.'

I’ve set up the field renderer, and it works the first time.

Then, I set up model actions on the model that contains A B and C, such that if one of them is updated, I run the following skuid snippet:

skuid.component.getById(‘avr’).render();

But the field editor with id=‘avr’ is not re-rendering. At least, the custom renderer doesn’t run when I update A B or C.

What’s the best way to accomplish this?

I’m basically trying to use skuid to create formula fields that update dynamically in the UI without requiring a save.

A quick update:

The model actions are working properly. When I change A, the snippet runs: skuid.component.getById(‘avr’).render();

But the custom renderer doesn’t fire.

Matt, can you post your Custom Field Renderer javascript code? Hard to diagnose this without seeing the field renderer code.

Sure!

var field = arguments[0],    model = field.model,
    row = field.row,
    mP = skuid.$M('Patient'),
    rP = mP.getFirstRow(),
    value = 0,
$ = skuid.$;
var abortions = Number(rP.Abortions__c) || 0,
    children =  Number(row.Children_Living_with_You__c) || 0;
value += row.In_School__c ? 1 : 0;
value += (rP&#46;Age__c <= 26) ? 1 : 0;
value += row&#46;Financial_Pressure__c ? 1 : 0;
value += (rP&#46;Marital_Status__c != 'Married') ? 1 : 0;
value += row&#46;Parents_In_Favor_of_Abortion__c ? 1 : 0;
value += (row&#46;Father_of_the_Baby_Intention__c == 'Abort') ? 1 : 0;
value += (row&#46;Pregnancy_Intention_on_Intake__c == 'Abort') ? 4 : 0;
value += (children >= 2 &amp;&amp; children <= 6) ? 1 : 0;
value += (abortions > 3) ? 3 : abortions;
if (row&#46;AVR_Score__c != value) {
    model&#46;updateRow(row,'AVR_Score__c',value,{initiatorId: field&#46;_GUID});
}
skuid&#46;ui&#46;fieldRenderers[field&#46;metadata&#46;displaytype][field&#46;mode](field,value);
var definition;
switch (value) {
    case 0:
    case 1:
        definition = 'Carry to Term';
        break;
    case 2:
    case 3:
    case 4:
        definition = 'Abortion Vulnerable';
        break;
    case 5:
    case 6:
    case 7:
        definition = 'Abortion Minded';
        break;
    default:
        definition = 'Abortion Determined';
}
if (row&#46;Abortion_Vulnerability_Rating__c != definition) {
    model&#46;updateRow(row, {Abortion_Vulnerability_Rating__c: definition});
}

This code works great, when it runs.

I have this action on the same model:

           <action>               <actions>
                  <action type="custom" snippet="renderAVR"/>
               </actions>
               <events>
                  <event>row&#46;updated</event>
               </events>
               <fields>
                  <field>Children_Living_with_You__c</field>
                  <field>Father_of_the_Baby_Intention__c</field>
                  <field>Financial_Pressure__c</field>
                  <field>In_School__c</field>
                  <field>Parents_In_Favor_of_Abortion__c</field>
                  <field>Pregnancy_Intention_on_Intake__c</field>
               </fields>
            </action> 

Bascially, when one of the fields required for the avrScore snippet above is updated, I want to run avrScore again.

The renderAVR snippet triggered by the model action (and it is getting triggered) says simply:

skuid&#46;component&#46;getById('avr')&#46;render();

I gave the field editor where the field rendered in the avrScore snippet the unique id ‘avr’. For some reason the .render() code appears to not cause the field editor to re-render.

Thanks Matt. Can you / have you put some console.log() statements in your Custom Field Renderer to verify that it is / is not being re-run as a result of the Model Actions?

I have two custom field renderers that I’m trying to implement this way.

The AVR renderer is not running when I make changes to the fields, even though skuid.component.getById(‘avr’).render(); is running.

The Tension renderer (below) is running on field change, but it’s running before skuid.component.getById(‘tension’).render()

When I change one of the fields that impacts tension, I get this in the log:
tensionScore started
tensionScore finished
renderTension run


Here’s the tensionScore code:

console&#46;log('tensionScore started');<br />var field = arguments[0],<br />&nbsp; &nbsp; value = 0,<br />&nbsp; &nbsp; myLife = 0,&nbsp;<br />&nbsp; &nbsp; badLife = 0,<br />&nbsp; &nbsp; shame = 0,<br />&nbsp; &nbsp; model = field&#46;model,<br />&nbsp; &nbsp; row = field&#46;row,<br />&nbsp; &nbsp; mP = skuid&#46;$M('Patient'),<br />&nbsp; &nbsp; rP = mP&#46;getFirstRow(),<br />$ = skuid&#46;$;<br /> &#47;&#47; &#46;&#46;&#46;<br />&#47;&#47; A BUNCH OF CALCULATIONS TO SET VALUES OF myLife, badLife, shame, and value &#47;&#47; &#46;&#46;&#46; <br />model&#46;updateRow(row,'Tension_Score__c',value,{initiatorId: field&#46;_GUID});<br />skuid&#46;ui&#46;fieldRenderers[field&#46;metadata&#46;displaytype][field&#46;mode](field,value);<br />var tension = [myLife, badLife, shame],<br />&nbsp; &nbsp; tensionStrings = ['My Life', 'Bad Life', 'Shame'],<br />&nbsp; &nbsp; maximum = [],&nbsp;<br />&nbsp; &nbsp; calculatedTension = '';<br />$&#46;each(tension, function(i,row){<br />&nbsp; &nbsp; if (row == value) {maximum&#46;push(i)}<br />});<br />$&#46;each(maximum, function(i,row){<br />&nbsp; &nbsp; calculatedTension += tensionStrings[maximum[i]] + ';';<br />});<br />if (row&#46;Tension__c != calculatedTension) {<br />&nbsp; &nbsp; model&#46;updateRow(row,{Tension__c: calculatedTension});<br />}<br />console&#46;log('tensionScore finished');


Interestingly, the Tension__c field is getting updated when this runs, but the Tension_Score__c field is not being updated.

Also interestingly, tensionScore runs a lot of times every time a switch tabs, and avrScore runs once. the values of the fields aren’t changing, but any models that have changes are being saved when a new tab is selected. This occurs whether or not the fields that are calling the custom renderers are on the tab.

Here are the model actions asking tensionScore to render:

on the PatientCase model (the same model as Tension_Score__c):

<action>               <actions>
              <action type="custom" snippet="renderTension"></action>
           </actions>
           <events>
              <event>row.updated</event>
           </events>
           <fields>
              <field>Bad_timing_Doesn_t_fit_my_plans __c</field>
              <field>Can_t_take_care_of_baby__ c</field>
              <field>In_School __c</field>
              <field>Pregnancy_Result_of_Infidelity__ c</field>
              <field>Pursuing_a_Career __c</field>
              <field>Shame_Can_t_tell_X_that_I_m_pregnant__ c</field>
              <field>Strict_Religious_Cultural_Background __c</field>
              <field>Unemployed__ c</field>
           </fields>
        </action>

on the Patient model:

<action>               <actions>
              <action type="custom" snippet="renderTension"></action>
           </actions>
           <events>
              <event>row.updated</event>
           </events>
           <fields>
              <field>Ethnicity __c</field>
              <field>Zip__ c</field>
           </fields>
        </action>

^bump^

^bump^ (again)

Any idea why the fields are not re-rendering when I update one of the fields that is used to calculate?