Insert dash after every 4th character in input

Viewed 78448

I want insert a dash after every 4th character in input. I have a credit card input box. When a user is typing and reaches each 4th character, then jQuery will insert a hyphen (-).

For example: 1234-5678-1234-1231

UPDATE: I'm trying some codes and i think i'm so close to correct code but i have some problems. Here is my code sample;

$('.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);

    }
}

});
8 Answers

If you are looking for a pure Javascript solution, look at my function below. It supports the American Express format (15 digits) as well as Visa, MasterCard and others (16 digits).

Watch out for the simple solutions that will replace the whole value and always put the focus at the end of the input: it can be annoying if the user edits what he previously entered.

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'));
<form action="" method="post">
  <fieldset>
    <legend>Payment</legend>
    <div>
      <label for="credit-card">Credit card</label>
      <input id="credit-card" type="text" autocomplete="off" />
    </div>
  </fieldset>
</form>

View on jsFiddle

Most easiest way is the following using simple javascript onkey and function... it will put a dash hyphen after every 3 characters you input/type.

function addDash(element) {
  let ele = document.getElementById(element.id);
  ele = ele.value.split('-').join(''); // Remove dash (-) if mistakenly entered.

  let finalVal = ele.match(/.{1,3}/g).join('-');
  document.getElementById(element.id).value = finalVal;
}
<input type="text" class="form-control" name="sector" id="sector" onkeyup="addDash(this)" required>

You can achieved with vanilla JS and do not require plugin to do that. Refer to the code below. You can change the var split to suit your needs. Credits to 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>

Related