; last updated - 18 minutes read

The open source branch of BootsFaces is still young. Only 14 months went by since the first release on Halloween 2014. But it's already an impressive success story. In November, we've seen more than 1.000 downloads from Maven Central and Bintray. Ed Burns mentioned BootsFaces in one of his talks at JavaOne. JSFCentral and Jaxenter.de have asked us to write articles about BootsFaces. Obviously, BootsFaces has stirred a lot of attention, and many projects use it for their daily work.

Since the Halloween 2014 release, we've published five releases. That's roughly a release every three months. The latest release took quite bit longer to finish. But it's loaded with a host of new features, so it has surely been worth the wait. Personally, I call it the AJAX release, because that's my big ticket. But there's more in store four you. Other big tickets are the advanced search expressions inspired by PrimeFaces and the theme support. Plus, BootsFaces 0.8.1 has six new components. Seven, if you count the experimental <b:dataTable />. But that not a finished component yet. However, I felt it already is useful enough to include it with BootsFaces, even if it still requires polishing and "sugaring".

But let's talk about first things first.

Download coordinates

BootsFaces is available in two different flavors. There's the regular version at Maven Central, and there's a highly-optimized version at GitHub. The optimized version is 50 KB smaller, requires Java 7 or higher and should be a bit faster. The version hosted a Maven Central is targeted at a broader audience. It only requires Java 6. Alternatively, you can check out the repository from GitHub and build BootsFaces from source.

Add these lines to your project's pom.xml:

net.bootsfaces bootsfaces 0.8.1 runtime


BootsFaces 0.8.0 vs 0.8.1

Actually, this article is a double announcement, covering both BootsFaces 0.8.0 and BootsFaces 0.8.1. Version 0.8.1 was originally intended to be a pure bugfix release. However, I when I started to fix the bugs, before long I noticed that many bug fixes affected exactly those classes I already had started to improve. So I merged my improvements with the master branch. This is why the 0.8.1 branch adds AJAX to <b:navLink />, and contains a new component (<b:flyOutMenu />). In any case, I recommend to skip the 0.8.0 version. I guess it's not a bad version - many of our beta testers worked happily with it - but 0.8.1 is a lot better. Especially, if you're fond of <b:switch /> and checkboxes.

AJAX

I always felt JSF supports AJAX poorly. My first attempt to improve JSF AJAX was AngularFaces. As it turned out, AngularFaces piqued the curiosity of the JSF experts, but it didn't attract as many developers as BootsFaces does. Many developers and architects shied away from adding AngularJS to their JSF application. So I decided to find a simpler solution. It consists of two parts: advanced search expressions - more about that in a minute - and using the well-known JavaScript callbacks for AJAX:

The interesting part is the onclick callback. Usually, it's used to call JavaScript code. BootsFaces 0.8+ allows you to add an EL expression that's called via AJAX. To distinguish the AJAX code from native JavaScript code you have to precede it with ajax:. This, in turn, even allows you to mix JavaScript and AJAX code:

The JavaScript code after the AJAX code has to be preceded by javascript:. However, there's a catch: the second bit of JavaScript code is called after the AJAX call has been started. That doesn't mean the AJAX call already has finished. If you want to call your JavaScript code after the request has been executed completely, use the oncomplete callback.

The advantage of this approach is that you don't have to use an event façet, like standard JSF forces you to do. It's also slightly simpler than the PrimeFaces approach because you can pass parameters to the method in a simple and intuitive way. No need to hassle with <f:param /> façets. Plus, the BootsFaces API isn't limited to the "click" event. You can use AJAX with every JavaScript event supported by our components. That even includes drag and drop, as you can see in my BootsFaces chess demo. In case you're interested, the source code of the demo is available in my GitHub repository.

There's an entire article dedicated an article to BootsFaces AJAX, so I'll leave it at that today. Maybe one last remark: we strive for compatibility to both standard JSF AJAX and PrimeFaces AJAX, but it's not top on our list. In particular, we've postponed support for <f:param />. It may be the parameter passing mechanism most JSF developers expect (and even demand), but I prefer the method syntax (ajax:board.onclick(row,column)). It's much more expressive.

