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

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

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 bind a component with an object in view scoped managed bean?

I am trying to create a dynamic panel (panel with various items) then i want to bind it with panel component in view page, the scope of managed bean which has the panel object is #ViewScoped.
I noticed that any ajax render this panel in the view page rebuild the managed bean, Why is that ?
Here is my code :
this is the managed bean :
package test;
import org.icefaces.ace.component.panel.Panel;
#ManagedBean(name = "myBean")
#ViewScoped
public class myBean {
private Panel myPanel;
// Constructor
public myBean() {
myPanel = drawPanel(); // this function initiate and add items to the panel
}
// Setters and Getters Methods
}
and this the view page :
<h:form>
<ace:panel binding="#{myBean.myPanel}"></ace:panel>
<ace:pushButton actionListener="#{myBean.something}">
<ace:ajax render="#form" />
</ace:pushButton>
</h:form>
in every time i pressed the button, the managed bean constructor invoked , Why does that happened ?
Also i noticed that if i remove the binding attribute from the panel component or make the scope of the managed bean session or application scope, the constructor didn't invoked.
Note : I am using icefaces 3 and jsf 2.0 .
Is there any solution for this situation ?
As the ICEFaces documentation says:
The Push Button is a component that allows entry of a complete form or just itself. It has the same functionality of a regular jsf command button but without having to add extra attributes.
Because the PushButton is a command button it do navigation. If you don't use its action attribute it will apply its default value. I can't find what it is (I just suspect that it is an empty string).
The JSF navigation rules depending on the action outcome of UICommands:
null or void : reloads the current view
empty string : recreates the current view (if the view recreated, the view scoped beans do the same)
non empty string : the next view determined by the navigation handler.
If the reason is the empty string default result of the action attribute, then use it in the facet:
<ace:pushButton action="#{myBean.nextPage}" actionListener="#{myBean.something}">
And pass back a null value in its linked handler method:
public class MyBean // You use myBean here in your question improperly
{
public String nexPage()
{ return null; }
}

How save or update single inputText field using ajax listener

I spent already more time as is good about some saving or updating issue in inputtext field, i go right to the point:
i have basic single input text with some basic attributtes
<h:inputText id="name" value="#{salesController.selectedSalesName}" />
here is a getter for inputText value
public String getSelectedSalesName(){
for(DealerListView dealer : dealerList){
if(dealer.getDealerId() == getSelectedDealerId()){
return dealer.getName();
}
}
return "";
}
nested in there i use ajax tag
<f:ajax event="change" render="name" listener="#{salesController.updateSelectedSalesName()}" />
a here is back bean method for updating a input text field
public void updateSelectedSalesName() {
DealerData dealDat = BeanFactory.getHotelDAOService(DealerData.class).findOne(selectedDealerId);
dealDat.setName(name);
BeanFactory.getHotelDAOService(DealerData.class).update(dealDat);
}
whole result of this is stack trace which say
value="#{salesController.selectedSalesName}": Property 'selectedSalesName' not writable on type sk.hotel.web.controller.SalesController
I know that something changes is need for that getter method but try some combinations without result which make corect update of value to database.
(I dont use any commands buttons for submit,update only response on pressing Enter in that inputText field.)
I want some guide how can be modified this save/update process whether on back-bean or jsf layout
or maybe someone solved similar situation already,and can share his solution.
Thanks all of you for advice posts.
Regards and nice day
First, add a field:
String selectedSalesName;
Add a setter and setter:
public String getSelectedSalesName() {
return selectedSalesName;
}
public void setSelectedSalesName(String selectedSalesName) {
this.selectedSalesName = selectedSalesName;
}
Add a ajaxListener(AjaxBehaviurEvent event) to create a new Dealer or Update current Dealer
public void ajaxListener(AjaxBehaviorEvent event) {
Dao dao = BeanFactory.getHotelDAOService(DealerData.class)
if (selectedDealerId == null) {
DealarData dealerData= new DealerData();
dealerDate.setName(getSelectedSalesName());
dao.add(dealerData);
setDealer(dealerData);
} else {
DealerData dealDat = dao.findOne(selectedDealerId);
dealDat.setName(name);
dao.update(dealDat);
}
}
A setter to the current dealer
int selectedDealerId;
public void setDealer(DealerData dealer) {
selectedDealerId = dealer.getId();
selectedSalesName = dealer.getName();
}
And the xhtml page:
<h:inputText value="#{salesController.selectedSalesName}" id="idSalesInput">
<a4j:ajax event="keyup" listener="#{salesController.ajaxListener}"
execute="idSalesInput"/>
</h:inputText>
Change "keyup" for the event you want to listen.
When you press a key, the listener is called, and the value of idSalesInput is submitted (the setSelectedSalesName() method is called here, for this reason you got the Property 'selectedSalesName' not writable exception),and the listener create or update a new DealerData.
Have a nice Day and sorry for my bad english!
Binding value in your inputText is two way, when it is rendered than getter is called to calculate value, when it is submited (like in your AJAX event) setter is called for that property to set value in your backing bean. So JSF tries to call setSelectedSalesName(String value). JSF can't write your property, which means can't call setter.
See also:
AJAX listener not being fired for inside

