web-dev-qa-db-fra.com

Insérer un tiret après chaque 4ème caractère en entrée

Je veux insérer un tiret après chaque 4ème caractère en entrée. J'ai une boîte de saisie de carte de crédit. Lorsqu'un utilisateur tape et atteint chaque 4ème caractère, jQuery insère un trait d'union (-).

Par exemple: 1234-5678-1234-1231

MISE À JOUR: J'essaie quelques codes et je pense que je suis si près de corriger le code mais j'ai des problèmes. Voici mon exemple de code;

$('.creditCardText').keyup(function() {

var cardValue = $('.creditCardText').val(),
    cardLength = cardValue.length;

if ( cardLength < 5 ) {
    if ( cardLength % 4 == 0 ) {
        console.log('4 lük geldi');
        cardValue += "-";
        $('.creditCardText').val(cardValue);
    }
} else {
    if ( cardLength % 5 == 0 ) {
        console.log('5 lük geldi');
        cardValue += "-";
        $('.creditCardText').val(cardValue);

    }
}

});
32
mrchad

Cette extension jquery insérera un espace tous les quatre caractères: https://github.com/stripe/jquery.payment

8
RecursivelyIronic

J'adore ce plugin pour le formatage automatique: ici .

Tant que vous utilisez déjà JQuery, c'est-à-dire.

Vous pouvez facilement forcer les tirets avec une seule ligne de code, comme suit:

$("#credit").mask("9999-9999-9999-9999");

Lorsque l'utilisateur tape dans le champ, les tirets apparaîtront automatiquement au bon endroit et ils ne pourront pas les supprimer.

De plus, vous pouvez accepter différentes longueurs ou formats de cartes de crédit avec le ? caractère dans votre masque. Par exemple, pour accepter des entrées de 14 et 16 chiffres, vous devez procéder comme suit:

$("#credit").mask("9999-9999-9999-99?99");

Gardez à l'esprit qu'il ne s'agit que d'une validation côté client


Modifier : Le plugin de masque suppose qu'il existe un ou plusieurs formats corrects pour le champ. Par exemple, il n'y a que quelques formats dans lesquels les numéros de carte de crédit entrent. Le plugin est là pour s'assurer que votre entrée sera seulement dans l'un de ces formats.

Donc techniquement, si vous voulez un tiret après tous les quatre chiffres, mais pour tout nombre de chiffres, alors ce plugin ne vous convient pas.

Je vous suggère de limiter les entrées possibles pour être raisonnables, car il n'existe certainement pas de carte de crédit longue à 1000 chiffres. Mais si vous voulez vraiment cette fonctionnalité, vous devrez écrire le script vous-même ou trouver un autre plugin. Pour l'instant, je n'en connais pas.

27
Nick

J'ai corrigé votre code, mais je suggère toujours fortement la validation du serveur et en utilisant quatre zones de texte, et en basculant intelligemment entre elles:

$('.creditCardText').keyup(function() {
  var foo = $(this).val().split("-").join(""); // remove hyphens
  if (foo.length > 0) {
    foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
  }
  $(this).val(foo);
});

Lien JSFiddle

Basé sur la réponse @ think123, dans Vanilla JS, sans JQuery:

document.querySelector('.creditCardText').addEventListener('input', function (e) {
    var foo = this.value.split("-").join("");
    if (foo.length > 0) {
        foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
    }
    this.value = foo;
});

Je sais que la question concerne JQuery mais je pense que cette réponse pourrait aussi aider.

10
rap-2-h

Si vous cherchez une solution Javascript pure, regardez ma fonction ci-dessous. Il prend en charge le format American Express (15 chiffres) ainsi que Visa, MasterCard et autres (16 chiffres).

Méfiez-vous des solutions simples qui remplaceront toute la valeur et mettez toujours le focus à la fin de la saisie: cela peut être gênant si l'utilisateur modifie ce qu'il a entré précédemment.

