Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript credit card field - Add space every four chars - Backspace not working properly

I have a credit card field that I want to handle while the user inputs its credit card number. Assumptions are that the user can enter digits and alphabetic characters, and a space must be added every four characters. The input part works fine, but I have problems with backspace. Deleting with the backspace key works if I the cursor is on a digits, but it does not work fine when the cursor is on a space: in this case the user must hold backspace to properly delete some input.

An additional requirement is to let clipboard actions (copy, cut, paste) work properly on that field.

I cannot use any plugin for the solution (like the JQuery Mask Plugin), and I won't use keyCode directly, if possible.

Updated JS Fiddle: https://jsfiddle.net/ot2t9zr4/10/

Snippet

$('#credit-card').on('keypress change blur', function () {
  $(this).val(function (index, value) {
    return value.replace(/[^a-z0-9]+/gi, '').replace(/(.{4})/g, '$1 ');
  });
});

$('#credit-card').on('copy cut paste', function () {
  setTimeout(function () {
    $('#credit-card').trigger("change");
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
  <form class="" action="" method="post">
    <fieldset>
      <legend>Payment</legend>
      <div class="beautiful-field field-group credit-cart">
        <label class="label" for="credit-card">Credit card</label>
        <input class="field" id="credit-card" value="" autocomplete="off" type="text" />
      </div>
    </fieldset>
  </form>
</div>
like image 914
ramo102 Avatar asked Apr 12 '16 09:04

ramo102


2 Answers

I wanted to share my solution, in case someone is still struggling to achieve the desired affect.

My code is a refined version of @tonybrasunas's answer. It will add spaces every 4 characters, filter out non-numerical characters, fix character position, backspace, and only move the cursor forward if the character is valid, but still allow pushing with valid characters.

This is flawless solution in my books. If you have any suggestions I'd love to hear them.



// FORMAT CC FIELD
//
//

$('#credit-card').on('input', function () {

  $(this).val(function (index, value) {
  
    // Store cursor position

    let cursor = $(this).get(0).selectionStart;
    
    // Filter characters and shorten CC (expanded for later use)
    
    const filterSpace = value.replace(/\s+/g, '');
    const filtered = filterSpace.replace(/[^0-9]/g, '');
    
    const cardNum = filtered.substr(0, 16);
    
    // Handle alternate segment length for American Express
    
    const partitions = cardNum.startsWith('34') || cardNum.startsWith('37') ? [4,6,5] : [4,4,4,4];
    
    // Loop through the validated partition, pushing each segment into cardNumUpdated
    
    const cardNumUpdated = [];
    let position = 0;
    
    partitions.forEach(expandCard => {
    
      const segment = cardNum.substr(position, expandCard);
      if (segment) cardNumUpdated.push(segment);
      position += expandCard;
      
    });
    
    // Combine segment array with spaces

    const cardNumFormatted = cardNumUpdated.join(' ');
    
    // Handle cursor position if user edits the number later
    
    if (cursor < cardNumFormatted.length - 1) {
        
      // Determine if the new value entered was valid, and set cursor progression
    
        cursor = filterSpace !== filtered ? cursor - 1 : cursor;
      
      setTimeout(() => {
      
        $(this).get(0).setSelectionRange(cursor, cursor, 'none');
        
      });
      
    }
    
    return cardNumFormatted;
    
  })
  
});

//
//
// END OF FORMAT CC FIELD


like image 178
rileybarabash221 Avatar answered Oct 14 '22 04:10

rileybarabash221


Bind keypress event only and see.

$('#credit-card').on('keypress change', function () {
  $(this).val(function (index, value) {
    return value.replace(/\W/gi, '').replace(/(.{4})/g, '$1 ');
  });
});

Check here.

like image 23
Developer107 Avatar answered Oct 14 '22 02:10

Developer107