Multiple Beans are Eligible for Injection

Standard

In some cases you may want to inject a controller (another backing bean) into another controller. In Eclipse it will show a warning: Multiple beans are eligible for injection to the injection point. This may prevent your server from starting.

The solution is to provide CDI with the name of the property to inject. The @Named annotation is shown below:

@Inject
@Named("myController")
private MyController myController;

Now CDI will know the proper controller to inject.

(KCDC) Kansas City Developers Conference 2015

Standard

The following presentation was given at kcdc.info on June 25, 2015

Topic: Building a more responsive design with JSF + Bootstrap 3

Modern web design has placed an emphasis on lightweight, responsive oriented design. Utilizing libraries such as Bootstrap 3 CSS / Javascript as well as font awesome one can create elegant designs, quickly and efficiently. We’ll dive into some best practices I’ve extract from solving real world problems when merging JSF with Bootstrap 3. Areas of emphasis would be error handling, responsive modals, and utilizing HTML5 data attributes to make job easier.

I would like to thank all the people that attended my presentation. It was a great opportunity to be around so many other excellent developers.

Presentation slides can be found online here (KCDC Presentation).

 

Alternative to p:defaultCommand

Standard

Using the standard JSF h:commandLink has a limitation when wanting to submit the form when the enter button is pressed. This solution uses the javascript keyCode keyboardevent built into browsers. When keyCode 13 (or enter key) is pressed the h:commandLink (which renders a <a> tag) is submitted. This will call its action that has been attached to the component.

<h:inputText value="#{backingBean.searchString}" onkeydown="if (event.keyCode === 13) {
$('a.submitSearchButton').click();
return false;
}"/>
<h:commandLink id="submitSearchButton" action="#{backingBean.submit}" value="submit"/>

This solution is most useful when the Primefaces defaultCommand component is not available.

Calling Bootstrap 3 modal from JSF

Standard

Dialogs or modals can be used in JSF to create more dynamic, and interactive pages. This solution will show how to call a Bootstrap 3 modal from both a JSF commandLink, and a Primefaces commandLink. Each example uses a formId to update the modals content.

JSF h:commandLink

JSF implementation uses an onclick event, which shows the modal, then updates the form inside the modal. While the order of execution can be problamatic in that you could show stale data in your modal for a brief second; this solution will work for most cases.

<h:commandLink value="Show Modal" action="#{backingBean.doAction}"
    onclick="$('#myModal').modal('show');" immediate="true">
    <f:ajax execute="@this" render=":myForm"/>
</h:commandLink>

It also should be noted that using the h:commandLink component requires a backing bean action.

Primefaces p:commandLink

The Primefaces component library has expanded the attributes available in the p:commandLink.  This functions the same as the h:commandLink, but uses less code to accomplish the same task.

<p:commandLink value="Show modal" styleClass="btn btn-primary" onclick="$('#myModal').modal('show');" update=":myForm" immediate="true" />

Bootstrap modal

The modal is straight forward. A p:commandLink is used to close the modal, and a form is wrapped around all important content that needs to be updated.

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModal" aria-hidden="true" data-keyboard="false" data-backdrop="static">
    <div class="modal-dialog modal-sm">
        <div class="modal-content">
            <h:form id="myForm">
                <div class="modal-header">
                    <h4 class="modal-title">Test Modal</h4>
                </div>
                <div class="modal-body">
                    Content area
                </div>
                <h:panelGroup layout="block" styleClass="modal-footer">
                    <p:commandLink value="Close" immediate="true" styleClass="btn btn-default" oncomplete="$('#myModal').modal('hide');" />
                </h:panelGroup>
            </h:form>
        </div>
    </div>
</div>

Self managing your own modals may be more work than using a prebuilt component like primefaces dialog. But the benefit is that the modal is responsive, and you still have full control over the design.

Using Font Awesome icons as CSS content

Standard

Font Awesome is a great web font icon pack to use with the Bootstrap 3 framework. While the implementation suggests using the <i> element; this is not always beneficial.

The solution is to specify the icons using pure CSS. This can be accomplished by substituting content values for the relevant icon within the Font Awesome font-family.

Take this CSS class for example which uses the “check” icon.

.act-submit:before {
    font-family: FontAwesome;
    display: inline-block;
    content: "\f00c";
    padding-right: .4em;
}

Now using the <a> tag you can add a check icon to a Bootstrap 3 button

