Posts Tagged Ajax

Detect if JavaScript is enabled

Because of the emergence of Ajax, people don’t disable JavaScript much nowadays.
I don’t know the percentage of people having disabled JavaScript. It is likely under 5%. But if you have a website visited by millions of visitors every month, even 1% is matter!

This is why I wrote the following code:

<noscript>JavaScript is DISABLED.</noscript>
<span id="displayIfJavaScript" style="display:none">JavaScript is ENABLED.</span>

<script>
document.getElementById('displayIfJavaScript').style.display = "block";
</script>

The text under the noscript tag will be displayed if JavaScript is disabled or not supported. The text under the span tag is not displayed by default and will be showed using JavaScript, this is why we can be sure JavaScript is enabled in that case.
You can obviously change the content of the noscript and span tags. You could, for example, hide a form which uses JavaScript validation to non-JavaScript users by putting the HTML code of the form under the span tag.

Please see below the above script in action:

, ,

No Comments

The selfRendered attribute

This is an interesting problem related to the RichFaces rich:suggestionbox tag.

Let’s take the following code:

<rich:suggestionbox for="q" minChars="1"
    suggestionAction="#{myBean.mySuggestionAction}" var="result"
    limitToList="true">
    <h:column>
        <h:outputText value="#{result}" />
    </h:column>
</rich:suggestionbox>

If you use the code above as it is, the whole page is going to be processed each time the suggestionAction is called. And because the minChars attribute is set to 1, the action is going to be called each time the user enters a character! ๐Ÿ˜ฎ
For obvious reason, such as performance issue, this is not ideal.

To avoid this behaviour, you simply need to set the attribute selfRendered to true as shown below:

<rich:suggestionbox for="q" minChars="1"
    suggestionAction="#{myBean.mySuggestionAction}" var="result"
    limitToList="true" selfRendered="true">
    <h:column>
        <h:outputText value="#{result}" />
    </h:column>
</rich:suggestionbox>

Here is the description of the selfRendered attribute from RichFaces documentation:

If “true”, forces active Ajax region render response directly from stored components tree, bypasses page processing. Can be used for increase performance. Also, must be set to ‘true’ inside iteration components, such as dataTable.

Don’t hesitate to add this attribute to increase the performance of your website. ๐Ÿ˜‰

, , ,

No Comments

The message tags of MyFaces and RichFaces

Working on an application using MyFaces and RichFaces, I had no choice but understand what is the difference between the message tag provided by Myfaces (h:message) and the message tag overridden by RichFaces (rich:message).

These tags allow to display information about the first FacesMessage that is assigned to the component referenced by the “for” attribute. The difference is that the RichFaces tag has some extra functionalities such as Ajax rendering, error markers and predefined css class names.
Have a look at the following page for more details: http://livedemo.exadel.com/richfaces-demo/richfaces/message.jsf

This is all nice and well but it is not the only difference. Indeed, the HTML code generated by both these frameworks will also be different!

First of all, let’s see how the tag <h:message styleClass="errormsg" for="element"/> will be transformed. If there is no message to display, nothing will be generated (which is a good behaviour). However, if a message is present, the tag will be replaced by the following HTML code:

<span class="errormsg">Required.</span>

So far, so good!

But now let’s check what code RichFaces is generating for the tag <rich:message styleClass="errormsg" for="element"/>.
The following is the code created if there is NO message to render:

<span class="rich-message errormsg" id="form:j_id255">
    <span class="rich-message-label"></span>
</span>

And here is the code which will replace the RichFaces tag if there is a message to display:

<span class="rich-message errormsg" id="form:j_id255">
    <span class="rich-message-label">Required.</span>
</span>

As you can see, the main difference is that RichFaces is wrapping the original span tag into another span tag. But, it is also generating some code even if there is no message to display! You would ask why is it doing that? The response is simple. The wrapper span element is necessary for RichFaces to Ajax-render the message tag if an error message has to be displayed for the targeting element.

So make sure you don’t put any padding or margin style in your custom CSS class which I called ‘errormsg’ in my example. Otherwise, you might have a gap when you were expecting nothing… (this happened to me) ๐Ÿ˜‰

, , , , , ,

1 Comment

limitToList attribute prevents flashing

If you have some elements (or even the whole page) that flash/twinkleย using RichFaces, it probably means that these elements are AJAX-rendering. The question is by whom and how to fix it?

A lot of tags in RichFaces can AJAX-render elements such as:

<a4j:form>
    <a4j:jsFunction name="updateName" reRender="showname">
        <a4j:actionparam name="param1" assignTo="#{userBean.name}"  />                  
    </a4j:jsFunction>
</a4j:form>

On the above example, the JavaScript function updateName will AJAX-render the element which has the ID showname.

In some cases, you would have some elements that would AJAX-render without asking them to do so!
I still didn’t figure it out why. ๐Ÿ™ (if anybody has an idea, please don’t hesitate to tell me!)

But, I found a way to prevent this!
You simply can add the following attribute to your tag:

limitToList="true"

You even can add it to the tags that don’t have a reRender attribute.
For example:

<a4j:form>
    <a4j:poll id="poll" interval="1000" limitToList="true" />
</a4j:form>

, , , ,

No Comments

No saved view state

How many of you did already get the following error when working with JSF?
I would be surprised if none of you got it at least once! ๐Ÿ˜‰

HTTP ERROR: 500

/web/home.htmlNo saved view state could be found for the view identifier: /web/home.html

RequestURI=/web/home.html

Caused by:

javax.faces.application.ViewExpiredException: /web/home.htmlNo saved view state could be found for the view identifier: /web/home.html
	at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:88)
	at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
	at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:151)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
	at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:341)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:83)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
	at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
	at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
	at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
	at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
	...

This very common error happens because your session has timed out. As you probably already know, JSF is storing the view state of your page in session. Obviously, when the session has timed out, it can’t restore the view state and so throws a ViewExpiredException.

The solution for this problem is to add the following lines in your web.xml file:

<context-param>
    <param-name>facelets.BUILD_BEFORE_RESTORE</param-name>
    <param-value>true</param-value>
</context-param>

When this initialization parameter is turned on, it changes ViewHandler.restoreView() to build the view before asking the StateManager for help.

However, if you are using RichFaces, for some reason this is breaking a few Ajax components! ๐Ÿ™
To be honest with you, I didn’t investigate in depth why these components don’t work with this parameter set to true.

What I did instead is to make sure the session actually never times out! ๐Ÿ˜‰
To do that, I am polling the server every 29 minutes (as my session time out is set to 30 minutes). Obviously, you can poll the server only every 59 minutes if you set your session time out to 60 minutes.

Here is the code I used to poll the server every 29 minutes:

<h:form>
    <a4j:poll id="poll" interval="1740000" limitToList="true" />
</h:form>

Note that the interval attribute is in milliseconds (29 minutes x 60 x 1000 = 1,740,000 milliseconds).

This solution is far from being perfect! Indeed, if, for example, a user doesn’t close his browser during the night, it means that we will have to keep the session opened during hours! ๐Ÿ˜
But, as far as I am concerned, it is still better than to throw an exception at the user face. ๐Ÿ˜‰

, , , , , , ,

2 Comments