JSF. How to disable page components by bean method - jsf

I want to disable some menuitem on my web page:
<p:menuitem value="Edit" update=":formedit:viewDisplayEdit" icon="ui-icon-document" oncomplete=... disabled="#{bean.ask(1)}"/>
And in my backup bean:
public boolean ask(int id)
{
Ask the database here for privilege "id" and return true if logged user have privilege "id"
else return false
}
Of course I'd like to check it only once - during the rendering of the page.
In this example, regardless of the result of the method "ask" menuitem is always enabled.
I know that I can set the boolean variable xmls code (#{bean.ask1}), but I would like a universal solution.
Could you help?

Make ask a private variable in the bean with get and set methods.
private boolean ask = true;
public boolean isAsk(){
return ask;
}
public void setAsk(boolean ask){
this.ask = ask;
}
Now for whatever condition you want to enable or disable the menu item, set or reset the ask variable appropriately in a different method in the bean.
if (condition = true){
setAsk(false);
}

Related

JSF 1.1 - How to get the ID attribute of h:selectBooleanCheckbox in backing bean

So, here is the jsf component:
<h:selectBooleanCheckbox id="cb#{index}" value="backingBean.value" />
And here is a part of the backing bean java:
/**
* getValue is a method which checks if a checkbox is selected or not, using the checkbox ID
*/
public boolean getValue() {
//TODO: get the checkbox id
String checkboxID = ??
if (getCheckedIDs().contains(checkboxID)) {
return true;
}
return false;
}
When the page is loading the checkboxes, I want to check this way if the checkbox is selected or not.
So the question is, what to write instead of ?? to get the ID of the checkbox who called the method?
It's very important that I can use only JSF 1.1, so there are many solutions which won't work with this version.
EDIT: as #Kukeltje correctly notes, the main issue is that the value expression is incorrect. Once you change that, the below is applicable.
You don't need to "calculate" the value ("set" or "unset") of your checkbox. JSF will simply call backingbean.setValue(x) (with x being true or false) depending on whether the checkbox is on or off at that moment (i.e. when you submit the page).
This happens automatically because you said value="#{backingBean.value}".
So in setValue() you simply store the argument, in getValue you return the stored argument. The rest is done by JSF for you.
If you want the checkbox to be on by default, you set the stored value to true.
For example:
private boolean storedValue = true; // or false if you want it to be off by default
public boolean getValue() {
return storedValue;
}
public void setValue(boolean value) {
this.storedValue = value;
}

How to get the ID attribute of h:selectBooleanCheckbox in backing bean

So, here is the jsf component:
<h:selectBooleanCheckbox id="cb#{index}" value="#{backingBean.value}" />
And here is a part of the backing bean java:
/**
* getValue is a method which checks if a checkbox is selected or not, using the checkbox ID
*/
public boolean getValue() {
//TODO: get the checkbox id
String checkboxID = ??
if (getCheckedIDs().contains(checkboxID)) {
return true;
}
return false;
}
When the page is loading the checkboxes, I want to check this way if the checkbox is selected or not. So the question is, what to write instead of ?? to get the ID of the checkbox who called the method? It's very important that I can use only JSF 1.1, so there are many solutions which won't work with this version.
Another very important thing is, that I cannot use the setter/getter in backing bean like here: https://stackoverflow.com/a/48006066/9158590, because I need to store the value of the checkbox immediately after it's checked or unchecked, not only after submit. I have already resolved the storing in backing bean right after checking, I only need to send back true or false when loading page.
This is because I use a page navigation, and for example, when I check a box in page 1, and go to another page, and then go back, the box isn't selected anymore (only in backing bean).
FacesContext context = FacesContext.getCurrentInstance();
UIComponent comp = context.getViewRoot().findComponent("Parent Element
id of HtmlSelectBooleanCheckbox ");
for(UIComponent c : comp.getChildren())
if(c instanceof HtmlSelectBooleanCheckbox)
{
// do something
}
Coming to your Question :
the value of the variable "#{backingBean.value}" is true then the checkbox will be selected

Disable one checkbox out of many in <h:selectManyCheckbox where checkboxes come from a LinkedHashMap [duplicate]

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 selectManyCheckboxwhere 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.

Update page after bean value has changed

I am trying to restrict the rendering of a PrimeFaces tab depending on whether a user is an admin or not.
I am using the following EL to do so:
<p:tab title="Admin" rendered="#{userSession.isAdmin}">
My UserSession class:
#ManagedBean(name="userSession")
#SessionScoped
public class UserSession {
.
.
.
public boolean isAdmin;
public UserSession() {
isAdmin = false;
}
public void addRole(String role) {
if (role.equals("ADMIN") {
this.isAdmin = true;
}
role.add(role)
}
}
The addRole() method gets called and adds the role "ADMIN". I know this isn't a good way of doing things, but I'm only using it for testing purposes at the moment.
My issue is, is that the tab is not being rendered because isAdmin is recognised as false in the constructor. If I change the constructor to true, then it does render.
How can I make it so that is will recognise isAdmin is true afterwards? i.e. after the ADMIN role has been given to the user's session?
Is it possible to 'reload' the page so it can refetch the 'isAdmin' property after it changes?
You could update any Primefaces Component using RequestContext at your ManagedBean methods. For instance in your case at UserSession.addRole(...) method.
RequestContext.getCurrentInstance().update("ID_OF_YOUR_TABVIEW")

Unable to retrieve the value of <h:selectBooleanCheckbox> inside my managed bean's action method

JSF view code:
<f:view>
<h:form>
<h:panelGrid>
<h:inputText id="key" value="#{myManagedBean.key}"/>
<h:selectBooleanCheckbox id="rerun" value="#{myManagedBean.rerun}" rendered="#{myManagedBean.displayRerun}"/>
<h:commandButton id="check" action="#{myManagedBean.check}"/>
</h:panelGrid>
</h:form>
<f:view>
JSF model code:
public class MyManagedBean {
private boolean displayRerun;
public void setDisplayRerun(boolean aDisplayRerun) {
this.displayRerun = aDisplayRerun }
public boolean getDisplayRerun() {
return this.displayRerun;
}
private String key;
public void setKey(String aKey) {
this.key = aKey
}
public String getKey() {
return this.key;
}
private boolean rerun;
public void setRerun(boolean arerun) {
this.rerun = arerun
}
public boolean getRerun() {
return this.rerun;
}
public String check() {
//do data validation
setDisplayRerun(true);
System.out.println(getRerun());
}
}
This always prints false regardless of whether the checkbox is checked or not.
Additional Information on my requirement:
Nick/BalusC, my managed bean is of request scope. It is indeed simplified code snippet that I presented. My page has couple of user input controls along with a command button. On submit of command button, I call action method of backing bean, in which I do data validation (in this case I lookup database and see if the inputs are already registered.) If already registered, I come back to the same page, this is when I display the singleBooleanCheckBox for the user to select and hit the command button again.
I am toggling the display of the checkbox based on a managedbean property (a boolean flag set during data validation).
When I re-submit the page with checkbox checked, I do not receive this data.
For further verification, I replace the selectBooleanCheckbox, with a command button with similar behavior (basically do not render it initially, but only show it on data validation). I mapped its #action to my managedbean's action method. To my surprise, when I hit the button, the action method is not executed. Instead, the page is refreshed like in a "immediate" scenario or a redirect.
I have been struggling on this for almost 6 hrs. Appreciate your experienced insights.
Thanks.
So, you've actually a rendered attribute on the checkbox (that was not present in your initial question) and the bean is request scoped (it would have worked when it was session scoped). The submitted checkbox value will not be gathered during apply request values phase when this attribtue evaluates false at that point.
You basically need to retain the condition responsible for the rendered attribute in the subsequent request as well. This can be done in several ways: putting bean in session scope, using Tomahawk's t:saveState or h:inputHidden with a bean binding. Each is outlined in detail in this answer.

Resources