<h:form prependId="false" id="vt_sel_form">
<p:panelGrid styleClass="center" columns="2">
<p:commandButton value="GO" oncomplete="alert(#{test.i})" actionListener="#{test.testfxn()}" update="#this"/>
</p:panelGrid>
</h:form>
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ViewScoped
#ManagedBean(name = "test")
public class TestClass implements Serializable {
int i ;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public void testfxn() {
setI(i++);
//i=i+10;
System.out.println("i" + i);
}
}
Here, alert(#{test.i}) is always displaying 0. How do i get backing bean value that changes when I click the commandButton. It works when I click button twice. It used to work fine when I used a4j:commandButton.
That's just because alert(#{test.i}); is evaluated when the commandButton is rendered. You can see the changed value by telling JSF to render the script again:
<h:commandButton value="click me" action="#{testClass.testfxn()}">
<f:ajax render="out" />
</h:commandButton>
<h:panelGroup id="out">
<h:outputScript>
alert(#{testClass.i});
</h:outputScript>
</h:panelGroup>
Unlike Richfaces where you can directly call javascript function, primefaces you need to have javascript function as:
function_name(xhr, status, args)
Using listed CommandButton as Example:
<p:commandButton value="GO" oncomplete="alert(#{test.i})" actionListener="#{test.testfxn()}" update="#this"/>
In function test.testfxn() we have:
public void testfxn(){
RequestContext reqCtx = RequestContext.getCurrentInstance();
i = i++;
reqCtx.addCallbackParam("i", i);
}
Here,In function call to backing bean from actionlistener the variables are added to RequestContext.
Now In javascript function:
function draw(xhr, status, args) {
console.log("We are into draw function");
jsonString = JSON.parse(args.i); //json variable is taken out from args variable.
console.log("The value of i "+ i);
}
Related
Here is the situation:
I have a component, whose value is a property of my ViewScoped bean, which gets a FacesMessage generated for it do to some error when the form is first submitted
On a subsequent user action, a h:commandlink is clicked, which uses f:ajax, and its actionlistener sets the component to no longer be rendered
Upon receiving the reponse, the component is no longer rendered (as expected), but the FacesMessage for it still remains and is displayed
I am using Mojarra JSF 2.1, and IceFaces 3.0 - although this example and the problematic behavior are seen using only standard JSF components. Here is a small example that demonstrates the behavior:
test.xhtml
<h:form id="testform">
<h:message for="tv"/>
<h:inputText id="tv" value="#{testBean.testVal}" rendered="#{testBean.testValRendered}" required="true" />
<h:commandButton value="Submit"/>
<h:commandLink actionListener="#{testBean.toggleTestVal}" value="Toggle input">
<f:ajax execute="#this" render="#form"/>
</h:commandLink>
</h:form>
Bean code
#ViewScoped
#ManagedBean(name = "testBean")
public class TestBean {
private String testVal;
private boolean testValRendered;
public TestBean() {
testValRendered = true;
}
public String getTestVal() {
return testVal;
}
public void setTestVal(String testVal) {
this.testVal = testVal;
}
public boolean isTestValRendered() {
return testValRendered;
}
public void setTestValRendered(boolean testValRendered) {
this.testValRendered = testValRendered;
}
public void toggleTestVal(ActionEvent ae) {
testValRendered = !testValRendered;
}
}
If I change the h:commandLink so that it does not use f:ajax, and set immediate='true' on it instead, then the message is removed properly. While this may work in some cases, I would like to understand why using f:ajax to render things as I have in my example does not work. Thanks.
The input component is submitted, processed and validated before its rendering condition has been toggled. The <h:message> isn't aware that the associated input component is not rendered. You'd like to check the very same rendering condition on the <h:message> as well:
<h:message for="tv" rendered="#{testBean.testValRendered}" />
<h:inputText id="tv" ... rendered="#{testBean.testValRendered}" />
My h:form contains a p:selectOneMenu component, which has two values single and multiple. The h:form also contains a default p:inputText. My objective is to add multiple p:inputText component only when value multiple is selected. Please see the attached screenshot-
Below is my view, which suppose to send ajax request, whenever icon button is clicked-
<h:form>
<p:panel header="Dynamically Add textbox">
<p:selectOneMenu id="runType" value="#{repeateRun.runType}">
<f:selectItems value="#{repeateRun.runList}" var="runType" itemLabel="#{runType}" itemValue="#{runType}" />
<p:ajax update="outPanel" listener="#{repeateRun.renderComponent}" />
</p:selectOneMenu>
<h:panelGrid id="runList">
<ui:repeat value="#{repeateRun.runs}" var="run">
<p:inputText value="#{run.runValue}" />
</ui:repeat>
</h:panelGrid>
<p:outputPanel id="outPanel">
<p:commandButton update="runList" icon="ui-icon-plusthick" title="Add more" rendered="#{repeateRun.showAddButton}">
<f:ajax render="runList" listener="#{repeateRun.addRun}" />
</p:commandButton>
</p:outputPanel>
</p:panel>
</h:form>
The #ViewScoped #ManagedBean RepeateRun is following-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
#ManagedBean
#ViewScoped
public class RepeateRun implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> runList;
private List<Run> runs;
private int runValue;
private String runType;
private boolean showAddButton = false;
private static final String SINGLE = "Single";
private static final String MULTIPLE = "Multiple";
//Note : Getters Setters are removed while putting here
#PostConstruct
public void initBean() {
this.setRunList(this.populateRunList());
this.setRuns(this.populateRuns());
}
public void addRun() {
if (this.runs == null) {
this.setRuns(this.populateRuns());
} else {
this.runs.add(this.defaultRun());
}
}
public void renderComponent() {
if (this.getRunType().equals(SINGLE)) {
this.setShowAddButton(false);
} else {
this.setShowAddButton(true);
}
}
private List<String> populateRunList() {
List<String> runList = new ArrayList<String>();
runList.add(SINGLE);
runList.add(MULTIPLE);
return runList;
}
private Run defaultRun() {
Run defaultRun = new Run();
defaultRun.setRunValue(1);
return defaultRun;
}
private List<Run> populateRuns() {
List<Run> runs = new ArrayList<Run>();
runs.add(this.defaultRun());
return runs;
}
}
So after selecting the value Multiple in f:selectItems the plus icon button comes but the button is not invoking attached method i.e. addRun. To confirm the method addRun call after clicking, I put some sysout statements in addRun method. I saw that sysout is not flushed. At the same time I saw some xml response in the firebug.
Where is the problem?
The problem was with f:ajax which doesn't work with p:commandButton. Below are the culprit lines-
<p:commandButton update="runList" icon="ui-icon-plusthick" title="Add more" rendered="#{repeateRun.showAddButton}">
<f:ajax render="runList" listener="#{repeateRun.addRun}" />
</p:commandButton>
The above lines should be replaced with below line
<p:commandButton actionListener="#{repeateRun.addRun}" update="runList" icon="ui-icon-plusthick" title="Add more" rendered="#{repeateRun.showAddButton}" />
I Have an accordion panel with a list of students and I have set dynamic="true", In a tabs of accordion panel, I have command button which invokes the method in backing bean.
here the content of first tab is empty and rest all is fine. To correct this ,I have set dynamic="false" now the content of tab is appearing but command button click doesnot invoke the method of backing bean on first click. Iam not sure what is happening.. Im using prime faces 3.4 and jsf2
<p:accordionPanel value="#{testBean.students}" var="stud" dynamic="true" activeIndex="#{systemManagedBean.formBean.id}">
<p:tab title="#{stud.name}" id="studId">
<p:commandButton process="#this" value="edit" icon="ui-icon-pencil" styleClass="btn-primary" style="margin-left:734px;" action="#{testBean.edit}">
<f:setPropertyActionListener target="#{testBean.stydent}" value="#{stud}"></f:setPropertyActionListener>
</p:commandButton>
I have tried proceess=#form did not make any change..
The following code is working:
The xhtml:
<h:form>
<p:accordionPanel value="#{so15320248.students}" var="student">
<p:tab title="#{student.name}">
<p:commandButton icon="ui-icon-pencil" value="Edit" actionListener="#{so15320248.edit(student)}"/>
</p:tab>
</p:accordionPanel>
</h:form>
The managed bean:
#ManagedBean(name = "so15320248")
#ViewScoped
public class SO15320248 implements Serializable {
private static final long serialVersionUID = -2285963068688871710L;
private List<Student> students;
#PostConstruct
public void init() {
students = new ArrayList<Student>();
students.add(new Student("Student 1"));
students.add(new Student("Student 2"));
}
public void edit(Student student) {
System.out.println("===========================");
System.out.println(student.getName());
System.out.println("===========================");
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
I have a custom UIInput wrapped in a composite component like this:
<cc:interface componentType="SingleUpload">
<cc:attribute name="value" required="true" />
...
</cc:interface>
<cc:implementation>
...
<p:fileUpload id="fileUpload" update="#form" auto="true"
fileUploadListener="#{cc.fileUploaded}" rendered="#{cc.attrs.value == null}"/>
...
<h:commandButton rendered="#{cc.attrs.value != null}" action="#{cc.removeFile}">
<p:ajax execute="#this" update="#form" />
</h:commandButton>
...
</cc:implementation>
The backing component looks like this:
#FacesComponent(value = "SingleUpload")
public class SingleUpload extends UIInput implements NamingContainer, Serializable {
/** */
private static final long serialVersionUID = 2656683544308862007L;
#Override
public String getFamily() {
return "javax.faces.NamingContainer";
}
public void fileUploaded(FileUploadEvent event) throws IOException {
FileData file = new FileData();
file.setContentMimeType(MimeTypeUtils.getContentType(event.getFile().getContentType(), event.getFile().getFileName()));
file.setInputStream(event.getFile().getInputstream());
file.setName(FilenameUtils.getName(event.getFile().getFileName()));
setValue(file);
}
public void removeFile() {
resetValue();
// value should be null now, but it is not, why??
FileData value=(FileData) getValue();
}
}
It is used this way:
<ki:singleUpload value="#{fileModel.file}" title="File Upload" />
So when the action removeFile is called, i want to set the value to null. This works, when I follow these steps:
load a page containing a singleUpload component with no initial value (fileModel.file == null)
upload a file, so value in SingleUpload is not null anymore
remove the file
But when I do the following
load a page containing a singleUpload component with an initial value (fileModel.file != null)
remove the intial value (click on button, removeFile is called)
=> removing the value from the component does not seem to be possible. Why??
I'm currently practicing JSF and EJB, but right now I can't get the page to show the information requested, this have input text and submit button (input.xhtml) and the expected result is to show the text submitted.
/input.xhtml #16,56 value="#{welcome.name}": Target Unreachable, identifier 'welcome' resolved to null
I've tried everything to fix it, this is part of the input.xthml
<ui:define name="content">
<h:form>
<h:panelGrid columns="3">
<h:outputText value="Name:"/>
<h:inputText value="#{welcome.name}" title="name" id="name"
required="true" />
<h:message for="name" style="color: red"/>
</h:panelGrid>
<h:commandButton action="show" value="submit"/>
</h:form>
</ui:define>
</ui:composition>
This is the bean.
#ManagedBean
#RequestScoped
public class Welcome {
private String name;
private String message;
public String getMessage() {
return "Hello " + name;
}
public void setMessage(String message) {
this.message = message;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
The code looks fine and it should work just fine. I only don't see how this is related to JPA and EJB. You would have exactly the same problem when you removed JPA/EJB from your testcase, right? You can just leave those tags and this detail out of the question.
As to the concrete problem, because you omitted the import declarations, I can given the symptoms only guess that you're actually importing #ManagedBean from the javax.annotation package instead of the javax.faces.bean package. The former won't make the bean to be managed by JSF, but the latter wil do. Check and fix your imports. Note that the #RequestScoped also needs to be from the same package, not from the javax.enterprise.context package.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class Welcome {
// ...
}
write like this
#ManagedBean(name="welcome")
#RequestScoped
public class welcome implements Serializable {
private String name;
}
In html write like this
<h:inputText value="#{welcome.name}" title="name" id="name"
required="true" />