Render picklist entries from selected multipicklist values

  • 1
  • Question
  • Updated 3 years ago
  • Answered
This is an extension of a great post here: https://community.skuidify.com/skuid/topics/how_do_i_render_custom_picklist_values

I'm trying to take the selected values from a multipicklist field and render them as a picklist.

Here's my custom renderer:
var field = arguments[0],    value = skuid.utils.decodeHTML(arguments[1]),
$ = skuid.$;
console.log('Rendering Session 1');
var intakeModel = skuid.$M('BabyMeIntake'),
    intakeRow = intakeModel.getFirstRow(),
    interests = intakeModel.getFieldValue(intakeRow,'Learning_Interests__c');
if (interests) {
    var interestsArray = interests.split(';');
    var picklistEntries = field.metadata.picklistEntries;
    picklistEntries.length = 0;
    
    $.each(interestsArray,function(i,str){
        picklistEntries.push(
            { value: str, label: str, defaultValue: false, active: true }
    );
    });
}
if (!value) {
    value = (interestsArray && interestsArray.length) ? interests[0] : value;
    field.model.updateRow(field.row, field.id, value, {initiator_id: field._GUID});
}
console.log('updatedfield:');
    console.log(field);
    
skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);


The problem I'm having is that the picklist still renders all of the entries, despite the fact that the 'field' showing up in the console log has the correct shortened list of picklistEntries.

What am I doing wrong?


Also, not sure if this is related, but I'm using a model action when the 'Learning_Interests__c' field is updated to render the field editor that has the field with this custom renderer, like so:
skuid.$C('SessionOneFields').render();
That seems to be working, although the rendering logic seems to run more than once each time, for some reason I don't understand. If I don't have the model action, the field renderer doesn't run, but if I have it, it runs multiple times.


?
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb

Posted 3 years ago

  • 1
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
^^bump^^
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Sodium Sodium Sodium Sodium
Sodium Sodium Sodium Sodium
Sodium Sodium Sodium Sodium
Sodium Sodium Sodium Sodium
Batman!


(all humor aside, can anyone help with this?)
Photo of Andrew Duensing

Andrew Duensing, Employee

  • 740 Points 500 badge 2x thumb
Hey Matt, I got a couple things that might point you in the right direction, but unfortunately I didn't have the time to fully solve this.

As far as I can tell field.metadata.picklistEntries is actually only used on UI only fields. This might not be 100% accurate, but without doing an extensive read through the source code, this is the behavior that is presented.

That being said, your snippet should work on a UI only field. Maybe you can use a UI only field and leverage some model actions to accomplish what you are trying to do.
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Hey Matt -

A few questions:

1) Is the field that the custom renderer is rendering a Dependent picklist?  Although this might have changed in Banzai (7.x), I believe field.metadata.picklistEntries will be used unless the field is a dependent picklist in which case it will be ignored.

2) Is the field that the custom renderer is rendering called "Learning_Interests__c" or is "Learning_Interests__c" a different field than the one that is being rendered?  You are obtaining the value for "Learning_Interests__c" but if it's the same as the field being rendered, you already have the value in the "value" variable.  if it's different fields, then you might want to add a "true" for the third parameter to getFieldValue so you get the escaped version of the value.

3) Do you have any conditional rendering setup on the field being rendered?

4) Do you get the "double render" behavior when "value" is NOT empty/null/undefined, when it is empty/null/undefined or in both scenarios?
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Matt -

Couple more things I just noticed:

1) The line of code you have for updateRow contains a problem with "initiatorId"  You have it specified with an underscore (initiator_id) and it should be initiatorId.  This change should solve your double rendering problem.

field.model.updateRow(field.row, field.id, value, {initiator_id: field._GUID});
To
field.model.updateRow(field.row, field.id, value, {initiatorId: field._GUID});

2) The line of code in the block that does the update row uses "interests[0]".  The variable "interests" is a semi-colon delimited string, not an array.  So, what this is doing is setting the value to the first character of the semi-colon delimited list.  This should likely change to either interestsArray[0] if you want the first item in the list only, or just interests if you want the entire semi-colon list.

value = (interestsArray && interestsArray.length) ? interests[0] : value;
To

value = (interestsArray && interestsArray.length) ? interestsArray[0] : value;
OR
value = (interestsArray && interestsArray.length) ? interests : value;
Here's a sample page that modifies the "Account Sources" of "Account" using a very similar approach to what your code does but with the fixes above applied.  It works as you are expecting yours to work so if after making these changes, you're code still isn't working as intended, I'm guessing the field is a dependant picklist possibly?

<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" showheader="true" tabtooverride="Account">   <models>
      <model id="Account" limit="1" query="true" createrowifnonefound="false" sobject="Account" adapter="" type="">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="AccountSource"/>
         </fields>
         <conditions>
            <condition type="param" enclosevalueinquotes="true" operator="=" field="Id" value="id"/>
         </conditions>
         <actions/>
      </model>
   </models>
   <components>
      <pagetitle model="Account" uniqueid="sk-3VpoSu-68">
         <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="Account" mode="edit" uniqueid="sk-3VpoSu-69" buttonposition="">
         <columns>
            <column width="50%">
               <sections>
                  <section title="Basics">
                     <fields>
                        <field id="Name"/>
                        <field id="AccountSource" valuehalign="" type="CUSTOM" snippet="sourcesRenderer"/>
                     </fields>
                  </section>
               </sections>
            </column>
            <column width="50%">
               <sections>
                  <section title="System Info">
                     <fields>
                        <field id="CreatedDate"/>
                     </fields>
                  </section>
               </sections>
            </column>
         </columns>
      </basicfieldeditor>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript>
         <jsitem location="inlinesnippet" name="sourcesRenderer" cachelocation="false">var field = arguments[0]
, $ = skuid.$
, value = skuid.utils.decodeHTML(arguments[1]);
console.log(field);
var sources = 'Foo;Bar;Fiddle;';
if (sources) {
    var sourcesArray = sources.split(';');
    var picklistEntries = field.metadata.picklistEntries;
    picklistEntries.length = 0;
    
    $.each(sourcesArray,function(i,str) {
        if (str) {
            picklistEntries.push(
                { value: str, label: str, defaultValue: false, active: true }
        );
        }
    });
}
if (!value) {
    value = (sourcesArray &amp;&amp; sourcesArray.length) ? sourcesArray[0] : value;
    field.model.updateRow(field.row, field.id, value, {initiatorId: field._GUID});
}
console.log(field);
    
skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
</jsitem>
      </javascript>
   </resources>
   <styles>
      <styleitem type="background" bgtype="none"/>
   </styles>
</skuidpage>
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Thanks, Barry. You're the man.

I won't get to test this out until tomorrow, but I don't have a dependent picklist, so those few changes should do the trick!
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Good deal, let me know if it doesn't work.
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
It works!
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Awesome, glad to hear!