At work, I'm building a JavaEE 8 webapp and I'm using Facelets for templating. I'm using JSF components as little as possible, because I'm taking the HTML code from another project and I don't want to heavily couple the front with the back.
I have a case where in a page I'm showing all the registered users in a table. Naturally, I want to click on a user's name and navigate to a profile page where it shows the user's information.
This is easy with a JSF Datatable, put a setPropertyActionListener and update the backing bean's target value with the current value of the datatable variable.
In my case though, the datatable is created entirely on the client with the DatatableJS library (if i remember correctly) and I'm pulling all the user data with JQuery.
Now, is there a way to update a backing bean value (let's say it holds the user's ID), so if I then go to the profile page it can show me the user's data?
I don't really want to create the table with a JSF Datatable, the JQuery implementation has a nice search input, pagination and sorting out of the box, don't want to have to implement these myself. I'm also a bit reluctant to use Primefaces Datatable although it has these features, because I don't know if it will look how we want it with our CSS...
This is not the normal way to do a select-item-from-table-and-show/edit-details operation in JSF.
The preferred way to do it is to do the database list fetch on the server side (NOTE: Having a client allowed free direct database access is a MAJOR security risk!). You'd then wrap that list in a JSF DataModel object, which adds row-tracking information to the data you just fetched. Then in the datatable, each row would have a commandButton or commandLink that the user would click on to select the row to display/edit. The commandButton or link would reference an action method (NOT a listener!) which would obtain the row to be edited from the DataModel which it could then present for editing by simply navigating to the detail edit page. No AJAX required.
The PrimeFaces datatable tags extend the basic h:dataTable to allow scrolling, column sorting, subtotalling, and other useful features with little or no coding. They use AJAX when necessary as PrimeFaces itself uses jQuery internally. And please note that if you call jQuery directly that you may need to ensure that both JSF and your own code agree on which version of jQuery they are going to use!
As far as CSS goes, PrimeFaces allows you to "skin" a JSF webapp at a logical level, so you can define a set of CSS classes that will treat the various elements of a dataTable (and other JSF components) consistently for the entire webapp automatically. No need for manual element overrides unless you want to. You should have no problems blending legacy pages with JSF pages as far as style goes.
Some general comments, though. JSF is a very pure implementation of Model/View/Controller and for that reason, there ideally shouldn't be any application logic on the View (HTML). It should all be done on the server. Aside from making it a LOT easier to code, debug, and maintain ($$$) webapps, it's also more efficient and more secure. If you go schlepping out database keys to a web page, evil me can easily substitute keys for things I shouldn't have access to, for example. You can't do that when everything important lives only on the server.
On the other hand, if you absolutely cannot be persuaded to give up client-side database operations, then the answer still isn't AJAX. Instead you'd have to formulate a URL that targets the detail edit view and includes the record ID of the record to be edited as a URL parameter. Normally JSF does not use parameters on URLs because everything lives in backing beans, but as of about version 2.2, there are tags and methods that simplify injection of parameters by brute force as well.
An IDE is no substitute for an Intelligent Developer.
HI Tim, so sorry for the late response once again, the last couple of months have been overwhelming with the project and I'm all over the place.
I did find a dirty work-around to this, by POSTing the ID to the backend, navigating to the other page and GETing the results I want through an endpoint.
I remember you telling me again about the JSF DataModel and I'll be damned still haven't tried that out. Will do so though as soon as I finish this post, may as well save me headaches from now on. The process you mention about editing entries was more or less what I had in mind as well, that's what I was used to. Will definitely switch to it if I go the JSF Datatable way. I'll do my best to include a Datatable, I know it's really powerful.
Primefaces is definitely my preferred way, if it's skinned the way I want it I'll include it, since it seems easy to change the JQuery version if my project uses another. We're actively using JQuery everywhere so hopefully that will do the trick. I've tried to skin it differently in the past but I failed, most probably wasn't doing it right.
It's not that I necessarily want to use the client for the DB stuff, but eventually we'll go for tokens to accompany the calls to the backend. That's what they're using for the current PHP platform and also what I was instructed to do. We'll probably switch the UI to something else at some point, that's why I don't want to include JSF that much.
I'll do some quick examples tonight and post back when I give it a go at work too.
Tim thanks so much for the advice, sadly I don't have a senior dev at work and it's easy to get overwhelmed with all I'm supposed to do.
Something to bear in mind in JSF is that it's based on Inversion of Control.
That means that backing beans don't "get" data from the View form, instead JSF itself transfers the data to the backing beans. In MVC terms, the backing beans are the Models and all the Controllers are in the FacesServlet and the internal logic that implements the JSF tags. So you virtually never write a Controller in JSF.
When a JSF action method fires as a result of a command submit, the data from the form fields will already have been validated and transferred into the backing bean. In fact, unless each and every form field has a valid value, JSF will neither update the bean nor fire the action method. You are 100% guaranteed that the data will be all present and valid when the action method is called. This is also true of JSF AJAX listener methods.
I would not adapt the PHP logic too slavishly. While I really like PHP for quick-and-dirty stuff, accent the "dirty" part. PHP is notoriously bad at security.
An IDE is no substitute for an Intelligent Developer.
I guess I've been trying to adapt to the previous platform instead of letting JSF do its thing. In fact I have a couple of use cases coming up that will benefit a lot from JSF validation...
Regarding security, I played a bit with the new Security API and it's awesome. A lot easier to authenticate and authorize than before. And I believe that since JQuery calls are included in the secure web resources (along with the views), they're secured by default. So I won't be needing any tokens to go along with the calls.
I think it's time to actually go the JSF way and stop re-using blindly the current resources.