<a href="#" class="btn btn-primary act-submit">Submit</a>

A complete list of the Font Awesome icon content values can be found on this cheatsheet.

Implicit vs Explicit navigation in JSF

Standard

The use of navigation cases in JSF is somewhat subjective. This article will briefly discuss the differences, advantages, and disadvantages between implicit vs explicit navigation

Explicit Navigation

Navigation prior to JSF 2.0 required the use of explicit navigation cases. This means you would have to place all navigation rules in a “faces-config.xml” file. Take for example the following navigation rule:

<navigation-rule>
   <from-view-id>step1.xhtml</from-view-id>
   <navigation-case>
       <from-outcome>goToStep2</from-outcome>
       <to-view-id>step2.xhtml</to-view-id>
   </navigation-case>
</navigation-rule>

This example above could be used in JSF 1.2 to redirect from step1.xhtml to step2.xhtml. While the following implementation is simple, it fails to address many issues that can arise when developing larger applications.

What are the drawbacks of explicit navigation?

  1. Changing of file names can result in outcomes going to pages that do not exist
  2. A larger overhead especially if your application has complex conditions. This is due to it having to parse the XML to match the result from the action method
  3. Using JSF 1.2 meant navigation rules use a POST for page to page navigation which makes for a horrible user experience. Pages would not be bookmarkable; thus have bad SEO. Note: JSF 2.0 you can specify the <redirect /> attribute to a navigation-case to force a page redirect.

What are the benefits?

  1.  Only one location to find all your rules for navigation; no hunting through backing beans.
  2.  IDE has tools to draw the rules in a GUI. Gives you a visual of your available workflow.

Implicit Navigation

This advancement in JSF 2 made it so there was no need to declar navigation rules. Instead the outcome can be placed in the action attribute. JSF has the logic to find the correct view id. There are 2 ways to use implicit navigation.

Specifying a outcome in a JSF page

This solution is straight forward, you can specify the page name you wish to navigate to. The “xhtml” extension will automatically be appended.

<h:commandButton action="step2?faces-redirect=true" value="Navigate to step2.xhtml" />

Another option would be to use a h:link would use a get request to invoke a redirect

<h:link outcome="step2" value="navigate to step2"/>

Specifying a outcome in a Backing Bean

The JSF page calls a backing bean that has a outcome.

<h:commandButton action="#{backingBean.navigateStep2}" value="Navigate to step2.xhtml" />

Backing bean has a method which returns a string which is the outcome.

@ManagedBean
@ViewScoped
public class BackingBean implements Serializable {
 
	public String navigateStep2(){
	    return "step2?faces-redirect=true";
	}
}

What are the drawbacks of implicit navigation?

  1. Your business objects / backing bean logic becomes tied together, and can get messy
  2. Moving pages around can cause a lot of maintenance to update implicit routes.

What are the benefits?

  1. No hunting through a cluttered xml file to find navigation cases.
  2. Less overhead when looking up the outcome for a action.

How to skip Maven unit tests

Standard

All Maven unit tests are ran by default. When a test fails the project will not build. While this forces you to have a stable build of your project before deploying; it may not be ideal in some situations.

Skipping Over Failed Unit Tests

Within the in maven-surefire-plugin in your pom, specify the skipTests parameter

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <version>2.x.x</version>
   <configuration>
      <skipTests>true</skipTests>
   </configuration>
</plugin>

Now all tests will be skipped on the next build.

Using a comparator to sort 2 separate instances

Standard

Consider you have 2 separate classes; “dog” and “cat”. Both of these classes share a common interest in that they are animals. Each of these animals have a date of birth. In this example I will demonstrate how to merge 2 object arrays of both types (“dog” and “cat”) and sort them by their common property; date of birth.

Where might I need this?

In the case of needing both cats and dogs on the same dataTable in JSF this would provide a merged object array to iterate through.

The Code

Creating the abstract class “animal” to be extended by both the dog and cat classes. This abstract class defines what both a cat and dog have in common; a name.

public abstract class Animal {

    /**
     * All animals must have a name
     */
    protected String name;

    public abstract String getName();

    public abstract void setName(String name);

}

Both the cat and dog classes are very similar. For the purpose of this tutorial they both only have a date of birth.

public class Cat extends Animal {

    private Date dob;

    public Cat(String name, Date dob) {
        setDob(dob);
        setName(name);
    }