Read the full story on our showcase page on AJAX.

Search expressions

One of the pain points of JSF - and JSF AJAX in particular - is, that programmers are forced to use ids. Before I learned about JSF, I had written an AJAX framework that figures out automatically which parts of the DOM tree have to be updated (much like the automatic AJAX approach of ICEfaces or my BabbageFaces framework does). So when I got familiar with JSF, I was sort of disgusted they forced developers to micro manage the AJAX request. Mind you, as much as I loving being able to control everything, I hate to be forced to have to control everything at the micromanagement level. I prefer clever defaults. It's good to know you can influence things if I need to, but most of the time I'm just happy to follow the defaults. So the design goal of BootsFaces is just that: find defaults that make most of you happy, and give you a way to override our default if we've guessed wrong.

The problem with ids is that you have to know exactly what your JSF tree looks like. Most developers look a bit puzzled when I mention that, typically answering "But it's my page - sure I know the tree structure!". Even so, ids make it difficult to refactor your JSF code or to rearrange elements of the page.

Maybe that's a bit too abstract. Let me quote myself from one of my first articles. Many JSF forms are series of input field consisting of the label, the input field, and an error message. Details may vary: sometimes the label is above the input field, sometimes the error message is below the input field, but the general pattern still holds. Most of the time an input field consists of these three components. Standard JSF forces you to refer these components to each other using ids:

JSF source code with annotations showing the repetitions

