Primefaces code is lengthy and it may be hard to keep the oversight in a big web application.
Some example:
HTML
<p:selectOneMenu id="clientToCopyRoles" value="#{form.clientToCopyRoles}"
rendered="#{form.copyAllowed}">
<f:selectItem value="#{null}" itemLabel="#{msg.clientSelect}"/>
<f:selectItems value="#{form.possibleClientsForCopying}"/>
</p:selectOneMenu>
<p:commandButton id="copyRolesToClient"
rendered="#{form.copyAllowed}"
disabled="#{form.canCopyRoles}"
action="#{form.copyRolesToClient()}"
value="#{msg.copyToClient}"/>
Required Java
private boolean copyAllowed;
private Client clientToCopyRoles;
private List<SelectItem> possibleClientsForCopying;
private boolean canCopyRoles;
public Client getClientToCopyRoles() {
return clientToCopyRoles;
}
public void setClientToCopyRoles(Client clientToCopyRoles) {
this.clientToCopyRoles = clientToCopyRoles;
}
public boolean isCopyAllowed() {
return copyAllowed;
}
public void copyRolesToClient() {
businessLogic.copyRolesToClient(clientToCopyRoles);
}
public List<SelectItem> getPossibleClientsForCopying() {
return possibleClientsForCopying;
}
public boolean isCanCopyRoles() {
return canCopyRoles;
}
This is long, there is no obvious relationship between the class fields and the components in HTML, and it misleads programmers to implement complicated and slow logic in the getters which, as we know, need to be invoked several times by JSF during processing, and must never throw any exceptions. What I would want is something like this:
HTML
<p:selectOneMenu id="clientToCopyRoles" java="#{form.clientToCopyRoles}"
nullItemLabel="#{msg.clientSelect}" />
<p:commandButton id="copyRolesToClient" java="#{form.copyRolesToClient}"
value="#{msg.copyToClient}"/>
Required Java
private final SelectOneMenu<Client> clientToCopyRoles = new SelectOneMenu<>();
private final CommandButton copyRolesToClient = new CommandButton();
public Form() {
clientToCopyRoles.setRendered(true);
clientToCopyRoles.setNullItemSelctable(true);
clientToCopyRoles.setItems(possibleClientsForCopying, Client::getName);
clientToCopyRoles.onChange(selectOneMenu ->
copyRolesToClient.setDisabled(selectOneMenu.getSelectedItem() != null));
copyRolesToClient.setRendered(true);
copyRolesToClient.setDisabled(true);
copyRolesToClient.onClick(commandButton ->
businessLogic.copyRolesToClient(clientToCopyRoles.getSelectedItem()));
}
public SelectOneMenu<Client> getClientToCopyRoles() {
return clientToCopyRoles;
}
public CommandButton copyRolesToClient() {
return copyRolesToClient;
}
Of course, I could write such classes as SelectOneMenu
and CommandButton
, but it would still leave me with much more of HTML:
<p:selectOneMenu id="clientToCopyRoles" value="#{form.clientToCopyRoles.selectedItem}"
rendered="#{form.clientToCopyRoles.rendered}">
<f:selectItem value="#{null}" itemLabel="#{msg.clientSelect}"/>
<f:selectItems value="#{form.clientToCopyRoles.items}"/>
</p:selectOneMenu>
<p:commandButton id="copyRolesToClient"
rendered="#{form.copyRolesToClient.rendered}"
disabled="#{form.copyRolesToClient.disabled}"
action="#{form.copyRolesToClient.click()}"
value="#{msg.copyToClient}"/>
And if I forget to explicitly assign an attribute like rendered
in the HTML, I could set it to true
or false
on my bean and nothing would happen.
It feels to me like this is something so basic that it should definitely (and I assume, it is) somewhere in the Primefaces classes, and I was just unable to find or understand it correctly. I took a close look at the package javax.faces.component
, which is what the Primefaces’ components’ binding
attribute expect, where I assumed to find it. There are some things related, there is something like UISelectMany
and UISelectItems
, but it does not look like a clean and easy-to-use API to be used for programming the front-end, but for doing the internals (HTML, AJAX, etc.).
Are there such kind of back-end classes for the Primefaces components, either official part of, or maybe is there a project around which deals with just this (at least the Java part, perhaps)? I would like to introduce the default instead of writing my own, if possible.