/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.wicket.examples.forminput; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.List; import java.util.Locale; import org.apache.wicket.examples.WicketExamplePage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.Check; import org.apache.wicket.markup.html.form.CheckBox; import org.apache.wicket.markup.html.form.CheckGroup; import org.apache.wicket.markup.html.form.ChoiceRenderer; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.ListMultipleChoice; import org.apache.wicket.markup.html.form.Radio; import org.apache.wicket.markup.html.form.RadioChoice; import org.apache.wicket.markup.html.form.RadioGroup; import org.apache.wicket.markup.html.form.FormComponentUpdatingBehavior; import org.apache.wicket.markup.html.form.SimpleFormComponentLabel; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.request.http.WebRequest; import org.apache.wicket.util.convert.ConversionException; import org.apache.wicket.util.convert.IConverter; import org.apache.wicket.util.convert.MaskConverter; import org.apache.wicket.validation.validator.RangeValidator; /** * Example for form input. * * @author Eelco Hillenius * @author Jonathan Locke */ public class FormInput extends WicketExamplePage { /** * Form for collecting input. */ private class InputForm extends Form<FormInputModel> { /** * Construct. * * @param name * Component name */ @SuppressWarnings("serial") public InputForm(String name) { super(name, new CompoundPropertyModel<>(new FormInputModel())); // Dropdown for selecting locale add(new LocaleDropDownChoice("localeSelect")); // Link to return to default locale add(new Link<Void>("defaultLocaleLink") { public void onClick() { WebRequest request = (WebRequest)getRequest(); setLocale(request.getLocale()); } }); add(new TextField<String>("stringProperty").setRequired(true).setLabel( new Model<>("String"))); add(new TextField<>("integerProperty", Integer.class).setRequired(true).add( new RangeValidator<>(1, Integer.MAX_VALUE))); add(new TextField<>("doubleProperty", Double.class).setRequired(true)); add(new TextField<Integer>("integerInRangeProperty").setRequired(true).add( new RangeValidator<>(0, 100))); add(new CheckBox("booleanProperty")); add(new Multiply("multiply")); // display the multiply result Label multiplyLabel = new Label("multiplyLabel", new PropertyModel<Integer>( getDefaultModel(), "multiply")); // just for fun, add a border so that our result will be displayed as '[ x ]' multiplyLabel.add(new BeforeAndAfterBorder()); add(multiplyLabel); RadioChoice<String> rc = new RadioChoice<>("numberRadioChoice", NUMBERS).setSuffix(""); rc.setLabel(new Model<>("number")); rc.setRequired(true); add(rc); RadioGroup<String> group = new RadioGroup<>("numbersGroup"); add(group); ListView<String> persons = new ListView<String>("numbers", NUMBERS) { @Override protected void populateItem(ListItem<String> item) { Radio<String> radio = new Radio<>("radio", item.getModel()); radio.setLabel(item.getModel()); item.add(radio); item.add(new SimpleFormComponentLabel("number", radio)); } }.setReuseItems(true); group.add(persons); CheckGroup<String> checks = new CheckGroup<>("numbersCheckGroup"); add(checks); ListView<String> checksList = new ListView<String>("numbers", NUMBERS) { @Override protected void populateItem(ListItem<String> item) { Check<String> check = new Check<>("check", item.getModel()); check.setLabel(item.getModel()); item.add(check); item.add(new SimpleFormComponentLabel("number", check)); } }.setReuseItems(true); checks.add(checksList); add(new ListMultipleChoice<>("siteSelection", SITES)); // TextField using a custom converter. add(new TextField<URL>("urlProperty", URL.class) { @Override protected IConverter<?> createConverter(Class<?> type) { if (URL.class.isAssignableFrom(type)) { return URLConverter.INSTANCE; } return null; } }); // TextField using a mask converter add(new TextField<UsPhoneNumber>("phoneNumberUS", UsPhoneNumber.class) { @Override protected IConverter<?> createConverter(Class<?> type) { if (UsPhoneNumber.class.isAssignableFrom(type)) { // US telephone number mask return new MaskConverter<>("(###) ###-####", UsPhoneNumber.class); } return null; } }); // and this is to show we can nest ListViews in Forms too add(new LinesListView("lines")); add(new Button("saveButton")); add(new Button("resetButton") { @Override public void onSubmit() { setResponsePage(FormInput.class); } }.setDefaultFormProcessing(false)); } @Override public void onSubmit() { // Form validation successful. Display message showing edited model. info("Saved model " + getDefaultModelObject()); } } /** list view to be nested in the form. */ private static final class LinesListView extends ListView<String> { /** * Construct. * * @param id */ public LinesListView(String id) { super(id); // always do this in forms! setReuseItems(true); } @Override protected void populateItem(ListItem<String> item) { // add a text field that works on each list item model (returns // objects of type FormInputModel.Line) using property text. item.add(new TextField<>("lineEdit", new PropertyModel<String>( item.getDefaultModel(), "text"))); } } /** * Choice for a locale. */ private final class LocaleChoiceRenderer extends ChoiceRenderer<Locale> { @Override public Object getDisplayValue(Locale locale) { return locale.getDisplayName(getLocale()); } } /** * Dropdown with Locales. */ private final class LocaleDropDownChoice extends DropDownChoice<Locale> { /** * Construct. * * @param id * component id */ public LocaleDropDownChoice(String id) { super(id, FormInputApplication.LOCALES, new LocaleChoiceRenderer()); // set the model that gets the current locale, and that is used for // updating the current locale to property 'locale' of FormInput setModel(new PropertyModel<>(FormInput.this, "locale")); add(new FormComponentUpdatingBehavior() { @Override protected void onUpdate() { // note that we don't have to do anything here, as our property // model already calls FormInput.setLocale when the model is // updated // force re-render by setting the page to render to the bookmarkable // instance, so that the page will be rendered from scratch, // re-evaluating the input patterns etc setResponsePage(FormInput.class); } }); } } /** available sites for the multiple select. */ private static final List<String> SITES = Arrays.asList("The Server Side", "Java Lobby", "Java.Net"); /** available numbers for the radio selection. */ static final List<String> NUMBERS = Arrays.asList("1", "2", "3"); /** * Constructor */ public FormInput() { // Construct form and feedback panel and hook them up final FeedbackPanel feedback = new FeedbackPanel("feedback"); add(feedback); add(new InputForm("inputForm")); } /** * Sets locale for the user's session (getLocale() is inherited from Component) * * @param locale * The new locale */ public void setLocale(Locale locale) { if (locale != null) { getSession().setLocale(locale); } } private static class URLConverter implements IConverter<URL> { public static final URLConverter INSTANCE = new URLConverter(); @Override public URL convertToObject(String value, Locale locale) { try { return new URL(value); } catch (MalformedURLException e) { throw new ConversionException("'" + value + "' is not a valid URL"); } } @Override public String convertToString(URL value, Locale locale) { return value != null ? value.toString() : null; } } }