(By the way, isn't it strange that I've published this image almost four years ago - and in all that time nobody complained about me forgetting the #{...} required by JSF?)

The idea I pursued when I wrote my original article was to generate labels and messages automatically. Later that idea materialized as AngularFaces. BootsFaces is a less radical approach to improve JSF, so the challenge is to find a way to improve the JSF markup within the constraints of the JSF architecture. Advanced search expressions to the rescue:

BootsFaces follows the Bootstrap tradition by adding a label or a caption to the input field by default, so these two items can be linked automatically by the framework. However, the error message still needs to know which input field it's responsible for. Standard JSF makes you define an id for the input field, and use this id to define the message:

Why isn't there a search expression like @previous? Well, both PrimeFaces and BootsFaces offer you precisely that. That's a couple of keystrokes less, and - maybe more important - this approach is more resilient to changes of your JSF file.

Standard JSF adds a few helpful search expressions: @form, @this, @all and @none. PrimeFaces adds a couple of search expressions that turned out to be very useful. Starting with version 0.8.0, BootsFaces offers a slightly different set of advanced search expressions. Of course, BootsFaces shares a couple of search expressions with PrimeFaces, trying to be compatible despite the different implementation. In particular, BootsFaces allows you to use @next and @previous (very useful search expressions to define input fields and their labels and error messages) and @(.css-class-name). The latter is more flexible than using ids because ids often change when the structure of the page is modified. CSS classes don't. Alternatively, you can use our wildcard notation: update="**:firstNameId" looks recursively for the id, so the search expression is still valid after moving screen elements around.

Read the full story on our showcase page on advanced search expressions. Or read my article comparing the search expressions of standard JSF, PrimeFaces and BootsFaces.

By the way, if you like our advanced search expressions, please vote for the pending Jira ticket. Thomas Andraschko - the original creator of the PrimeFaces search expressions - offers to donate the search expression framework to standard JSF. It was fun to implement my own search expression framework, but being able to use the search expressions with the standard Mojarra or MyFaces components would be a much better solution.

Update July 28, 2017: The advanced search expressions have been included with JSF 2.3. Thanks to Thomas for being so tenacious!

Theme support

Many developers asked us to add theme support. Actually, BootsFaces already offered theme support, but we overhauled it and made it simpler to use. Now you can even switch themes at runtime.

Starting with BootsFaces 0.8.0, the library contains all sixteen Bootswatch themes out of the box. You can simply activate them by adding a parameter to the web.xml file:

BootsFaces_THEME cerulean

Read the full story on our showcase page explaining themes.

RTL support

That's a pretty exciting one. We've added support for languages none of the team members speak. Judging from the feedback of our early adopters, we've done it right. That's encouraging because I considered it risky to support languages such as Arabic writing from right to left (as opposed to the languages following the Latin tradition, which is to write from left to right).

Actually, BootsFaces doesn't support RTL languages without help. You need to add a Bootstrap plugin to your JSF page: https://github.com/morteza/bootstrap-rtl. Read the full story at our showcase.

New components

Like always, we've added a couple of new components:

  • <b:switch /> That's one of the switches made popular by smartphones. Basically, it's a checkbox, but it looks different.
  • <b:image /> is a simple image that's fully AJAX aware.
  • <b:carousel /> can be used to implement an image slide show in a few lines. But it's more versatile: you can also use this component to implement a multi-part wizard.
  • <b:inputTextarea /> For some reason, we only implemented the one-line input field <b:inputText />. BootsFaces 0.8 adds also a multi-line version.
  • <b:message /> That's the counterpart of <h:message />, but with a Bootstrap look. Plus, it can deal with the advanced search expressions.
  • <b:flyOutMenu /> is a traditional side menu. Most Bootstrap applications don't use this old-school component, but it's popular (and useful) nonetheless, so we've added it to BootsFaces.
  • <b:dataTable /> Every once in a while a developer would complain about the missing datatable. Until recently, I refused to implement this component because there's no way to beat the PrimeFaces datatable. You know, <p:dataTable /> is just great. Tons and tons of features. BootsFaces can be used with PrimeFaces, so using the PrimeFaces datatable in a BootsFaces application seems to be a good idea to me. But... well, the sad truth is many developers and architects are reluctant to add multiple JSF component libraries for fear of incompatibilities. So I decided to try a different take on the datatable. The unique selling point of <b:dataTable /> is that it is rendered on the client side. It's based on a powerful Bootstrap database widget available under the MIT license. As of version 0.8.1, our datatable is limited to some basic functionality. We're going to add functionality during the next versions.

Labels and input fields

To my astonishment, I learned that BootsFaces didn't add an asterisk to the label of a mandatory input field. Neither did it change the label color if a validation constraint is violated. BootsFaces 0.8.0 fixes that:

  • The asterisk of required fields is added by the CSS class bf-required.
  • Both the field and the label bear the CSS class bf-no-message, bf-info, bf-warning, bf-error or bf-fatal, depending on the severity (or existence) of the FacesMessage associated with the input field.
  • By default, bf-error and bf-fatal color the label red. bf-warning colors the label orange. We've added ths feature to <b:inputText/>, <b:inputTextArea/>, <b:selectBooleanCheckbox/>, <b:switch/>, <b:selectOneMenu/>, <b:selectMultiMenu (although this currently doesn't render labels) and <b:slider/>.

Dealing with CSS and JavaScript files

Many developers had problems with conflicting CSS and JavaScript files. Earlier versions of BootsFaces took a very opinionated approach: it works out of the box, but it's hard to tweak it or to integrate it into third-party ecosystems. So we added a couple of configuration parameters allowing you to modify the default settings. As usual, BootsFaces also tries to detect some common situations automatically. In particular, it doesn't load its own version of jQuery if you've included another version of jQuery in your JSF page.

Read the full story on our showcase page explaining how to influence resource loading and ordering.

Build system

We've finally managed to get rid of out ANT build files. Like mentioned above, we now support the two most popular build tools. If you're familiar with Maven or Gradle, you can checkout, compile and run BootsFaces from source in a minute.

By the way, we've also experimented with Grunt to concatenate and minify the CSS sources. That didn't work reliably enough, so we've dropped Grunt again. Actually, the benefit of minifying and concatenating CSS and JavaScript files is debatable. Granted, today concatenated files boost your application's performance significantly, but when http/2 arrives, the situation will change. By then, concatenating files probably results in a performance hit.

