AlloyUI - Working with Widgets, Part 1

 What is an Alloy widget?

A widget is something that does some sort of task. Like what, you might ask? For instance, in Alloy, there's a TreeView widget, where you can configure it to display an hierarchy of data, and this hierarchy can be ajaxed in, or shown right away, and with a lot of different options.
That would be a pretty complex widget.
A simple widget would be the Tooltip widget, which just shows users some content when they hover over an item on the page.
 
In Alloy, there's a large collection of widgets, as well as a robust framework for building your own.
 
In this blog post, I'm going to cover some of the widgets that we have in Alloy, then in the next one, I'll post how to create your own. I'm splitting it up because I'm finding both posts have a lot of info to cover, and I don't want people to zone out or miss info they might have found useful because it was buried in a super long post.
 
So let's go ahead and get our sandbox ready:
 
AUI().use('', function(A){
 // Our code will go here
});

I'll reference the name of the widget above the code so you can see the module that we'll be using in order to run it.
 
So let's go ahead and create a TreeView of a user directory that has drag and dropping of elements, and expandable folders.
 
Here's the demo: TreeWidget
Here's the code you would have to write:
 
You would use the aui-tree-view module
 
var users = new A.TreeViewDD({
     children: [{
           label: 'Users',
           expanded: true,
           children: [{
                label: 'Nate Cavanaugh',
                expanded: true,
                children: [
                     {label: 'Documents', leaf: false},
                     {label: 'Downloads', leaf: false},
                     {label: 'Movies', leaf: false},
                     {label: 'todo_list.txt'}
                ]
      }]
 }]
}).render();
 
Let's look at what's going on here. First we're doing a traditional object construction in JavaScript, which is creating a new object. You're saying give me a new TreeView, and let's call it "users".
 
So what's with that .render() at the end?
 
That render() does not have to be called until you're absolutely ready to display the widget. In fact, there are many times where you may wish or need to configure a widget, but only render it under certain circumstances, or after a certain period of time has passed.
 
But if you don't care about waiting, you can just do it all inline (render will still return a reference to the widget).
 
We've just created a tree widget, and have this users variable, so what? Why is this exciting if you're just *using* widgets?
 
Because even if you're just using widgets, you can still do VERY interesting stuff with these widgets. Remember how we talked about working with elements?
 
The widget API is VERY similar to the Node API, meaning that in the same way that you can do get/set for properties on a Node, you can also do that on a Widget. And in the same way that you can use .on() for nodes, you can also do the same thing for Widgets.
 
But before we jump into that, let's look at another widget, something like Tooltip.
 
So let's go ahead and create a Tooltip. We'll use the aui-tooltip module:
var tooltip = new A.Tooltip({
     trigger: '.use-tooltip',
     bodyContent: 'Hello World!'
}).render();
 
What we're doing here is saying give us a new Tooltip, and show it when you hover over any item with the css class of .use-tooltip. It's also saying to show the content of the body to be "Hello World!". Now, in most cases, this wouldn't be super helpful because you wouldn't want to have the same tooltip text for multiple items, but there is a way to easily have it read the title attribute of the element instead. I'm simply manually using the bodyContent to illustrate the next part.
 
So now we have our tooltip object, what can we do to it? Well, all of those things we passed into it, like trigger, and bodyContent can all be read or changed using get/set, and not only that, but you can listen in to when they're changed as well.
 
This might take a second to realize just how cool this is, but take my word for it, it's insanely powerful.
 
Let's take a look. We'll go ahead and change the message of the tooltip to instead say "Hey there Earth!".
 
tooltip.set('bodyContent', 'Hey there Earth!');
 
Now when you hover over it, the tooltip will say 'Hey there Earth!'.
 
Moderately cool, but the real power comes from the change events that are used with this. Whenever you use get or set, the widget fires a custom event for that change.
So in this case, the event that got fired was " bodyContentChange". Every attribute on the widget fires a "change" event when it gets changed, and you can listen to it in two phases.
 
You can basically listen to the attribute get changed before the value is changed, and prevent it if you want, or after it gets changed.
 
This took me a few minutes to sink in, but here are the benefits:
 
Even as a person using the widgets, you have the ability to listen to interesting moments of what's going on and manipulate widgets on the page.
 
