Kortic, Anthony Ladeuil

Contrôle automatisé de pattern zipcodes

Postulat

Permettre l'ouverture du clavier ad hoc sur mobile selon les patterns de code postaux par pays.

  • Compatibilité devices mobile/desktop
  • Contrôle du pattern à la saisie et indicateur visuel
  • Automatisation (ajout d'un simple attribut)
  • Evolution des patterns facilitée
  • Pattern par défaut personnalisable
  • Nécessite JQuery

nb : vous devez créer une classe CSS personnelle .error ou utiliser celle disponible dans les sources du site voir la css

Exemples

Si vous souhaitez participer, même modestement, au maintien du site et pour son usage, vous pouvez cliquer sur le joli bouton…

Source Javascript $.fn.zipcode

;(function ($) {

    'use strict';

/*
    $.array_range = function(start, count){
        return Array(count).fill(0).map((e,i) => i + start);
    };
*/



    $.fn.zipcode = function(opts) {

        var settings = $.extend({
                'attribute': 'data-zipcode',
                'maxlength' : 10,
                'useLocale': false,
                'sendpattern': false
            }, opts),

            // inputmode disponible quand les navigateurs voudront bien l'implémenter.
            patterns = {
                'default': { // 5 digits type number
                    'type': 'number',
                    'inputmode': 'numeric',
                    'length': 5,
                    'regex': /^[0-9]{5}$/
                },
                'nl': {
                    'type': 'text',
                    'inputmode': 'text',
                    'length': 10,
                    'regex': /^(?:NL-)?(?:[1-9][0-9]{3} ?(?:[A-EGHJ-NPRTVWXZ][A-EGHJ-NPRSTVWXZ]|S[BCEGHJ-NPRTVWXZ]))$/i
                },
                'be': {
                    'type': 'number',
                    'inputmode': 'numeric',
                    'length': 4,
                    'regex': /^[0-9]{4}$/
                },
                'uk': {
                    'type': 'text',
                    'inputmode': 'text',
                    'length': 8,
                    'regex': /((?:(?:gir)|(?:[a-pr-uwyz])(?:(?:[0-9](?:[a-hjkpstuw]|[0-9])?)|(?:[a-hk-y][0-9](?:[0-9]|[abehmnprv-y])?)))) ?([0-9][abd-hjlnp-uw-z]{2})/,
                    'only': /[0-9A-Z]/
                },
                'us': {
                    'type': 'text',
                    'inputmode': 'text',
                    'length': null,
                    'regex': /^[0-9]{5}(?:(-| )[0-9]{4})?$/,
                    'only': / [0-9]\-/
                }
            };


        $(this).each(function() {

            var element_ = $(this),
                key = settings.useLocale === false ? ( element_.attr(settings.attribute).length ? element_.attr(settings.attribute).toLowerCase() : 'default') : settings.useLocale.toLowerCase(),
                pattern  = patterns[ $.array_key_exists(key, patterns) ? key : 'default' ];

                element_.attr({
                    'type': pattern.type,
                    'inputmode': pattern.inputmode,
                    'maxlength': pattern.length !== null ? pattern.length : settings.maxlength
                }).data('is_selected', false);

                if(pattern.type !== 'text') {
                    element_.data('count', 0).attr({
                        'min': 0,
                        'max': '9'.repeat(pattern.length),
                        'step': 1000
                    });
                }

                // envoyer la regExp au back pour contrôle
                if(settings.sendpattern) {
                    var inputPattern = $('<input/>', {
                        'type': 'hidden',
                        'value': pattern.regex,
                        'name': 'pattern'
                    });
                    element_.parents('form').append(inputPattern);
                }

                element_.on('change keyup',  function(){

                    element_.removeClass('error');

                    var reg = new RegExp( pattern.regex, 'ig');

                    if(element_.val().length) {
                        if(!reg.test(element_.val())){
                            element_.addClass('error');
                        }

                    }

                }).on('keyup keydown touchstart touchend', function(e) {

                    var currentVal = element_.val().trim();

                    if( $.inArray(e.type, ['keyup', 'touchend']) !== -1) {
                        element_.data('count', currentVal.length);
                    }

                    element_.data('is_selected', window.getSelection().toString().length > 0);

                    if(pattern.inputmode === 'numeric' && $.inArray(e.type, ['keydown', 'touchstart']) !== -1) {

                        if ( $.inArray(e.which, [38, 40]) != -1 ) {
                            e.preventDefault();
                        }

                        if ( $.inArray( parseInt(e.which, 10), $.range(48, 10).concat([8, 9, 13]).concat($.range(37, 4)) ) == -1 ) {
                            e.preventDefault();
                        }

                        if ( element_.data('count') == element_.attr('maxlength') && $.inArray( parseInt(e.which, 10), $.range(48, 10)) != -1 && !element_.data('is_selected') ) {
                            e.preventDefault();
                        }

                        if ( currentVal.length > element_.attr('maxlength') ) {
                            element_.val(currentVal.substr(0, element_.attr('maxlength')));
                        }

                    }
                });

            return this;

        });
    };

    $(document).ready(function(){

        // appel générique pour les champs avec attribut data-zipcode
        $('[data-zipcode]').zipcode({
            'sendpattern': true // ajoute un champ caché dans le formulaire parent du champ pour envoyer la RegExp pour traitement back
        });

        /*
         **
         ***
            appel pour les champs avec attribut data-specific et/ou variable locale définie

            $('[data-specific]').zipcode({
                'attribute': 'data-specific',
                'useLocale': 'fr' // ou variable js globale
            });
         ***
         **
        */

    });

})(jQuery);
Voir aussi…
Si vous souhaitez participer, même modestement, au maintien du site et pour son usage, vous pouvez cliquer sur le joli bouton…