Single Select Checkbox Using JSF - jsf

I am creating registration form in JSF and I have field as Active, Inactive where I need to use check boxes and these checkboxes should be SINGLE SELECT ONLY. (Note: I can use radio button and solve the problem, however due to some problem I have to use check boxes).
Please suggest me how to get this done?
Thanks in advance...

I think what you need is <h:selectBooleanCheckbox>. The value binded to this component can only be either true (Active) or false (Inactive). It will be something like the following:
<h:selectBooleanCheckbox id="active" value="#{mrBean.active}" >
<f:ajax render="inactive" listener="#{mrBean.onActiveStatusChange}" />
</h:selectBooleanCheckbox>
<h:selectBooleanCheckbox id="inactive" value="#{mrBean.inactive}" >
<f:ajax render="active" listener="#{mrBean.onInactiveStatusChange}" />
</h:selectBooleanCheckbox>
#ManagedBean
#RequestScoped
public class MrBean {
private boolean active;
private boolean inactive;
#PostConstruct
public void prepareMrBean() {
this.active = true;
}
public void onActiveStatusChange() {
if (active) inactive = false;
}
public void onInactiveStatusChange() {
if (inactive) active = false;
}
}

Related

Trigger listener clicking on ace:textEntry

I'm using JSF 2.0 and I want to invoke a function defined in a Java controller when I click on an ace:textEntry.
I tried in this way:
<ace:textEntry readonly="true" value="#{myController.getValue()}"
onclick="#{myController.myFunc()}"/>
but when my page is open, the click event is called instantly.
So, I tried with:
<ace:textEntry readonly="true" value="#{myController.getValue()}">
<ace:ajax event="click" listener="#{myController.myFunc()}"/>
</ace:textEntry>
but my page is not rendered.
Is there another way to implement this behaviour ?
PS: I can use similar JSF components instead of ace:textEntry too.
First, you do not access getters directly in JSF for value backing - you access the property. Secondly, you should call the listener with the correct signature. To correct your example I would first rewrite the call like this,
<ace:textEntry readonly="true" value="#{myController.value}">
<ace:ajax event="click" listener="#{myController.myFunc}"/>
</ace:textEntry>
Then define MyController, like this;
#Named
#ViewScoped
public class MyController {
private value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void myFunc(javax.faces.event.AjaxBehaviorEvent event) {
/* Do somethinig here... */
}
}

How to Compare the values JSF selectonemenu

I am developing a JSF application
I have 2 selectOnemenu controls and submit button.
I need to disable the button if the values of 2 fields are equal
<h:selectOneMenu id="from" value="#{currencyBean.history.fromCurrency}" >
<f:selectItems value="#{currencyBean.currency}" var="c" itemValue="#{c}" itemLabel="#{c.name}"/>
</h:selectOneMenu>
<p:outputLabel for="to" value="to:" />
<h:selectOneMenu id="to" value="#{currencyBean.history.toCurrency}" >
<f:selectItems value="#{currencyBean.currency}" var="c" itemValue="#{c}" itemLabel="#{c.name}"/>
</h:selectOneMenu>
<p:commandButton id="calculateButton" value="Convert" update=":convert :historyPanel" onstart="PF('statusDialog').show()" onsuccess="PF('statusDialog').hide()" validateClient="true" ajax="true" action="#{currencyBean.Calculate()}" />
I tried to use onchange with ajax but everytime I change one dropdown the value of the second drowpdown became null in the backbean so I cannot read it.
Here is my backbean
#Named(value = "currencyBean")
#RequestScoped
public class CurrencyBean implements Serializable {
/**
* Creates a new instance of CurrencyBean
*/
private History history;
private Currency currency;
private Date currentDate;
#Inject
private Loginbean loginBean;
private List<History> historyList;
public List<History> getHistoryList() {
int userId = loginBean.getUserId();
if (userId != -1) {
return new HistoryHelper().GetHistoryListByUser(userId);
}
return null;
}
public CurrencyBean() {
history = new History();
}
public History getHistory() {
return history;
}
public void setHistory(History history) {
this.history = history;
}
public Currency[] getCurrency() {
return Currency.values();
}
public Date getCurrentDate() {
return new Date();
}
public void Calculate() {
int userId = loginBean.getUserId();
if (userId != -1) {
new CurrencyClient().Convert(userId, this.history);
}
}
}
any clue ?
My assumption is that all of your problems come from your managed bean scope. You have #Request scope so every request your managed bean will be removed from container, thus when you define onchange="submit()" (this is only my assumption because you haven't define how you implement onchange attribute) and you select value from one selectBox component values for this component is updated but the first one is still null. When you select second selectBox value updated from first selectBox doesn't exists anymore as managed bean has been removed after first request. You should try with wider scope for instance #ViewScope. If it doesn't help then further informations like implementation onchange attribute will be needed

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.

a4j:support in a reRender is not working

