| /* |
| * 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.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(Link.onClick("defaultLocaleLink", (link) -> { |
| 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 |
| public 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 |
| public 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(Button.onSubmit("resetButton", (btn) -> { |
| // just set a new instance of the page |
| 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")); |
| } |
| |
| @Override |
| public void onSelectionChanged(Locale newSelection) |
| { |
| // 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); |
| } |
| |
| /** |
| * @see org.apache.wicket.markup.html.form.DropDownChoice#wantOnSelectionChangedNotifications() |
| */ |
| @Override |
| protected boolean wantOnSelectionChangedNotifications() |
| { |
| // we want round-trips when a the user selects another item |
| return true; |
| } |
| } |
| |
| /** 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; |
| } |
| } |
| } |