I am using the RichFaces 4 in my JSF application, but I`d like call a method from my bean when the user press the save button (for example: to save in a file text.txt)
Is there a way to call a java method when the user click on rich:editor save button?
Here is the code i`m using
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</h:head>
<h:body>
<h:form>
<rich:editor id="editor" toolbar="full" value="#{editorBean.value}"
style="margin-bottom: 1em" height="400" >
<a4j:ajax event="change" render="panel" status="panelUpdateStatus" />
<a4j:ajax event="dirty" render="panel" status="panelUpdateStatus">
<a4j:attachQueue requestDelay="1000" />
</a4j:ajax>
</rich:editor>
<rich:panel id="panel">
<f:facet name="header">
Output from Editor
<a4j:status name="panelUpdateStatus">
<f:facet name="start">
(Updating)
</f:facet>
</a4j:status>
</f:facet>
<h:outputText escape="false" value="#{editorBean.value}" />
</rich:panel>
</h:form>
EditorBean
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class EditorBean implements Serializable{
/**
*
*/
private static final long serialVersionUID = 5383915229820571701L;
private String value;
/**
* #return the value
*/
public String getValue() {
return value;
}
/**
* #param value the value to set
*/
public void setValue(String value) {
this.value = value;
}
public void save(){
System.out.println(" Saving ");
//Code to save
}
}
<form>
<editor></editor>
<a4j:commandButton value="Ok" type="submit" execute="#form" action="{editorBean.save()}" />
</form>
Bean:
public void save(){
System.out.println(" Saving: " + this.value);
//Code to save
}
This should submit the form, so the editor value gets saved to the bean.
When pressing the button, the editor content should show in your System.out.
Related
ı do not get any warning or error messages in console. debug mode breakpoints does not work in valueChangeListener method in bean class. another methods work at debug mode in bean class. ı tried also ajax with listener.(ı am using maven) does anbody have idea?
xhtml file:
<?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:f="http://java.sun.com/jsf/core"
xmlns:b="http://bootsfaces.net/ui"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<ui:composition template="/template/template.xhtml">
<ui:define name="menu">
<ui:include src="/template/menu.xhtml">
<ui:param name="menuId" value="4"></ui:param>
</ui:include>
</ui:define>
<ui:define name="content">
<ui:include src="../template/progress.xhtml"></ui:include>
<h:form id="nameForm">
<h:outputScript library="primefaces" name="jquery/jquery.js"
/>
<b:column col-xs="12" col-md="8">
<b:panel style="width:80%">
<b:panelGrid colSpans="4,8">
<p:tabView id="tabView" style="min-width:450px;" >
<p:tab title="..." >
<b:panelGrid colSpans="3,9" columns="2"
cellpadding="10">
<p:selectOneMenu value="#{beanController.a}"
id="AId"
valueChangeListener="#{beanController.aSelected}" onchange="submit()">
<p:ajax event="change"/>
<f:selectItems
value="#{beanController.aList}" />
</p:selectOneMenu>
</b:panelGrid>
</p:tab>
beanController.java:
#ManagedBean(name = "beanController")
#ViewScoped
public class BeanController {
public void aSelected(ValueChangeEvent event){
You can use <f:ajax />, like that :
<f:ajax event="blur" listener="#{beanController.updateDataListener}" update=":#{p:component('tabView')}"/>
#ManagedBean(name = "beanController")
#SessionScoped
public class BeanController implements Serializable{
private String a;
public void updateDataListener(AjaxBehaviorEvent event)
{
......
}
}
I have 2 questions here for the code below.
The first one is, how can I have an itemValue in selectItem for my selectOneRadio as a return value from a function? I know this is working for a normal itemValue, if I put just "0", it shows up on the next page, but any of the getCaseValueByIndex() returns nothing.
My second question is, instead of listing each selectItem one by one, can i dynamically create them? What I was thinking is creating a function called getCasesCount which would return the size of the cases array (in this case, its 6) and then run a for loop like so:
for (int i = 0; i < casesCount; i++) {
<f:selectItem itemValue="#{CustomBuild.getCaseValueByIndex(i)}" itemLabel="# {CustomBuild.getCaseKey(i)}"/>
}
So then what would happen is that would create the same code I have but dynamically so that If i added or removed items in my LinkedHashMap, the code would reflect those changes rather than crashing for an outofbounds or null pointer error.
index.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://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="css/stylesheet.css" rel="stylesheet" type="text/css" />
<title>Jadestar's PC Solutions</title>
</head>
<body>
<h4>Please choose your components.</h4>
<h4>To be eligible for the system builder's discount,
you must select at least <span class ='highlight'> 1 </span> component from each category.</h4>
<br></br>
#{CustomBuild.initialize()}
<h3>Computer Case</h3>
<h:form>
<h:selectOneRadio value="#{CustomBuild.chosenCase}">
<f:selectItem itemValue="#{CustomBuild.getCaseValueByIndex(0)}" itemLabel="#{CustomBuild.getCaseKeyByIndex(0)}"/>
<f:selectItem itemValue="#{CustomBuild.getCaseValueByIndex(1)}" itemLabel="#{CustomBuild.getCaseKeyByIndex(1)}"/>
<f:selectItem itemValue="#{CustomBuild.getCaseValueByIndex(2)}" itemLabel="#{CustomBuild.getCaseKeyByIndex(2)}"/>
<f:selectItem itemValue="#{CustomBuild.getCaseValueByIndex(3)}" itemLabel="#{CustomBuild.getCaseKeyByIndex(3)}"/>
<f:selectItem itemValue="#{CustomBuild.getCaseValueByIndex(4)}" itemLabel="#{CustomBuild.getCaseKeyByIndex(4)}"/>
<f:selectItem itemValue="#{CustomBuild.getCaseValueByIndex(5)}" itemLabel="#{CustomBuild.getCaseKeyByIndex(5)}"/>
</h:selectOneRadio>
<br></br>
<h:commandButton id="submit" value="submit" action="responsePage" />
</h:form>
</body>
</html>
responsePage.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://xmlns.jcp.org/jsf/html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="css/stylesheet.css" rel="stylesheet" type="text/css" />
<title>Response</title>
</head>
<body>
<h4><h:outputText escape="false" value="#{CustomBuild.chosenCase}"/></h4>
<h:form prependId="false">
<h:commandButton id="backButton" value="Back" action="index" />
</h:form>
</body>
</html>
CustomBuild.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Part1;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
/**
*
* #author Administrator
*/
#ManagedBean(name = "CustomBuild")
#SessionScoped
public class CustomBuild implements Serializable {
LinkedHashMap <String, String> cases = new LinkedHashMap<String, String>();
String chosenCase;
public String getChosenCase() {
return chosenCase;
}
public void setChosenCase(String chosenCase) {
this.chosenCase = chosenCase;
}
public float getCaseValueByKeyFloat(String key) {
float caseValueByValue = Float.parseFloat(cases.get(key));
return caseValueByValue;
}
public String getCaseKeyByIndex(int index) {
Object newKey = cases.keySet().toArray()[index];
//String tempKey = getCaseValueByIndex(index);
//String newKey = getCaseKeyByValue(tempKey);
return newKey.toString();
}
public String getCaseValueByIndex(int index) {
String caseValue = (new ArrayList<String>(cases.values())).get(index);
return caseValue;
}
public void initialize() {
cases.put("59.95" ,"Eleo 500 $59.95");
cases.put("79.95" ,"Eleo 700 $79.95");
cases.put("99.95" ,"Star Maker $99.95");
cases.put("104.95" ,"Anzooc 1200 $104.95");
cases.put("119.95" ,"Eleo 900 $119.95");
cases.put("139.95" ,"Criticase 1000 $139.95");
}
public CustomBuild() {
System.out.println("Custom Computer");
}
}
You can create an object which holds your key and value pairs.
After that you can use a list of these objects in your bean and use the following code in the xhtmls:
<h:selectOneRadio value="#{CustomBuild.chosenCase}">
<f:selectItems value="#{CustomBuild.getCases}" var="case" itemValue="#{case.value}" itemLabel="#{case.key}" />
</h:selectOneRadio>
Note: if you use an object in selectItem's value, you will need a converter, and to set the proper value you will need a proper equals in your bean.
If you want to stick with the hashmap, here a possible solution for you:
<h:selectOneRadio value="#{CustomBuild.chosenCase}">
<f:selectItems value="#{CustomBuild.cases.keySet()}" var="key" itemValue="#{CustomBuild.getValueByKez(key)}" itemLabel="#{key}" />
</h:selectOneRadio>
I'm new to jsf.
I'm trying to send value to java bean from commandButton to change src in ui:include and render it with ajax so I when clicked commandButton I could refresh part from the page without load the whole page
and below is my code
\\\\\\\ The Bean File
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named("urls")
#RequestScoped
public class URLPagesBean
{
private String urlSRC = "";
public String getUrlSRC() {
return urlSRC;
}
public void setUrlSRC(String urlSRC) {
this.urlSRC = urlSRC;
}
public String getURL()
{
String url = "";
if(urlSRC == "page1" || urlSRC == "" || urlSRC == null)
{
url = "page1.xhtml";
}
else if (urlSRC == "page2")
{
url = "page2.xhtml";
}
return url;
}
}
/////////////
The Index file
\\\\\\\\\\\\\\\\\\\\\\
<h:body >
<h:panelGroup layout="block" styleClass="mainContentBox">
<h:panelGroup layout="block" styleClass="mainTopBox">
<h:panelGroup layout="block" styleClass="logoBox"></h:panelGroup>
</h:panelGroup>
<h:form id="subMenuForm">
<h:panelGroup layout="block" styleClass="mainLiftBox">
<h:panelGroup id="msgBoard" layout="block" styleClass="mainMenuButtons">Message Board
<h:panelGroup layout="block" styleClass="subMenuBox">
<h:commandButton id="showMsgBoard" styleClass="subMenuButtonCommand" value="Page1"/>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="mainMenuButtons">Registrations Book
<h:panelGroup layout="block" styleClass="subMenuBox">
<h:commandButton id="registrInternalApprov" styleClass="subMenuButtonCommand" value="Page2">
<f:ajax render="mainCenterBox" />
</h:commandButton>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup id="mainCenterBox" styleClass="mainCenterBox" layout="block">
<ui:include id="centerView" src="#{urls.URL}"/>
</h:panelGroup>
</h:form>
</h:panelGroup>
</h:body>
///////////////////////////////////////
page1.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 xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Page 1</title>
</h:head>
<h:body>
<ui:fragment>
Page 1
</ui:fragment>
</h:body>
</html>
///////////////////////////
page2.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 xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Page 2</title>
</h:head>
<h:body>
<ui:fragment>
Page 2
</ui:fragment>
</h:body>
</html>
///////////////////////////
Use action attribute of h:commandButton like
<h:commandButton value="Submit"
action="#{registrationAction.submitRegistration}" />
I'm trying to load some data after a user logs in to my app. I need the username to load data specific to the user. The problem I'm having is that I have a SessionScoped backing bean that contains the code to log the user in, and then I have a ViewScoped page specific backing bean (which injects the SessionScoped bean) which is to load the data for the page.
Currently this is the code that I have and I get a null pointer when loading the data because the username doesn't exist when the loadData() method is called.
I'm having a hard time coming up with a solution to this problem as I'd like to NOT have to put the login dialog on every page and keep it in the template.xhtml file if possible.
template.xhtml
...
<!-- Login Dialog -->
<p:dialog id="loginDialog" header="Login" widgetVar="loginWidget" modal="true" visible="#{!accessBacking.hasAccess}" closable="false">
<h:form id="loginForm">
<p:messages id="loginFormMessages" severity="error" autoUpdate="true" showDetail="true" />
<h:panelGrid columns="2" cellspacing="10" width="300">
<p:outputLabel for="username" value="Username" />
<p:inputText id="username" value="#{accessBacking.username}" required="true" requiredMessage="Username is Required" />
<p:outputLabel for="password" value="Password" />
<p:password id="password" value="#{accessBacking.password}" required="true" requiredMessage="Password is Required" />
<h:panelGroup></h:panelGroup>
<h:panelGroup>
<p:commandButton value="Login" styleClass="ui-priority-primary" actionListener="#{accessBacking.checkViewAccess}" oncomplete="handleAuthenticationRequest(xhr, status, args)" update="loginFormMessages" />
</h:panelGroup>
</h:panelGrid>
</h:form>
</p:dialog>
...
userGroups.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 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">
<h:body>
<f:metadata>
<f:event type="preRenderView" listener="#{userGroupBacking.setCurrentMenu}" />
</f:metadata>
<ui:composition template="/templates/template.xhtml">
<p:dataTable var="user" value="#{userGroupBacking.users}" editable="true" id="userTable">
...
AccessBacking.java
#ManagedBean(name="accessBacking")
#SessionScoped
public class AccessBacking {
private String username;
private String password;
public boolean checkViewAccess() {
Access access = new Access();
if(access.authenticate(username, password)) {
// user is logged in
}
}
}
UserGroupBacking
#ManagedBean(name="userGroupBacking")
#ViewScoped
public class UserGroupBacking {
#ManagedProperty(value="#{accessBacking}")
private AccessBacking accessBacking;
public void setAccessBacking(AccessBacking accessBacking) {
this.accessBacking = accessBacking;
}
#PostConstruct
public void init() {
loadData();
}
/**
* Loads the data for the page
*/
public void loadData() {
Dao dao = new Dao(ds);
users = dao.findAllUsers(accessBacking.getUsername(), accessBacking.getRoles()); // NULL POINTER BECAUSE ACCESSBACKING.GETUSERNAME() IS NULL SINCE THE USER HASN'T LOGGED IN YET.
}
}
I've figured out a good solution by using ui:param. Basically I set a ui:param with my backing bean value in my page specific xhtml and then reference that ui:param in my template.
Updated code from question with new solution:
template.xhtml
...
<!-- NOTE the 'myBacking' instead of the 'userGroupBacking' -->
<!-- Login Dialog -->
<p:dialog id="loginDialog" header="Login" widgetVar="loginWidget" modal="true" visible="#{!myBacking.hasAccess}" closable="false">
<h:form id="loginForm">
<p:messages id="loginFormMessages" severity="error" autoUpdate="true" showDetail="true" />
<h:panelGrid columns="2" cellspacing="10" width="300">
<p:outputLabel for="username" value="Username" />
<p:inputText id="username" value="#{accessBacking.username}" required="true" requiredMessage="Username is Required" />
<p:outputLabel for="password" value="Password" />
<p:password id="password" value="#{accessBacking.password}" required="true" requiredMessage="Password is Required" />
<h:panelGroup></h:panelGroup>
<h:panelGroup>
<p:commandButton value="Login" styleClass="ui-priority-primary" actionListener="#{myBacking.checkViewAccess}" oncomplete="handleAuthenticationRequest(xhr, status, args)" update="loginFormMessages" />
</h:panelGroup>
</h:panelGrid>
</h:form>
</p:dialog>
...
userGroups.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 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">
<h:body>
<f:metadata>
<f:event type="preRenderView" listener="#{userGroupBacking.setCurrentMenu}" />
</f:metadata>
<!-- THIS IS PART OF THE SOLUTION -->
<ui:param name="myBacking" value="#{userGroupBacking}" />
<ui:composition template="/templates/template.xhtml">
<p:dataTable var="user" value="#{userGroupBacking.users}" editable="true" id="userTable">
...
AccessBacking.java
#ManagedBean(name="accessBacking")
#SessionScoped
public class AccessBacking {
private String username;
private String password;
public boolean checkViewAccess() {
Access access = new Access();
if(access.authenticate(username, password)) {
// user is logged in
}
}
}
UserGroupBacking
#ManagedBean(name="userGroupBacking")
#ViewScoped
public class UserGroupBacking {
#ManagedProperty(value="#{accessBacking}")
private AccessBacking accessBacking;
public void setAccessBacking(AccessBacking accessBacking) {
this.accessBacking = accessBacking;
}
#PostConstruct
public void init() {
loadData();
}
// CHECKS AGAINST ACCESSBACKING
public boolean isHasAccess() {
return accessBacking.isHasAccess();
}
// CHECKS AGAINST ACCESSBACKING
public boolean checkViewAccess() {
return accessBacking.checkViewAccess();
}
/**
* Loads the data for the page
*/
public void loadData() {
Dao dao = new Dao(ds);
users = dao.findAllUsers(accessBacking.getUsername(), accessBacking.getRoles());
}
}
So, I have a backing bean, Foo, and a template with a client, request and response. the clients are redundant, I want just one client.
Clients:
thufir#dur:~$
thufir#dur:~$ cat NetBeansProjects/NNTPjsf/web/foo/request.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./template.xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<ui:define name="left">
<h:form>
<h:inputText size="2" maxlength="50" value="#{foo.bar}" />
<h:commandButton id="submit" value="submit" action="response" />
</h:form>
</ui:define>
<ui:define name="content">
<h:outputText value="#{foo.bar}"></h:outputText>
</ui:define>
</ui:composition>
thufir#dur:~$
thufir#dur:~$ cat NetBeansProjects/NNTPjsf/web/foo/response.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./template.xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<ui:define name="left">
<h:form>
<h:inputText size="2" maxlength="50" value="#{foo.bar}" />
<h:commandButton id="submit" value="submit" action="response" />
</h:form>
</ui:define>
<ui:define name="content">
<h:outputText value="#{foo.bar}"></h:outputText>
</ui:define>
</ui:composition>
thufir#dur:~$
Which I think is ok, in and of itself.
Backing bean:
package guessNumber;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
#Named
#SessionScoped
public class Foo implements Serializable {
private String bar = "bar";
private String response = "response";
public Foo() {
}
/**
* #return the bar
*/
public String getBar() {
return bar;
}
/**
* #param bar the bar to set
*/
public void setBar(String bar) {
this.bar = bar;
}
/**
* #return the response
*/
public String getResponse() {
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
session.invalidate();
response = "hmm";
return response;
}
/**
* #param response the response to set
*/
public void setResponse(String response) {
this.response = response;
}
}
What I would like is just a single client, request_response or something. So that the text input form stays on the left and the result on the right. That's done with composition tags? Or, a third "general client" which has two sub-clients?
You need to change your commandButton on the request page to call an action method in the backing bean:
<h:commandButton id="submit" value="submit" action="#{foo.doAction}" />
In the action method set the response:
public String doAction() {
response = "hmm";
return "response";
}
The return value of the action method navigates to the page /response.xhtml.
But you don't need two pages. You can return null from the action method to reload the current (request) page:
public String doAction() {
response = "hmm";
return null;
}
Then the changed values for bar and response can be shown on the right side:
<ui:define name="content">
<h:outputText value="#{foo.bar}"></h:outputText>
<h:outputText value="#{foo.response}"></h:outputText>
</ui:define>