org.opensingular.form.wicket.behavior.InputMaskBehavior.java Source code

Java tutorial

Introduction

Here is the source code for org.opensingular.form.wicket.behavior.InputMaskBehavior.java

Source

/*
 * Copyright (C) 2016 Singular Studios (a.k.a Atom Tecnologia) - www.opensingular.com
 *
 * 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 org.opensingular.form.wicket.behavior;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.json.JSONObject;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>Classe responsvel por adicionar mscara a um {@code input}.</p>
 *
 * <p>Usa como implementao <i>javascript</i> a <strong>API JQuery InputMask</strong>.</p>
 *
 * <p>Algumas opes podem ser adicionadas por padro s configuraes de mscara. Elas
 * so as seguintes:</p>
 *
 * <ul>
 *     <li>placeholder: ''</li>
 *     <li>skipOptionalPartCharacter: ''</li>
 *     <li>showMaskOnHover: false</li>
 *     <li>showMaskOnFocus: false</li>
 *     <li>greedy: false</li>
 * </ul>
 *
 * @see <a href="https://github.com/RobinHerbots/jquery.inputmask">JQuery InputMask</a>
 * @author Daniel Bordin
 */
public class InputMaskBehavior extends Behavior {

    public static final Logger logger = LoggerFactory.getLogger(InputMaskBehavior.class);

    public static final String MASK_ATTR = "mask";
    public static final String MAX_LENGTH_ATTR = "repeat";

    private String jsonOptions;

    /**
     * <p>Enumerador com algumas mscaras predefinidas.</p>
     */
    public static class Masks {
        /**
         * <p>Mscara que permite apenas valores numricos: [0-9].</p>
         */
        public static final Masks NUMERIC = new Masks("9");

        /**
         * <p>Mscara para datas do tipo DD/MM/AAAA.</p>
         */
        public static final Masks FULL_DATE = new Masks("99/99/9999");

        /**
         * <p>Mscara para datas do tipo MM/AAAA.</p>
         */
        public static final Masks SHORT_DATE = new Masks("99/9999");

        /**
         * <p>Mscara para CPF.</p>
         */
        public static final Masks CPF = new Masks("999.999.999-99");

        /**
         * <p>Mscara para CNPJ.</p>
         */
        public static final Masks CNPJ = new Masks("99.999.999/9999-99");

        /**
         * <p>Mscara para CEP.</p>
         */
        public static final Masks CEP = new Masks("99.999-999");

        public static final Masks TIME = new Masks("9{1,2}:99");

        private String mask;

        public Masks(String mask) {
            this.mask = mask;
        }

        /**
         * <p>Retorna a mscara correspondente a este enumerador.</p>
         *
         * @return a mscara correspondente a este enumerador.
         */
        public String getMask() {
            return mask;
        }

        public static Masks valueOf(String s) {
            try {
                Field f = ReflectionUtils.findField(Masks.class, s);
                if (f != null) {
                    return (Masks) f.get(null);
                }
            } catch (IllegalAccessException e) {
                logger.error(e.getMessage(), e);
            }
            return new Masks(s);
        }
    }

    /**
     * <p>Instancia um novo <i>behavior</i> com a mscara especificada.</p>
     *
     * <p>Apenas as opes de mscaras padres sero carregadas.</p>
     *
     * @param mask a mscara especificada.
     * @see <a href="https://github.com/RobinHerbots/jquery.inputmask">JQuery InputMask</a>
     */
    public InputMaskBehavior(String mask) {
        this(mask, null);
    }

    /**
     * <p>Instancia um novo <i>behavior</i> com a mscara especificada.</p>
     *
     * <p>Apenas as opes de mscaras padres sero carregadas.</p>
     *
     * @param mask a mscara especificada.
     * @see <a href="https://github.com/RobinHerbots/jquery.inputmask">JQuery InputMask</a>
     */
    public InputMaskBehavior(Masks mask) {
        this(mask.getMask(), null);
    }

    /**
     * <p>Instancia um novo <i>behavior</i> com mscara e opes especificadas.</p>
     *
     * <p>Alm das opes especificadas, as opes padres tambm sero carregadas.</p>
     *
     * @param mask a mscara especificada.
     * @param options as opes especificadas.
     * @see <a href="https://github.com/RobinHerbots/jquery.inputmask">JQuery InputMask</a>
     */
    public InputMaskBehavior(String mask, Map<String, Object> options) {
        this(mask, options, true);
    }

