[SalesForce] Lightning picklist for an SObject-Field – which one to choose ui:inputSelect or lightning:select or force:inputField or lightning:input

I need to decide which path to proceed:

  • <ui:inputSelect />
  • <lightning:select />
  • <force:inputField />
  • <lightning:input /> (Beta)
  • write my own component…

Use case:

Mass edit of n records in a table done by <aura:iteration>. Must be capable of working in nested iterations, too. Data should be bound easily to a field of a list of SObject I am iteration over. Picklistvalues should get populated as easy as possible and respect translations, fielddependencies, etc.


PART ONE – ui:inputSelect vs. lighning:select


I've seen this post Difference between lightning and ui tags

The accepted answer refers to the the Winter 17 release notes here

You can find base Lightning components in the lightning namespace to complement the existing ui namespace components. In instances where there are matching ui and lightning namespace components, we recommend that you use the lightning namespace component. The lightning namespace components are optimized for common use cases. Beyond being equipped with the Lightning Design System styling, they handle accessibility, real-time interaction, and enhanced error messages.

But to decide which one to use, this is far too general to figure the exact differences and decide which one to use.

What I've seen so far:

  • Eventname for onchange: ui ==> change , lightning ==> onchange
  • Tags for options: ui ==> <ui:inputSelectOption> , lightning ==> <option>
  • lightning:select seems always to render a label even with blank label-attribute, it consumes space for an empty label and messing-up rendering inside of tables.
  • What else?

Why do we find these differences?

Why Salesforce changed these things? (Now it's hard to switch an compare the two of them). Why salesforce has introduced two different flavors of the same? This is highly irritating for beginners.

Are there differences in data-binding and event-handling?

My observation on ui:inputSelect is, that if you just assign a value like <ui:inputSelect value="{!v.whatever}" /> it does not get (default)selected on the UI. Is that improved on lightning or am I doing something wrong for ui and that data-binding should work even for both?

Best Practice to choose?

Should we even care on ui or might the answer be: just forget about ui namespace for new project! Always use lightning namespace. ui is just for backward compatibility and legacy first-generation-lightning-components? Is that true? I'm somehow reading between the lines and would like to become clear on that.

Best Practice to simply display SObject Picklist Fields? (USE CASE NO. 1!)

Honestly I find both of them very unsatisfying. Coming from Visualforce and using <apex:inputField> for one decade, this feels like back in the Stone age. What is the state of the art very best we can actually do to simply render an SObject Picklist Field with all of it's

  • Schema-defined Picklist Values OR Global Picklist Values
  • TRANSLATIONS
  • Field Dependencies

Do we really still have to do something like this http://www.sfdcmonkey.com/2016/12/05/how-to-fetch-picklist-value-from-sobject-and-set-in-uiinputselect/

That's ridiculous compared to Visualforce.


PART TWO – Alternatives?


There are more Alternatives to choose from:

I had my sad experiences with <force:inputField> in the past and read about long standing Known Issues. I simply gave up on it. Of course I need to use it in <aura:iteration>. Is there any hope for this to get mature? Like at all, I mean?

There is a new kid on the block <lightning:input> (Beta). How high I could raise my expectations? Are my expectations too high and should I get used to the absence?

Finally write my own select-components?

I would like to avoid it. But has anyone done it and came up with something better than what we can get out-of-the-box?

Best Answer

I go pragmatic here, with an extra level of indirection to try to cope with the shifting sands of Lightning.

If I'm not sure, then I write a custom component which delegates to the lightning: version.

So, for example, I have a custom date input component like this:

<aura:component implements="flexipage:availableForAllPageTypes,c:FormQuestion" access="global" extends="c:FormElement" >
    <div aura:id="container">
        <lightning:input aura:id="inputField" type="date" value="{!v.value}" label="{!v.question}" required="{!v.required}" messageWhenBadInput="{!v.errorMessage}" messageWhenValueMissing="{!v.question + ' is required'}" validity="{!v.validity}" />
    </div>
</aura:component>

When Winter 18 is out, I can just swap in the <lightning:formattedDateTime> component instead of <lightning:input> and add any custom logic along the way to handle any oddities required during the delegation.

It does mean more components, but I think the extra layer of abstraction is worth it for now. Once the components are all out of Beta, then we can breath a sigh of relief!