Render component based on users access to a field

  • 1
  • Question
  • Updated 4 months ago
  • Answered
Anyone have a good way to conditionally render a component based on whether the user has access to edit a particular field?

I have buttons in a button set that edit a field, but if the user doesn't have permission to edit that field, they don't need the buttons...
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb

Posted 4 months ago

  • 1
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Using a 'snippet returns true' rendering condition, with a snippet like the following works for me.

var model = skuid.$M('Comments'),
    field = model.getField('Pinned__c');
 
return field.editable;

Technically you could make that a one-liner like so:

return skuid.$M('Comments').getField('Pinned__c').editable;
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,674 Points 20k badge 2x thumb
Joining the schizophrenic champions club I see.
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Photo of John Dahlberg

John Dahlberg, Champion

  • 2,442 Points 2k badge 2x thumb
To extend the thought here, here's a snippet to evaluate if a user has access to query an object for using on rendering logic.  This is handy when you have tabs that have page includes in them where you can disable the tab if the underlying include would be inaccessible.  For example, on record detail pages, we have a tabsets to keep the related lists organized and each of these are their own page so we can reuse related lists on many pages. 

The other benefit of this approach is that you don't need knowledge of the specific skuid Model name.  With page includes, you have to maintain uniqueness of model names so you don't run into conflicts with your models, which implies a lot of model names to keep track of in snippets.  Moving the snippet logic to the general sObject means only one snippet per object.  Ideally It would be nice to pass the SObject name as a parameter into the snippet from the pagebuilder so there's only one snippet, but we're not there yet with snippet parameters.


if(skuid.utils.getAPIDescribeSObject('Account') !== null)
    { 
        if( skuid.utils.getAPIDescribeSObject('Account').queryable == 'true' ) 
        {
            return true;
        }
    }
else{
    return false;
}


Likewise, you could disable a new record button if the user doesn't have permission to crate a target object record:

if(skuid.utils.getAPIDescribeSObject('Account') !== null)
    { 
        if( skuid.utils.getAPIDescribeSObject('Account').createable == 'true' ) 
        {
            return true;
        }
    }
else{
    return false;
}


A couple details of interest.  Unlike the skuid.model API, the values in skuid.utils.getAPIDescribeSObject return as a string, which is why the return is wrapped in the if statement.  Also, there's a null check, which handles script errors if the user has no access to the object.
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Thanks, John.

Is there a way to extend your logic to a specific field? What if the user has access to edit an object but not a specific field?
Photo of John Dahlberg

John Dahlberg, Champion

  • 2,442 Points 2k badge 2x thumb
Matt - Just worked out this snippet for you.  The API call returns the fields of the SObject as an array.  You can loop through that list for the field you're interested in and work with any of the attributes of the field.  

SObj = skuid.utils.getAPIDescribeSObject('Account');

if(SObj !== null)
    { 
        var fields = SObj.fields;
        $.each(fields,function(e,field){
            if(field.name == 'LastName' && field.updateable == 'true'){
                result = true ;
            }
        });
    }
return result;