Showing posts with label AJAX. Show all posts
Showing posts with label AJAX. Show all posts

Wednesday, February 12, 2014

JSF 2.2 Tip of the Day: Using JSF AJAX Events

Please wait...

Introduction

The JSF framework provides an easy to use AJAX event handling mechanism. The jsf.js library is included in Mojarra and MyFaces. There are two particular methods of interest: jsf.ajax.addOnError(callback) and jsf.ajax.addOnEvent(callback). I will be covering the latter handler.

The JsDoc does not really explain the jsf.ajax.addOnEvent(callback) code very well. Since it is Javascript, you can read it, but I think a simple example of its flexibility with some comments might work better.

Using the addOnEvent is very simple. You register the callback, and it gets called during the lifecycle. The important thing here to remember is that the callback must be a function. Otherwise, it will throw an error. You can control what event processing occurs during the lifecycle.

Events

The callback is invoked during the AJAX request and response lifecycle. The status passed to the callback are listed below.

Event Description
begin This is the start of the AJAX request.
complete This is invoked right after AJAX response is returned.
success This is invoked right after successful processing of AJAX response and update of HTML DOM.


Based on the status, we can take appropriate action on the AJAX event. A great example to demonstrate AJAX event handling is to provide feedback to the user to indicate the status of their request. I will demonstrate how to create an AJAX based progress loader to demonstrate the events.

Code

The code for our AJAX loader is very simple, and could be moved into a composite component if necessary. The NetBeans developed Maven project can be downloaded from the references section below.

index.xhtml



This code controls our progress bar by making changes to the CSS in DOM. The CSS idea is not mine, but it is clever. Here is the CSS.

loader.css



A simple CSS layout, and our Javascript callback to jsf.ajax.addOnEvent(callback) is all it takes to make a cool progress loader.

References

Monday, September 09, 2013

JSF 2.1 Tip of the Day: Creating a Custom Switch List

I found some code where I was tweaking on an example that Jim Driscoll wrote as a series of articles on Java.net.

I decided that I should publish it along with the references to the other articles.

JSF has a number of component frameworks available from groups like PrimeFaces and RichFaces. These are better choices than this code to accomplish the same thing.

However, you don't need all the additional code to do the same thing with plain old vanilla JSF. You will just need to write all the code.

The code for this project can be found here: switchlist-example

index.xhtml



ListHolder.java



References

Tuesday, August 06, 2013

JSF 2.x Tip of the Day: jsf.js AJAX onEvent() and onError() Examples

I was looking for some information on what I could do with the jsf.js AJAX scripts in JSF. Specifically, I was wondering if I could do some event handling, and how it should be accomplished. I was surprised that there really was not a complete example that I could find. I did find some blog posts from Jim Driscoll and some comments on stackoverflow by +Bauke Scholtz which show a partial solution, but nothing complete.

I decided to combine the good parts of Jim's blog post with some of the goodies from +Bauke Scholtz to create a complete example. In this example, I use a solution from Jim to demonstrate the events that are returned from the onEvent() and onError() listeners.  Along with a common request... A spinner for AJAX requests.

Once you download, and run the code. You will see a spinner while the AJAX request is processing. In my case, I use a Thread.sleep(2000); to cause the spinner to display for a little while.

The code for project can be found here: jsf-ajax-demo

index.xhtml



IndexBean.java



References

This is based on the primarily on the work published by Jim Driscoll and Bauke Scholz. This is just a more complete example  of what they mentioned in their articles.

Tuesday, January 08, 2013

Internet Explorer 9 (IE9) Table White Space Issues

I was tasked with fixing a problem in our product where one of our data tables (HTML) was rendering on IE9 with spaces randomly scattered throughout the table this resulted in the data being in the wrong columns, or headers appearing in the wrong place. I originally thought I might there might be "holes", or null values in my data which was resulting in the error. I was wrong.

It is actually a bug in IE9.

The issue shows up, most often, when using AJAX when there is partial page rendering. It seems according to forum remarks to be focused on white space between table tag elements like line breaks, spaces, or carriage returns. So if you use HTML tidy, you will screw up your output. Nice one Microsoft!

Fortunately, there are "fixes" out there to help you get along. Here is the fix which I slightly modified from an answer on stackoverflow. A shout out goes to Blago for his recursive function listed below.

You can implement it this way.
Here are some references on the issue if you are interested.

Monday, September 10, 2012

JSF 2.1 Tip of the Day: Using <iframe /> Elements with PrimeFaces

Carousel and LightBox
We have some requirements on a project I am working on to display <iframe /> elements which are connected to external pages within our JSF pages. Since JSF supports template language such as plain HTML, we could directly use an <iframe /> in the page. However, it would not match up with our existing page layouts.

PrimeFaces offers a component called a Light Box (<p:lightBox />) which supports <iframe /> elements directly. You can see an example from the PrimeFaces showcase for how to use it.

I thought I would share a more interesting approach using a <p:caraousel /> object to display multiple <iframe /> elements in a more "sexy" approach.

The cool thing is that the code is really easy to implement!

The code was developed using NetBeans 7.2 and Apache Maven. The code can be downloaded here: iframe-example.zip

code


Saturday, September 08, 2012

JSF 2.1 Tip of the Day: PrimeFaces 3.4 Advanced Table Example with JPA

PrimeFaces 3.4 Data Table
I was working on an example table to demonstrate some of the PrimeFaces data table capabilities. I think I may use it as an interview problem: "Create an advanced table with the layout seen in this picture using JPA".

The example was developed using Maven on NetBeans 7.2. The source code can be downloaded from here: advanced-table.zip.

Index.xhtml


Wednesday, August 15, 2012

JSF 2.1 Tip of the Day: PrimeFaces Dialog <p:dialog/>

We have been doing a lot of work lately with PrimeFaces. A common set of questions comes up about displaying <p:dialog/> boxes on a page.
  1. How do I update elements on the page outside of the dialog?
  2. How do I include information from external pages?
  3. Can I nest forms and dialogs?
The last one is the easiest to answer: NO. You may get away with it in some cases, but the HTML specification does not allow <form> tags to be nested inside other forms. So your dialog can contain a form, but should be outside of the form that opens it.

Some components do not need to live inside a <form> to work. For example <h:button /> tags do not need to be inside a <form>. You can update <h:outputText /> elements outside a <form> with AJAX.

The second question is also easy. Using <ui:include /> you may add other JSF content to your dialog. You could also use a <ui:decorate />, <ui:component />, <ui:define />, or <ui:composition />. I personally like <ui:include />

The first question is best answered with some code. I have some interesting tidbits of code in here including using String concatenation in Expression Language (EL). The key to updating elements on the page comes from the update attribute on the <p:commandButton /> elements.

The project and code I have included below were developed using NetBeans 7.2 IDE on GlassFish 3.1.2.2, and PrimeFaces 3.3.1.

The code can be downloaded here: primefaces-dialog-examples.zip


IndexBean.java


Thursday, July 05, 2012

PrimeFaces AJAX Enabled <p:selectOneMenu />

I saw a question posed on stackoverflow called Trouble with Primefaces 3.0.M2 SelectOneMenu Ajax behavior and I had just done an example a couple of months ago on a car trip so I decided to post my solution here, and reference it.

Essentially the problem is how to control the list of items in a second <p:selectOneMenu/< from the selection made in the first menu. The question comes up frequently enough that I decided to write up a demo application.

The application was developed using NetBeans 7.1.2 and PrimeFaces 3.2 originally. It has been updated to use PrimeFaces 3.3.1 which is the most current at the time of writing. I validated it on GlassFish 3.1.2.

 The Apache Maven project can be downloaded from here: primefaces-ajax-selectone.zip

This demo wants the user to pick a state, and then a city. A key problem is not just the update, but not displaying city values if a state is not selected. Also erasing the selected city, if the state has changed.

index.xhtml



DataBean.java


Thursday, January 12, 2012

JAX-RS Tip of the Day: Client Content Negotiation

