How do I render custom picklist values?

For (1), my question is, does it still not pick the correct value if the status is “Working”? For (2), try adding the following line after “var picklistEntries = field.metadata.picklistEntries;” picklistEntries.length = 0;

Thanks Zach. adding that line fixed (2). For (1), the page saves the values fine. When the model refreshes or the page loads and the value is one of the first two (working, ready for review), it loads the correct value as the default. However, when the value is one of the second two (reviewed & approved, reviewed & needs changes), those values are not populated as an existing value. I can edit the field and change its value, though. The rest of the fields seem to load fine. So, something about the logic around building the picklist entries seems to be interfering with loading the existing value in to the field.

Thanks, that helps me confirm what the problem is. Change value = arguments[1] to be value = skuid.utils.decodeHTML(arguments[1]), and that should resolve (1). Here’s the detailed explanation of why this is necessary: XSS vulnerability prevention. Whenever you do a Custom Field Renderer on a Text / Textarea / Picklist field, Skuid preemptively HTML encodes the current value stored for a particular field / row, so that, if you, the author of the Custom Field Renderer, happen to accidentally display this text to the screen without first properly encoding it, if necessary, then you won’t inadvertently introduce an XSS vulnerability into your page. So, from the theoretical to your specific scenario: the reason that “Reviewed & Approved” and “Reviewed & Needs Changes” aren’t working is that they contain a character, the &, which has to be HTML encoded. So the value that you are getting handed in arguments[1] is actually Reviewed & Approved. So by using skuid.utils.decodeHTML(), you’re converting this back into the actual value. Then, because you’re leveraging the skuid.ui.fieldRenderers to actually do your output (as opposed to hand-coding your own picklist), the XSS vulnerability prevention is taken care of. So the lesson to learn here is this: Whenever doing custom Field Renderers for Text/Textarea/Picklist fields, always decode the value passed in via arguments[1], like so:

var field = arguments[0], value = skuid.utils.decodeHTML(arguments[1]); 

Excellent - that fixed it! Good lessons learned here. Thanks so much for your help on this, Zach. For anyone’s future reference, below is the “final” version of my custom picklist renderer.

var field = arguments[0], value = skuid.utils.decodeHTML(arguments[1]); userModel = skuid.model.getModel('User'), userRow = userModel.getFirstRow(), userRole = userModel.getFieldValue(userRow,'Contact.Current_Role__c'), isTeacher = (userRole == 'Teacher'), grpModel = skuid.model.getModel('Guided Reading Plan'), grpRow = grpModel.getFirstRow(); // Prevent teachers from making any edits if the status is approved by forcing the mode to read-only if ((value === 'Reviewed & Approved') && isTeacher) { field.editable = false; field.mode = 'read'; } if (field.mode == 'edit') { var picklistEntries = field.metadata.picklistEntries; picklistEntries.length = 0; // if you don't do this, then the "real" values are already in the picklist and the code below will add duplicate values // if there is no record yet, add a default value. NOTE: when the page is saved, the grp model is only saved when the value in this field is not blank. I am NOT using the Skuid field property "Add 'None' Option" because I only want this option to appear when there isn't already a record. if (skuid.model.isNewId(grpRow.Id)) { picklistEntries.push( { value: '', label: '-- Select a Status to Create --', defaultValue: false, active: true } ); } // create picklist values for the basic statuses picklistEntries.push( { value: 'Working', label: 'Working', defaultValue: false, active: true }, { value: 'Ready for Review', label: 'Ready for Review', defaultValue: false, active: true } ); // create picklist values for the review/approval statuses if the user is not a teacher if (!isTeacher) { picklistEntries.push( { value: 'Reviewed & Approved', label: 'Reviewed & Approved', defaultValue: false, active: true }, { value: 'Reviewed & Needs Changes', label: 'Reviewed & Needs Changes', defaultValue: false, active: true } ); } } // Run the standard picklist renderer for the given mode skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value); 

Hey Zach I’m trying to use this code but it doesn’t seem to be doing anything for me. I’m trying to  remove a picklist value, but it keeps showing up… here is my snippet:

var field = arguments[0], value = skuid.utils.decodeHTML(arguments[1]); var picklistEntries = field.metadata.picklistEntries; picklistEntries.length = 0; // if you don't do this, then the "real" values are already in the picklist and the code below will add duplicate values picklistEntries.push( { value: 'Fixed', label: 'Fixed', defaultValue: false, active: true }, { value: 'Indexed', label: 'Indexed', defaultValue: false, active: true } ); // Run the standard picklist renderer for the given mode skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value); 

If I log it in the console I can see that my changes have been made, however it doesn’t reflect on the page…

Moshe, one “wrinkle” to the Picklist renderer is that if the Picklist is either (a) Dependent on the values of another picklist, or (b) Dependent on the record’s Record Type, then field.metadata.picklistEntries is NOT considered when building the Picklist — rather, an internal function is run that goes and determines the appropriate values to display based on the value of the controlling picklist and/or Record Type field on the current record.

If you want to completely override this behavior, you’ll need to roll your own custom picklist renderer using our internal skuid.ui.renderers API, and as J describes in this community post.

If you want to rely on the internal renderer, but adjust the values AFTER the renderer has been run, you might try removing the displayed values directly from the output

It works!

Hi,

I have a picklist with 4 values, i would like to remove 2 values. I  am following the below code, but it is not removing those values.