Here's an example: 
All widgets have an attribute called " visible", and when this attribute is changed, the widget hides or shows. Usually you just call widget.hide() or widget.show().
 
But let's say on our tooltip, we want to listen before it shows, and if a certain element is missing on the page, we will prevent the tooltip from being shown.
 
We would do:
 
tooltip.on('visibleChange', function(event){
     if(!A.one('#myEl')){
         event.preventDefault();
     }
});
So now, the tooltip will only show up if an element with the id of myEl is on the page.
 
Or here are some more practical examples:
 
Let's say you're creating a Dialog, and you toggle the visibility of the dialog based on if a separate ButtonItem widget is active?
 
You would use the aui-button-item widget, and the aui-dialog widget, and do:
 
var dialog = new A.Dialog({title: 'Hello', bodyContent: 'Lorem Ipsum'}).render();
var buttonItem = new A.ButtonItem({active: true, label: 'Toggle Dialog'});

buttonItem.after('activeChange', function(event){
 dialog.set('visible', event.newVal);
});

Or what about if you have a ColorPicker widget, and want to update the value of a text input when the hex code changes? You can even pass in the events when you create the widget.
 
You would use the aui-color-picker
 
new A.ColorPicker({
     after: {

   
   
   
   
   
   
   
            hexChange: function(event){ 
   
   
   
   
   
   
   
                 
   
   
   
                 A.one('#myInputNode').val(event.newVal);

   
   
   
            } 
   
   
   
         } }).render();
Another thing I mentioned last time was that Widgets can be plugged just like Nodes. Well, remember our handy dandy IO plugin? We can plug any widget with it, and it will automatically know what elements it should grab internally.
 
For instance, let's create another dialog again, and let's plug it: 
var dialog = new A.Dialog({title: 'Hello World'}).plug(A.Plugin.IO, {uri: 'test.html'}).render();
The plugin will smartly grab the area where the content goes, but not the area of the titlebar, and add a loading mask, and insert the content of the ajax request into there.
 
A couple of notes:
 
The .render() method, will, by default, add the widget into the body element. But if you pass it either a selector or a element, it will render the widget into that element on the page.
 
So I could have easily done this:
new A.ColorPicker().render('#myContainer');
 For Widgets, if you attach a listener " on" that event, it fires before the change has been made, so you can think of it as a "before" stage. It's kind of confusing, but it works.
If you listen to the " after" stage, it's after the work has already been done.
In most cases, you'll only care about being notified after, unless you want to prevent something from happening, or want to know before it happens.
90% of the time, I use " after" to listen to widget events.
 
Anyways, that's it for now on using the widgets. Next time, we'll talk about how you can make your own widget, and what a widget is actually made of.
See you then!
Blogs
Nice .... thank you, Nate
o This is a wonderful opinion. The things mentioned are unanimous and needs to be appreciated by everyone.
HI Jonas
Could you please tell how to send the second level (child node)id from alloy to portlet class and how to retrieve that value?
If i understand you correctly you want to send the id of the selected node on click?
If so here is how i did it:

var tree = new A.TreeView({ .... });

tree.on("lastSelectedChange", function(e){
var id = e.newVal.get("id");

// generate your portlet url here
var url = ....;

var jsonResult = Y.io(url, cb);
});

Hoppe it helps.
Actually i posted an error as you need to create a callback and process the response there:

var cb =
{
xdr: "json",
timeout: 5000,
on: {
success: function (x, o) {
var jsonResponse = o.responseText;
}
}
}
Below is my coding, here where in need to call the business class and get the values... Try to modify my code...

<%
ArrayList mainSecsList=null;
//System.out.println("getAttribute %%%%%%%%%%%%%"+request.getAttribute("MainSecsList"));
if(request.getAttribute("MainSecsList")!=null)
mainSecsList=(ArrayList)request.getAttribute("MainSecsList");
System.out.println("mainSecsList %%%%%%%%%%%%%"+mainSecsList);

%>
<%
ArrayList subSecsList=null;
//System.out.println("getAttribute %%%%%%%%%%%%%"+request.getAttribute("MainSecsList"));
if(request.getAttribute("SubSecsList")!=null)
subSecsList=(ArrayList)request.getAttribute("SubSecsList");
System.out.println("SubSecsList %%%%%%%%%%%%%"+subSecsList);