Like always, I recommend to use the CombinedResourceHandler of OmniFaces. It fixes a couple of weird resource loading problems (Glyphicons aren't loaded without OmniFaces), and if you activate caching, the CombinedResourceHandler is blazing fast.

Miscellaneous

I won't bore you with the complete list of changes, but you may find these four improvements interesting:

  • We've added a disabled attribute to most BootsFaces components.
  • Menus and submenus can now be nested (in a <b:navBar />.
  • We've added the attributes style and styleClass to many components. In some cases, we've also added contentStyle and contentStyleClass.
  • <b:button /> now supports outcome="@none", outcome="" or simply no outcome to suppress the default behavior.

Bug fixes

Suffice it to say we've corrected quite a few bugs. :) If you really need to know: We've published the entire list in our release notes.

Known bugs

I'm reluctant to admit it. But there's no easy way out. BootsFaces 0.8.1 does have a couple of bugs. We've decided to publish the version nonetheless because BootsFaces 0.8.1 is way better than both BootsFaces 0.8.0 and BootsFaces 0.7.0. But there are a couple of bug reports troubling me. Under certain conditions, command buttons call the Java bean method twice. At the time of writing, we're busily working on this issue.

Breaking changes

It's already a long post, so I'm tempted to drop this section. But no, it's important to talk about the migration path, even if migration to BootsFaces 0.8 should be painless for most projects. There are a few changes that may break the compatibility to your BootsFaces 0.7 application:

  • We've removed the "fade" class from modal dialogs (<b:modal />). This gives you the opportunity to decide yourself if you need the fade effect or not. If you do, add fade to the list of styleClasses.
  • The id of <b:icon /> and <b:iconAwesome /> is not the regular client id, without the suffix _icon, unless it's an appended or a prepended icon.
  • The HTML code of several components uses a slightly different id than they used in previous versions. Instead, they use ids that are compatible to jQuery. In most cases, you shouldn't even notice, because you couldn't do anything with the ids anyways.

Kudos

A project like BootsFaces isn't possible without the help of the community - in other words, without your help. In particular, many developers opened issues on our bug tracker, nudged us into the right direction by asking questions, chatting about us on Twitter or adding code to BootsFaces. I'm sure I've forgotten many important contributors in my list, but I'd like to try to mention everyone who's contributed code and agreed to be mentioned. Thanks to: Alexander Hofmeister, Yeray Santana Borges, George Moralis, Lukáš Vasek, Duncan Bloem and countless others. Your contribution matters!

Do you want to contribute to BootsFaces?

Talking of which: would you like to contribute to BootsFaces yourself? It's easy: open an issue on our bug tracker to report errors, feature request or enhancement proposals. Fork BootsFaces and open a pull request to contribute code, or fork the documentation project to improve the documentation. report about us on Reddit, StackOverflow, HackerNews... you get the idea. Or simply tweet about us!

What about the future?

The BootsFaces team follows the Unix tradition. In other words: we feel perfectly happy with a version below 1.0. That doesn't mean we don't think BootsFaces isn't already production-ready. It is. I'm told many development teams already use it in production. We're just shy of admitting it by moving the version number to 1.0. But we've already talked about it, so I'm positive we'll deliver a 1.0 version in 2016.

In the meantime, we've already started to work on BootsFaces 0.9. It's hard to tell what this version will contain. Mind you, that's up to you. Your questions on StackOverflow and your issues on our bug tracker have a lot of influence. So it's sort of a look into the crystal ball. Here's what we plan to do if you don't convince us to do something more important: Most likely this version will contain a full-blown data table component. We also plan to add components for swipe gestures and mobile support. And of course, there probably are many rough edges to smooth. For example, we've added AJAX to the most important components - but many components aren't AJAX aware yet. Talking of AJAX: we didn't implement the callback functions onsuccess and onerror yet. Standard JSF also allows for an onevent callback function, but chances are we won't implement it because it is already covered by our unified AJAX and JavaScript API.

In any case, I'm going to hold a talk about BootsFaces and AngularFaces at the Javaland conference in Spring 2016. I'd like to meet you there!


Comments