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; 018 019import org.apache.wicket.Component; 020import org.apache.wicket.application.IComponentInstantiationListener; 021import org.apache.wicket.behavior.Behavior; 022import org.apache.wicket.markup.ComponentTag; 023import org.apache.wicket.markup.html.form.AbstractTextComponent; 024import org.apache.wicket.markup.html.form.Button; 025import org.apache.wicket.markup.html.form.FormComponent; 026import org.apache.wicket.model.IModel; 027import org.apache.wicket.validation.IValidator; 028import org.apache.wicket.validation.ValidatorAdapter; 029import org.apache.wicket.validation.validator.PatternValidator; 030 031/** 032 * Behavior which renders HTML5 attributes. 033 * 034 * @see #onInput(AbstractTextComponent, ComponentTag) 035 * @see #onButton(Button, ComponentTag) 036 */ 037public class HTML5Attributes extends Behavior 038{ 039 private static final long serialVersionUID = 1L; 040 041 @Override 042 public void onComponentTag(Component component, ComponentTag tag) 043 { 044 if (component instanceof AbstractTextComponent) 045 { 046 onInput((AbstractTextComponent<?>)component, tag); 047 } 048 else if (component instanceof Button) 049 { 050 onButton((Button)component, tag); 051 } 052 } 053 054 /** 055 * Writes HTML5 attributes for {@link AbstractTextComponent} inputs: 056 * 057 * <ul> 058 * <li>{@code required} if component {@link AbstractTextComponent#isRequired()}</li> 059 * <li>{@code placeholder} for {@link AbstractTextComponent#getLabel()}</li> 060 * <li>{@code pattern} for {@link AbstractTextComponent}s with a {@link PatternValidator}</li> 061 * <ul> 062 * 063 * @param input 064 * input component 065 * @param tag 066 * component tag 067 */ 068 protected void onInput(AbstractTextComponent<?> input, ComponentTag tag) 069 { 070 if (input.isRequired()) 071 { 072 tag.put("required", "required"); 073 } 074 075 IModel<String> label = input.getLabel(); 076 if (label != null && label.getObject() != null) 077 { 078 tag.put("placeholder", label.getObject()); 079 } 080 081 for (IValidator<?> validator : input.getValidators()) 082 { 083 while (validator instanceof ValidatorAdapter) 084 { 085 validator = ((ValidatorAdapter<?>)validator).getValidator(); 086 } 087 088 if (validator instanceof PatternValidator) 089 { 090 tag.put("pattern", ((PatternValidator)validator).getPattern().toString()); 091 } 092 } 093 } 094 095 /** 096 * Writes HTML5 attributes for {@link Button}s: 097 * 098 * <ul> 099 * <li>{@code formnovalidate} if {@link Button#getDefaultFormProcessing()} returns {@code false} 100 * </li> 101 * <ul> 102 * 103 * @param button 104 * button component 105 * @param tag 106 * component tag 107 */ 108 protected void onButton(Button button, ComponentTag tag) 109 { 110 if (!button.getDefaultFormProcessing()) 111 { 112 tag.put("formnovalidate", "formnovalidate"); 113 } 114 } 115 116 /** 117 * A listener to instantiations of {@link FormComponent}s to add HTML5 attributes. 118 */ 119 public static class InstantiationListener implements IComponentInstantiationListener 120 { 121 /** 122 * Adds {@link HTML5Attributes} to all {@link FormComponent}s. 123 */ 124 @Override 125 public void onInstantiation(Component component) 126 { 127 if (component instanceof FormComponent) 128 { 129 component.add(new HTML5Attributes()); 130 } 131 } 132 } 133}