I have a button. If this is pressed, a checkbox should be rendered.
This of course works pretty well. The checkbox should, when changed call a function, which should just System.out.println() something so I see it's called.
The problem is: just the simple checkbox function, without the rerendering works pretty well. But as soon as the a4j:support is rerendered, it's not working, the System.out.println() is never called
This looks so easy, but I don't know why it's not working at all!
Any hint/trick?
This is old environment, so JSF 1.2 only.
My xhtml
<s:div id="sdBoolCheckboxtest">
#{testController.testRerenderBool}
<s:div id="sdRerender" rendered="#{testController.testRerenderBool}">
<h:selectBooleanCheckbox id="myscheckbox" value="#{testController.testBool}">
<a4j:support ajaxSingle="true" event="onclick" immediate="true"
status="globalStatus" action="#{testController.testCheckbox()}" />
</h:selectBooleanCheckbox>
</s:div>
</s:div>
</h:form>
My Java class:
#Name("testController")
#AutoCreate
public class TestController {
private boolean testBool = false;
public boolean isTestRerenderBool() {
return testRerenderBool;
}
public void setTestRerenderBool(boolean testRerenderBool) {
this.testRerenderBool = testRerenderBool;
}
private boolean testRerenderBool;
public void switchtestRerenderBool(){
System.out.println("switch");
testRerenderBool = !testRerenderBool;
}
public void testCheckbox(){
System.out.println("drin");
}
public boolean isTestBool() {
return testBool;
}
public void setTestBool(boolean testBool) {
this.testBool = testBool;
}
}
Okay, i got it working, with these changes:
First i added #Scope(ScopeType.CONVERSATION) to the TestController
#Name("testController")
#AutoCreate
#Scope(ScopeType.CONVERSATION)
public class TestController {
...
}
And as a second change, I changed the <s:div to an <a4j:outputPanel
<a4j:outputPanel id="sdBoolCheckboxtest">
This solved my problem, but I'm still wondering why I need the #Scope(ScopeType.CONVERSATION) (I found the hint with the a4j:outputPanel here)
Any explanation would be helpful, thanks!

Input fields hold previous values only if validation failed

I came up with a strange problem. I tried to isolate the problem so following is my simplified code.
public class MyBean {
private List<Data> dataList;
Data selectedData;
public MyBean() {
dataList = new ArrayList<Data>();
dataList.add(new Data("John", 16));
dataList.add(new Data("William", 25));
}
public List<Data> getDataList() {
return dataList;
}
public void edit(Data data) {
selectedData = data;
}
public void newData() {
selectedData = new Data(null, null);
}
public Data getSelectedData() {
return selectedData;
}
public class Data {
String name;
Integer age;
Data(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
}
xhtml:
<rich:modalPanel id="pop">
<h:form>
Name: <h:inputText value="#{myBean.selectedData.name}" required="true" id="txtName"/><br/>
Age : <h:inputText value="#{myBean.selectedData.age}" required="true" id="txtAge"/>
<a4j:commandButton value="Save"/>
<a4j:commandButton value="Close" onclick="Richfaces.hideModalPanel('pop');return false;"/>
<br/>
<rich:message for="txtName"/><br/>
<rich:message for="txtAge"/>
</h:form>
</rich:modalPanel>
<h:form>
<rich:dataTable value="#{myBean.dataList}" var="data">
<rich:column>#{data.name}</rich:column>
<rich:column>
<a4j:commandLink value="Edit" action="#{myBean.edit(data)}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
</rich:column>
</rich:dataTable>
<a4j:commandButton value="New" action="#{myBean.newData()}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
</h:form>
This is the path to error:
Load the page
Click the "Edit" link in first row(popup displays)
In popup, clear the "Age" field and click "Save".(Required message shown)
Click cancel(without filling "Age" field)
Click second link.
Now it shows irrelevant data(previous data). - This is the problem
Even when I click "New" button it shows incorrect data.
This happens only if a validation is failed in the popup.
Is there a solution for this?
This problem is in JSF 2 also recognized and explained in detail in the following answer: How can I populate a text field using PrimeFaces AJAX after validation errors occur? If you were using JSF 2, you could have used OmniFaces' ResetInputAjaxActionListener or PrimeFaces' <p:resetInput> or resetValues="true" for this.
To the point, you need to clear the state of the EditableValueHolder component when it's about to be ajax-rendered, but which isn't included in the ajax-execute. To clear the state, in JSF 2 you would have used the convenience method resetValue() for this, but this isn't available in JSF 1.2 and you need to invoke the 4 individual methods setValue(null), setSubmittedValue(null), setLocalValueSet(false), setValid(true) to clear the state.
To figure out which components are to be ajax-rendered, but aren't been ajax-executed, in JSF 2 you would have used PartialViewContext methods for this, but this is not available in JSF 1.2 which hasn't standardized ajax yet. You'd need to fiddle with RichFaces specific ajax API in order to figure that. I can't tell that from top of head, so here's a kickoff example assuming that you already know the components which needs to be cleared. Imagine that the form in your popup has id="popForm" and the name input field has id="nameInput", here's how you could clear it inside the newData() method:
UIInput nameInput = (UIInput) context.getViewRoot().findComponent("popForm:nameInput");
nameInput.setValue(null);
nameInput.setSubmittedValue(null);
nameInput.setLocalValueSet(false);
nameInput.setValid(true);
do one thing on cancel action set all popup values null. now in your next click all values set to be default.
or on click set all previous values null. and set all respective values after that.
I had the same problem. if you are using Primefaces, the solution is as simple as putting resetValues="true" on your p:commandLink or p:commandButton that loads the selected item.
After validation failed if you want to remain same as input data which you have pass as submission parameter, then set value attribute as your form bean name as mention below i.e.
<input type="text" id="fname" path="fname" value="${myFormBean.fname}"/>

Resources