JSF 2 sending parameters via URL - jsf-2

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>

Related

Pass param from one jsf page to another

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.

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 Message on SUBMIT action

I begin with my case:
JSF 2.1
Tomcat 7.0.27
Netbeans as IDE
JSF and PRIMEFace (but optional)
Level JSF beginner
Level JAVA good and not god
I have done a simple JSF site to learn how to works with JSF. My question is based on Login example at this step the problem is not related about that login that is obviously insicure.
A bit of code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
/**
*
* #author
*/
#ManagedBean
#SessionScoped
//#RequestScoped
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private final String userName = "User";
private final String userPassword = "12345";
private String name;
private String password;
private boolean isLogged=false;
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword( String password ) {
this.password = password;
}
public String login() {
if( !(userName==null || password==null)
&&
(userName.equals( name ) && userPassword.equals( password ))) {
isLogged=false;
return "main";
} else {
isLogged=true;
return "index";
}
}
public boolean getIsLogged(){
return isLogged;
}
}
The page index
<?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">
<h:head>
<title>TSAM 7.5 Login</title>
</h:head>
<h:body>
Login system
<br />
<!--<h:link outcome="welcomePrimefaces" value="Primefaces welcome page" />-->
<h:form>
User : <h:inputText value="#{user.name}" />
Password : <h:inputSecret value="#{user.password}" />
<h:commandButton action="#{user.login()}" value="Submit" />
<h:commandButton value="reset" type="reset" />
<h:commandButton value="otherpage" action="otherpage"></h:commandButton>
</h:form>
</h:body>
</html>
The main page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:event type="preRenderView" listener="#{user.isLogged}"/>
<f:view contentType="text/html">
<h:head>
<f:facet name="first">
<meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
<title>PrimeFaces</title>
</f:facet>
</h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" resizable="true" closable="true" collapsible="true">
Header
</p:layoutUnit>
<p:layoutUnit position="south" size="100" closable="true" collapsible="true">
Footer
</p:layoutUnit>
<p:layoutUnit position="west" size="175" header="Left" collapsible="true">
<p:menu>
<p:submenu label="Resources">
<p:menuitem value="Demo" url="http://www.primefaces.org/showcase-labs/ui/home.jsf" />
<p:menuitem value="Documentation" url="http://www.primefaces.org/documentation.html" />
<p:menuitem value="Forum" url="http://forum.primefaces.org/" />
<p:menuitem value="Themes" url="http://www.primefaces.org/themes.html" />
</p:submenu>
</p:menu>
</p:layoutUnit>
<p:layoutUnit position="center">
Welcome to PrimeFaces
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
First
I use action="#{user.login()}" to make navigation action is this correct or there is a better pattern?
But the real question is: How to show a message If I redirect?
I like to show a message I know the example by PrimeFace http://www.primefaces.org/showcase/ui/dialogLogin.jsf. but it doesn't redirect or show anything.
But if i use only "plain" JSW without PrimeFace, i like to put a
because it is similar to PrimeFaces so switch is simple.
I'd like to adopt a "pattern" so i can reuse it for eg when i do a serch an no data is present, or when i call "erease DB" and application say work in progress an then say OK all bank account are esreased (Only an example!! but interesting because there are 2 message).
Thanks
I try
public String login() {
if (!(userName == null || password == null)
&& (userName.equals( name ) && userPassword.equals( password ))) {
isLogged = true;
return "main";
} else {
isLogged = false;
FacesMessage facesMsg;
facesMsg = new FacesMessage( FacesMessage.SEVERITY_ERROR, "No login", "No login because username or passsword are incorrect etc" );
FacesContext fc = FacesContext.getCurrentInstance();
fc.addMessage( "loginError", facesMsg );
return "index";
}
}
And edited the page
<h:body>
Login system
<br />
<!--<h:link outcome="welcomePrimefaces" value="Primefaces welcome page" />-->
<h:form>
User : <h:inputText value="#{user.name}" />
Password : <h:inputSecret value="#{user.password}" />
<h:commandButton action="#{user.login()}" value="Submit" />
<h:commandButton value="reset" type="reset" />
<h:commandButton value="Cambio Password" action="changePassword"></h:commandButton>
</h:form>
<h:message for="" style="color:red;margin:8px;"/>
</h:body>
It works but it's not ok because it's not ok to put a string in the bean. And I need the multilanguage this string has to generated by the beans.... mmm this is not OK something i'm missing.
There's extremely a lot of noise in the question. I understand that your question ultimately boils down to:
How do I create a localized faces message in bean action method?
In that case, just get the message from the current resource bundle yourself.
As you're talking about localization, you should surely already have something like as
<resource-bundle>
<base-name>com.example.i18n.text</base-name>
<var>text</var>
</resource-bundle>
in your faces-config.xml. You could just get it in the bean as well with help of ResourceBundle which JSF itself is actually also using under the covers
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
ResourceBundle text = ResourceBundle.getBundle("com.example.i18n.text", locale);
This way you could compose your message as
String summary = text.getString("messages.no_login_summary");
String detail = text.getString("messages.no_login_detail");
new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail);

