Pages

Wednesday 5 March 2014

The "Liferay.Store" component (JavaScript )




Since AlloyUI became a base component for Liferay, various amazing tools became available for the Liferay developer.
One of these are the JavaScript components such as Liferay.Store. This component allows the developer to store user-related data quickly on the server. To see how it works, let's consider a portlet which stores how the user prefers her coffee: black, sweet or with milk. We can just create a select input with the options (github):
How do you like your coffee? 

<select id="<portlet:namespace/>coffeePref" name="<portlet:namespace/>coffeePref"> 
    <option value="black">Black</option> 
    <option value="sweet">Sweet</option> 
    <option value="milk">With milk</option>
</select>
As one would expect, the choice will be lost when the page is reloaded. Here enters  Liferay.Store: it asynchronously saves any information on the server, relating it to the authenticated user. In this case, when the select input changes we will store the new value. First, we open a new <aui:scipt> element, which should declare the use of the liferay-store module:
<aui:script use="liferay-store">

</aui:script>
In it, we retrieve the input using the YUI API and bind a function to its change event:
<aui:script use="liferay-store">
    A.one('#<portlet:namespace/>coffeePref').on(
        'change',
        function(event) { }
    );
</aui:script>
Now comes the beef: the function retrieves the current value of the select input and stores it using the Liferay.Store component (github):
<aui:script use="liferay-store">
    A.one('#<portlet:namespace/>coffeePref').on(
        'change',
        function(event) {
            var instance = this;

            Liferay.Store('<portlet:namespace/>coffee-preference', instance.val());
        }
    );
</aui:script>
In this case, we store the value of the input in a key composed by the portlet namespase followed by the coffee-preference suffix.
One can retrieve this value from JavaScript but it is a common pattern to fetch it on the server side, since it avoids unnecessary requests and slowdowns. This is what we'll do; for that, we use the get() method from the com.liferay.portal.util.SessionClicks class:
<%

String coffeePreference = SessionClicks.get(request, renderResponse.getNamespace() + "coffee-preference", "");

%>
Now, we can use the retrieved value to verify which option was selected - e.g. this way (github):
<select id="<portlet:namespace/>coffeePref" name="<portlet:namespace/>coffeePref">
    <option value="black" <%= "black".equals(coffeePreference) ? "selected" : "" %>>Black</option>
        <option value="sweet" <%= "sweet".equals(coffeePreference) ? "selected" : "" %>>Sweet</option>
    <option value="milk"  <%= "milk".equals(coffeePreference) ? "selected" : "" %>>With milk</option>
</select>
This is a rather simple process to save small, user-bound bits of data asynchronously and can save a lot of time. The full code can be found on GitHub and BitBucket, if you'd like to see the example running.


No comments:

Post a Comment