Clear JSF form input values after submitting - forms

If there's a form, and has a textbox and a button, how do you erase the content of the textbox after you submit the form?
<h:inputText id="name" value="#{bean.name}" />
<h:commandButton id="submit" value="Add Name" action="#{bean.submit}" />
After I enter a value in the textbox and submit, the value still appears in the textbox. I need to clear the content of the textbox once its been submitted. How can I achieve this?

Introduction
There are several ways to achieve this. The naive way is to simply null out the fields in backing bean. The insane way is to grab JS/jQuery for the job which does that after submit or even during page load. Those ways only introduces unnecessary code and indicates a thinking/design problem. All you want is just starting with a fresh request/page/view/bean. Like as you would get with a GET request.
POST-Redirect-GET
The best way is thus to just send a redirect after submit. You probably already ever heard of it: POST-Redirect-GET. It gives you a fresh new GET request after a POST request (a form submit), exactly as you intended. This has the additional benefit that the previously submitted data isn't re-submitted when the enduser ignorantly presses F5 afterwards and ignores the browser warning.
There are several ways to perform PRG in JSF.
Just return to same view with faces-redirect=true query string. Assuming a /page.xhtml, you could do so in action method:
public String submit() {
// ...
return "/page.xhtml?faces-redirect=true";
}
If you're still fiddling around with navigation cases the JSF 1.x way, then it's a matter of adding <redirect/> to the navigation case in question. See also How to make redirect using navigation-rule.
To make it more reusable, you can obtain the view ID programmatically:
public String submit() {
// ...
UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
return view.getViewId() + "?faces-redirect=true";
}
Either way, if you've view parameters which needs to be retained in the request URL as well, then append &includeViewParams=true to the outcome. See also Retaining GET request query string parameters on JSF form submit.
If you're making use of some URL rewriting solution which runs outside JSF context, then you'd best grab the current request URL (with query string) and use ExternalContext#redirect() to redirect to exactly that.
public void submit() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
StringBuffer requestURL = ((HttpServletRequest) ec.getRequest()).getRequestURL();
String queryString = ((HttpServletRequest) ec.getRequest()).getQueryString();
ec.redirect((queryString == null) ? requestURL.toString() : requestURL.append('?').append(queryString).toString());
}
It's only a mess which should really be refactored to some utility class.
Request/View scoped bean
Note that this all works only nicely in combination with request or view scoped beans. If you've a session scoped bean tied to the form, then the bean wouldn't be recreated from scratch. You've then another problem which needs to be solved as well. Split it into a smaller session scoped one for the session scoped data and a view scoped one for the view scoped data. See also How to choose the right bean scope?
Faces Messages
If you've a faces message to be shown as result of successful action, then just make it a flash message. See also How to show faces message in the redirected page.
public String submit() {
// ...
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(clientId, message);
context.getExternalContext().getFlash().setKeepMessages(true);
return "/page.xhtml?faces-redirect=true";
}
Ajax
Only if you happen to have an ajax-only page on which a F5 would always trigger a fresh new GET request, then simply nulling out the model field(s) in action method shouldn't harm that much.
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
Pure Java/JSF implementation for double submit prevention

You can blank out the property of the managed bean that should not be repainted when you render the response. This can be done done using code similar to the snippet posted below:
private String name;
public String getName(){return name;}
public void setName(String name){this.name=name};
public String submit()
{
//do some processing
...
// blank out the value of the name property
name = null;
// send the user back to the same page.
return null;
}
The reason for the current behavior can be found in how the JSF runtime processes requests. All JSF requests to a view are processed in accordance with the JSF standard request-response lifecyle. In accordance with the lifecyle, the managed bean contents are updated with the value from request (i.e. the value of DataForm.Name is set) before the application event (DataForm.submit) is executed. When the page is rendered in the Render Response phase, the current value of the bean is used to render the view back to the user. Unless the value is changed in an application event, the value will always be one that is applied from the request.