[~ # ~] démo [~ # ~] : https://jsfiddle.net/pmrotule/217u7fru/

input_credit_card = function(input)
{
    var format_and_pos = function(char, backspace)
    {
        var start = 0;
        var end = 0;
        var pos = 0;
        var separator = "-";
        var value = input.value;

        if (char !== false)
        {
            start = input.selectionStart;
            end = input.selectionEnd;

            if (backspace && start > 0) // handle backspace onkeydown
            {
                start--;

                if (value[start] == separator)
                { start--; }
            }
            // To be able to replace the selection if there is one
            value = value.substring(0, start) + char + value.substring(end);

            pos = start + char.length; // caret position
        }

        var d = 0; // digit count
        var dd = 0; // total
        var gi = 0; // group index
        var newV = "";
        var groups = /^\D*3[47]/.test(value) ? // check for American Express
        [4, 6, 5] : [4, 4, 4, 4];

        for (var i = 0; i < value.length; i++)
        {
            if (/\D/.test(value[i]))
            {
                if (start > i)
                { pos--; }
            }
            else
            {
                if (d === groups[gi])
                {
                    newV += separator;
                    d = 0;
                    gi++;

                    if (start >= i)
                    { pos++; }
                }
                newV += value[i];
                d++;
                dd++;
            }
            if (d === groups[gi] && groups.length === gi + 1) // max length
            { break; }
        }
        input.value = newV;

        if (char !== false)
        { input.setSelectionRange(pos, pos); }
    };

    input.addEventListener('keypress', function(e)
    {
        var code = e.charCode || e.keyCode || e.which;

        // Check for tab and arrow keys (needed in Firefox)
        if (code !== 9 && (code < 37 || code > 40) &&
        // and CTRL+C / CTRL+V
        !(e.ctrlKey && (code === 99 || code === 118)))
        {
            e.preventDefault();

            var char = String.fromCharCode(code);

            // if the character is non-digit
            // OR
            // if the value already contains 15/16 digits and there is no selection
            // -> return false (the character is not inserted)

            if (/\D/.test(char) || (this.selectionStart === this.selectionEnd &&
            this.value.replace(/\D/g, '').length >=
            (/^\D*3[47]/.test(this.value) ? 15 : 16))) // 15 digits if Amex
            {
                return false;
            }
            format_and_pos(char);
        }
    });

    // backspace doesn't fire the keypress event
    input.addEventListener('keydown', function(e)
    {
        if (e.keyCode === 8 || e.keyCode === 46) // backspace or delete
        {
            e.preventDefault();
            format_and_pos('', this.selectionStart === this.selectionEnd);
        }
    });

    input.addEventListener('paste', function()
    {
        // A timeout is needed to get the new value pasted
        setTimeout(function(){ format_and_pos(''); }, 50);
    });

    input.addEventListener('blur', function()
    {
        // reformat onblur just in case (optional)
        format_and_pos(this, false);
    });
};

input_credit_card(document.getElementById('credit-card'));
4
pmrotule

En modifiant la suggestion de @ think123 et @ TheStoryCoder , j'ai ajouté selectionStart et SelectionEnd pour le curseur. Après cela, augmentez la position du curseur à un endroit approprié et modifiez la position du curseur. Cela devrait résoudre la position du curseur à la position non attendue.

$('.creditCardText').keyup(function() {

  var ss, se, obj;
  obj = $(this);
  ss = obj[0].selectionStart;
  se = obj[0].selectionEnd;

  var curr = obj.val();

  var foo = $(this).val().split("-").join(""); // remove hyphens
  if (foo.length > 0) {
    foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
  }

  if(( (curr.length % 5 == 0) && ss == se && ss == curr.length ) || (ss == se && (ss % 5 == 0))){
      ss += 1;
      se += 1;
  }

  if (curr != foo){
    $(this).val(foo);
    obj[0].selectionStart = ss;
    obj[0].selectionEnd = se;
  }

});
3
Su Ming Yuan

Tous ceux qui ont répondu au-dessus de moi ont raison et leur code est certainement court et soigné, mais est un peu avancé, dans le sens où ils utilisent soit des expressions régulières soit un plugin. Quelque chose comme cela peut également être réalisé avec js/jquery de base, qui, à en juger par votre exemple de code que vous essayez de réaliser. Comme cette question a environ 3 ans, vous devez avoir obtenu ce que vous vouliez maintenant, mais oui, vous étiez proche. Voici ce que vous auriez dû essayer:

    //Html
    /* <input type="text" class="creditCardText" maxlength="19" /> */
    $('.creditCardText').keyup(function () {
      var cctlength = $(this).val().length; // get character length

      switch (cctlength) {
      case 4:
        var cctVal = $(this).val();
        var cctNewVal = cctVal + '-';
        $(this).val(cctNewVal);
        break;
      case 9:
        var cctVal = $(this).val();
        var cctNewVal = cctVal + '-';
        $(this).val(cctNewVal);
        break;
      case 14:
        var cctVal = $(this).val();
        var cctNewVal = cctVal + '-';
        $(this).val(cctNewVal);
        break;
      default:
        break;
     }
  });

Lien JSFiddle

1
Brajinder Singh

Vous pouvez le faire avec Vanilla JS et n'avez pas besoin de plugin pour le faire. Reportez-vous au code ci-dessous. Vous pouvez modifier le var split pour répondre à vos besoins. Crédits à https://webdesign.tutsplus.com/tutorials/auto-formatting-input-value--cms-26745 .

(function($, undefined) {

    "use strict";

    // When ready.
    $(function() {
        
        var $form = $( "#form" );
        var $input = $form.find( "input" );

        $input.on( "keyup", function( event ) {
            
            console.log('sss')
            // When user select text in the document, also abort.
            var selection = window.getSelection().toString();
            if ( selection !== '' ) {
                return;
            }
            
            // When the arrow keys are pressed, abort.
            if ( $.inArray( event.keyCode, [38,40,37,39] ) !== -1 ) {
                return;
            }
            
            var $this = $(this);
            var input = $this.val();
                    input = input.replace(/[\W\s\._\-]+/g, '');
                
                var split = 4;
                var chunk = [];
               
                for (var i = 0, len = input.length; i < len; i += split) {                              chunk.Push( input.substr( i, split ) );
                }

                 console.log(chunk)
                $this.val(function() {
                    return chunk.join("-");
                });
        
        } );
        
        /**
         * ==================================
         * When Form Submitted
         * ==================================
         */
        $form.on( "submit", function( event ) {
            
            var $this = $( this );
            var arr = $this.serializeArray();
        
            for (var i = 0; i < arr.length; i++) {
                    arr[i].value = arr[i].value.replace(/[($)\s\._\-]+/g, ''); // Sanitize the values.
            };
            
            console.log( arr );
            
            event.preventDefault();
        });
        
    });
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form" method="post" action="">

        <label for="number">Enter number</label>
        <div class="flex">
            <input id="number" name="number" type="text" maxlength="15" />
        </div>

</form>
0
tnkh