Intro To PrimeFaces widgetVar

In these series of PrimeFaceswidgetVar , I will focus of the detailed use of the javascript API provided by PrimeFaces.

Diving into the API needs too much debugging since most of it is not provided in the official documentation.

The basics of debugging and knowing what to call and what this function would do is very simple and hard in the same time, since it would require some knowledge in Javascript and jQuery.

In Google Chrome the console would provide a very helpful and powerful access to everything you need to know about this API, and without it I would tell, your application wouldn’t reach production level if you are building a real world website/application.

Contents:

  1. What is a widgetVar ?
  2. What the objects are made of ?
  3. What to expect from this API ?
  4. How to debug ?

PreRequests: a general understating of javascript and jQuery.

1- What is a widgetVar ?

widgetVar is the name of the client side variable that has various responsibilities like progressive enhancement of the markup, communication with the server side via ajax and more. For example it adds style on the fly to the DOM instead of rendering them with the markup, this helps reducing page size and less cpu cycles.

Most of the PrimeFaces components have the same structure, markup and a script. Script is actually a javascript object that belongs to PrimeFaces.widget.*  namespace.

In order to see the final output of the component in browser, the component goes through a flow.

  • Component as JSF<p:dialog id=”dialog1″ header=”Basic Dialog” widgetVar=”dlg” />
  • converts into- HTML<div id=”form:dialog1″ title=”Basic Dialog”> </div>
  • Javascriptdlg = new PrimeFaces.widget.Dialog(‘form:dialog1’, {});

what-is-widgetVar

This JS object is the backbone of the JSF component on the client-side.

 

2- What the objects are made of  ?

In general most of the components have functions and properties based on the desired behavior as any normal object does. In PrimeFaces there’re shared functions and properties among these objects, in result of extending the PrimeFaces.widget.BaseWidget. See here

Functions
  • init()   As the name indicates, Called by the constructor.
  • getJQ()  A wrapper funtion to the jQuery object, as if selecting with $()
  • refresh() Refreshes the component after re-configuring.
