views:

53

answers:

4

Hi Folks,

I am trying to invoke an ajax call as soon as my input fields length is 15 (for now I have just put in an alert box in place of .ajax{ }), but the alert box is not firing up until I click somewhere on the screen after input field is filled with 15 characters. what am I doing wrong here?

$("#serialCode").change(function () {
    var d = $("#serialCode").val();
    if (d.length == 15) {
        var $code = d.substring(0, 9);
        alert('Serial code ' + $code);
    }
    $(this).val("");
});
+1  A: 

The change event doesn't fire until you lose focus on the input.

Try using keyup instead:

$("#serialCode").keyup(function () {
    var d = this.value;
    if (d.length == 15) {
        var $code = d.substring(0, 9);
        alert('Serial code ' + $code);
    }
  //  this.value = '';
});

You should note that people can get around this by using the GUI to paste text into the input, so you may want to add the same functionality on change as well.

$("#serialCode").bind('keyup keydown change', function () {

Because there are multiple events, you should have some sort of flag that is set when the AJAX request is sent, so you're not sending it multiple times.

patrick dw
Hi Patrick, How would keyup fucntion work? because after every character there will be a keyup event. Am I wrong herE?
t3ch
@t3ch - Yes, after each character there's a keyup. That's why I commented out the last line where the value is erased. But a person could hold a key down, and not keyup until several characters have been typed, so I added `keydown` which I think will fire if that happens. But a user could copy/paste some text without using any keys, so I added the `change` back in for that. Using this method, you would want to have some code that makes sure your AJAX request doesn't get sent multiple times. So the first event that finds 15 chars should send the request, and set a flag to prevent the others.
patrick dw
HI Patrick, a user can never enter a value through a keyboard. The input will come from a scanner and as soon as its 15 characters (which takes 1 sec maybe), it should submit it to server
t3ch
+2  A: 

You'll likely want to use keypress instead of keyup or keydown, as those won't be called for subsequent characters if someone holds a key down.

$("#serialCode").keypress(function () {
    var d = $("#serialCode").val();
    if (d.length == 15) {
        var $code = d.substring(0, 9);
        alert('Serial code ' + $code);
    }
    $(this).val("");
});
zincorp
The *keypress* event fires before the value of the text input is updated, so the length won't be the true length.
Andy E
That's a very good point. Also, if this is modified to check a length of 14 (pre-empting the 15th keystroke) then it could be prone to inaccuracy if the 15th keystroke happens to be a backspace. =) I like your answer. Upvoting that.
zincorp
Hi Zincorp, keypress isnt working for me. This input comes from a usb device which acts like a keyboard wedge. Using keypress is only giving me one character
t3ch
Can you configure it to press enter after its input?
zincorp
+2  A: 

I wrote a blog post earlier today on why onkeyup isn't a great idea for detecting user input. The better option is to either use onkeydown with a 0ms timer, or a combination of the newer HTML 5 event oninput for standards compliant browsers and onpropertychange in Internet Explorer.

These two events will handle other forms of input such as cut, paste, undo, redo, drag and drop, and even changes made by a native spell checker.

Something like this should work for you:

// Check for which event we need to bind to, onpropertychange or oninput
var evt = "onpropertychange" in document.body ? "propertychange" : "input";
$("#serialCode").bind(evt, function (event) {
    // For the onpropertychange event, check that the value property changed
    if (evt == "propertychange" && event.propertyName != "value")
        return;
    var d = $("#serialCode").val();
    if (d.length == 15) {
        var $code = d.substring(0, 9);
        alert('Serial code ' + $code);
    }
    $(this).val("");
});

Note that if you need to support older browsers, you'll need to use some form of event detection to see if these events are available and if not, fall back to the keydown with timer method.

Andy E
Would it be bad to just bind both "propertychange" and "input" to the handler without bothering to check first?
Pointy
@Pointy: I'm not sure if *oninput* is supported by IE 9, which would mean it would fire and handle both events. Also, I was leaving it kind of open for another test in case neither event is available.
Andy E
Oh right; duhh.
Pointy
Hi Andy, thanks for the help. I am using FF 3. As someone suggested in one of the reply to use onKeypress, that didnt work for me either.
t3ch
Hi Andy, if you dont mind, could you please tell me what exactly you are doing with first few lines of code.
t3ch
@t3ch: I noticed a small error in my code, not surprisingly I managed to confuse myself. I added comments to the first few lines. The short version is - check if the browser supports *onpropertychange* or *oninput* and bind to the resulting event name. The if statement inside the handler checks that, if the event firing is the *onpropertychange*, the property that changed was the *value* property.
Andy E
If you only need support for Firefox 3, just bind to "input". I'm looking at creating a plugin to normalize as much of the input event as possible across browsers.
Andy E
A: 

i experienced issues with the jQuery ajax interface. those issues disappeared when i decided to just use to javascript only interace.

see this link hosted at IBM. once you read this you will never again have a question with how ajax does or should function.

jason m