%>

<form method="post" name="<portlet:namespace />fm" id="<portlet:namespace />fm">
<body>
<table id="MainTable" width="100%" border="0" style="backgroundemoticonfffff;">
<div id="markupBoundingBox">
<ul id="markupContentBox">
<%

int rowId=0;

if(mainSecsList!=null){
Iterator ite=mainSecsList.iterator();
while(ite.hasNext()){
AlloyVO alloyVO=(AlloyVO)ite.next();
rowId++;
System.out.println("RowId %%%%%%%%%%%%%"+rowId);
%>
<li >
<span id="child"><a href="#"><%=alloyVO.getSecTitle()%></a></span>
<ul >
<li>
<a href="#">child child 1</a>
</li>
<li>
<a href="#">folder folder 2</a>
<ul>
<li>
<a href="#">child child child 1</a>
</li>
<li>
<a href="#">folder folder folder 2</a>
<ul>
<li>
<a href="#">child child child child 1</a>
</li>
<li>
<a href="#">child child child child 2</a>
</li>
</ul>
</li>
</ul>
</li>

</ul>

</li>

<%}}%>
</ul>
</div>
</table>
<aui:script use="aui-tree-data">


AUI().ready('aui-tree-view', function(A) {

var treeView = new A.TreeView({
boundingBox: '#markupBoundingBox',
contentBox: '#markupContentBox',
io: {
cache: false,
url: '<portlet:actionURL name="getElements"/>',
},
type: 'normal',
children:children
})
.render();

var children = [{
label: 'Thesaurus',
id: '#child',
expanded: true,
draggable: false,
type: 'io'
}];

});

</aui:script>
</body>
</form>
Hi Miguel,
I am new for alloy. Could you please give me the war file of TreeView using alloy? if it so its very helpful for me
Hi there.

I think that there might be a bug with the TreeView. When i load the children, via ajax io, the fetched children can't be expanded. I have made a post here: http://www.liferay.com/community/forums/-/message_boards/message/6717647 .

I have copied the full example in the alloy ui site and it works fine as long as the children are not loaded via ajax.
HI all
Could you please tell how to send the second level (child node)id from alloy to portlet class and how to retrieve that value?
I am new for alloy. can anyone please give me the war file of TreeView using alloy? if it so its very helpful for me
The demo link http://alloy.liferay.com/deploy/sandbox/tree_widget_example.html doesn't work.
Hi Nate. I just discovered AlloyUI after working with yui3 the past year. It seems to be a better version of many of the same widgets I've been building in plain yui3.

Some of this overview repeats yui3 functionality. Is there a doc which explains where yui3 ends and alloyUI begins?
Hi Michael,
You're right, these blogs covered a lot of areas that overlap, since they're meant to be more introductory in nature.
But some good resources to see what we've added on top of YUI would be to browse our additions to the YUI Gallery (http://yuilibrary.com/gallery/show/#A). As you can see, we've made quite a few contributions to the Gallery, and that's a good listing of the additions on top of YUI. For instance, if you look at the AlloyUI Component listing, we have added a lot of useful functionality around Widgets.
I have some blog posts in the works going into more about what functionality we've added.

Thanks for the comment Michael,
Hi Nate,

First of all, thanks for giving us Alloy UI!

Nate, I am trying to evaluate this for one of our customers who happens to have an eCommerce portal based on Liferay 5.2.3. In our evaluation we are also looking at ExtJS and if I look at the Alloy UI and ExtJS their programming model seems to be similar. Both having the terms like Panel, Dialog, etc. But if I look at the widgets and the richness of the client side features, I frankly see that Alloy UI is where ExtJS was couple of years back.

Now, could you please help me with some insight into Alloy UI as to what are the key points where I would have the edge if I go with Alloy UI. Also, some comparison of Alloy UI with ExtJS would be of great help. Some of the key criteria of my evaluation is:
1. Widgets
2. Richness in terms of responding to user actions/events
3. Rendering performance
4. Stability
5. Support
6. Adaptations by other people/companies
7. Long term road-map
8. Foot-print
9. Documentation
10. Licensing
11. Community

Thanks in advance!
Ajit