001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.markup.html.form; 018 019import java.util.Iterator; 020import java.util.List; 021 022import org.apache.wicket.model.IModel; 023import org.apache.wicket.request.mapper.parameter.INamedParameters; 024import org.apache.wicket.request.mapper.parameter.PageParameters; 025import org.apache.wicket.util.string.Strings; 026import org.apache.wicket.util.visit.IVisit; 027import org.apache.wicket.util.visit.IVisitor; 028 029/** 030 * This StatelessForm is the same as a normal form but with the statelesshint default to true. The 031 * form can be newly constructed when the onSubmit of its form or its buttons is called. So you 032 * can't depend on state within the page. The only state you can depend on is what was submitted 033 * from the browser. So the model of the form or the formcomponents are updated with the submit 034 * values. 035 * 036 * <strong>Note</strong>: Use {@link org.apache.wicket.markup.repeater.RepeatingView} in the case when 037 * {@link org.apache.wicket.markup.html.form.FormComponent}s need to be rendered inside a repeater. See 038 * the javadoc of {@link org.apache.wicket.markup.repeater.AbstractRepeater} for more information. 039 * 040 * @author jcompagner 041 * @param <T> 042 * The type of the {@link Form}'s model object 043 */ 044public class StatelessForm<T> extends Form<T> 045{ 046 private static final long serialVersionUID = 1L; 047 048 /** 049 * Construct. 050 * 051 * @param id 052 */ 053 public StatelessForm(String id) 054 { 055 super(id); 056 } 057 058 /** 059 * Construct. 060 * 061 * @param id 062 * @param model 063 */ 064 public StatelessForm(String id, IModel<T> model) 065 { 066 super(id, model); 067 } 068 069 @Override 070 protected boolean getStatelessHint() 071 { 072 return true; 073 } 074 075 @Override 076 protected MethodMismatchResponse onMethodMismatch() 077 { 078 setResponsePage(getPage().getClass(), getPage().getPageParameters()); 079 return MethodMismatchResponse.ABORT; 080 } 081 082 @Override 083 protected CharSequence getActionUrl() 084 { 085 return urlForListener(getPage().getPageParameters()); 086 } 087 088 /** 089 * Remove the page parameters for all form component otherwise they get appended to action URL 090 * 091 * {@inheritDoc} 092 */ 093 @Override 094 public void process(IFormSubmitter submittingComponent) 095 { 096 // get the parameters before processing the form because the 097 // application may remove this form from its parent in #onSubmit() (WICKET-5158) 098 final PageParameters parameters = getPage().getPageParameters(); 099 100 super.process(submittingComponent); 101 102 if (parameters != null) 103 { 104 visitFormComponents(new IVisitor<FormComponent<?>, Void>() 105 { 106 @Override 107 public void component(final FormComponent<?> formComponent, final IVisit<Void> visit) 108 { 109 parameters.remove(formComponent.getInputName()); 110 } 111 }); 112 if (submittingComponent instanceof AbstractSubmitLink) 113 { 114 AbstractSubmitLink submitLink = (AbstractSubmitLink)submittingComponent; 115 parameters.remove(submitLink.getInputName()); 116 } 117 118 // remove the special parameter for IRequestListener 119 List<INamedParameters.NamedPair> namedParameters = parameters.getAllNamed(); 120 Iterator<INamedParameters.NamedPair> iterator = namedParameters.iterator(); 121 while (iterator.hasNext()) 122 { 123 INamedParameters.NamedPair namedParameter = iterator.next(); 124 if (Strings.isEmpty(namedParameter.getValue())) 125 { 126 parameters.remove(namedParameter.getKey()); 127 break; 128 } 129 } 130 } 131 } 132}