/******************************************************************************* * Copyright (c) 2015 Development Gateway, Inc and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the MIT License (MIT) * which accompanies this distribution, and is available at * https://opensource.org/licenses/MIT * * Contributors: * Development Gateway - initial API and implementation *******************************************************************************/ /** * */ package org.devgateway.toolkit.forms.wicket.components.form; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.model.IModel; import java.util.HashSet; import java.util.Set; /** * @author mpostelnicu {@link GenericBootstrapFormComponent} that can show and * hide other components */ public abstract class GenericEnablingBootstrapFormComponent<TYPE, FIELD extends FormComponent<TYPE>> extends GenericBootstrapFormComponent<TYPE, FIELD> { private static final long serialVersionUID = 1L; private Set<Component> visibilityBoundComponents = new HashSet<Component>(); private Set<Component> visibilityReverseBoundComponents = new HashSet<Component>(); /** * @param id */ public GenericEnablingBootstrapFormComponent(final String id) { super(id); } /** * @param id * @param model */ public GenericEnablingBootstrapFormComponent(final String id, final IModel<TYPE> model) { super(id, model); } /** * @param id * @param labelModel * @param model */ public GenericEnablingBootstrapFormComponent(final String id, final IModel<String> labelModel, final IModel<TYPE> model) { super(id, labelModel, model); } /** * Returns true if the bound components should have * {@link #setVisibilityAllowed(boolean)} to true otherwise returns false. * * @param selectedValue * the selected value of the current component, that may be taken * into consideration when evaluating the visibility of the bound * components * @return */ protected abstract boolean boundComponentsVisibilityAllowed(TYPE selectedValue); /** * change visibility status of bound components based of the fact the level * has an affirmative answer or not * * @param target */ protected void updateBoundComponents(final AjaxRequestTarget target) { TYPE selectedValue = this.getModelObject(); if (selectedValue != null) { for (Component component : visibilityBoundComponents) { component.setVisibilityAllowed(boundComponentsVisibilityAllowed(selectedValue)); if (target != null) { target.add(component); } } } } /** * Reversed of {@link #updateBoundComponents(AjaxRequestTarget)} * * @param target */ protected void updateReverseBoundComponents(final AjaxRequestTarget target) { TYPE selectedValue = this.getModelObject(); if (selectedValue != null) { for (Component component : visibilityReverseBoundComponents) { component.setVisibilityAllowed(!boundComponentsVisibilityAllowed(selectedValue)); if (target != null) { target.add(component); } } } } /** * Each time the component gets updated we also refresh the bound * components' visibility */ @Override protected void onUpdate(final AjaxRequestTarget target) { super.onUpdate(target); updateBoundComponents(target); updateReverseBoundComponents(target); } /** * Re-apply the visibility states of all bound components, this is good * because {@link #onInitialize()} is invoked after the models are * initialized, so we know the value of the saved entity selection */ @Override protected void onInitialize() { super.onInitialize(); updateBoundComponents(null); updateReverseBoundComponents(null); } /** * Add component that is bound to the value of this current component, * changing the selected element of this component may influence if the * bound component is visible or not. By default all bound components are * not visible * * @param c * @return */ public GenericEnablingBootstrapFormComponent<TYPE, FIELD> addBoundComponent(final Component c) { TYPE selectedValue = this.getModelObject(); c.setVisibilityAllowed(selectedValue == null ? false : boundComponentsVisibilityAllowed(selectedValue)); visibilityBoundComponents.add(c); return this; } /** * This is the negated version of * {@link GenericEnablingBootstrapFormComponent#addBoundComponent(Component)} * * @param c * @return */ public GenericEnablingBootstrapFormComponent<TYPE, FIELD> addReverseBoundComponent(final Component c) { TYPE selectedValue = this.getModelObject(); c.setVisibilityAllowed(selectedValue == null ? false : !boundComponentsVisibilityAllowed(selectedValue)); visibilityReverseBoundComponents.add(c); return this; } }