    public Date getDob() {
        return this.dob;
    }

    public void setDob(Date date) {
        this.dob = date;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

}

The dog class is identical to the cat class.

public class Dog extends Animal {

    private Date dob;

    public Dog(String name, Date date) {
        setDob(date);
        setName(name);
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    public Date getDob() {
        return this.dob;
    }

    public void setDob(Date date) {
        this.dob = date;
    }

}

The Solution

To sort both cats and dogs by date of birth first begin by creating a list of each type then adding a few objects to each. The code below adds 2 animals to each type. Then all objects are added to a list of object array. Using collection.sort comparator it checks which type of object is being passed. It then casts that object to its instance type and gets the date of birth. The final statement in the method is the compareTo function which compares the date of birth for each type. Using this approach you can see that you could easily add additional object array types and sort them all by a common date.

 List <Cat> cats = new ArrayList <> ();
 cats.add(new Cat("Chester", new Date(105, 9, 4)));
 cats.add(new Cat("Peaches", new Date(105, 8, 1)));

 List <Dog> dogs = new ArrayList <> ();
 dogs.add(new Dog("Willie", new Date(115, 2, 4)));
 dogs.add(new Dog("Buster", new Date(89, 3, 4)));

 List <Object> objects = new ArrayList <> ();

 objects.addAll(cats);
 objects.addAll(dogs);

 Collections.sort(objects, new Comparator <Object> () {@
     Override
     public int compare(Object m1, Object m2) {
         Date d1 = null;
         Date d2 = null;

         if (m1 instanceof Cat) {
             d1 = ((Cat) m1).getDob();
         } else {
             d1 = ((Dog) m1).getDob();
         }

         if (m2 instanceof Cat) {
             d2 = ((Cat) m2).getDob();
         } else {
             d2 = ((Dog) m2).getDob();
         }

         return d1.compareTo(d2);
     }
 });

 for (Object o: objects) {
     if (o instanceof Cat) {
         System.out.println("Name: " + ((Animal) o).getName() + " DOB: " + ((Cat) o).getDob());
     } else {
         System.out.println("Name: " + ((Animal) o).getName() + " DOB: " + ((Dog) o).getDob());
     }
 }

The following code is available on Github.

Why checkboxes in forms are emulated

Standard

If you have ever investigated the Primefaces datatable selection component you will find that the check boxes are not true html checkboxes but emulated with images. The code that is generated by the component looks similar to this.

<div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default">
   <span class="ui-chkbox-icon ui-icon ui-icon-blank ui-c"></span>
</div>

Why isn’t it making true HTML checkboxes?

The reason for this is implementation all has to do with caching. When a check box is formed in JSF or any other language for that matter it is given a name. If you were to use a JSF datatable and add a checkbox to each row with the same name it would generate the following in each row:

<input type="checkbox" name="myForm:0">
<input type="checkbox" name="myForm:1">

The issue with this is that these names can be reused. If you were to check myForm:0 , then perform an ajax event that removes the selected checkbox item from the list. Then browser would have no recognition of the item being removed. The browser cache will still believe that myForm:0 is checked. This is why the solution multiple checkboxes on the page is to emulate then with CSS.

What if I have to use true HTML checkboxes?

If you MUST use real input checkboxes then your solution is to disable caching on your browser. This can be accomplished using a web filter and modifying response headers.

Collapse.JS creating a dropdown icon on panel heading

Standard

By default Bootstrap 3 comes integrated with CollapseJS which offers expandable accordion like panels. These panels are very simple to setup and work great. However, since the font is uncolored it may not be obvious to some users that this panel expands.

Appears to be collapsible

Appears to be collapsible

Using pure CSS a dropdown icon can be placed on all panels that you create. The css places the icon after the link, and switches the icon to a down arrow once the panel has been expanded.

The CSS

.panel-heading a:after {
   font-family: 'Glyphicons Halflings';
   content: "\e114";
   float: right;
   color: grey;
}

.panel-heading a.collapsed:after {
   content: "\e080";
}

The result

The result is a more user intuitive collapsible panel. The main difference between using the Primefaces collapsible panel and the bootstrap js version is data accessibility. Primefaces will call a ajax event once the panel is to be rendered. Whereas CollapseJS will have already loaded the data from the backend bean. This may require you to update at the prerendered content manually, but the benefits of self managing the panels far outweighs the negatives.