Properties
  • id   The generated ID of the component. If the component is a child of a naming container (ex. form) it would beformId:componentId
  • cfg  An object of configuration. This object define exactly how the component should behave.
  • jq jQuery object. getJQ() would return it.
  • jqId The full qualified jQuery Id to be used inside $()  function or jQuery()  (ex. #formId\:componentId ).

3- What to expect from this API ?

All light-wight client-side modifications/manipulations could be done with this API (keeping in mind, changing the component client-side will not be reflected to the JSF component tree permanently).

Changing the behavior on the fly based on versus scenarios the application might run into, without the need to call the server or triggering a partial update.

For example, selecting all the checkboxs, changing the poll frequency time and so much more.

What happens if you don’t declare a widgetVar for your component ?

Each component on the client-side must have a representative object (well not all, see who has a widgetVar), basically PrimeFaces generates the widgetVar’s name based on the following “equation”.

"widget_" + componentId.replace(/:/g, "_")

lets take an example,  an inputText with the id “myInputTextId”

<p:inputText id="myInputTextId" />

Notice that we didn’t specify a widgetVar name for the inputText, so the widgetVar name would be: widget_myInputTextId

This variable is placed in the global scope, so you can access it through:

window["widget_myInputTextId"]

OR from the namesapce of PrimeFaces “widgets”

PrimeFaces.widgets['widget_myInputTextId']

OR the shortcut for the previous namespace

PF('widget_myInputTextId')
[table id=1 /]
   /**
     * BaseWidget for PrimeFaces Widgets
     */
    PrimeFaces.widget.BaseWidget = Class.extend({

        init: function(cfg) {
            this.cfg = cfg;
            this.id = cfg.id;
            this.jqId = PrimeFaces.escapeClientId(this.id);
            this.jq = $(this.jqId);

            //remove script tag
            $(this.jqId + '_s').remove();
        },

        //used in ajax updates, reloads the widget configuration
        refresh: function(cfg) {
            return this.init(cfg);
        },

        //returns jquery object representing the main dom element related to the widget
        getJQ: function(){
            return this.jq;
        },

        /**
         * Removes the widget's script block from the DOM.
         *
         * @param {string} clientId The id of the widget.
         */
        removeScriptElement: function(clientId) {
                $(PrimeFaces.escapeClientId(clientId) + '_s').remove();
        }
    });

4- How to debug ?

Google chrome console is your best friend, make sure you follow the detailed instruction on how to get started using the console.

Go to PrimeFaces Demo page,  open your Google chrome console and try to typePrimeFaces , hit enter:
PrimeFaces-console-object

You would have an Object with some functions and properties, expand the object by clicking on the arrow Arrow AM

PrimeFaces-object-expand

In that main object of PrimeFaces, there’re some handy functions and objects you might need to use, an example would be to know the type of the client browser.

In the console, type: PrimeFaces.browser

PrimeFaces-browser

How can I know the functions and the properties of the components ?

All the components belong to PrimeFaces.widget.*   namespace, so trying to type PrimeFaces.widget.  in the console:
PrimeFaces-widget-namesapce

As you can see, chrome would give a suggestion of what you can have. Here you can find all the components.

To see the list of the functions and properties, for example selectBooleanCheckbox, type: PrimeFaces.widget.SelectBooleanCheckbox.prototype

selectbooleancheckbox-prototype
The first function is check()  obviously it would mark the checkbox as checked… keep this function in mind. We will use it later.

What’s that got to do with the widgetVar ?

The widgetVar is an instance of one of these objects, when you give a selectBooleanCheckbox a widgetVar name, lets say selectBooleanCheckboxWV , this variable has all the functions and properties of the Class we have seen before.

Go to selectBooleanCheckbox demo page, you have two checkboxs, inspect the first one.

 

You can see right away the highlighted node, take the closest parent id and keep it in your mind, in my case it’s j_idt87:j_idt90

Where’s the widgetVar of that checkbox ?

In this page the widgetVar is not specified for this component, if you take a look of the jsf xhtml code of that checkbox, you would find only a value attribute.

Now as I have mentioned before (in section 3), even if you don’t specify a widgetVar name for your component, PrimeFaces will generate one.
Using this function:

"widget_" + componentId.replace(/:/g, "_")

It will replace each :  with an _ , so back to our inspected id: j_idt87:j_idt90 applying the widgetVar function to it, the outcome would be widget_j_idt87_j_idt90 .

Type in your console PrimeFaces.widgets.


A suggestion would come up with all the variables start with ‘widget’, our checkbox widgetVar is the bordered one.

Select it and add a single .

 

All the functions and properties are shown in detail (you can see also “private” access variables, not as the prototype would result)

Now it’s time to use the check() function we explored before, in your console type:

PrimeFaces.widgets.widget_j_idt87_j_idt90.check()
//you might have another widgetVar name, depends on the generated id

 

As you can see that the checkbox is checked now.

 

PrimeFaces Versions and WidgetVar

 In PrimeFaces 3.5 and 4.0 all the widgetVars are global objects, meaning you can access the checkbox directly by name:

widget_j_idt87_j_idt90.check()// PrimeFaces 3.5 and 4.0

In PrimeFaces 4.0 a shortcut has been introduced to the library, prefacing to delete the objects from the global access, that shortcut is PF

PF = function(widgetVar) {    	
    	var widgetInstance = PrimeFaces.widgets[widgetVar];
    	
    	if (!widgetInstance) {
	        PrimeFaces.error("Widget for var '" + widgetVar + "' not available!");
    	}
    	
        return widgetInstance;
    };

In PrimeFaces 5.0 they have limited the access globally, so instead of calling the widgetVar by name, you should call it with the shortcut, or with the full namespace we used before.

Widget for var X not available
if you have this message you probably didn’t get the widgetVar name right, or if you try to access some objects in the document.ready causing an early access to that object which is not ready enough, like uploadFile, in that case you might want to use setTimeout

widgetVar call formats

PrimeFaces.widgets.widget_j_idt87_j_idt90.check()
PrimeFaces.widgets['widget_j_idt87_j_idt90'].check()
PF('widget_j_idt87_j_idt90').check()

 

– Conclusion

The PrimeFaces’s Javascript API has no official documentation online, you have to debug as you have seen before to see what might come handy for you, also you can explore the source code of this api.

Note: these tests are on PrimeFaces 5.0

If you think something is wrong please feel free to comment :)
  1. Mohankumar says:

    Great post!! liked it so much

    Reply
  2. Sir Efrax says:

    thanks a lot by this information are very useful for my

    Reply
  3. Oguz says:

    Really nice post, thank you!

    Reply
  4. GSL says:

    I ran into an issue in trying to display the widget auto-complete within the console to obtain a list of available widget vars. Instead of just typing widget and getting the auto-complete drop-down menu, I got “undefined”. I had to type in PrimeFaces.widgets.w which then gave me the list of widget vars which included (in my case) widget_j_idt87 for a button widget on the PrimeFaces Showcase. It also appears in the last figure prior to your conclusion that you are also getting “undefined” when you don’t use the prefix that I describe.

    Reply
    • Hatem Alimam says:

      Yes, it’s probably you are using PrimeFaces 5 which has the shortcut PF for the widgets. You won’t find the widgets anymore on the window scope.
      I have updated the post into the latest PF 5.

      Reply
  5. daVe says:

    Thaaaank you very much.
    A very interesting PF/Js information, and you’ve open my eyes about the console!! I have no idea I was able to do all that things. It’s not just a log window, it’s a console indeed xD

    😉

    Reply
  6. mccamberos says:

    Very usefull article. Save my day! 🙂

    Reply
  7. This was a very informative!!! Thank you

    Reply
  8. Vadim says:

    Thanks Hatem!

    Your article is an invaluable aid for developers starting to work with the PF.

    Reply
  9. Henry Sasse says:

    Nice introduction to the PrimeFaces widgetVar and the Google Javascript console. Thank you!

    Reply
  10. Marco says:

    Very informative article.
    I would just point out that the widgetVar can also be easily accessed in server side code just by calling “resolveWidgetVar” on any Primefaces widget. This shows to be quite useful if you have widgets inside iterating components (ui:repeat, p:dataTable, etc) and need simple programmatic behaviour (“RequestContext.getCurrentInstance().execute”)

    Thank you for sharing.

    Reply
  11. Bruno says:

    Very useful article. Thanks for sharing that !

    Reply
  12. zahra says:

    Thanks a lot, very usefull

    Reply
  13. Jack Chen says:

    Thanks,
    I read your post, and follow your steps to use PrimeFaces.widgets.widget_j_idt87_j_idt90.check at PrimeFaces Demo Page (http://www.primefaces.org/showcase/ui/input/booleanCheckbox.xhtml)

    But it doesn’t work, the check box won;t be checked successfully, is there any issue here?

    Reply
  14. tuga says:

    Very informative! thanks

    Reply
  15. Erick says:

    Very useful. Thank you very much.

    Reply
  16. Valentin says:

    Hi,

    Very nice post on widgetVar, thanks for sharing !

    Reply
  17. Great article! I had some knowledge regarding this (Primefaces) JavaScript library, but after reading this article, my concepts have become even better.

    Thanks

    Reply
  18. Alex says:

    Nice article and pretty well explained. Thanks.

    Reply
  19. Jeffrey V. says:

    Nice article. I’ve decided to use widgetVar on an assignment. I’m really having a hard time though finding additional information on this topic. Looks like your leading the way so far. It would be nice if you could do a follow up article with a deeper study on this topic. Or point us to an API. That would be nice… and very helpful. Thanks for putting this out there.

    Reply
  20. Hi Hatem,

    Thank you so much for this article as it is of great help to any developer who comes across PrimeFaces!
    Actually I used this with PrimeFaces 6.2 and it work as well.

    Cheers,
    Hugo.

    Reply
  21. Hello says:

    Thanks u very much

    Reply
  22. Jackson says:

    OMG, thank you so much for this explanation.

    Reply
  23. Ibrahim says:

    Très chouette article sur les widgetVar.
    J’ai toujours du mal avec PrimeFaces.
    Merci Hatem

    Reply

Reply to Hatem Alimam