Accueil Kortic

    Zipcode patterns

    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

    Plus d'informations sur les formats des codes postaux par pays.

    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 = async 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}$/
                    },
                    'au': {
                        '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() {

                let 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('input',  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…
    2020-04-05