    /**
     * <p>Instancia um novo <i>behavior</i> com mscara e opes especificadas.</p>
     *
     * <p>Alm das opes especificadas, as opes padres tambm sero carregadas.</p>
     *
     * @param mask a mscara especificada.
     * @param options as opes especificadas.
     * @see <a href="https://github.com/RobinHerbots/jquery.inputmask">JQuery InputMask</a>
     */
    public InputMaskBehavior(Masks mask, Map<String, Object> options) {
        this(mask.getMask(), options, true);
    }

    /**
     * <p>Instancia um novo <i>behavior</i> com mscara e opes especificadas.</p>
     *
     * <p>Alm das opes especificadas, as opes padres podero ser carregadas dependendo
     * do parmetro {@code appendDefaultOptions}.</p>
     *
     * @param mask a mscara especificada.
     * @param options as opes especificadas.
     * @param appendDefaultOptions indica quando carregar as opes padres.
     * @see <a href="https://github.com/RobinHerbots/jquery.inputmask">JQuery InputMask</a>
     */
    public InputMaskBehavior(final String mask, final Map<String, Object> options, boolean appendDefaultOptions) {
        Map<String, Object> opts = new HashMap<>();
        if (Objects.nonNull(options)) {
            opts.putAll(options);
        }
        if (appendDefaultOptions) {
            setDefaultOpcoes(opts);
        }
        if (Objects.nonNull(mask)) {
            opts.put(MASK_ATTR, mask);
        }
        setJsonOptions(opts);
    }

    public InputMaskBehavior(final Map<String, Object> options, boolean appendDefaultOptions) {
        this((String) null, options, appendDefaultOptions);
    }

    /**
     * <p>Instancia um novo <i>behavior</i> com mscara e opes especificadas.</p>
     *
     * <p>Alm das opes especificadas, as opes padres podero ser carregadas dependendo
     * do parmetro {@code appendDefaultOptions}.</p>
     *
     * @param mask a mscara especificada.
     * @param options as opes especificadas.
     * @param appendDefaultOptions indica quando carregar as opes padres.
     * @see <a href="https://github.com/RobinHerbots/jquery.inputmask">JQuery InputMask</a>
     */
    public InputMaskBehavior(final Masks mask, final Map<String, Object> options, boolean appendDefaultOptions) {
        this(mask.getMask(), options, appendDefaultOptions);
    }

    private void setDefaultOpcoes(Map<String, Object> options) {
        options.put("placeholder", "");
        options.put("skipOptionalPartCharacter", "");
        options.put("showMaskOnHover", Boolean.FALSE);
        options.put("showMaskOnFocus", Boolean.FALSE);
        options.put("greedy", Boolean.FALSE);
    }

    private void setJsonOptions(Map<String, Object> options) {
        this.jsonOptions = new JSONObject(options).toString();
    }

    /**
     * <p>Retorna as opes usadas para criar este <i>behavior</i>, j em format {@code json}.</p>
     *
     * @return o {@code json} das opes usadas por este <i>behavior</i>.
     */
    protected String getJsonOptions() {
        return jsonOptions;
    }

    @Override
    public void renderHead(Component component, IHeaderResponse response) {
        super.renderHead(component, response);
        response.render(OnDomReadyHeaderItem.forScript("(function(){" + getScript(component) + ";})()"));
    }

    /**
     * <p>Retorna o <i>script</i> gerado para este <i>behavior</i>.</p>
     *
     * @param component componente o qual este <i>behavior</i> dever ser adicionado.
     * @return o <i>javascript</i> gerado.
     */
    protected String getScript(Component component) {
        return "var $this = $('#" + component.getMarkupId() + "');"
        //  + "$this.on('paste', function(event) {console.log(event); setTimeout(function(){$this.change();},1);});"
                + "$this.on('drop', function(event) {" + "  event.preventDefault();"
                + "  $this.val(event.originalEvent.dataTransfer.getData('text'));"
                + "  $this.inputmask('remove').inputmask(" + jsonOptions + ");"
                + "  setTimeout(function(){$this.change();},1);" + "});" + "$this.inputmask('remove').inputmask("
                + jsonOptions + ");";
    }
}