Pass param from one jsf page to another - jsf-2

I want to pass selectedExamId from chooseexam page to exam page, what is the good way to do that? is it a good practice to use two baking bean for single jsf page?
One more thing is I am getting same Question list each time?
I have following jsf page
chooseExam.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/admin/template.xhtml">
<ui:define name="content">
<h:selectOneRadio value="#{examBean.selectedExamId}">
<f:selectItems value="#{chooseExamBean.exams}" var="exam" itemValue="#{exam.examId}" itemLabel="#{exam.examName}"/>
</h:selectOneRadio>
<h:commandButton value="Submit" action="/user/exam?faces-redirect=true"/>
</ui:define>
</ui:composition>
</h:body>
</html>
and
exam.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/admin/template.xhtml">
<ui:define name="content">
<ui:repeat value="#{examBean.questions}" var="question">
<h:outputLabel value="#{question.question}"/>
<h:selectOneRadio value="#{examBean.questionAnswerMap[question]}">
<f:selectItem itemValue="#{question.choice1}" itemLabel="#{question.choice1}"/>
<f:selectItem itemValue="#{question.choice2}" itemLabel="#{question.choice2}"/>
<f:selectItem itemValue="#{question.choice3}" itemLabel="#{question.choice3}"/>
<f:selectItem itemValue="#{question.choice4}" itemLabel="#{question.choice4}"/>
</h:selectOneRadio>
</ui:repeat>
<h:commandButton value="Submit" action="#{examBean.calculate}"/>
</ui:define>
</ui:composition>
</h:body>
</html>
following are the backing beans
ChooseExamBean.java
#Component
#ManagedBean
public class ChooseExamBean {
List<Exam> exams;
#Autowired
private ExamService examService;
#PostConstruct
public void init(){
exams = examService.getAllExams();
}
public List<Exam> getExams() {
return exams;
}
public void setExams(List<Exam> exams) {
this.exams = exams;
}
}
and
ExamBean.java
#Component
#ManagedBean
public class ExamBean {
private List<Question> questions;
private Map<Question, String> questionAnswerMap = new HashMap<>();
private int score;
private Long selectedExamId;
#Autowired
private QuestionService questionService;
#PostConstruct
public void init() {
if(selectedExamId != null)
questions = questionService.getQuestionsForExam(selectedExamId);
}
public Map<Question, String> getQuestionAnswerMap() {
return questionAnswerMap;
}
public void setQuestionAnswerMap(Map<Question, String> questionAnswerMap) {
this.questionAnswerMap = questionAnswerMap;
}
public List<Question> getQuestions() {
if(questions == null)
questions = questionService.getQuestionsForExam(selectedExamId);
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Long getSelectedExamId() {
return selectedExamId;
}
public void setSelectedExamId(Long selectedExamId) {
this.selectedExamId = selectedExamId;
}
public String calculate() {
score = questionAnswerMap.size();
return "result?faces-redirect=true";
}
}

Since you are using a RequestScope Beans for the (ExamBean and the ChooseExamBean) you cant keep the values after the response , so you should user the viewParam tag to pass the value from the first page to the second page.
you should make something like the following :
1- the ChooseExam.jsf , you have your radioButtons that will save its value in the chooseExamBean :
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head></h:head>
<h:body>
<h:form>
<h:selectOneRadio label="examType" value="#{chooseExamBean.examNumber}">
<f:selectItem itemLabel="exam1" itemValue="1"/>
<f:selectItem itemLabel="exam2" itemValue="2"/>
</h:selectOneRadio>
<h:commandButton value="commandButton1" action="#{chooseExamBean.navigateToExamPage}" />
</h:form>
</h:body>
</html>
</f:view>
2- in the action of the commandButton you will call a method in the bean to navigate , before navigation you will append a param to the url like the following in the navigateToExamPage method :
#ManagedBean(name = "chooseExamBean")
#RequestScoped
public class ChooseExamBean {
public ChooseExamBean() {
super();
}
private String examNumber;
public void setExamNumber(String examNumber) {
this.examNumber = examNumber;
}
public String getExamNumber() {
return examNumber;
}
public Object navigateToExamPage() {
return "exam?faces-redirect=true&examId="+getExamNumber();
}
}
3- in the exam.jsf page , you have to get the value of the parameter , here you will use the tag like the following :
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head></h:head>
<h:body>
<h:form>
<f:metadata>
<f:viewParam name="examId" value="#{examBean.examNumber}"/>
<f:event type="preRenderView" listener="#{examBean.onLoad}" />
</f:metadata>
<h:outputText value="#{examBean.examNumber}"/>
</h:form>
</h:body>
</html>
</f:view>
the view param have to attributes :
1- name :which is the name of the parameter that you want to get from the url.
2- value :which is where you want to set the value of the parameter.
so in our case the name is "examId" and we want to set the value in "examBean.examNumber" .
here you will find a problem if you didnt use tag , because you want to get the examId onPage Load in the postConstrct method , but the f:param will be called after the postConstruct , so we have to use the like the following :
<f:event type="preRenderView" listener="#{examBean.onLoad}" />
this will help us to perform custom task before a JSF page is displayed.
4- in you examBean :
#ManagedBean(name = "examBean")
#RequestScoped
public class ExamBean {
public ExamBean() {
super();
}
private String examNumber;
public void setExamNumber(String examNumber) {
this.examNumber = examNumber;
}
public String getExamNumber() {
return examNumber;
}
public void onLoad () {
System.out.println("onLoad = "+getExamNumber());
}
}
Please use this with your requirements and everything will go smooth.
Please refer to the following answer here, here and here .
Hope that Helps.

Related

a4j:ajax keyup event not working

After a long time I'm using a4j:ajax to get simple text from h:inputText and render to h:outputText but it's not working
I found many examples like this but none of them worked for me.
this id my bean
import javax.faces.bean.*;
#ManagedBean(name="usertest")
#RequestScoped
public class UserBean {
private String name = "john";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
and this is my index.xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:head>
</h:head>
<body>
<h:form id="f1">
<h:inputText id="name1" value="#{usertest.name}">
<a4j:ajax event="keyup" render="name2" execute="#form"></a4j:ajax>
</h:inputText>
<h:outputText id="name2" value="#{usertest.name}"></h:outputText>
</h:form>
</body>
</html>
I'm using JSF 2.0 and RichFaces 4.0
Any solution would help me.
Tanks

rich:dataScroller only displaying first page

my datascroller displays only first 5 records whenever i try to navigate.. i Am sure m making some silly mistake..
this my xhtml file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="/template/BasicTemplate.xhtml">
<ui:define name="content">
<h:form>
<h:panelGrid>
<rich:dataScroller for="sampleData" maxPages="20" id="scroller"
page="#{richBean.scrollerPage}">
<rich:dataTable id="sampleData" value="#{richBean.employees}"
var="loc" rows="5">
<rich:column>
<h:outputText value="#{loc.empId}" />
</rich:column>
<rich:column>
<h:outputText value="#{loc.empName}" />
</rich:column>
<rich:column>
<h:outputText value="#{loc.dept}" />
</rich:column>
</rich:dataTable>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</html>
and this my java file
#ManagedBean(name = "richBean", eager = true)
#SessionScoped
public class JavaBeatRichfacesBean {
private List<employee> employees;
private int scrollerPage=1;
public int getScrollerPage() {
System.out.println("getScrollerPage");
return scrollerPage;
}
public void setScrollerPage(int scrollerPage) {
System.out.println("setScrollerPage");
this.scrollerPage = scrollerPage;
}
public JavaBeatRichfacesBean() {
this.employees = new ArrayList<employee>();
employee employee = null;
for (int i = 1; i < 50; i++) {
employee = new employee();
employee.setEmpId(String.valueOf(i));
employee.setEmpName("Name : " + i);
employee.setDept("JSF");
employees.add(employee);
}
}
public List<employee> getEmployees() {
System.out.println(employees.size());
return employees;
}
public void setEmployees(List<employee> employees) {
this.employees = employees;
}
}
EDITED
Two thing i have noticed is
I have to refresh each time to change page navigation.
if use h:dataTable instead of rich:dataTable.. it is working
properly ,Surprisingly ..
and if i add execute="#form" render="#form" in rich:datatable is working properly but i have double click everything..
any explanation why this happening would be useful..

JSF 2 sending parameters via URL

I'm trying to send parameter via URL and it fails, because I somewhat can't assign value to the bean or I can't concat value with URL string. By the way when I write color value by hand everything works, for example:
<h:button outcome="viewParams?c=red"/>
This is the page code from which I'm trying to send parameter.
<h:form>
<h:selectOneMenu value="#{viewMngr.selectedColor}">
<f:selectItems value="#{viewMngr.colors}" var="c"
itemLabel="#{c}" itemValue="#{c}" />
<f:ajax listener="#{viewMngr.valueChanged}" />
</h:selectOneMenu>
<h:button outcome="viewParams?c=#{viewMngr.selectedColor}"/>
</h:form>
This is viewManager bean code (as far as I can see bean value is set, because I'm able to print it out)
#ManagedBean
public class ViewMngr {
private ArrayList<String> colors = new ArrayList<String>();
private String selectedColor;
public ViewMngr()
{
getColors().add("red");
getColors().add("green");
getColors().add("blue");
getColors().add("gray");
getColors().add("yellow");
getColors().add("orange");
}
public ArrayList<String> getColors() {
return colors;
}
public void setColors(ArrayList<String> colors) {
this.colors = colors;
}
public String getSelectedColor() {
return selectedColor;
}
public void setSelectedColor(String selectedColor) {
System.out.println("Selected color: " + selectedColor);
this.selectedColor = selectedColor;
}
public void valueChanged() {
System.out.println("Value changed!");
}
}
Now here is the code from second page which tries to catch that parameter:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<f:metadata>
<f:viewParam name="c" value="#{color.color}"/>
</f:metadata>
<h:body style="background-color:#{color.color}">
<fieldset>
<h:form>
<h:outputText value="Some text!"/>
</h:form>
</fieldset>
</h:body>
</html>
And here is color bean:
#ManagedBean
public class Color {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
if(color != null)
System.out.println(color);
this.color = color;
}
}
Being your destination page viewParams.xtml:
<h:button outcome="viewParams">
<f:param name="c" value="#{viewMngr.selectedColor}" />
</h:button>
Takes the view id and appends the params to the url.
It turned out that button needed to be rerendered because c value didn't get set. The tricky part was that viewMngr.selectedColor was set but to set parameter c, button needed to be rerendered. Here is the edited code:
<h:body>
<fieldset>
<h:form prependId="false">
<h:selectOneMenu value="#{viewMngr.selectedColor}">
<f:selectItems value="#{viewMngr.colors}" var="c"
itemLabel="#{c}" itemValue="#{c}" />
<f:ajax listener="#{viewMngr.valueChanged}" render="buttonId"/>
</h:selectOneMenu>
<h:button id="buttonId" outcome="viewParams?c=#{viewMngr.selectedColor}"/>
</h:form>
</fieldset>
</h:body>

Spring Web flow with JSF evaluation

I am new to Spring Web flow.
This is my code.
main-flow.xml
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="hello" class="org.springframework.webflow.samples.booking.hello"/>
<view-state id="hello">
<transition on="click" to="test"></transition>
</view-state>
<action-state id="test">
<evaluate expression="hello.saytest()">
</evaluate>
<transition on="yes" to="page1" ></transition>
<transition on="no" to="page2"></transition>
</action-state>
<view-state id="page1"></view-state>
<view-state id="page2"></view-state>
</flow>
Hello.java
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
public class hello implements Serializable {
String name;
/**
*
*/
#Override
public String toString() {
return "hello [name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private static final long serialVersionUID = 1L;
public boolean saytest() {
System.out.println(name);
String test = "new";
if (name == test) {
return true;
} else {
return false;
}
}
}
hello.xhtml
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
template="/WEB-INF/layouts/standard.xhtml">
<ui:define name="notes">
<p>
Check the calendar widget and the tooltips on the credit card fields.
The form uses Ajax-based validations to redisplay server-side errors without refreshing the entire page.
The booking bean backing the form is a flow-scoped object (see <strong>booking-flow.xml</strong>).
</p>
</ui:define>
<ui:define name="content">
<h:form>
<h:outputLabel for="price">Enter the Name:</h:outputLabel>
<h:inputText id="name" value="#{hello.name}">
</h:inputText>
<p:commandButton id="click" action="click" value="click" />
</h:form>
</ui:define>
</ui:composition>
Here I am trying to get some value from hello.xhtml and try to evaluate it in main-flow.xml.
If the value which i tried is new then it have to navigate to page1 or it have to take it to page2.xhtml.Now I my case even i enter new in inputtext box it take to me to page2 only.
Can anyone help me.
Change
if (name == test)
to
if (name.equals(test))
Or, simply,
if (name.equals("new"))
See http://www.javabeginner.com/learn-java/java-string-comparison

f:validateRequiered doesn't work as expected

I have just created a NetBeans project with JSF 2.0 and I have a problem with f:validateRequired. The bean
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class TestBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String action() {
return "test";
}
}
and the page
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Test</title>
<h:outputStylesheet name="css/stylesheet.css" />
</h:head>
<h:body>
<h:form>
<div id="content">
Value:
<h:message for="test" />
<h:inputText value="#{testBean.value}" id="test">
<f:validateRequired />
</h:inputText>
<br/>
<h:commandButton action="#{testBean.action}" value="Action" />
</div>
</h:form>
</h:body>
</html>
seems to be allright, but the h:message isn't there until I supply the requered="true" attribute on the inputText. What I am missing? Why the validation does not occure whithout the requered="true" attribute?
I figured the answer: fields with empty input are not validated at all by default. If you wish to validate such field you have to set required=true. See UIInput.validateValue() JavaDoc
You can enable the validation of empty fields by setting the javax.faces.VALIDATE_EMPTY_FIELDS context parameter to true. See JavaDoc. After doing that the example above works as expected.
I know this post is kind of old, but I'm using MyFaces and apparently javax.faces.VALIDATE_EMPTY_FIELDS is set to false by default.

Resources