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.ajax.form; 018 019import org.apache.wicket.Component; 020import org.apache.wicket.WicketRuntimeException; 021import org.apache.wicket.ajax.AjaxRequestTarget; 022import org.apache.wicket.ajax.attributes.AjaxCallListener; 023import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; 024import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice; 025import org.apache.wicket.markup.html.form.CheckGroup; 026import org.apache.wicket.markup.html.form.FormComponent; 027import org.apache.wicket.markup.html.form.RadioChoice; 028import org.apache.wicket.markup.html.form.RadioGroup; 029import org.apache.wicket.util.lang.Args; 030import org.danekja.java.util.function.serializable.SerializableConsumer; 031 032/** 033 * This is an Ajax behavior that is meant to update a group of choices that are represented 034 * by multiple components. 035 * <p> 036 * Use the normal {@link AjaxFormComponentUpdatingBehavior} for the normal single component fields. 037 * <p> 038 * Notification is triggered by a {@code change} JavaScript event - if needed {@link #getEvent()} can be overridden 039 * to deviate from this default. 040 * 041 * @author jcompagner 042 * @author svenmeier 043 * 044 * @see org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior#onUpdate(org.apache.wicket.ajax.AjaxRequestTarget) 045 * @see org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior#onError(org.apache.wicket.ajax.AjaxRequestTarget, RuntimeException) 046 * @see RadioChoice 047 * @see CheckBoxMultipleChoice 048 * @see RadioGroup 049 * @see CheckGroup 050 */ 051public abstract class AjaxFormChoiceComponentUpdatingBehavior extends 052 AjaxFormComponentUpdatingBehavior 053{ 054 private static final long serialVersionUID = 1L; 055 056 /** 057 * Construct. 058 */ 059 public AjaxFormChoiceComponentUpdatingBehavior() 060 { 061 super("change"); 062 } 063 064 @Override 065 protected void updateAjaxAttributes(AjaxRequestAttributes attributes) 066 { 067 super.updateAjaxAttributes(attributes); 068 069 attributes.setSerializeRecursively(true); 070 attributes.getAjaxCallListeners().add(new AjaxCallListener() 071 { 072 private static final long serialVersionUID = 1L; 073 074 @Override 075 public CharSequence getPrecondition(Component component) 076 { 077 return String.format("return attrs.event.target.name === '%s'", getFormComponent().getInputName()); 078 } 079 }); 080 } 081 082 /** 083 * 084 * @see org.apache.wicket.behavior.AbstractAjaxBehavior#onBind() 085 */ 086 @Override 087 protected void onBind() 088 { 089 super.onBind(); 090 091 if (getComponent() instanceof RadioGroup || getComponent() instanceof CheckGroup) 092 { 093 getComponent().setRenderBodyOnly(false); 094 } 095 } 096 097 @Override 098 protected void checkComponent(FormComponent<?> component) 099 { 100 if (!AjaxFormChoiceComponentUpdatingBehavior.appliesTo(getComponent())) 101 { 102 throw new WicketRuntimeException("Behavior " + getClass().getName() + 103 " can only be added to an instance of a RadioChoice/CheckboxChoice/RadioGroup/CheckGroup"); 104 } 105 } 106 107 /** 108 * @param component 109 * the component to check 110 * @return if the component applies to the {@link AjaxFormChoiceComponentUpdatingBehavior} 111 */ 112 static boolean appliesTo(Component component) 113 { 114 return (component instanceof RadioChoice) || 115 (component instanceof CheckBoxMultipleChoice) || (component instanceof RadioGroup) || 116 (component instanceof CheckGroup); 117 } 118 119 /** 120 * Creates an {@link AjaxFormChoiceComponentUpdatingBehavior} based on lambda expressions 121 * 122 * @param onUpdateChoice 123 * the {@code SerializableConsumer} which accepts the {@link AjaxRequestTarget} 124 * @return the {@link AjaxFormChoiceComponentUpdatingBehavior} 125 */ 126 public static AjaxFormChoiceComponentUpdatingBehavior onUpdateChoice( 127 SerializableConsumer<AjaxRequestTarget> onUpdateChoice) 128 { 129 Args.notNull(onUpdateChoice, "onUpdateChoice"); 130 return new AjaxFormChoiceComponentUpdatingBehavior() 131 { 132 private static final long serialVersionUID = 1L; 133 134 @Override 135 protected void onUpdate(AjaxRequestTarget target) 136 { 137 onUpdateChoice.accept(target); 138 } 139 }; 140 } 141}