The value for the useBean class attribute is invalid [duplicate] - forms

This question already has answers here:
JasperException: The value for the useBean class attribute is invalid
(6 answers)
Closed 3 years ago.
I am new in JSP and trying to to simple power calculater. So I take 2 numbers from user and later I get result of calculation and show on page. Here is my bean class:
package org.mypackage.power;
public class MyPow {
private double base;
private double pow;
private double result;
MyPow()
{
base = 0;
pow=1;
}
/**
* #return the base
*/
public double getBase() {
return base;
}
/**
* #param base the base to set
*/
public void setBase(double base) {
this.base = base;
}
/**
* #return the pow
*/
public double getPow() {
return pow;
}
/**
* #param pow the pow to set
*/
public void setPow(double pow) {
this.pow = pow;
}
/**
* #return the result
*/
public double getResult() {
return Math.pow(base, pow);
}
/**
* #param result the result to set
*/
public void setResult(double result) {
this.result = result;
}
}
And here is the index page:
<HTML>
<BODY>
<FORM METHOD=POST ACTION="result.jsp">
What's your base? <INPUT TYPE=TEXT NAME=base SIZE=20>
What is your power <INPUT TYPE=TEXT NAME=power SIZE=10>
<P><INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>
And here is the JSP page that will show the result
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Hello World!</h1>
<jsp:useBean id="powerBean" scope="session" class="org.mypackage.power.MyPow" />
<jsp:setProperty name="powerBean" property="*"/>
<jsp:getProperty name="powerBean" property="result"/>
</body>
</html>
And this code gives
The value for the useBean class attribute is invalid
My class is under the org.mypackage.power.MyPow package. Before I update this it was a simple hello world and was working correctly. But I just change class and add new fields and changed JSP page. Could anyone help me please?
I am using Tomcat 7.0.14 and Netbeans 7.01

This error basically means that
MyPow powerBean = new MyPow();
has failed.
The beans are required to have a public constructor. So, change the package-private constructor
MyPow() {
// ...
}
to a public constructor
public MyPow() {
// ...
}
This way JSP (which is by itself in a different package) will be able to access and invoke the bean's constructor.

You only need to restart Tomcat. This will solve your problem. The easy way, from your Tomcat root directory (Mac or Linux):
$ ./bin/shutdown.sh
$ ./bin/startup.sh
In Windows it must be with .bat files...

public User() {
super();
}
After adding default constructor, it worked fine without error

Related

org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.faces.flow.FlowScoped