You can clear the form from the Bean method that gets called when the form is submitted;`
private String name;
private String description;
private BigDecimal price;
/*----------Properties ------------*/
/*-----Getter and Setter Methods---*/
public void save()throws SQLException{
String sql = "INSERT INTO tableName(name,description,price) VALUES (?,?,?)";
Connection conn = ds.getConnection();
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, getName());
pstmt.setString(2, getDescription());
pstmt.setBigDecimal(3, getPrice());
pstmt.executeUpdate();
} catch (SQLException e) {
e.getMessage();
e.toString();
}finally{
conn.close();
clear();
}
}//End Save Method
public void clear(){
setName(null);
setDescription(null);
setPrice(null);
}//end clear`
Notice that the clear() method is called from the save method after all the operations of the save method is complete. As an option you could perform the clearing only if the methods operation was successful...The method below is placed in the ProductController Class...
public String saveProduct(){
try {
product.save();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
The method call from the view/jsp would look like the Following:
<h:commandButton value="Save" action="#{productController.saveProduct}"/>

You can do it with jQuery.
I had the similar problem. I needed to clear popup window form.
<rich:popupPanel id="newProjectDialog" autosized="true"
header="Create new project">
<h:form id="newProjectForm">
<h:panelGrid columns="2">
<h:outputText value="Project name:" />
<h:inputText id="newProjectDialogProjectName"
value="#{userMain.newProject.projectName}" required="true" />
<h:outputText value="Project description:" />
<h:inputText id="newProjectDialogProjectDescription"
value="#{userMain.newProject.projectDescription}" required="true" />
</h:panelGrid>
<a4j:commandButton id="newProjectDialogSubmit" value="Submit"
oncomplete="#{rich:component('newProjectDialog')}.hide(); return false;"
render="projects" action="#{userMain.addNewProject}" />
<a4j:commandButton id="newProjectDialogCancel" value="Cancel"
onclick="#{rich:component('newProjectDialog')}.hide(); return false;" />
</h:form>
</rich:popupPanel>
jQuery code:
$('#newProjectForm').children('input').on('click', function(){$('#newProjectForm').find('table').find('input').val('');});

I added a code snippet how to reset all values for the current ViewRoot recursively for JSF 2 here:
Reset all fields in form
This works for submitted forms showing validation errors as well as for newly entered values in a form.

Related

CustomAction Types in AEM From Component

I am creating a form using form-components. I have email-field and UserName field. I want to send an email to the given email id on click of submit button. In the form I select my custom action type which invoke a servlet which is responsible to send an email. My custom action type has only forward.jsp as script file :
<%#page import="com.day.cq.wcm.foundation.forms.FormsConstants"%><sling:defineObjects/><%
System.out.println(":::::::::::::::"+resource.getPath());
FormsHelper.setForwardPath(slingRequest, resource.getPath() + ".custommail.html");
FormsHelper.setRedirectToReferrer(request, true);
%>
I can see my forward.jsp is getting called when i click submit button, as i can see resourcePath(content/geometrixx/en/toolbar/newsletter/jcr:content/par/start) in stdout.log. But servlet not getting call, In case i hit localhost:4502/content/geometrixx/en/toolbar/newsletter/jcr:content/par/start.custommail.html servlet gets invoke, don't know why its not invoking with FormsHelper.
And also how can we pass parameter i.e. email-field to servlet.
Any Idea.
Thanks
You need to have a servlet registered to your form start component and the proper selector. If you are using the foundation form this would be something like this:
#SlingServlet(resoruceTypes = "foundation/components/form/start", methods = "POST", selectors = "custommail", extenstions = "html", generateComponent = false)
public class CustomMailServlet extends SlingAllMethodsServlet {
#Override
protected void doPost(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException, IOException {
//your code here
}
}
Checkout this blog http://labs.sixdimensions.com/blog/2012-08-20/sending-email-adobe-cq-api/ to get and understanding of Email functionality in AEM.

Why the getters in JSF2 Bean class are getting invoked even before submitting the Form elements? [duplicate]

Let's say I specify an outputText component like this:
<h:outputText value="#{ManagedBean.someProperty}"/>
If I print a log message when the getter for someProperty is called and load the page, it is trivial to notice that the getter is being called more than once per request (twice or three times is what happened in my case):
DEBUG 2010-01-18 23:31:40,104 (ManagedBean.java:13) - Getting some property
DEBUG 2010-01-18 23:31:40,104 (ManagedBean.java:13) - Getting some property
If the value of someProperty is expensive to calculate, this can potentially be a problem.
I googled a bit and figured this is a known issue. One workaround was to include a check and see if it had already been calculated:
private String someProperty;
public String getSomeProperty() {
if (this.someProperty == null) {
this.someProperty = this.calculatePropertyValue();
}
return this.someProperty;
}
The main problem with this is that you get loads of boilerplate code, not to mention private variables that you might not need.
What are the alternatives to this approach? Is there a way to achieve this without so much unnecessary code? Is there a way to stop JSF from behaving in this way?
Thanks for your input!
This is caused by the nature of deferred expressions #{} (note that "legacy" standard expressions ${} behave exactly the same when Facelets is used instead of JSP). The deferred expression is not immediately evaluated, but created as a ValueExpression object and the getter method behind the expression is executed everytime when the code calls ValueExpression#getValue().
This will normally be invoked one or two times per JSF request-response cycle, depending on whether the component is an input or output component (learn it here). However, this count can get up (much) higher when used in iterating JSF components (such as <h:dataTable> and <ui:repeat>), or here and there in a boolean expression like the rendered attribute. JSF (specifically, EL) won't cache the evaluated result of the EL expression at all as it may return different values on each call (for example, when it's dependent on the currently iterated datatable row).
Evaluating an EL expression and invoking a getter method is a very cheap operation, so you should generally not worry about this at all. However, the story changes when you're performing expensive DB/business logic in the getter method for some reason. This would be re-executed everytime!
Getter methods in JSF backing beans should be designed that way that they solely return the already-prepared property and nothing more, exactly as per the Javabeans specification. They should not do any expensive DB/business logic at all. For that the bean's #PostConstruct and/or (action)listener methods should be used. They are executed only once at some point of request-based JSF lifecycle and that's exactly what you want.
Here is a summary of all different right ways to preset/load a property.
public class Bean {
private SomeObject someProperty;
#PostConstruct
public void init() {
// In #PostConstruct (will be invoked immediately after construction and dependency/property injection).
someProperty = loadSomeProperty();
}
public void onload() {
// Or in GET action method (e.g. <f:viewAction action>).
someProperty = loadSomeProperty();
}
public void preRender(ComponentSystemEvent event) {
// Or in some SystemEvent method (e.g. <f:event type="preRenderView">).
someProperty = loadSomeProperty();
}
public void change(ValueChangeEvent event) {
// Or in some FacesEvent method (e.g. <h:inputXxx valueChangeListener>).
someProperty = loadSomeProperty();
}
public void ajaxListener(AjaxBehaviorEvent event) {
// Or in some BehaviorEvent method (e.g. <f:ajax listener>).
someProperty = loadSomeProperty();
}
public void actionListener(ActionEvent event) {
// Or in some ActionEvent method (e.g. <h:commandXxx actionListener>).
someProperty = loadSomeProperty();
}
public String submit() {
// Or in POST action method (e.g. <h:commandXxx action>).
someProperty = loadSomeProperty();
return "outcome";
}
public SomeObject getSomeProperty() {
// Just keep getter untouched. It isn't intented to do business logic!
return someProperty;
}
}
Note that you should not use bean's constructor or initialization block for the job because it may be invoked multiple times if you're using a bean management framework which uses proxies, such as CDI.
If there are for you really no other ways, due to some restrictive design requirements, then you should introduce lazy loading inside the getter method. I.e. if the property is null, then load and assign it to the property, else return it.
public SomeObject getSomeProperty() {
// If there are really no other ways, introduce lazy loading.
if (someProperty == null) {
someProperty = loadSomeProperty();
}
return someProperty;
}
This way the expensive DB/business logic won't unnecessarily be executed on every single getter call.
See also:
Why is the getter called so many times by the rendered attribute?
Invoke JSF managed bean action on page load
How and when should I load the model from database for h:dataTable
How to populate options of h:selectOneMenu from database?
Display dynamic image from database with p:graphicImage and StreamedContent
Defining and reusing an EL variable in JSF page
Measure the render time of a JSF view after a server request
With JSF 2.0 you can attach a listener to a system event
<h:outputText value="#{ManagedBean.someProperty}">
<f:event type="preRenderView" listener="#{ManagedBean.loadSomeProperty}" />
</h:outputText>
Alternatively you can enclose the JSF page in an f:view tag
<f:view>
<f:event type="preRenderView" listener="#{ManagedBean.loadSomeProperty}" />
.. jsf page here...
<f:view>
I have written an article about how to cache JSF beans getter with Spring AOP.
I create a simple MethodInterceptor which intercepts all methods annotated with a special annotation:
public class CacheAdvice implements MethodInterceptor {
private static Logger logger = LoggerFactory.getLogger(CacheAdvice.class);
#Autowired
private CacheService cacheService;
#Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
String key = methodInvocation.getThis() + methodInvocation.getMethod().getName();
String thread = Thread.currentThread().getName();
Object cachedValue = cacheService.getData(thread , key);
if (cachedValue == null){
cachedValue = methodInvocation.proceed();
cacheService.cacheData(thread , key , cachedValue);
logger.debug("Cache miss " + thread + " " + key);
}
else{
logger.debug("Cached hit " + thread + " " + key);
}
return cachedValue;
}
public CacheService getCacheService() {
return cacheService;
}
public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}
}
This interceptor is used in a spring configuration file:
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut">
<bean class="org.springframework.aop.support.annotation.AnnotationMatchingPointcut">
<constructor-arg index="0" name="classAnnotationType" type="java.lang.Class">
<null/>
</constructor-arg>
<constructor-arg index="1" value="com._4dconcept.docAdvance.jsfCache.annotation.Cacheable" name="methodAnnotationType" type="java.lang.Class"/>
</bean>
</property>
<property name="advice">
<bean class="com._4dconcept.docAdvance.jsfCache.CacheAdvice"/>
</property>
</bean>
Hope it will help!
Originally posted in PrimeFaces forum # http://forum.primefaces.org/viewtopic.php?f=3&t=29546
Recently, I have been obsessed evaluating the performance of my app, tuning JPA queries, replacing dynamic SQL queries with named queries, and just this morning, I recognized that a getter method was more of a HOT SPOT in Java Visual VM than the rest of my code (or majority of my code).
Getter method:
PageNavigationController.getGmapsAutoComplete()
Referenced by ui:include in in index.xhtml
Below, you will see that PageNavigationController.getGmapsAutoComplete() is a HOT SPOT (performance issue) in Java Visual VM. If you look further down, on the screen capture, you will see that getLazyModel(), PrimeFaces lazy datatable getter method, is a hot spot too, only when enduser is doing a lot of 'lazy datatable' type of stuff/operations/tasks in the app. :)
See (original) code below.
public Boolean getGmapsAutoComplete() {
switch (page) {
case "/orders/pf_Add.xhtml":
case "/orders/pf_Edit.xhtml":
case "/orders/pf_EditDriverVehicles.xhtml":
gmapsAutoComplete = true;
break;
default:
gmapsAutoComplete = false;
break;
}
return gmapsAutoComplete;
}
Referenced by the following in index.xhtml:
<h:head>
<ui:include src="#{pageNavigationController.gmapsAutoComplete ? '/head_gmapsAutoComplete.xhtml' : (pageNavigationController.gmaps ? '/head_gmaps.xhtml' : '/head_default.xhtml')}"/>
</h:head>
Solution: since this is a 'getter' method, move code and assign value to gmapsAutoComplete prior to method being called; see code below.
/*
* 2013-04-06 moved switch {...} to updateGmapsAutoComplete()
* because performance = 115ms (hot spot) while
* navigating through web app
*/
public Boolean getGmapsAutoComplete() {
return gmapsAutoComplete;
}
/*
* ALWAYS call this method after "page = ..."
*/
private void updateGmapsAutoComplete() {
switch (page) {
case "/orders/pf_Add.xhtml":
case "/orders/pf_Edit.xhtml":
case "/orders/pf_EditDriverVehicles.xhtml":
gmapsAutoComplete = true;
break;
default:
gmapsAutoComplete = false;
break;
}
}
Test results: PageNavigationController.getGmapsAutoComplete() is no longer a HOT SPOT in Java Visual VM (doesn't even show up anymore)
Sharing this topic, since many of the expert users have advised junior JSF developers to NOT add code in 'getter' methods. :)
If you are using CDI, you can use Producers methods.
It will be called many times, but the result of first call is cached in scope of the bean and is efficient for getters that are computing or initializing heavy objects!
See here, for more info.
You could probably use AOP to create some sort of Aspect that cached the results of our getters for a configurable amount of time. This would prevent you from needing to copy-and-paste boilerplate code in dozens of accessors.
If the value of someProperty is
expensive to calculate, this can
potentially be a problem.
This is what we call a premature optimization. In the rare case that a profiler tells you that the calculation of a property is so extraordinarily expensive that calling it three times rather than once has a significant performance impact, you add caching as you describe. But unless you do something really stupid like factoring primes or accessing a databse in a getter, your code most likely has a dozen worse inefficiencies in places you've never thought about.
I would also advice using such Framework as Primefaces instead of stock JSF, they address such issues before JSF team e. g in primefaces you can set partial submit. Otherwise BalusC has explained it well.
It still big problem in JSF. Fo example if you have a method isPermittedToBlaBla for security checks and in your view you have rendered="#{bean.isPermittedToBlaBla} then the method will be called multiple times.
The security check could be complicated e.g . LDAP query etc. So you must avoid that with
Boolean isAllowed = null ... if(isAllowed==null){...} return isAllowed?
and you must ensure within a session bean this per request.
Ich think JSF must implement here some extensions to avoid multiple calls (e.g annotation #Phase(RENDER_RESPONSE) calle this method only once after RENDER_RESPONSE phase...)

How to manage errors when creating an ICEFaces' OutputReource

I am trying to generate an export file out of some items, which should conform to some "criteria" in order to be able to be exported. The thing is: the user should select some items (by using checkboxes) and then click on the ICEFaces' OutputResource in order to export (hopefully all) the selected items.
The parts involved in this process are the following:
The OutputResource in the XHTML:
<ice:outputResource rendered="#{not myBackingBean.emptySelection}" resource="#{myBackingBean.excelResource}" label="export to Excel" shared="false" target="_self" />
The backing bean holding the resource:
#ManagedBean(name = "myBackingBean")
#ViewScoped
#WindowDisposed
public class MyBackingBean implements Serializable
{
...
private ExcelResource resource;
...
}
And, finally, the actual resource:
...
import com.icesoft.faces.context.Resource;
...
public class ExcelResource implements Resource
{
...
#Override
public InputStream open() throws IOException
{
//do some selection here. If there is no valid ticket to export then
//this method will return null, otherwise it will return an InputStream
//and everything will work properly
if (everythingOk)
{
return new ByteArrayInputStream(...);
}
//hopefully, it won't get to this point
return null;
}
As you can see, I'm implementing the com.icesoft.faces.context.Resource interface and overriding the open() method to create the Excel export "on the fly".
Now, once againg, what I want to do is to filter some of the originally selected items and, in case no item is left, navigate to some error page. If this was an h:commandButton or an ice:commandLink then I would use the action property to do it, but I cannot do this here because this is an ice:outputResource. Is there some workaround for this?. Please notice it is not enough to use the rendered property to do this because the user can select something (which will immediately render the ice:outputResource) but the selection should be filtered before exporting it.
Last but not least: I'm using Websphere 8 and ICEFaces 3 to do this.
Thanks in advance!
I've managed to do what I was looking for, this time using some buttons with real actions to redirect to pages.
What I did was the following:
MyBackingBean has now a method to determine whether or not the selection is empty;
It also has a method to determine if the selection is valid (this is: not empty and without any invalid item in it);
There is an <ice:commandLink> rendered when the selection is invalid. This commandLink has the actual redirection to the error page.
The <ice:outputResource> will be rendered when the <ice:commandLink> is not rendered (i.e.: when the selection is completely valid).
And now, the code:
First, the commandLink:
<ice:commandLink rendered="#{not myBackingBean.validSelection}"
disabled="#{myBackingBean.emptySelection}"
label="download excel report}"
action="redirect_to_error_page" />
Remember:
MyBackingBean.isEmptySelection() returns true if there is no item selected.
MyBackingBean.isValidSelection() returns true if there is at least one item selected and also each and every selected item is a valid item (this is: an item that is valid for export)
Now, the outputResource:
<ice:outputResource
rendered="#{myBackingBean.validSelection}"
resource="#{myBackingBean.excelResource}"
label="download excel report}" shared="false" target="_self" />
Last but not least, you may have figured out the fact that the <ice:outputResource> will now handle only valid selection (the actual redirection to the error page is being done by the <ice:commandLink>). This means there has to be a way to filter the items before passing them to the resource for the actual export. Well, in my case I decided to create a filter(...) method in the backing bean.
#ManagedBean(name = "myBackingBean")
#ViewScoped
#WindowDisposed
public class MyBackingBean implements Serializable
{
...
private ExcelResource resource;
...
public List<MyItems> getFilteredList(List<MyItems> allSelectedItems)
{
...
//do some selection here and return a list containing only valid items
return validItemsList;
}
public ExcelResource getExcelResource()
{
return new ExcelResource(getFilteredList(allSelectedItems));
}
public boolean isEmptySelection()
{
//return true if the selection is EMPTY, false otherwise.
}
public boolean isValidSelection()
{
//return true if the selection is NOT EMPTY and it has
//only VALID items in it, false otherwise.
}
}
This way you can generate the ExcelResource "on the fly" with nothing but valid items in it. By the time the <ice:outputResource> is being rendered in the XHTML, it will contain only valid and exportable items!.
I hope someone will find this useful :)

<h:form> within <ui:repeat> not entirely working, only the last <h:form> is processed

I will like to edit a list of items in the same page. Each item should be edited using a separate form. I am creating a h:form within ui:repeat. Only when the last form is submitted, the user input is applied to the managed bean. For all other forms, user input is not applied to the model.
#ManagedBean
public class Controller {
Logger logger = Logger.getLogger("TestWeb");
private List<Customer> customerList;
public List<Customer> getCustomerList() {
if (customerList == null) {
customerList = new ArrayList<Customer>();
customerList.add(new Customer("Daffy Duck", "daffy#example.com"));
customerList.add(new Customer("Bugs Bunny", "bugs#example.com"));
customerList.add(new Customer("Samity Sam", "sam#example.com"));
}
return customerList;
}
public String updateCustomer(Customer c) {
logger.info("Updating: " + c.getName());
return null;
}
}
In the view, I have
<ui:repeat var="c" value="#{controller.customerList}">
<h:form>
<h3>Edit Customer</h3>
Name: <h:inputText value="#{c.name}"/><br/>
E-mail: <h:inputText value="#{c.email}"/><br/>
<h:commandButton value="Update"
action="#{controller.updateCustomer(c)}"/>
</h:form>
</ui:repeat>
I search for hours without any solution. What will be the correct way to do this? I can hack it by using a single form and using a ui:repeat within it. But there are many issues with that and I will rather not take that route. Thanks.
This is a bug in state saving of <ui:repeat> in Mojarra. There are several similar issue reports at http://java.net/jira/browse/JAVASERVERFACES, among others issue 2243.
You have basically 2 options: use another iterating component (e.g. <c:forEach>, <h:dataTable>, <t:dataList>, <p:dataList>, etc), or replace Mojarra by MyFaces (the <ui:repeat> in this construct works properly in there).

Default value of form object's field

I have a form where depending on the select state ([checkboxOn/checkboxOff]) a check box should appear or not. When the check box is displayed it should be checked by default.
How to handle that situation, taking into account that
when select is in 'checkboxOff'
state, I would have
MyFormObject.isCheckboxOn == false;
when select is in 'checkboxOn' state,
the value should be as in request?
All of this should work also on Validation errors postback, and when new form is shown and on valid form case.
Also, I would like to avoid using JavaScript on client side.
Here is some code, which needed to be extended:
class MyFormObject {
private String selectValue;
private boolean isCheckboxOn;
...
}
and two Spring controller's method:
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
return new ModelAndView('/form.jsp', 'command', new MyFormObject());
}
#RequestMapping(method = RequestMethod.POST)
public ModelAndView processSubmit(BindingResult result, MyFormObject command) {
if (result.hasErrors()) {
return new ModelAndView('/form', 'command', command);
}
...
return new ModelAndView('redirect:/success.jsp');
}
If you want to exclude the checkbox field from your view when isCheckboxOn is set to false, you can surround the checkbox field with a c:if in your JSP:
<c:if test="isCheckboxOn">
(your checkbox <input> tag goes here)
</c:if>
To check the box by default, you can use Spring's form tag library to bind directly to the checkbox field in the model, or you can use another c:if to add a checked to your <input> tag.