lightning_kal

Lightning Input Component Value Binding

At the last LV SFDC DG meetup, a very talented developer, Thomas Crouse, gave a presentation on an introduction to Lightning Components. He used a typeahead component as a great example to illustrate many of the core concepts of the framework (e.g., event communication, component composition, etc.). I encourage you to check out the recording on Youtube. One of the less obvious things that his presentation led me to investigate a bit more was how value bindings work for ui:input components.  The rest of this post covers that investigation.

The simplistic way a typeahead could be implemented outside of the Lightning Component framework (i.e., raw JavaScript) would be to get the current value of an HTML input element in an event handler for the keyup event. Interestingly, that alone does not work for a ui:inputText component. I’ll explain why not and the alternative that does work.

The simplistic (but incorrect) approach, for a ui:inputText, is as follows:

The event handler code attempts to get the current value of the searchInput. The value attribute of the ui:inputText is an inherited attribute defined on its super-component ui:input (accessed in the below code with “v.value”.

This code all compiles and executes fine, but the searchValue never has the full value of whatever has been entered in the ui:inputText by the user, as they are typing. So, what’s going on?

The auradocs page for ui:inputText defines the keyup event as:

The event fired when the user releases a keyboard key on the component.

So, the event handler should have fired when the user finished typing the character and, indeed it did. The problem is that the value attribute (v.value) was not set.

There is an attribute inherited from ui:input named updateOn. It accepts a comma separated list of events that will trigger the value attribute’s binding to be updated. The exact documentation from the auradocs for ui:inputText (which is inherited from ui:input) is:

Updates the component’s value binding if the updateOn attribute is set to the handled event. Default value is “change”.

Since the default value is “change” for ui:inputText instances the keyup doesn’t trigger a change to the value attribute. The event handler is triggered, but the value attribute’s value is not set. It will have whatever the value was the last time the change event executed, which may be a value of undefined if the change event has not yet been executed (e.g., first time typing in the input).

The Solution

You can specify a different value for the updateOn attribute, so that the value attribute’s new value is set correctly for the keyup event handler. Putting it all together, the component markup just needs to change to specify “keyup” for the updateOn.

During the investigation, I looked at the source of the ui:input component, and saw that it had an “input” event with the description of “The event fired when the user enters an input.” It isn’t in the auradocs, I suspect, because it isn’t marked as GLOBAL, so I’m not sure that it should really be used for this purpose as it isn’t exactly part of the GLOBAL api of the ui:input component. However, specifying updateOn=”input” did work.

More

It’s a lot of fun developing and experimenting with the Lightning Component framework and I highly encourage you to check it out. If you are completely new to Lightning Components, do the Lightning Components Trailhead Module and read the Lightning Components Developer’s Guide.  If you are completely new to JavaScript, JavaScript Basics from Mozilla has a great JavaScript crash course that covers the basics of JavaScript quite well.