One of the less discussed aspects of JAX-RS based on the HTTP 1.1 specification is client negotiation. We often write our applications from the server side and expect the client to send us an Accept: */* header which details which media types the client can accept. The server simply returns whatever we have coded for example @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}). However I bet a number of you have seen something like this before:
http://www.example.com/documents/mydoc?format=doc
http://www.example.com/documents/mydoc.xml
The first example is not very subtle. It tells you the client wants a mydoc.doc by requesting a specific format. The second example is more subtle, and the end user (client) may not notice. I made it a "little" more obvious by changing it to .xml. However, most folks would have missed it if I used mydoc.doc. You would have assumed it was a MS Word document to start with. In actuality, the media type returned here is controlled by the file extension.

Note: Updated the source code to include header based negotiation, but this is just mimicking server content negotiation.

In the attached Apache Maven project developed on NetBeans 7.1: jersey-content-negotiation.zip. I demonstrate how to do it.

The first example returns JSON by default, and other media formats as requested. If it does not understand the media type requested, it simply returns plain text.

On the second example which uses the media type extension, I return a 400 - Bad Request instead of plain text like the first example. This subtlety is based on the fact that the client is requesting a specific type based on extension. If you ask for .pdf and get .txt, the result may cause an unanticipated consequence so it is better to throw an exception.

The mixed media type returns are possible because of the Response being wrapped as demonstrated in a previous post: JAX-RS Tip of the Day: Use Response to wrap... Responses.

ContentNegotiationResource.java



Client Negotiation Examples

Wednesday, January 11, 2012

JAX-RS Tip of the Day: Use Response to wrap... Responses

One of the really nice features of JAX-RS is the ability to implement fine grained control over the response returned from the server based on the client request. The Response.ResponseBuilder gives us incredible flexibility to generate the response. Since it uses the builder pattern, it is easy to daisy-chain the information we want into a custom response.

I would highly recommend that you consider returning a custom response for all requests. I would like to explain with an example. I would like to perform a @POST request where I am creating a new object on the server. Since it is a HTTP 1.1 request, I look at Hypertext Transfer Protocol -- HTTP/1.1 (RFC-2616) to see what I must, should, and may return. The difference in the word choices has specific meaning in the specification. In my case, I would like to be completely compliant.

10.2.2 201 Created
The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead.
A 201 response MAY contain an ETag response header field indicating the current value of the entity tag for the requested variant just created, see section 14.19.

OK, the basic response must return 201 - Created status, and a Location header. It should contain an entity (which may only be entity-headers) and may contain an ETag. This is all very easy to do with Jersey. As you can see from the code snippet, we read the @FormParam information from a form, and create an object which we add to a List<Widget%gt; objects signified by the ws.add(widget) we get the index value for use in our URI. Next we create a URI from our request, and add a path to it for our index.

Finally we use Apache Commons Codec Hex to generate a hex string for our ETag. Finally this is all combined in a Response sent back to the client. This can be seen below.

Tuesday, January 10, 2012

Interesting Articles on JAX-RS

What do I Read?

I was asked what articles I really like on Jersey, and how to learn more about it. Here is an incomplete list.

If you find more really good ones, please post comments, and I will add them to the list if I like them.

Thursday, January 05, 2012

JAX-RS Tip of the Day: Using @CookieParam

I am not a fan of using cookies in REST based services. I think that it makes the service less usable since the client must be able to store and retrieve cookies. This limits usage of the service, and introduces state outside of the service. Even the RFC for cookies is called HTTP State Management Mechanismcurl can be used to send cookies to test so not all is lost.

Alright, if I have not talked you out of using them yet, you must have a need for them.  (Please rethink the idea though).

Use of cookies is accomplished by using the @CookieParam annotation. Also you can return responses as shown in the code below which include cookies.

Cookies have a limitations on the use of some characters, and names so please look at the RFC noted above for additional limitations. I demonstrate a couple of limitations which include the use of semi-colons (;), and commas(,). The nice thing about this example is you can see the output in a real browser (Internet Explorer not included) since most can handle application/json objects which are returned.

Here is the example code developed using NetBeans 7.1 RC2 and GlassFish 3.1.1cookie-parameters.zip

CookieParameterResource.java


Saturday, December 31, 2011

JAX-RS Tip of the Day: Using YUI2 and YUI3 DataTables with Jersey and jQuery

This is a great example (if I do say so myself) that demonstrates some really cool capabilities of Jersey combined with Yahoo User Interface versions 2 and 3 combined with jQuery to demonstrate interoperability of multiple technologies.

The example code that I have included uses GlassFish 3.1.1 with Jersey 1.11 and was developed using NetBeans 7.1 RC2. The data is from the default sample database included in NetBeans. Here is the code: jsonp-database.zip

The YUI2, YUI3, and jQuery libraries are provided by Yahoo and Google CDN. This is a further example of a truly RESTful application where the application is provided as a mashup of multiple web resources.

Yahoo User Interface (YUI) is an incredibly well developed UI framework for the web. The DataSource implementation is easy to use and is extremely adaptable. It is also very stable, and Yahoo eats its own dogfood like Google so it is battle tested. YUI3 is the next generation code, and the DataTable implementation includes a number of new features.

jQuery is an extremely popular Javascript framework with great AJAX functionality. I have included two examples (YUI2/YUI3) in which jQuery provides JSON data to the Yahoo DataSource.

Jersey provides the heavy lifting. In all of the examples I provide the data in a variety of formats, but I focus on providing both JSON and JSONP. JSONP allows us to use have cross-domain capabilities. The code also demonstrates how to use Jettison to encapsulate POJOs. The best part is that the data can be tested not only using your browser, but can also be tested using curl. This provides a very simple visual means of verifying data.

So what does it look like... look at the images below. The results speak for themselves.

YUI2 DataTable using JSP

YUI3 DataTable with JSONP and JAX-RS (Jersey)

Now for the most important part, how do you get here.

Technical Details

The CustomerFacadeREST class is the most interesting. The JSP and HTML pages have the details of how to use the various YUI DataSources along with jQuery. I will not print the pages out, and suggest that you simply download the code and examine it.

CustomerFacadeREST.java



CODE


Here is the code: jsonp-database.zip

JAX-RS Tip of the Day: Changing JSON-JAXB Default Mapping

JSON-JAXB marshalling and un-marshalling by default uses a MAPPED configuration by default. However this can be changed by creating a @Provider which can change the default JSONConfiguration.

The example below changes the configuration to use BadgerFish which provides a better representation of an XML document. This representation does not provide the visual clarity that JSON generally provides, and is not generally human readable beyond basic notation. However, as noted that is not the point.

JSONJAXBContextResolver.java


This class specifically handles the Customer object, and maps it to use BadgerFish. Output:

Friday, December 30, 2011

JAX-RS Tip of the Day: Automatic Mapping of Jettison JSON Objects

One of the more interesting features in JAX-RS (Jersey) is the ability to automatically "wrap" POJOs. This combined with automatic wrapping of JAXB annotated beans, and using Jackson to create JSON objects is a powerful mix. However, sometimes we want to wrap an object, and add some additional metadata.

This tip is a very simple tip which allows you to create Jettison JSONObject, and JSONArray objects to create new objects, "wrap" existing objects, or add additional metadata. I mention "wrap" the objects, please don't confuse this with JSONP.

To enable automatic POJO mapping, and Jettison objects add the following to the web.xml
This simple configuration will give you considerable flexibility in how you handle your objects. This will now allow you to produce JSONObjects like the code example below:

Wednesday, December 28, 2011

Multiple File Upload Examples

I received an email today from a developer who was looking for examples of how to do multiple file uploads. I had written a post previously Multiple File Upload Options which detailed some of the options available. The option I recommended was Andrew Valums ajax-upload. The developer had indicated that the servlet I contributed was not working with Internet Explorer correctly. He was correct.

The code that I provided to Andrew Vallums was expecting application/octet-stream. However Internet Explorer and Opera were sending multipart/form-data. This would not work with the servlet example I posted since the handling mechanism is considerably different.

Alan O'Driscoll and I discovered the differences using Wireshark to sniff the packets and see what was being sent over the wire. As a result, I have written a new servlet to handle the differences between browsers.

The example application I wrote has a number of different examples included with minor variations on the theme. The version most folks are interested in is example #6 which uses the ajax-upload, and the new servlet. Here is the Apache Maven project which was developed on NetBeans and tested on GlassFish v 2.1.1.

Here is a link to the Mercurial project: apache-file-upload-ee5.

Here is another resource for file upload plugins: 9 Powerful jQuery File Upload Plugins. I discovered it while I was looking for something else.

MultiContentServlet.java


Tuesday, July 05, 2011

JSF 2.x: Creating a Pure AJAX Application with Apache Tomahawk

Official logo of Greenville, South CarolinaImage via Wikipedia
I was working on creating an application to make calls to a MongoDB database. I was having some difficulties getting the REST based services to work. I decided to make sure that my coding principles were sound so I wrote this application.

The application uses Expression Language (EL), and "pure" JavaScript (no JS frameworks).

Disclaimer: There were no-frameworks harmed in the making of this application.

The application makes an AJAX call to a GeoNames web service called http://api.geonames.org/weatherIcaoJSON?ICAO=KGSP which returns the weather information for Greenville-Spartanburg (Greenville, SC) Airport. There are some other examples which demonstrate some of the things you can do in Expression Language (EL), and how to inject it into JavaScript.

The application I believe demonstrates that you can JSF without managed beans, and make separate AJAX calls to populate the page with data. This is not a normal method of creating a JSF application, but does demonstrate the flexibility of the JSF framework.

The application was done using Apache Maven on NetBeans 7.0 IDE. The source can be downloaded here: jsf2-tomahawk2.zip

Requirements
  • NetBeans 7.0 (You could use just Maven)
  • Apache Maven 2.2+
  • Internet Connection (Required if dependencies are not on system)

index.xhtml



project.js


/*
 * Copyright 2011 Blue Lotus Software, LLC.
 * Copyright 2011 John Yeary.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var weather;
var weatherJSON;

function ajaxWeather() {
    if (!document.getElementById('panelTab1.content').hasChildNodes()) {
        return;
    }
    var url = 'http://ws.geonames.org/weatherIcaoJSON?ICAO=KGSP';
    var xhr;
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else {
        alert('You are using Internet Explorer. Switch to a real browser!');
    }
    xhr.onreadystatechange=function(){
        if (xhr.readyState == 4 && xhr.status == 200){
            weather = xhr.responseText;
            weatherJSON = eval('(' + weather + ')');
            document.getElementById('panelTab1:unavailable').textContent = '';
            document.getElementById('panelTab1:stationName').textContent = weatherJSON.weatherObservation.stationName;
            document.getElementById('panelTab1:ICAO').textContent = weatherJSON.weatherObservation.ICAO;
            document.getElementById('panelTab1:latitude').textContent = weatherJSON.weatherObservation.lat + "\u02da";
            document.getElementById('panelTab1:longitude').textContent = weatherJSON.weatherObservation.lng + "\u02da";
            document.getElementById('panelTab1:temperature').textContent = weatherJSON.weatherObservation.temperature + "\u02daC";
            document.getElementById('panelTab1:humidity').textContent = weatherJSON.weatherObservation.humidity +"%";
            document.getElementById('panelTab1:windSpeed').textContent = weatherJSON.weatherObservation.windSpeed + " knots";
            document.getElementById('panelTab1:windDirection').textContent = weatherJSON.weatherObservation.windDirection +"\u02da"
        }
        if (xhr.readyState == 4 && xhr.status == 503){
            document.getElementById('panelTab1:unavailable').textContent = 'Weather service is unavailable. Please reload page';
        }
    }
    xhr.open('GET', url, true);
    xhr.send();
}

function setText(){
    if (document.getElementById('panelTab6:div1') != null) {
        document.getElementById('panelTab6:div1').textContent = msg;
    }
}

Enhanced by Zemanta

Friday, May 27, 2011

RichFaces 3.3 (Ajax4JSF) and Apache Myfaces Tomahawk AJAX Example

I was working on an application at the office which involved mixing RichFaces 3.3 along with Apache MyFaces Tomahawk. Although some JSF frameworks claim interoperability, it is best to test them out to confirm that they will work in your specific project.

In the example application attached, I have created a facelets based application which uses Tomahawk components combined with RichFaces A4J to provide AJAX support.

It is a simple demonstration using AJAX to answer a comical question of which came first, the chicken, or the egg. Here is the example code: a4j-example.zip

index.xhtml


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:t="http://myfaces.apache.org/tomahawk"
      >
    <head>
        <title>The Chicken or Egg Question...</title>
    </head>
    <body>
        <t:panelTabbedPane id="panelTabbedPane1" serverSideTabSwitch="true">
            <t:panelTab id="panelTab1" label="Questionable Panel">
                <h:panelGrid id="panelGrid1" columns="1">
                    <t:div id="div1">
                        <t:outputText id="outputText1" value="Which came first? #{index.value}"/>
                    </t:div>
                    <t:panelGroup id="panelGroup1">
                        <t:div id="div2" rendered="#{!empty index.value}">
                            <h:outputText value="I guess you know best don't you!"
                                          style="color: green; font-weight: bold;
                                          font-variant: small-caps; font-size: x-large"/>
                        </t:div>
                    </t:panelGroup>
                    <h:form id="form1">
                        <h:selectOneMenu id="selectOneMenu1" value="#{index.value}"
                                         valueChangeListener="#{index.selectOneMenuAction}">
                            <f:selectItems id="selectItems1" value="#{index.items}"/>
                            <a4j:support id="support1" event="onchange" reRender="div1,panelGroup1"/>
                        </h:selectOneMenu>
                    </h:form>
                </h:panelGrid>
            </t:panelTab>
            <t:panelTab id="panelTab2" label="Empty"/>
            <t:panelTab id="panelTab3" label="The Big Empty"/>
        </t:panelTabbedPane>
    </body>
</html>


Enhanced by Zemanta

Popular Posts