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
Related
I'm building the content of a p:slideMenu by binding the value to a MenuModel in a backing bean. This is necessary because the content is generated dynamically based on the result of a database query. Using
#Named
#ViewScoped
public class BackingBeanView0 implements Serializable {
private static final long serialVersionUID = 1L;
private MenuModel menuModel = new DynamicMenuModel();
#PostConstruct
private void init() {
DefaultMenuItem menuItem = new DefaultMenuItem("Click me!",
null, //icon
"/index.xhtml" //url
);
menuItem.setCommand("#{backingBeanView0.onMenuItemClick('Hello world!')}");
menuItem.setImmediate(true);
menuModel.addElement(menuItem);
}
[getter and setter for menuModel]
public void onMenuItemClick(String message) {
System.out.println(BackingBeanView0.class.getName()+" message: "+message);
}
}
as recommended by #Melloware (this does not show the need to create the model in the backing bean) causes backingBeanView0.onMenuItemClick to be not invoked
to be displayed with a delay for a few seconds. Moving the wanted backing bean method to a view scoped bean doesn't change this behavior.
The onXXX properties for Javascript callbacks on DefaultMenuItem can't be used to trigger a method in a backing bean afaik. I noticed that the command property in DefaultMenuItem isn't used in the Primefaces source code and it is not documented in the Primefaces 6.2 user guide.
I'm providing a SSCCE at https://gitlab.com/krichter/primefaces-menuitem-bean-callback. It doesn't contain more information than the MCVE above and merely exists to ease the investigation of the problem.
I'm using Primefaces 6.2.
I think I know what you are asking. In the example below, I call the bean controller method myController.changeAccount and I also provide an OnComplete Javascript callback as if I built the menu in XHTML.
final DefaultMenuItem item = new DefaultMenuItem(bean.getLongName());
item.setCommand("#{myController.changeAccount('" + bean.getShortName() + "')}");
item.setImmediate(true);
item.setOncomplete("melloware.handleAccountChange(xhr, status, args);");
Change:
DefaultMenuItem menuItem = new DefaultMenuItem("Click me!",
null, //icon
"/index.xhtml" //url
);
To:
DefaultMenuItem menuItem = new DefaultMenuItem("Click me!");
You cannot combine a "URL" parameter and an Action command in the same menuitem it uses the URL first. If you need to send to a new location have your Command simply return that as a string and you will navigate to that page for example:
public String onMenuItemClick(String message) {
System.out.println(BackingBeanView0.class.getName()+" message: "+message);
return "/index.xhtml";
}
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
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; }
}
I have some fields of a bean that I need to show programmatically. Is something like this:
HtmlPanelGrid panel = new HtmlPanelGrid();
panel.setColumns(4);
HtmlOutputLabel fieldOut = new HtmlOutputLabel();
fieldOut.setId("fieldOutId");
fieldOut.setValue("name");
panel.getChildren().add(fieldOut);
HtmlInputText fieldIn = new HtmlInputText();
fieldIn.setId("fieldInId");
fieldIn.setPartialSubmit(true);
fieldIn.setValueExpression(
"field", UtilFaces.createValueExpression("#{newElementBean.fieldName}",String.class));
panel.getChildren().add(fieldIn);
mainForm.getChildren().add(panel);
In newElements.xhtml i've defined a form which is binded to mainForm, in this way:
<ice:form binding="#{newElementBean.mainForm}">
<ice:inputText id="ANOTHERFIELD" value="#{newElementBean.anotherField}"/>
<ice:commandButton action="#{newElementBean.save}" value="Save"/>
</ice:form>
When I click on the save button and I go to the next view, the field "ANOTHERFIELD" has taken the value from the bean, and shows up correctly, but the fields that were dinamically generated shows empty. Its values in the backing bean also are null. It's like the ValueExpression is not working for the HtmlInputText that I created in the backing bean. I'm using Icefaces 3.3 with Mojarra 2.1.17.
How is this caused and how can I solve it?
I solved it. I made two mistakes:
The proper setValueExpression call is like this:
fieldIn.setValueExpression("value", UtilFaces.createValueExpression("#newElementBean.fieldName}");
I was incorrectly using "field1" as 1st argument instead of "value".
This is not visble in the question, but my createValueExpression() helper method was also wrong. The following is working for me:
public static ValueExpression createValueExpression(String expression) {
Application app = FacesContext.getCurrentInstance().getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
return elFactory.createValueExpression(elContext, expression, Object.class);
}
I have to create some commandLinks dynamically and attach some action listener to it, So I've put <h:panelGrid> on the JSP page and used such code to add the commandLinks and to assign action listeners to:
public ManagedBean(){
List<UIComponenet> child = panelGrid.getChilderen();
list.clear();
List<MyClass> myList = getSomeList();
for (MyClass myObj : myList){
FacesContext ctx = FacesContext.getCurrentContext();
HtmlCommandLink cmdLink = (HtmlCommandLink) ctx.getApplication.createComponent(HtmlCommandLink.COMPONENT_TYPE);
cmdLink.setValue(myObj.getName());
cmdLink.setActionLinstner(new ActionListener(){
public void processAction(ActionEvent event) throws AbortProcessingException{
System.out.println (">>>>>>>>>>>>>>>>>I am HERE ");
}
});
child.add(cmdLink);
}
}
But unfortunately, when I press this commandLinks, an exception thrown! How can I add component event listeners at runtime?
(Note, the code above my contain syntax/compilation errors as I just wrote).
First, you need to manually assign ID to any dynamically created UINamingContainer, UIInput and UICommand components. Otherwise JSF can't locate them in the component tree based on the request parameters, because it wouldn't match the autogenerated ID's.
Thus, at least do:
HtmlCommandLink link = new HtmlCommandLink();
link.setId("linkId");
// ...
Second, you're supposed to create an ActionListener as MethodExpression as follows:
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression methodExpression = context.getApplication().getExpressionFactory().createMethodExpression(
context.getELContext(), "#{bean.actionListener}", null, new Class[] { ActionEvent.class });
link.addActionListener(new MethodExpressionActionListener(methodExpression));
// ...
...and of course have the following method in the backing bean class behind #{bean}:
public void actionListener(ActionEvent event) {
// ...
}
All the above dynamic stuff basically does the same as the following raw JSF tag:
<h:commandLink id="linkId" actionListener="#{bean.actionListener}" />
I had the same problem.
Transient components do not work with actionListeners.
Do not call
FacesContext.getCurrentInstance().getViewRoot().setTransient(true);
or
component.setTransient(true);
As soon as I removed it, it was OK.