I´m trying to develop a simple example of new functionality of JSF 2.2, #FlowScope, I develop it with eclipse luna, glassfish 4.0, I guess the code is right cause I caught it on the web, probably the error is with the configuration of the project. Could anyone give me an Idea of what could be? Pleas ask me further information if it´s hard to understand with these few information but actually I don´t know what more I can write to help and this is my first question on stackoverflow.
public class NestedFlowBuilder implements Serializable {
private static final long serialVersionUID = 1L;
#Produces
#FlowDefinition
public Flow defineCallingFlow
(#FlowBuilderParameter FlowBuilder flowBuilder) {
String flowId = "secondJavaFlow";
flowBuilder.id("", flowId);
flowBuilder.viewNode(flowId, "/java-calling-flow/start-page.xhtml")
.markAsStartNode();
flowBuilder.viewNode("results",
"/java-calling-flow/results-page.xhtml");
flowBuilder.returnNode("return").fromOutcome("/return-page-for-java-calling-flow");
flowBuilder.returnNode("home").fromOutcome("/index");
flowBuilder.flowCallNode("go-to-nested")
.flowReference("", "thirdJavaFlow")
.outboundParameter("paramForNestedFlow",
"#{javaCallingFlowBean.param1}");
return(flowBuilder.getFlow());
}
#Produces
#FlowDefinition
public Flow defineNestedFlow
(#FlowBuilderParameter FlowBuilder flowBuilder) {
String flowId = "thirdJavaFlow";
flowBuilder.id("", flowId);
flowBuilder.viewNode(flowId,
"/java-nested-flow/start-page.xhtml")
.markAsStartNode();
flowBuilder.viewNode("results",
"/java-nested-flow/results-page.xhtml");
flowBuilder.returnNode("return-to-previous-start")
.fromOutcome("secondJavaFlow");
flowBuilder.returnNode("return-to-previous-results")
.fromOutcome("results");
flowBuilder.inboundParameter("paramForNestedFlow",
"#{javaNestedFlowBean.param3}");
return(flowBuilder.getFlow());
}
package coreservlets;
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.flow.FlowScoped;
import javax.inject.Named;
#Named
#FlowScoped("thirdJavaFlow")
public class JavaNestedFlowBean implements Serializable {
private static final long serialVersionUID = 1L;
private String param3, param4;
public String doFlow() {
if (param3.equalsIgnoreCase(param4)) {
FacesContext context = FacesContext.getCurrentInstance();
FacesMessage fMessage =
new FacesMessage("Params must be distinct");
fMessage.setSeverity(FacesMessage.SEVERITY_ERROR);
context.addMessage(null, fMessage);
return(null);
} else {
return("results");
}
}
public String getParam3() {
return param3;
}
public void setParam3(String param3) {
this.param3 = param3;
}
public String getParam4() {
return param4;
}
public void setParam4(String param4) {
this.param4 = param4;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Java Calling Flow Start PAge</title>
</head>
<body>
<h:form>
<h:messages globalOnly="true" styleClass="error"/>
<h:panelGrid columns="3" styleClass="formTable">
Param 1:
<h:inputText value="#{javaCallingFlowBean.param1}" id="param1"
required="true"
requiredMessage="Param 1 is required"/>
<h:message for="param1" styleClass="error"/>
Param 2:
<h:inputText value="#{javaCallingFlowBean.param2}" id="param2"
required="true"
requiredMessage="Param 2 is required"/>
<h:message for="param2" styleClass="error"/>
<f:facet name="footer">
<h:commandButton value="Show Results"
action="#{javaCallingFlowBean.doFlow}"/><br/>
</f:facet>
</h:panelGrid>
</h:form>
</body>
</html>
I get this error:
javax.el.ELException: /java-calling-flow/start-page.xhtml #17,40 value="#{javaCallingFlowBean.param1}": org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.faces.flow.FlowScoped
http://courses.coreservlets.com/Course-Materials/pdf/jsf/jsf2/JSF-2.2-Faces-Flow-2.pdf from pag 33

Can not get data table row selection in PrimeFaces, jsf?

I'm working on a project. I need to get a list from MySql database and list it. I'm using JSF 2.1 Primeface 3.5 and Eclipse Juno. I run my code but it doesn't work. You can see my codes in below
//LOGIN CLASS
import parts
#ManagedBean
#SessionScoped
public class Login {
private String username, password;
private PreparedStatement ps, ps2;
private ResultSet rs, rs2;
private List<Application> applications = new ArrayList<Application>();;
private Application selectedApplication;
// GETTERS SETTERS
public String login() {
Connection object = new Connection();
try {
ps = nesne
.getCon()
.prepareStatement(
"select Username, Password from company where Username=? and Password=?");
ps.setString(1, getUsername());
ps.setString(2, getPassword());
rs = ps.executeQuery();
while (rs.next()) {
getList();
return "application";
}
} catch (Exception e) {
System.err.println(e);
}
return "confirm";
}
private List<Application> getList() {
Baglanti nesne = new Baglanti();
try {
ps2 = nesne
.getCon()
.prepareStatement(
"select ApplicationName from application where CompanyID=(select ID from company "
+ "where Username=? and Password=?)");
ps2.setString(1, getUsername());
ps2.setString(2, getPassword());
rs2 = ps2.executeQuery();
while (rs2.next()) {
Application obj = new Application();
obj.setApplicationName(rs2.getString("ApplicationName"));
applications.add(obj);
}
} catch (Exception e) {
System.err.println(e);
}
return applications;
}
APPLICATION CLASS
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class Application {
private int ID;
private int CompanyID;
private String Type;
private Date Date;
private String ApplicationName;
private int CurrentMessageCount;
private int MaxMessage;
private String isPro;
//GETTERS SETTERS
application.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"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Login Confirmed</title>
</h:head>
<h:body>
<h1 class="ui-widget-header ui-corner-all" align="center">Application
List</h1>
<br />
<h:form id="form">
<p:growl id="msgs" showDetail="true" />
<p:dataTable id="applications" var="application"
value="#{login.applications}">
<p:column headerText="Application" style="width:24%">
<h:outputText value="#{login.applications}" />
</p:column>
<p:column style="width:4%">
<p:commandButton id="selectButton" icon="ui-icon-search"
title="View">
<f:setPropertyActionListener value="#{application}"
target="#{login.selectedApplication}" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
I can login properly after that ı saw this page.
Now where is my mistake?
Your var="application" is conflicting with the implicit EL object referring the application context (the ServletContext). You can find here a list of all implicit EL objects. Memorize them. You should never declare an EL variable on exactly those names.
Give it a different name. E.g. var="app", var="_application", etc.
In data table var property mean that every item from database will be accesible as this "var" value. i.e:
You have class Foo:
class Foo{
int number;
String text;
//Setters and getters
}
And another class which handle list of Foo objects (your model as CDI Bean):
#Named
class Boo{
List<Foo> list = new ArrayList<>();
//Getter and setters
}
So to list it all in jsf page you should use it like this:
<p:dataTable id="list" var="listobject" value="#{boo.list}">
<p:column headerText="Number" style="width:24%">
<h:outputText value="#{listobject.number}" />
</p:column>
<p:column headerText="Text" style="width:24%">
<h:outputText value="#{listobject.String}" />
</p:column>
</p:dataTable>
So summary "var" value is accessor string to boo object.
Look also:
PrimeFaces datatable demo and here
Mkyong datatable tutorial

How to setConstraintViolations on EditorDriver using return value of client side Validator Validate method call

Using GWT 2.5.0,
I would like to use Client side validation and Editors. I encounter the following error when trying to pass the ConstraintViolation java.util.Set to the EditorDriver as follows.
Validator a = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Person>> b = a.validate(person);
editorDriver.setConstraintViolations(b);
The method setConstraintViolations(Iterable<ConstraintViolation<?>>) in the type EditorDriver<Person> is not applicable for the arguments (Set<ConstraintViolation<Person>>)
The only somewhat relevant post I could find was Issue 6270!
Below is an Example which brings up a PopUpDialog with a Person Editor that allows you to specify a name and validate it against your annotations. Commenting out the personDriver.setConstraintViolations(violations); line in the PersonEditorDialog will allow you to run the example.
I don't have enough reputation points to post the image of the example.
Classes
Person
public class Person {
#NotNull(message = "You must have a name")
#Size(min = 3, message = "Your name must contain more than 3 characters")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
PersonEditorDialog
public class PersonEditorDialog extends DialogBox implements Editor<Person> {
private static PersonEditorDialogUiBinder uiBinder = GWT
.create(PersonEditorDialogUiBinder.class);
interface PersonEditorDialogUiBinder extends
UiBinder<Widget, PersonEditorDialog> {
}
private Validator validator;
public PersonEditorDialog() {
validator = Validation.buildDefaultValidatorFactory().getValidator();
setWidget(uiBinder.createAndBindUi(this));
}
interface Driver extends SimpleBeanEditorDriver<Person, PersonEditorDialog> {
};
#UiField
ValueBoxEditorDecorator<String> nameEditor;
#UiField
Button validateBtn;
private Driver personDriver;
#UiHandler("validateBtn")
public void handleValidate(ClickEvent e) {
Person created = personDriver.flush();
Set<ConstraintViolation<Person>> violations = validator
.validate(created);
if (!violations.isEmpty() || personDriver.hasErrors()) {
StringBuilder violationMsg = new StringBuilder();
for (Iterator<ConstraintViolation<Person>> iterator = violations.iterator(); iterator.hasNext();) {
ConstraintViolation<Person> constraintViolation = (ConstraintViolation<Person>) iterator
.next();
violationMsg.append(constraintViolation.getMessage() + ",");
}
Window.alert("Detected violations:" + violationMsg);
personDriver.setConstraintViolations(violations);
}
}
#Override
public void center() {
personDriver = GWT.create(Driver.class);
personDriver.initialize(this);
personDriver.edit(new Person());
super.center();
}
}
SampleValidationFactory
public final class SampleValidationFactory extends AbstractGwtValidatorFactory {
/**
* Validator marker for the Validation Sample project. Only the classes and
* groups listed in the {#link GwtValidation} annotation can be validated.
*/
#GwtValidation(Person.class)
public interface GwtValidator extends Validator {
}
#Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
EditorValidationTest
public class EditorValidationTest implements EntryPoint {
/**
* This is the entry point method.
*/
public void onModuleLoad() {
PersonEditorDialog personEditorDialog = new PersonEditorDialog();
personEditorDialog.center();
}
}
UiBinder
PersonEditorDialog.ui.xml
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:e="urn:import:com.google.gwt.editor.ui.client">
<ui:style>
.important {
font-weight: bold;
}
</ui:style>
<g:HTMLPanel>
<g:Label>Enter your Name:</g:Label>
<e:ValueBoxEditorDecorator ui:field="nameEditor">
<e:valuebox>
<g:TextBox />
</e:valuebox>
</e:ValueBoxEditorDecorator>
<g:Button ui:field="validateBtn">Validate</g:Button>
</g:HTMLPanel>
</ui:UiBinder>
GWT Module
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.0//EN"
"http://google-web-toolkit.googlecode.com/svn/tags/2.5.0/distro-source/core/src/gwt-module.dtd">
<module rename-to='editorvalidationtest'>
<inherits name='com.google.gwt.user.User' />
<inherits name='com.google.gwt.user.theme.clean.Clean' />
<inherits name="com.google.gwt.editor.Editor"/>
<!-- Validation module inherits -->
<inherits name="org.hibernate.validator.HibernateValidator" />
<replace-with
class="com.test.client.SampleValidationFactory">
<when-type-is class="javax.validation.ValidatorFactory" />
</replace-with>
<!-- Specify the app entry point class. -->
<entry-point class='com.test.client.EditorValidationTest' />
<!-- Specify the paths for translatable code -->
<source path='client' />
<source path='shared' />
</module>
Libs required on Classpath
hibernate-validator-4.1.0.Final.jar
hibernate-validator-4.1.0.Final-sources.jar
validation-api-1.0.0.GA.jar (in GWT SDK)
validation-api-1.0.0.GA-sources.jar (in GWT SDK)
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
log4j-1.2.16.jar
As discussed in the comments, the following cast was determined to be a valid workaround.
Set<?> test = violations;
editorDriver.setConstraintViolations((Set<ConstraintViolation<?>>) test);
This is what I do over and over again :
List<ConstraintViolation<?>> adaptedViolations = new ArrayList<ConstraintViolation<?>>();
for (ConstraintViolation<Person> violation : violations) {
adaptedViolations.add(violation);
}
editorDriver.setConstraintViolations(adaptedViolations);
The driver has a wild card generic type defined and you can not pass in the typed constraint violations.

Struts 2: updating a list of objects from a form with model driven architecture

I already searched and found several approaches here, but I can't get them working for my project.
I want to show an edit page for a list of objects, which should all be updated at once. I use the model driven architecture approach to achieve this, but I can't get it running properly. I can always display and iterate the list and its values, but I can't modify its values.
So here is what I'm currently doing:
I have a Model 'Teilzeitgrad' in my database, which has some simple attributes with getters and setters.
public class Teilzeitgrad {
private Date datumAb;
private Date datumBis;
private double betrag;
// ... getters and setters
}
In my Action-Class I implement the ModelDriven Interface with a List of Teilzeitgrad-Objects
public class DienstabschnittViewJahrAction implements ModelDriven<List<Teilzeitgrad>>, Preparable
{
List<Teilzeitgrad> teilzeitgrads;
private String tzgTypKey;
private Integer jahrIndex;
public String execute() {
return SUCCESS;
}
public List<Teilzeitgrad> getModel()
{
if(teilzeitgrads == null) {
teilzeitgrads = getTeilzeitgradListByTypAndJahr(getTzgTypKey(), getJahrIndex());
}
return teilzeitgrads;
}
public List<Teilzeitgrad> getTeilzeitgrads()
{
return teilzeitgrads;
}
public void setTeilzeitgrads(List<Teilzeitgrad> teilzeitgrads)
{
this.teilzeitgrads = teilzeitgrads;
}
#Override
public void prepare() throws Exception
{
// TODO Auto-generated method stub
}
public String getTzgTypKey()
{
return tzgTypKey;
}
public void setTzgTypKey(String tzgTypKey)
{
this.tzgTypKey = tzgTypKey;
}
public Integer getJahrIndex()
{
return jahrIndex;
}
public void setJahrIndex(Integer jahrIndex)
{
this.jahrIndex = jahrIndex;
}
}
The action mapping in struts.xml is defined as follows:
<action name="*/auth/GroupAdmin/processEditDienstabschnittJahr" method="execute" class="org.hocon.ul.portal.action.DienstabschnittViewJahrAction">
<result name="success" type="redirect">${referer}</result>
</action>
In my JSP File I'm iterating the model object, displaying its values in textfields or lists as follows:
<ul:form action="auth/GroupAdmin/processEditDienstabschnittJahr">
<s:iterator value="model" status="rowStatus">
<tr>
<td style="text-align: center;">
<s:date name="model.get(#rowStatus.index).datumAb" var="datumAb_DE" format="dd.MM.yyyy" />
<s:textfield style="width:70px;" name="model.get(#rowStatus.index).datumAb" value="%{#datumAb_DE}" label="DatumAb"></s:textfield >
</td>
<td style="text-align:center;">
<s:date name="model.get(#rowStatus.index).datumBis" var="datumBis_DE" format="dd.MM.yyyy" />
<s:textfield style="width:70px;" name="model.get(#rowStatus.index).datumBis" value="%{#datumBis_DE}" label="DatumBis"></s:textfield >
</td>
<td class="currency">
<s:set var="tzgBetrag">
<fmt:formatNumber type="NUMBER" maxFractionDigits="0"><s:property value="%{getBetrag()*100}"></s:property></fmt:formatNumber>
</s:set>
<s:textfield style="width:30px;" maxlength="3" name="model.get(#rowStatus.index).betrag" value="%{#tzgBetrag}" label="Betrag"></s:textfield >
</td>
</tr>
</s:iterator>
<s:submit style="width:24px; height:24px;" type="image" src="../../../res/24px/floppy-disk.png" value="Speichern"></s:submit>
</ul:form>
The ul-tag is from a custom taglib, which adds a customer specific url parameter to action path.
So when I display the page it shows all my Teilzeitgrad-records with a row for each entry. But when I submit the form, the list of my models is not populated. The setter setTeilzeitgrads(List<Teilzeitgrad> teilzeitgrads) is not even called at all.
I also tried to access the list in array-syntax:
<s:textfield style="width:70px;" name="teilzeitgrads[#rowStatus.index].datumAb" value="%{#datumAb_DE}" label="DatumAb"></s:textfield >
but this did also not work.
Any help solving this case is apreciated! Thanks in advance!
Lenzo
Ok - here is a very basic working example of list indexing. The main change is to move the creation of the model from getModel() to prepare(). This is because getModel() is called for every value you need to set the list - so you end up re-creating your model each time overwriting the previous change.
package com.blackbox.x.actions;
import java.util.ArrayList;
import java.util.List;
import com.blackbox.x.actions.ListDemo.ValuePair;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
public class ListDemo extends ActionSupport implements ModelDriven<List<ValuePair>>, Preparable {
private List<ValuePair> values;
#Override
public List<ValuePair> getModel() {
return values;
}
public String execute() {
for (ValuePair value: values) {
System.out.println(value.getValue1() + ":" + value.getValue2());
}
return SUCCESS;
}
public void prepare() {
values = new ArrayList<ValuePair>();
values.add(new ValuePair("chalk","cheese"));
values.add(new ValuePair("orange","apple"));
}
public class ValuePair {
private String value1;
private String value2;
public ValuePair(String value1, String value2) {
this.value1 = value1;
this.value2 = value2;
}
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
}
}
and the corresponding jsp
<%# taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
</head>
<body>
<s:form action="list-demo" theme="simple">
<table>
<s:iterator value="model" status="rowStatus">
<tr>
<td><s:textfield name="model[%{#rowStatus.index}].value1" value="%{model[#rowStatus.index].value1}"/></td>
<td><s:textfield name="model[%{#rowStatus.index}].value2" value="%{model[#rowStatus.index].value2}"/></td>
</tr>
</s:iterator>
</table>
<s:submit/>
</s:form>
</body>
</html>
Have you tried an approach like this?
<s:iterator var="teilzeitgrad" value="teilzeitgrads" status="listStatus">
<s:set name="paramName">teilzeitgrads[${ listStatus.index }].datumAb</s:set>
<s:textfield name="%{#paramName}" value="%{#teilzeitgrad.datumAb}"/>
</s:iterator>
You are submitting values to model, you have to submit them to your list teilzeitgrads.
For example see http://www.dzone.com/tutorials/java/struts-2/struts-2-example/struts-2-model-driven-action-example-1.html.
Update
How about
name="teilzeitgrads[%{#rowStatus.index}].datumBis".
Assuming you've got the configuration correct - the problem is probably due to the way you're defining the indexing. Try changing the name attribute on the textfield to use
model[%{#rowStatus.index}].datumBis
and let OGNL sort out the access methods. (I'd also use Firebug in Firefox to see what is actually being sent when you submit the form)
Thanks to all of you getting along with this issue! Your hints were most useful. I finally got it up and running rewriting everything from the scratch. I can edit my models now using the following Action-Class:
public class TeilzeitgradEditAction implements ModelDriven<List<Teilzeitgrad>> {
List<Teilzeitgrad> teilzeitgrads;
private String tzgTypKey;
private Integer jahr;
public String execute() {
return SUCCESS;
}
#Override
public List<Teilzeitgrad> getModel()
{
if(teilzeitgrads == null) {
teilzeitgrads = getTeilzeitgradListByTypAndJahr(tzgTypKey, jahr);
}
return teilzeitgrads;
}
public List<Teilzeitgrad> getTeilzeitgrads()
{
return teilzeitgrads;
}
public void setTeilzeitgrads(List<Teilzeitgrad> teilzeitgrads)
{
this.teilzeitgrads = teilzeitgrads;
}
// getters and setters for local attributes
}
and this JSP-Code:
<ul:form action="auth/GroupAdmin/processEditDienstabschnittJahr">
<s:iterator var="teilzeitgrad" value="teilzeitgrads" status="listStatus">
<tr>
<td>
<s:date name="%{#teilzeitgrad.datumAb}" var="datumAb_DE" format="dd.MM.yyyy" />
<s:textfield name="teilzeitgrads[%{#listStatus.index}].datumAb" value="%{#datumAb_DE}"/>
</td>
</tr>
</s:iterator>
<s:submit style="width:24px; height:24px;" type="image" src="../../../res/24px/floppy-disk.png" value="Speichern"></s:submit>
Thanks a lot for your support!
Cheers,
Lenzo

How to make a form submit when its rendered based on a value in a request scoped bean

I discovered a problem in my little program, and Im wondering if anyone have any tips or advice on how to solve this problem as best as possible.
I have the bean testBean which is in request scope. It contains the following:
public class testBean {
private boolean internal = false;
private String input = "";
public String internalTrue() {
System.out.println("Set internal true");
setInternal(true);
return null;
}
public String submitForm() {
System.out.println("");
return null;
}
public boolean isInternal() {
return internal;
}
public void setInternal(boolean internal) {
this.internal = internal;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
}
My file welcomeJSF.jsp contains this:
<f:view>
<h:form>
<h:commandButton value="Set internal true" action="#{testBean.internalTrue}" />
</h:form>
<h:panelGrid columns="1" rendered="#{testBean.internal}">
<h:form>
<h:outputText value="JavaServer Faces" /><h:inputText value="#{testBean.input}" />
<h:commandButton value="Go" action="#{testBean.submitForm}" />
</h:form>
</h:panelGrid>
</f:view>
When I run the application Im presented with the button "Set internal true". I click it and Im presented with the form where I have the button "Go". Clicking "Go" does not trigger the method in my bean, most likely because of the field actually not being rendered on the server anymore, and thus it wont run the method. Is there any smart solutions to this?
In advance, thanks for your time.
The children of the panel will never decode input because its rendered attribute always evaluates to false during the APPLY REQUEST VALUES phase. This is a sensible thing to do from a security point of view.
(source: ibm.com)
One thing you could do is take advantage of the fact that JSF components maintain state for the lifetime of the view.
The new bean:
public class TestBean {
private String input = null;
private UIComponent panel;
public String internalTrue() {
panel.setRendered(true);
return null;
}
public String submitForm() {
panel.setRendered(false);
System.out.println("submitForm");
return null;
}
public UIComponent getPanel() { return panel; }
public void setPanel(UIComponent panel) { this.panel = panel; }
public String getInput() { return input; }
public void setInput(String input) { this.input = input; }
}
The new view bound to the bean:
<f:view>
<h:form>
<h:commandButton value="Set internal true"
action="#{testBean.internalTrue}" />
</h:form>
<h:panelGrid binding="#{testBean.panel}" columns="1"
rendered="false">
<h:form>
<h:outputText value="JavaServer Faces" />
<h:inputText value="#{testBean.input}" />
<h:commandButton value="Go" action="#{testBean.submitForm}" />
</h:form>
</h:panelGrid>
</f:view>
Using the binding attribute on the panelGrid will cause setPanel to be called when the view is created/restored.
Note that you may have some testing to do depending on how your implementation's and/or libraries' StateManager stores views between requests (which may in turn be affected by the javax.faces.STATE_SAVING_METHOD init parameter). The view might be stored in a hidden field in the form, in the session keyed to the view ID (which may cause collisions with multiple browser windows), in the session keyed to a unique ID created by a GET or JSF navigation, or by some completely custom mechanism. The pluggable nature of the framework makes it versatile, but in this case it means you need to double-check how your implementation behaves.