Form doesn't submit values when commandLink is used instead of commandButton

I made following jsf page. In my Managed Bean i want evaluate the input,
but i dont get the values.
If i press my commandLink i dont get any values. when i use a commandButton it works:
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="../templates/common.xhtml">
<ui:define name="pageTitle">Test</ui:define>
<ui:define name="pageHeader">Test</ui:define>
<ui:define name="body">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green"
layout="table" />
</h:panelGroup>
<h:form>
<h:outputLabel value="#{bundle.SearchAdressLabel_name}"
for="axname" />
<h:inputText id="axname"
value="#tbaxController.name}"
title="#{bundle.SearchAdressTitle_name}" />
</h:panelGrid>
<br />
<br />
<h:commandButton id="submit" value="#{bundle.SearchAdressLabel_cmdsearch}" action="#{tbaxController.prepareList}">
</h:commandButton>
<h:commandLink action="#{tbaxController.prepareList}"
value="#{bundle.SearchAdressLabel_cmdsearch}" immediate="true" />
<br />
<br />
<h:commandLink value="#{bundle.SearchAdressLabel_cmdclear}"
type="reset" />
</h:form>
</ui:define>
</ui:composition>
</html>
Here is a part of my MB:
#ManagedBean(name = "tbaxController")
#SessionScoped
public class tbaxController implements Serializable {
private static final long serialVersionUID = 1L;
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger
.getLogger(tbaxController.class);
private Tbax current;
private DataModel items = null;
#EJB
private TbaxFacade ejbFacade;
private PaginationHelper pagination;
private int selectedItemIndex;
private String name;
public tbaxController() {
}
public String getname() {
// Get the field
return searchAxart;
}
public void setname(String oname) {
// Set the field this.searchAxart
this.name = oname.trim();
}
...
public String prepareList() {
logger.info("prepareList:" + name); **//null with commandLink!
recreateModel();
return "ADList";
}
...
Why does my prepareList method doesn't get any values with a commandLink?
The immediate="true" makes jsf to step over the process validation and update model phases. It jump directly to invoke application phase. That's why you don't get any values on the model. Try removing it and see what happens.

inputText validator doesn't display error message

I have a simple form that get code then display his libelle, I added a validator bean that check if the code exist.
My problem is I can't display the error message whith when the code doesn't exist.
Here is the code:
test.xhtml
<!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">
<h:head><title>Test</title>
</h:head>
<body class="bodyMain">
<h:form>
<h:panelGrid columns="3">
<h:outputText value="Code: " />
<h:inputText id="code" value="#{myBean.code}"
validator="#{myBean.validateCode}">
<f:ajax execute="#this" render="libelle" listener="#{myBean.setLibelle()}"/>
</h:inputText>
<h:message for="code" style="color:red"/>
</h:panelGrid>
<h:panelGrid id="libelle" columns="2">
<h:outputText value="Libelle: " />
<h:outputText value="#{myBean.libelle}" />
</h:panelGrid>
</h:form>
</body>
</html>
MyBean.java
#ManagedBean
#ViewScoped
public class MyBean implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private String code="";
private String libelle="";
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code=code;
}
public String getLibelle() {
return this.libelle;
}
public void setLibelle(String libelle) {
this.libelle=libelle;
}
public void setLibelle() {
if (code.compareTo("1")==0)
libelle="One";
else
libelle="";
}
public void validateCode(FacesContext context, UIComponent toValidate, Object value) throws ValidatorException {
String code = (String)value;
if (code.compareTo("1") != 0) {
FacesMessage message = new FacesMessage("Code doesn't exist");
throw new ValidatorException(message);
}
}
}
Thank you for your help to resolve this problem
You're not updating the <h:message> component by the <f:ajax>. You need to give the <h:message> an id and include it in the <f:ajax render>.
<h:inputText id="code" value="#{myBean.code}" validator="#{myBean.validateCode}">
<f:ajax execute="#this" render="libelle codeMessage" listener="#{myBean.setLibelle()}"/>
</h:inputText>
<h:message id="codeMessage" for="code" style="color:red"/>
Unrelated to the concrete problem, don't initialize properties to empty strings. Let them by default null. Also, comparing objects should be done with equals() method, not with compareTo(). Finally, using a dropdown list with all available values instead of an input field would be more user friendly.

Resources