Using #ManageProperty and datatable var "currentRow"

I have a view-scoped bean ManageFoo.java:
#ManagedBean(name = "ManageFoo")
#ViewScoped
public class ManageFoo {
#ManagedProperty(value = "#{currentRow}")
private Foo currentRowBean;
.
.
public void setCurrentRowBean(Foo foo) {...}
public Foo getCureentRowBean() {...}
public void edit(ActionEvent e) {
getCurrentRowBean();
.
.
}
}
I then have the facelets file ManageFoo.xhtml:
<h:dataTable value=#{ManageFoo.foos} var="currentRow">
<h:column>
<h:commandLink actionListener="#{ManageFoo.edit}"/>
.
.
When the 'commandLink' is clicked, however, 'getCurrentRowBean' returns null.
I have this working fine using FacesContext and a getBean("currentRow") helper method, but I'm trying to "JSF 2ify" my web application by using ManagedProperty's, ManagedBean's, etc. Am I just not implementing this properly or am I trying to use ManageProperty's in a way that doesn't make sense?
After feedback from Balus, his solution works well for my action methods, but I'm having trouble getting it to work for methods that return values (such as boolean). The following method is used in a bunch of "rendered" attributes for each row. For example, if you are editing a certain row, all of the other edit buttons on the other rows disappear and the edit button for the current row is replaced by a cancel edit button and save button. So, this method has different return results for each row:
public boolean isCurrentRowEditing() {
if(getCurrentRowDataBean().equals(getCurrentDataEditing())) {
return true;
} else {
return false;
}
}
Since I'm trying to eliminate the "getCurrentRowDataBean()" method everywhere, I need a way for this to work.
The #ManagedProperty is set directly after bean's construction. At the point the bean is been constructed, JSF is definitely not busy iterating over the datatable. Also, your bean is put in view scope, so it's been set when the view is requested for the first time, not when you submit the form to the same view. The #{currentRow} will always be null.
There are several ways to achieve this. If you're running an EL 2.2 capable container or are using JBoss EL, then you could just pass it to the action (not listener!) method:
<h:commandLink action="#{manageFoo.edit(currentRow)}"/>
(note that I fixed your managed bean name to start with lowercase, conform the coding conventions)
with
public void edit(Foo currentRow) {
// ...
}
If you aren't running an EL 2.2 capable container nor can't use JBoss EL, then you need to bind the datatable's value to DataModel and use DateModel#getRowData() inside the action(listener) method to obtain the current row.
See also:
How can I pass selected row to commandLink inside dataTable? (shows all possible ways)
Recommended JSF 2.0 CRUD frameworks (shows DataModel way)
Update backing bean in datatable from h:commandButton and JPA (shows EL 2.2 way)
Update as per your update, just compare it in EL. E.g.
rendered="#{currentRow == manageFoo.currentRow}"
and
rendered="#{currentRow != manageFoo.currentRow}"
(note that this only works if its equals() is properly implemented!)

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