My Idea/Requirement is to render dynamically generated jsf page and bind/capture the user filled data and save into db. Dynamically rendering part is working fine but not able to capture the user filled data back to my managedbean. I am using Jsf 2.1.
LoginManagedBean.java (requestscoped)
private String fieldName;
//getters and setters
public String trytry()
{
HtmlInputText inputText = (HtmlInputText) FacesContext.getCurrentInstance().getApplication().createComponent(HtmlInputText.COMPONENT_TYPE);
inputText.setId("it");
inputText.setValueExpression("value", FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(FacesContext.getCurrentInstance().getELContext(),"#{loginmb.keyValueMap['" + inputText.getId() + "']}", String.class));
panelGroupChilds.add(inputText);
grid.getChildren().add(panelGroupTextbox);
return "done";
}
public String save() {
System.out.println("fieldName --- " + this.fieldName);
return "save";
}
done.xhtml (dynamically rendered page)
<h:panelGrid binding="#{loginmb.docGridElems}"></h:panelGrid>
<h:commandButton id="cndB" value="SAVE" action="#{loginmb.save()}"></h:commandButton>
I am able to see the rendered textbox in done.xhtml but on submit the save button, I am not able to get the value of "feildName" (it is null). I am not able to find where i went wrong.
I even tried to bind the Map but could not able to get it.
Related
I have a simple form using primefaces and JSF. On clicking save, it displays another jsf page where I have a primefaces datatable. It should display the newly created record in the datatable which is not the case. In order to see the new record, I have to go back to another page, then reopen the page where I have the datatable. And I can see the new record. How to solve this issue such that on clicking save I can see the new record?
<p:dataTable id="dta" value="#{CarComponent.listCars}" var="current" rows="15" paginator="true" paginatorPosition="bottom">
</dataTable>
//method where listCars is populated
public String carLists(){
listCars = new arrayList(carDao.findAll());
return "/jsf/listOfcars.xhtml";
}
//save method - on clicking save it should display the datatable
public String save(Cars car){
carService.save(car);
return "/jsf/listOfcars.xhtml";
}
public String getlistCars() {
return listCars;
}
public void setlistCars(String listCars) {
this.listCars = listCars;
}
I can only guess, but I assume that the CarService class is at least ViewScoped or even SessionScoped? In either way, as Fritz said in the comment, the list of cars is obviously not updated since the view is not re-rendered.
You can either do a redirect with return "/jsf/listOfCars.xhtml?faces-redirect=true" if the bean is #ViewScoped, or you have to add the newly generated car to the list of cars like
public String saveCar(Car car) {
carService.save(car);
listCars.add(car);
return "/jsf/listOfCars.xhtml";
}
I need to build a JSF page with some input form and when click save all this information have to be stored.In particular an input form need to submit a string and then the system makes some check and store or discard the string(for example i need to save an event in my calendar and add some other person).
I tried to use only a view scoped bean but when i call the method to check the string the bean is destroyed, so i change this method to return an empty string and all was fine but when i reload the page the input form are still filled with old information.
How i can reset input or how i can improve my solution.
Thanks for help
After using the value of the fields in your action method, just fill it with a blank value and re render your form. Here's an example:
Facelets code
<h:form>
<h:input value="#{theBean.theString}" />
<h:commandButton value="Submit" action="#{theBean.action}">
<f:ajax render="#form" />
</h:commandButton>
</h:form>
Managed bean code
#ManagedBean
#ViewScoped
public class TheBean {
private String theString;
//getters and setters
public void action() {
//do something with the submitted value of theString
//at the end, clean it manually
theString = "";
}
}
I have created jsf form at backing bean. I have created form, it is being shown on screen with values successfully. When I click sumbit button, backing bean method is invoked with ActionEvent but updated input values are not submitted to backend. Backign bean entity object values are not updated.
Is there any wrong? Thanks so much for your helps,
Br.
Ramazan
HtmlForm form = new HtmlForm();
form.setId(appletWrapper.getName()+"_FORM");
PanelGrid panelGrid = (PanelGrid)createComponent(PanelGrid.COMPONENT_TYPE);
form.getChildren().add(panelGrid);
panelGrid.setColumns(4);
panelGrid.setId(appletWrapper.getName()+"_FORM_PANEL");
for (FieldWrapper fieldWrapper : appletWrapper.getFields()) {
panelGrid.getChildren().add(new UIFieldLabel(fieldWrapper).component(entities));
panelGrid.getChildren().add(newFieldComponent(fieldWrapper, entities));
}
HtmlPanelGroup panelGroup = new HtmlPanelGroup();
panelGroup.setId(appletWrapper.getName()+"_PANEL_GROUP");
panelGrid.getFacets().put("footer", panelGroup);
CommandButton commandButton = new CommandButton();
panelGroup.getChildren().add(commandButton);
commandButton.setId(appletWrapper.getName()+"_UPDATE");
commandButton.setAjax(true);
commandButton.setValue("update");
commandButton.setProcess("#this");
commandButton.setType("submit");
MethodExpression updateEntityME = createMethodExpression("#{mainBean.entityUpdateListener}", null, new Class[] {ActionEvent.class });
commandButton.addActionListener(new MethodExpressionActionListener(updateEntityME));
return form;
Edited: I gave all components a fixed id.
One of my coponents genarated like that;
InputText inputText = (InputText)createComponent(InputText.COMPONENT_TYPE);
inputText.setId(fieldAlphanumericWrapper.getName());
inputText.setValueExpression("value", createValueExpression("#{mainBean.selection."+fieldAlphanumericWrapper.getProperty()+"}", Object.class));
return inputText;
My backing bean target method;
public void entityUpdateListener(ActionEvent actionEvent) {
TAccount tAccount = (TAccount)getSelection();
System.out.println("tAccount.gettWebsite():"+tAccount.gettWebsite());
}
The main problem is that actually; When I press commandButton mainBean.setSelection is not invoked, so backing bean object is not updated. I cant take updated object instance through actionEvent instance.
I found solution, cause of problem was this line;
commandButton.setProcess("#this");
I have changed to this and problem solved.
commandButton.setProcess("#form");
Br.
Ramazan
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
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.