I need your help in disabling and enabling an item from the selectManyCheckbox
component in a jsf page. First of all, the selectManyCheckbox component is showing three chechboxes which are (Loan - Health - Transfer). The list will be populated from a bean which it has the code:
private List<hrCertificate> hrCertificatesList = new ArrayList<hrCertificate>();
//Getter and Setter
Private String loanFlag="";
@PostConstruct
public void init() {
this.hrCertificatesList.add(new hrCertificate(("Loan"), "LC"));
this.hrCertificatesList.add(new hrCertificate(("Health"), "HI"));
this.hrCertificatesList.add(new hrCertificate(("Trasnfer"), "TE"));
}
In the same bean, I will be running a SQL statement that will return either Yes or No and that value I am adding it to the loanFlag
variable.So if the flag="Y", I need to enable the loan checkbox so the user can select it else I need to disable it from the selectManyCheckbox
. The issue is that I am facing difficulties in applying the logic to disable and to enable the item selectManyCheckbox
where in the above code I am listing and enabling them all the time.
The code for the selectManyChexkbox:
<p:selectManyCheckbox id="hrCertificates" value="#{user.selectedHRCertificates}" layout="pageDirectio>
<f:selectItems value="#{user.hrCertificatesList}"
var="hrCertificate" itemLabel="#{hrCertificate.hrCertificateName}"
itemValue="#{hrCertificate.hrCertificateCode}"/>
</p:selectManyCheckbox>
So how to apply the logic
Could you edit your hrCertificate class to add a disabled
boolean field? If yes, then you can add itemDisabled="#{hrCerticate.disabled}"
to your f:selectItems
which should be the easiest solution.
Another option would be to use a Map<hrCertificate, Boolean>
instead of a List<hrCertificate>
.
private Map<hrCertificate, Boolean> hrCertificatesMap = new HashMap<hrCertificate, Boolean>();
@PostConstruct
public void init() {
hrCertificatesMap.put(new hrCertificate(("Loan"), "LC"), null);
hrCertificatesMap.put(new hrCertificate(("Health"), "HI"), null);
hrCertificatesMap.put(new hrCertificate(("Trasnfer"), "TE"), null);
}
// Then when you're done with your SQL query, update your Map to add the corresponding boolean values...
.xhtml
<p:selectManyCheckbox id="hrCertificates" value="#{user.selectedHRCertificates}" layout="pageDirectio>
<f:selectItems value="#{user.hrCertificatesMap.keySet().toArray()}" var="hrCertificate" itemLabel="#{hrCertificate.hrCertificateName}" itemValue="#{hrCertificate.hrCertificateCode}" itemDisabled="#{user.hrCertificatesMap.get(hrCertificate)}" />
</p:selectManyCheckbox>
First, note that a property does not retire an actual attribute backing it, you only need a getter. So you can have:
public class MyBean implements Serializable {
private FilterEnum certFilter = FilterEnum.NO_FILTER;
private List<Certificate> certificates;
... // including certificates initialization.
public FilterEnum getCertFilter() {
return this.certFilter;
}
public void setCertFilter(FilterEnum certFilter) {
this.certFilter = certFilter;
}
public List<Certificate> getCertificates() {
// I am sure there is a cooler way to do the same with streams in Java 8
ArrayList<Certificate> returnValue = new ArrayList<>();
for (Certificate certificate : this.certificates) {
switch (this.certFilter) {
case FilterEnum.NO_FILTER:
returnValue.add(certificate);
break;
case FilterEnum.ONLY_YES:
if (certificate.isLoan) {
returnValue.add(certificate);
}
break;
case FilterEnum.ONLY_NO:
if (!certificate.isLoan) {
returnValue.add(certificate);
}
break;
}
}
return returnValue;
}
}
If you insist that you want to do the filter "in the .xhtml", you can combine c:forEach
from JSTL with <f:selectItem>
(note item, not items), but it will make your xhtml more complicated and may cause issues if you want to use Ajax with it.