Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Monday, 27 July 2015

Temporarily disable or conditional executing of PrimeFaces AJAX calls

Introduction

In JSF 2.0, the AJAX functionality is standardised in the specification and can be used in a consistent way between JSF implementations and component libraries like PrimeFaces.
With the addition of new functionality, new usage patterns become a habit. But new usages also brings more advanced scenarios with their own issues.

The situation I want to discuss today, is where you have the need for some partial screen update with AJAX but which you don't want in all situations. The conditional aspect which I referred to in the title of the text.

Problem description


Suppose you have the following screen area:


It contains the following elements from left to right
* A field to enter an existing code. When the end user leaves the field, the code is looked up.
* A second, read only field or label, where the description of the code is placed when it is an existing one.
* A button, which is only available when the first field doesn't contain an existing code and lets you add a new one.

Within the JSF page, the structure looks something like this.

<h:panelGroup id="codeArea">
    Code :
    <p:inputText value="#{codeBean.code}id="code">
        <p:ajax event="blur" listener="#{codeBean.onBlurCode}" update="codeArea"/>
    </p:inputText>
    <p:inputText value="#{codeBean.codeDescription}" disabled="true" placeholder="description"/>
    <p:commandButton icon="fa fa-plus-circle" actionListener="#{codeBean.addCode}" update="codeArea" disabled="#{empty codeBean.description}"/>
</h:panelGroup>

With the ajax tag within the input field, we can perform the partial screen update when we leave the input field. We need to update the complete group as the button needs to become disabled as we enter an existing code.

Conditional executing

This construct works perfectly when you tab out of the input field.  The blur event triggers the AJAX execution and the server side code checks if the code exists. Due to the partial screen update the button becomes disabled when the code doesn't exists or enabled when the code isn't found.

But there is a scenario which fails; when the focus is in the input field and we click on the command button.  You will found out that the click on the button is ignored.  

If we inspect what is happening in the network console of the browser; we see that there is an AJAX request to the server which corresponds to the blur event of the field.  But there is no request which corresponds to the click on the button.
This is because the blur event replaced the DOM element in the browser with another, for the end user identical component. So the click is on an element which no longer exist on the screen after the AJAX  completes.

So how can we solve this? Luckily PrimeFaces uses JQuery on the client side.  So when we could disable the onblur event execution in the case when we click on the button, we have a solution. And the good thing is that we can achieve this, quite easily.

The mousedown event is executed before the blur event. This is can bee seen by the following testing code. (thanks to mudassir)

So by adding the following code:

onmousedown="$(PrimeFaces.escapeClientId('frm:code')).off();"

We can remove all event handlers from the input field, and thus the click is executed.

Conclusion

Making the AJAX functionality can be easily achieved within PrimeFaces with the help of JQuery which is already available in the browser? In this text I showed you how you can disable the blur event in the case when you click a specific button but it will be active in other scenarios.



Monday, 8 June 2015

Focus HTML element after AJAX call with PrimeFaces


Introduction

The combination of AJAX updates to the screen and the focus of a field is more then once an issue for the developer. And this is not an issue of PrimeFaces, but comes with the fact of using AJAX.

This blog explains what you can due in the 2 most important scenarios what you normally encounter.

Problem description

Image you have on the screen 2 input fields, field A en field B.  There is an onBlur handler attached to field A which does a partial update of the screen, containing field B, with an AJAX call.

So what happens when the user is in field A en tabs out of the field? Leaving the field, results in the trigger of the onBlur handler. During the time that the AJAX calls is performed asynchronously, the browser performs the standard behaviour, and thus the focus is placed in the field B.

But then the AJAX call returns and results in updating the screen, and there are use cases where the developer decided to replace the field B. And since it is a replacement of the element in the DOM tree, the focus which was original in the field B is now lost because the field is replaced by another element.

Fixing focus issue

The first scenario describes the situation where the focus must be placed in a certain field which is updated by the AJAX call.  But it is always the same field regardless of the result of the server side code.

This can easily achieved by using the oncomplete attribute of the PrimeFaces widget who initiated the AJAX call.
This is JavaScript code which is performed when the AJAX call was successful (and thus there was no error) and the replacement of the DOM elements in the browser is completed.
So at this point the DOM tree is stable again and we can give a field the focus.

oncomplete="PrimeFaces.focus('frm:newProjectName');"

The above snippet places the focus in the newProjectName field when the AJAX is finished.

Conditionally define the focus

Another scenario is where the fields that needs to get the focus needs to be defined conditionally.  Lets examen this use case better with some screen example.



In the above case, we have a field to enter some kind of code.  And depending on the code, we sometimes needs additional information from the user.
So, there will be an AJAX handler (p:ajax) which call some java listener method to perform the server side functionality which defines if there is additional information needed. 

Initially the 'additional' field is disabled, so the focus is not placed in this field by the browser. And since the field is replaced by the AJAX call in the DOM tree, the focus would be lost anyway.

But from within the Java listener method, we can execute some JavaScript when the AJAX call is finished.  This is one of the great features of PrimeFaces.

So, by adding the following code in the Java method, we can place the focus in the additional field. And within Java it is easy when this focus must be placed there (the conditional aspect of this usecase)

RequestContext.getCurrentInstance().execute("PrimeFaces.focus('frm:additionalInfo');");

Conclusion

The focus and AJAX combination has some conflicts. In the Expert group for JSF 2.3, they are considering some additional tags to handle those situations.
Within PrimeFaces, we saw with 2 usecases that you can manage the problem with the usage of the excellent integration of JavaScript within PrimeFaces. This from within the view (JSF pages) as from within Java.

Have fun.

Tuesday, 8 October 2013

How to debug javascript in PrimeFaces 4.0

Introduction

With each new release of PrimeFaces, the JavaScript becomes more and more important in the framework.
This is no surprise as JavaScript is needed to give the end user a rich user interface. And in the latest release there is quit a lot of new JavaScript code added for the client Side validation framework.
But if you want to debug it in the browser, you see that the code is minified. And thus stepping through it line by line is not possible.
This post describes how you can do it.

Build custom version

The source code of PrimeFaces contains the human readable code and the idea is that we build a custom jar file which contains that readable version of the JavaScript.
As the code is open source, it is available on Google code. We can do a checkout with following command.
svn checkout http://primefaces.googlecode.com/svn/primefaces/tags/4_0

Now we go to the pom.xml file and make some small changes.
The most important one is the change of the version tag.  I have changed it to 4.0-DEBUG (you can find it at the top of the pom.xml file)
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <packaging>jar</packaging>
    <version>4.0-DEBUG</version>
    <name>primefaces</name>
    <url>http://www.primefaces.org</url>
PrimeFaces uses a maven plugin to generate the JSF components and configuration files. 
This plugin is located in the PrimeFaces maven repository which you must include into the pom file. Otherwise the build will fail.
    <pluginRepositories>
        <pluginRepository>
            <id>primeFaces_repository</id>
            <url>http://repository.primefaces.org/</url>
        </pluginRepository>
    </pluginRepositories>
When you now execute the mvn install command, you will have a customized version of PrimeFaces in your local Maven repository which contains the non minified version of JavaScript.

Using this version in your project, by specifying it in a profile so that it doesn’t go into production, you can do debugging in your favourite browser.

Conclusion

We following the above steps, you have a custom version of PrimeFaces where the JavaScript is not minified and thus can be debugged in the browser. Of course it is not suited to go to production with this version.