All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.foreach.across.modules.bootstrapui.utils.BootstrapElementUtils Maven / Gradle / Ivy

/*
 * Copyright 2019 the original author or authors
 *
 * Licensed 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 com.foreach.across.modules.bootstrapui.utils;

import com.foreach.across.modules.bootstrapui.elements.FormControlElement;
import com.foreach.across.modules.bootstrapui.elements.FormGroupElement;
import com.foreach.across.modules.bootstrapui.elements.FormInputElement;
import com.foreach.across.modules.bootstrapui.elements.InputGroupFormElement;
import com.foreach.across.modules.web.ui.ViewElement;
import com.foreach.across.modules.web.ui.elements.ContainerViewElement;
import lombok.NonNull;

import java.util.function.Consumer;

/**
 * Contains several static utility methods for working with elements.
 *
 * @author Arne Vandamme
 */
public abstract class BootstrapElementUtils
{
	protected BootstrapElementUtils() {
	}

	/**
	 * Will search for the first {@link FormControlElement} instance that is not an {@link InputGroupFormElement}.
	 * It is possible that the instance itself is returned.  This method will recurse through
	 * {@link com.foreach.across.modules.web.ui.elements.ContainerViewElement} types until an instance is returned.
	 *
	 * @param viewElement instance
	 * @return form control instance, or {@code null} if not found
	 */
	public static FormControlElement getFormControl( ViewElement viewElement ) {
		return getFormControl( viewElement, FormControlElement.class );
	}

	/**
	 * Will search for the first {@link FormControlElement} instance that matches the expected type.
	 * It is possible that the instance itself is returned.  This method will recurse through
	 * {@link com.foreach.across.modules.web.ui.elements.ContainerViewElement} types until an instance is returned.
	 *
	 * @param viewElement  instance
	 * @param expectedType the control should have
	 * @return form control instance, or {@code null} if not found
	 */
	public static  V getFormControl( ViewElement viewElement, Class expectedType ) {
		V control = null;

		if ( viewElement instanceof FormGroupElement ) {
			ViewElement candidate = ( (FormGroupElement) viewElement ).getControl();

			if ( candidate != null ) {
				control = getFormControl( candidate, expectedType );
			}
		}
		else if ( viewElement instanceof FormControlElement.Proxy ) {
			ViewElement candidate = ( (FormControlElement.Proxy) viewElement ).getControl();

			if ( candidate != null ) {
				control = getFormControl( candidate, expectedType );
			}
		}
		else if ( expectedType.isInstance( viewElement ) ) {
			control = expectedType.cast( viewElement );
		}

		if ( control == null && viewElement instanceof ContainerViewElement ) {
			for ( ViewElement child : ( (ContainerViewElement) viewElement ).getChildren() ) {
				control = getFormControl( child, expectedType );

				if ( control != null ) {
					return control;
				}
			}
		}

		return control;
	}

	/**
	 * Prefix all controls in a container. This is utility method that will scan
	 * for all unique {@link FormInputElement} controls and ensure they are prefixed only once.
	 * When it encounters a {@code FormControlElement.Proxy} it will also exclude the
	 * target {@link ViewElement} from control name updating.
	 * 

* This method will insert a . between the prefix and the original control name, unless * the control name starts with a special character. *

* See {@link #prefixControlNames(String)} and {@link ControlNamePrefixAdjuster} if you want to customize. * * @param prefix to apply to any input element * @param container in which to find all input elements * @see #prefixControlNames(String) * @see ControlNamePrefixAdjuster */ public static void prefixControlNames( @NonNull String prefix, @NonNull ContainerViewElement container ) { prefixControlNames( prefix ).accept( container ); } /** * Updates any control having a control name starting with a given prefix. * Said prefix will be replaced by the new one. Like {@link #prefixControlNames(String, ContainerViewElement)} * this method should handle different form control elements correctly. *

* See {@link #replaceControlNamesPrefix(String, String)} and {@link ControlNamePrefixAdjuster} if you want to customize. * * @param prefixToReplace prefix that should be replaced * @param newPrefix prefix that should be used instead * @param container in which to find all input elements * @see #replaceControlNamesPrefix(String, String) * @see ControlNamePrefixAdjuster */ public static void replaceControlNamesPrefix( @NonNull String prefixToReplace, @NonNull String newPrefix, @NonNull ContainerViewElement container ) { replaceControlNamesPrefix( prefixToReplace, newPrefix ).accept( container ); } /** * Create {@link ControlNamePrefixAdjuster} preconfigured to prefix all control names with the given prefix, * ignoring any first underscore character, adding dot separators and recursing through all children * in case the control is a container. *

* The return value is both a {@link Consumer} and {@link com.foreach.across.modules.web.ui.ViewElementPostProcessor}. * * @param prefix to add * @return adjuster instance */ public static ControlNamePrefixAdjuster prefixControlNames( @NonNull String prefix ) { return new ControlNamePrefixAdjuster().prefixToAdd( prefix ); } /** * Create {@link ControlNamePrefixAdjuster} preconfigured to update all control names that match the initial * prefix, and replace said prefix with the new value. Like {@link #prefixControlNames(String)} the return * value is preconfigured to recurse through container members, ignore underscores and add dot separators * where necessary. *

* The return value is both a {@link Consumer} and {@link com.foreach.across.modules.web.ui.ViewElementPostProcessor}. * * @param prefixToReplace prefix that should be replaced * @param newPrefix prefix that should be used instead * @return adjuster instance */ public static ControlNamePrefixAdjuster replaceControlNamesPrefix( @NonNull String prefixToReplace, @NonNull String newPrefix ) { return new ControlNamePrefixAdjuster().prefixToReplace( prefixToReplace ).prefixToAdd( newPrefix ); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy