0

I want to show an error message to a user, if he enters more characters in a text field than specified and this specification may change with the initial characters provided. Along with that, I need to process each character that user enters for some business purposes. e.g.

Let's think of a credit card field. enter image description here

Different credit card types have different Max Lengths. I would like to stop users from entering more characters in the field than their credit card type allows.

However, the credit card type can be detected only when the user provides few initial characters of the credit card.

My approach here is to try to detect credit card on every key press, and set the maxlength of the field according to credit card type detected. If not detected, keep the max length to 19 (which is maximum for all)

What I have tried

---------------------------------------------------------------------
|   Event    | Problem                                              |
| ------------------------------------------------------------------|
|            |  Change will not be triggered until the user         |     
|  OnChange  | moves out of the field. Since I need this event      |
|            | on every char entered, this is not helpful           |
|-------------------------------------------------------------------|
|            | It gives issues when a user presses the key for a    |
|  KeyDown   | longer duration. Characters are entered multiple     |
|            | times, but this event is triggered only once.        |
|-------------------------------------------------------------------| 
|  KeyUP     | Same as above.                                       |
|-------------------------------------------------------------------|
|  KeyPress  | I am getting older value. The newly added character  |
|            | is not available. Hence incorrect calculation        |
---------------------------------------------------------------------

I have an alternative of using time-out, but looking for better options.

My Question is different than this one. because of above mentioned reasons.

Please suggest a good solution for this.

Community
  • 1
  • 1
Mohit Kanwar
  • 2,962
  • 7
  • 39
  • 59
  • 1
    Please show the related code. – iCollect.it Ltd Jul 08 '15 at 11:54
  • use .change(function(){ ... }); instead of keypress(); – Ji_in_coding Jul 08 '15 at 11:55
  • 1
    @Ji_in_coding `change` only fires on `input` elements when they lose focus, which doesn't sound like the behaviour that the OP wants. – Rory McCrossan Jul 08 '15 at 11:56
  • how about using the keydown.. and use "counter" variable? – Ole K Jul 08 '15 at 11:56
  • @MohitKanwar you say you can't use `keyup`, but have you tried `keydown`? – Rory McCrossan Jul 08 '15 at 11:56
  • *"I don't want to use "keyup" event, since if user triggers a keydown event but not keyup the value would be modified but my function won't be called."* Why is that a problem? The keyup event is triggered eventually, at which point you still have time to verify the length. – Felix Kling Jul 08 '15 at 11:58
  • I have to trigger my event as soon as a character is entered in an input. "keyup" event won't be triggered if a user presses a key for longer duration. Effect would be: multiple values entered but event triggered only once when "keyup" happens. For the same reason, "keypress" and "keydown" are not suitable. If a key is pressed for longer duration, event is triggered only once. – Mohit Kanwar Jul 08 '15 at 12:25
  • Again, why is this an issue? You claim that is is an issue, but you don't explain why. – Felix Kling Jul 08 '15 at 12:25
  • ahh.. the issue here is, I want to trigger my function as soon as a new character is entered in the input. that means, the function must be triggered as soon as a new character is entered. – Mohit Kanwar Jul 08 '15 at 12:28
  • Try typing following in an input "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrr" without doing a keyup with r key. events "keyup" and "keypress" would be triggered once, and "keyup" would be triggered once at end. but I want to trigger my function each time "" changes to "r", "r" changes to "rr" and so on.. – Mohit Kanwar Jul 08 '15 at 12:31
  • $(someTextInputField).attr('maxlength',validLength); try this – Kishan Jul 09 '15 at 11:33
  • @Kishan I did that myself initially but this would stop insertion of the characters, this is not expected as per business requirements. :( – Mohit Kanwar Jul 09 '15 at 12:26
  • @Kishan agree, your answer is correct. – Mohit Kanwar Jul 13 '15 at 04:58

5 Answers5

4

I think this serves most of the cases you need.

This will work for every time the input is changed. And reset value if we enter more than allowed length.

var limit = 10; //your input limit
$(document).on('ready',function(){
    var oldValue = $( "input[type='text']" ).val();
    $( "input[type='text']" ).on('keydown',function(e) {
        oldValue = $( this ).val();
    })
    $( "input[type='text']" ).on('input propertychange',function(e) {
        newValue = $(this).val();
        if(newValue.length > limit){
            $(this).val(oldValue);
            alert('String too long.');
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text">

Updated fiddle.

rrk
  • 15,677
  • 4
  • 29
  • 45
  • using a combination of "input propertychange' and picking up value from "this" instead of jQuery selector worked for me. However, I still don't understand why. Can you explain your code? – Mohit Kanwar Jul 09 '15 at 06:28
  • @MohitKanwar `$(this)` means that we are getting the element which we have the binding on, I used it for exclusivity. `$( "input[type='text']" )` will work properly only if there is only one `input[type='text']` in the whole DOM. – rrk Jul 09 '15 at 13:10
  • yes, but somehow selecting field from jQuery returned older value and "this" returned newer value. and what does .on('input propertychange') means? Is it a different event? or when both input & propertychange are triggered ? – Mohit Kanwar Jul 09 '15 at 15:25
  • `input` is an html 5 event. https://developer.mozilla.org/en-US/docs/Web/Events/input But there is issues in IE9 and lower versions. So for that we use `propertychange` event https://msdn.microsoft.com/en-us/library/ms536956(v=vs.85).aspx for better browser compatability. – rrk Jul 09 '15 at 15:30
  • Input acts on most of the cases where we copy and paste, text drag and drop. – rrk Jul 09 '15 at 15:30
1

try this

This will work when you change input

$(someTextInputField).on('input',function(e){
  var txtLength =this.value.length;
  var validLength=4;
  if(txtLength > validLength){ 
      this.value=this.value.substr(0, validLength);
      alert("please enter only 4 character");
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<input id="someTextInputField" type="text">
Kishan
  • 1,182
  • 12
  • 26
  • "keyup" doesn't help if keypress event occurs but keyup doesn't. e.g. a long keypress event. – Mohit Kanwar Jul 09 '15 at 11:01
  • as stated by @Rejith R Krishnan input is an html 5 event. developer.mozilla.org/en-US/docs/Web/Events/input But there is issues in IE9 and lower versions. So for that we use propertychange event msdn.microsoft.com/en-us/library/ms536956(v=vs.85).aspx for better browser compatability. – Rejith R Krishnan – Mohit Kanwar Jul 10 '15 at 06:59
0

$(function() {
  var max_lenght = 5;
  
  $("#myTextInput").keypress(function(event) {
    if ($(this).val().length > max_lenght - 1 && $(this).val().length > 0) {
      event.preventDefault();
      alert("max_length reached");  
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" id="myTextInput" placeholder="type here..." />

Try this code, which check on keypress if max_lenght variable (which is 5 in this case) is reached (I added -1 to the condition).

Anwar
  • 4,162
  • 4
  • 41
  • 62
0

I suggest adding a 50ms delay to the keypress event. As follows.

$('#test').keypress(function(){
  setTimeout(function(){
    $('#debug').append('<br>' + $('#test').val());
  }, 50);


});

see example here

Ji_in_coding
  • 1,691
  • 1
  • 14
  • 17
0

here is a more simple (I believe) solution, as far as I understand the problem:

HTML:

<input type="text" id="test" />
<div id="result"></div>

JS:

var maxLength = 10;

$('#test').keypress(function(e){
  if($(this).val().length + 1 > maxLength){
    event.preventDefault();
  }
  else {
    $('#result').html($(this).val() + String.fromCharCode(event.which));
  }
});

play with it here in Codepen: http://codepen.io/anon/pen/zGWQvG

Ziv Levy
  • 1,904
  • 2
  • 21
  • 32