skuid&#46;ui&#46;fieldRenderers[field&#46;metadata&#46;displaytype][field&#46;mode](field,value);<br /><br />var select = field&#46;element&#46;find('select'); if (select&#46;length) {<br /> &#47;&#47; Remove unwanted entries<br /> $&#46;each(select&#46;children('option'),function(){<br /> if ($(this)&#46;val()==='BA') $(this)&#46;remove(); &nbsp; if ($(this)&#46;val()==='UA') $(this)&#46;remove(); }); } 

Thank you!
I was beating my head against the wall trying to figure out why overriding the skuid.metamodel.picklistEntries was not working.

I get an errror saying “TypeError: field.metadata is undefined” am I missing something here?

var field = arguments[0], value = skuid&#46;utils&#46;decodeHTML(arguments[1]); skuid&#46;ui&#46;fieldRenderers[field&#46;metadata&#46;displaytype][field&#46;mode](field,value); var select = field&#46;element&#46;find('select'); if (select&#46;length) { &#47;&#47; Remove unwanted entries $&#46;each(select&#46;children('option'),function(){ if ($(this)&#46;val() === 'Below Expectation'){ $(this)&#46;remove(); } }); select&#46;append($('<option value="cheese">Cheese</option>')); }

Hasantha,

It sounds like your snippet isn’t getting passed the field as arguments[0]. How are you launching you snippet? This code will only work if you’re running it as a custom field renderer.

oops, my bad thanks for pointing it out Matt :)

You guys rock! Thanks, this really helped :slight_smile:

Hey team, just wondering how I would modify this snippet to render radio buttons instead of the picklist dropdown?

Seems so simple but I haven’t been able to figure it out :slight_smile:

Thank you in advance!

I asked this in a comment above, though have not found a reply and am still stuck with it. How do I modify the snippet to render radio buttons instead of the standard picklist dropdown?

Thank you!

var $ = skuid.$; var field = arguments[0], value = skuid.utils.decodeHTML(arguments[1]); skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value); var select = field.element.find('select'); if (select.length) { $.each(select.children('option'),function(){ if ($(this).val() === 'Survey Complete - Qualified' || $(this).val() === 'Sent' || $(this).val() === 'Responded' || $(this).val() === 'Survey Complete - DNQ' || $(this).val() === 'Appointment Booked'){ $(this).remove(); } }); }<br>

I’m also trying to figure out how to render a picklist created by a custom field renderer snippet as Radio Buttons. 

I know based on this post: http://help.skuidify.com/m/11720/l/214170-skuid-ui-basic-renderers that I need to use renderas ‘RADIO_BUTTONS’ in some way, but not sure how. 

my snippet:

var field = arguments[0], row = field.row, // set the render condition isPercentage = (row.Indicator__r.Benchmark_Type__c == 'Percentage') ? true : false; value = skuid.utils.decodeHTML(arguments[1]), metadata = field.metadata, element = field.item.element, $ = skuid.$; if (isPercentage &amp;&amp; field.mode =='edit'){ //create a blank variable for picklist entries var picklistEntries = []; // set the picklist entries. note defaultValue doesn't matter, the first one will be default picklistEntries.push( { value: '0', label: 'No', defaultValue: true, active: true }, { value: '1', label: 'Yes', defaultValue: false, active: true } ); field.metadata.picklistEntries = picklistEntries; // render the field as a picklist skuid.ui.fieldRenderers.PICKLIST.edit(field,value); } else{ //use the default renderer skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value); }<br>

ask and ye shall receive, h/t to https://community.skuid.com/t/readonly-picklist-radio-buttons-can-still-be-changed-on-…

add a line 

field.options.type = 'RADIO_BUTTONS';

before your skuid.ui.fieldRenderers

So Robin you might try

value = skuid.utils.decodeHTML(arguments[1]); field.options.type = 'RADIO_BUTTONS'; skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode]

Thanks Jack! 

Hi Jack and Rob, 

Amazing, thank you for the help! I can now render the options as radio buttons (YAY!). As an added challenge, I would still like to remove unwanted entries. The existing script as suggested earlier does not seem to do the trick any more once the list is rendered as radio buttons. How would I have to modify this code to remove them?

Thank you in advance!


if (select&#46;length) { &nbsp;<br />&nbsp; &nbsp;$&#46;each(select&#46;children('option'),function(){<br />&nbsp; &nbsp; &nbsp; &nbsp; if ($(this)&#46;val() === 'Survey Complete - Qualified' || $(this)&#46;val() === 'Sent' || $(this)&#46;val() === 'Responded' || $(this)&#46;val() === 'Survey Complete - DNQ' || $(this)&#46;val() === 'Appointment Booked'){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $(this)&#46;remove();<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp;});

I am trying to render a custom picklist but the picklist is just rendering as normal and there are no errors in the console. Can some one point in the right 

Objective:
If the running user has a sales category of “Retail Sales” then only show the “Retail Sales” option in the picklist. Otherwise render as usual.

Notes:
This is a dependent picklist.

Code:

var $ = skuid.$; var field = arguments[0], value = skuid.utils.decodeHTML(arguments[1]); var isRetailSales = []; var userModel = skuid.model.getModel('RunningUser'), quoteModel = skuid.model.getModel('QuoteDetail'), userRow = userModel.getFirstRow(), userSalesCategory = userModel.getFieldValue(userRow,'AC_Sales_Category__c'), isRetailSales = (userSalesCategory == "Retail Sales"); skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value); var select = field.element.find('select'); if (isRetailSales &amp;&amp; field.mode == 'edit') { if (select.length) { // Remove unwanted entries $.each(select.children('option'),function(){ if ($(this).val() === 'Retail Sales'){ $(this).remove(); } }); } }<br>