Problem invoking a function on change event - javascript

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("");
});

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("");
});

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.

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.

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.

Related

jQuery event trigger is not working on annotorious and seadragon

I am trying to get the down arrow keyup event to fire automagically using jQuery. The annotorious/seadragon combination has a listener that opens all preconfigured tags when I press the down arrow.
I have written jQuery code to find the input field, put focus on it and then trigger the keyup event.
function triggerDownArrowOnInput() {
$("[id^=downshift][id$=input]").each(function(index) {
// There should only be 1, but let's not assume.
console.log(index);
if (index == 0) {
console.log("Found an input: " + $(this).attr("id"))
$(this).focus();
var event = jQuery.Event("keyup");
event.keyCode = event.which = 40; // down arrow
$(this).trigger(event);
} else {
console.log("Multiple elements found that match the id: " + $(this).attr("id"));
} // if
})
} // triggerDownArrowOnInput
The focus is working great, but not the trigger. If I manually hit the down arrow key, then the preconfigured tags all appear:
I have tried "keyCode" and "which" separately.
I have tried triggering $(this).keyup(event).
I have tried putting in a delay between the focus call and the trigger/keyup call.
I have tried calling $(document).trigger(event).
I thought maybe I was sending the event to the wrong element, but it appears (going through Dev tools) that only the Input field and the document have the listeners enabled.
No matter what I do, I can't get the event to fire. Any ideas?
Thanks.
I think I've got this working without jQuery, using a KeyboardEvent and dispatchEvent. With my tests I don't think you need the focus before hand either because it's an event on the element, but worth testing this on your application.
function triggerDownArrowOnInput() {
$("[id^=downshift][id$=input]").each(function(index) {
// There should only be 1, but let's not assume.
console.log(index);
if (index == 0) {
console.log("Found an input: " + $(this).attr("id"))
$(this).focus();
this.dispatchEvent(new KeyboardEvent('keyup',{'keyCode': 40, 'key':'ArrowDown', 'code':'ArrowDown'}));
} else {
console.log("Multiple elements found that match the id: " + $(this).attr("id"));
}
})
}
Have you tried keydown?
var e = jQuery.Event("keydown");
e.which = 40;
e.keyCode = 40
$(this).trigger(e);
function triggerDownArrowOnInput() {
$("[id^=downshift][id$=input]").each(function(index) {
// There should only be 1, but let's not assume.
console.log(index);
if (index == 0) {
console.log("Found an input: " + $(this).attr("id"))
$(this).focus();
var event = jQuery.Event("keydown");
event.keyCode = event.which = 40;
$(this).trigger(event);
} else {
console.log("Multiple elements found that match the id: " + $(this).attr("id"));
}
})
} // triggerDownArrowOnInput
I was able to get the event to fire, but still wasn't able to open the menu on focus. I ended up having to create a development environment for:
recogito/recogito-client-core
recogito/recogito-js
recogito/annotorious
recogito/annotorious-openseadragon
I then modified Autocomplete.jsx in recogito/recogito-client-core, added an OnFocus listener and then added the following code:
const onFocus = evt => {
if (!isOpen) {
this.setState({ inputItems: this.props.vocabulary }); // Show all options on focus
openMenu()
} // if
} // onFocus
Way more than I wanted to do, but it is working now.

Sliding down label depending on time difference

So I have two time fields, timeFrom and timeTo. What I want to do is get a label sliding down if the time difference is equal or greater than 2. But I can't figure out what I'm doing wrong here. Here's my code:
$(document).ready(function() {
$("#timeTo").change(function()) {
var timeTo = $("#timeTo").val();
var timeFrom = $("#timeFrom").val();
var diff = timeTo - timeFrom;
if (diff >= 2){
$("#cost_label").slideDown();
}
else{
$("#cost_label").slideUp();
}
});
$("#cost_label").hide();
$("#timeTo").trigger("change");
});
Try
$(document).ready(function () {
$("#timeTo").on('input', function () {
var timeTo = $("#timeTo").val();
var timeFrom = $("#timeFrom").val();
var diff = parseFloat(timeTo) - parseFloat(timeFrom);
alert(diff);
if (diff >= 2) {
$("#cost_label").slideDown({
complete: function () {
$("#cost_label").hide();
}
});
} else {
$("#cost_label").slideUp({
complete: function () {
$("#cost_label").hide();
}
});
}
});
});
Your label is to hide when the animation completes so it doesn't hide immediately
Strings read as integers, because you can't subtract Strings
on('input') instead of on(change), this is the right way to detect textfield changes
Removed parenthesis after anonymous function declaration, that was a syntax error ;)
You can always debug your problems and use logic to fix these issues.
Somewhat-working Demo
You may not need the + to typecast values and may not need to Math.abs if you're using type="number" inputs with sensible min/max limits.
The 'keyup' event will fire when a key goes from down to up position, so you will not need to unfocus (click or tab away from) the input box. You can also use 'keydown' too, if you're too eager to wait, and don't mind events that fire every 14 milliseconds when the user falls asleep on the keyboard.
Use the $.on instead of the event-named methods so that you can listen for multiple events (as a space separated list) and listen for the event on both inputs (selectors need comma separated list).
$(function(){
$('#cost_label').hide();
$('#timeFrom,#timeTo').on('keyup change', timeChange);
function timeChange(){
var from = +$('#timeFrom').val();
var to = +$('#timeTo').val();
if(Math.abs(to - from) >= 2)
$('#cost_label').slideDown();
else $('#cost_label').slideUp();
}
timeChange();
});
http://jsfiddle.net/LDB5X/ using input type="text"
http://jsfiddle.net/6M5V6/ using input type="number" (might not work in all browsers)
What is this 'input' event? I can't find it in the jquery docs

JavaScript keypress event not raised on Android browser

I have created a simple code to handle keypress event:
var counter = 0;
$('input').on('keypress', function () {
$('div').text('key pressed ' + ++counter);
});
JSFiddle.
But keypress event handler is not raised on mobile browser (Android 4+, WindowsPhone 7.5+).
What could be the issue?
I believe keypress is deprecated now. You can check in the Dom Level 3 Spec. Using keydown or keyup should work. The spec also recommends that you should use beforeinput instead of keypress but I'm not sure what the support of this is.
Use the keyup event:
// JavaScript:
var counter = 0;
document.querySelector('input').addEventListener('keyup', function () {
document.querySelector('div').textContent = `key up ${++counter}`;
});
// jQuery:
var counter = 0;
$('input').on('keyup', function () {
$('div').text('key up ' + ++counter);
});
Use jQuery's input event, like this:
$( 'input' ).on( 'input', function() {
...
} );
With this you can't use e.which for determining which key was pressed, but I found a nice workaround here: http://jsfiddle.net/zminic/8Lmay/
$(document).ready(function() {
var pattForZip = /[0-9]/;
$('#id').on('keypress input', function(event) {
if(event.type == "keypress") {
if(pattForZip.test(event.key)) {
return true;
}
return false;
}
if(event.type == 'input') {
var bufferValue = $(this).val().replace(/\D/g,'');
$(this).val(bufferValue);
}
})
})
Yes, some android browser are not supporting keypress event, we need use to only keydown or keyup but will get different keycodes, to avoiding different key codes use the following function to get the keycode by sending char value.
Eg:
function getKeyCode(str) {
return str && str.charCodeAt(0);
}
function keyUp(){
var keyCode = getKeyCode("1");
}
I think it is bad idea to use other events in place of 'keypress'.
What you need to do is just include a jQuery file into your project.
A file named jQuery.mobile.js or quite similar (ex. jQuery.ui.js) of any version can help you.
You can download it from : https://jquerymobile.com/download/

How do I get key values in HTML/Javascript

Okay, so i understand how to get the key value while using an input field... but I am taking about key values that are pressed while your browser isn't focused in any text box or text area.
I am trying to make a onscreen keypad that has buttons for 0, 1, 2, .. 9... however I want the user to be able to press the buttons with the keys on the keyboard.
I've seen this done in some websites, where if you press the S key on the homepage, it will take you to the signin screen. Facebook also does the L key, to like a photo.
So the question is: How do I get the key values in javascript, when the cursor isn't focused.
If you are using JQuery you just add the event handler to the document...
$(document).keypress(function(event) {
alert('Handler for .keypress() called. - ' + event.which);
});
(From http://forum.jquery.com/topic/how-to-catch-keypress-on-body)
Edit for zzzzBov's comment...
From the JQuery KeyPress documentation:
To determine which character was entered, examine the event object
that is passed to the handler function. While browsers use differing
properties to store this information, jQuery normalizes the .which
property so you can reliably use it to retrieve the character code.
you need to use window.onkeydown and then check for the keys you're interested in.
https://developer.mozilla.org/en-US/docs/Web/API/window.onkeydown
You should listen on key press event.
document.onkeypress = function(evt) {
evt = evt || window.event;
var charCode = evt.which || evt.keyCode;
alert("Character typed: " + String.fromCharCode(charCode));
};
For more info Look here Link
You need to add an event listener to the window. Then in the event handler, you get the keyCode property from the passed-in event. KeyCodes are semi-arbitrary in that they don't directly map to what you might think, so you have to use a table (first result on google: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes) to identify the keycodes you care about.
window.addEventListener('keypress',function (evt) {
switch (evt.keyCode) {
case 48:
zeroKeyPressed(); break;
case 49:
oneKeyPressed(); break;
...
}
}, false);
You would use a key press event.
Here's an example for your usage:
window.addEventListener('keypress', function (event) {
var key_code, key;
event = event || window.event; // IE
key_code = event.charCode || event.keyCode || event.which || 0;
key = String.fromCharCode(key_code);
// prevent keys 0-9 from doing what they normally would do
if (key_code >= 48 && <= 57) {
event.preventDefault();
alert('The user pressed ' + key);
}
}, false);
Using plain js, you can use this in your layout.htmlcs, at the beginning:
#{
<script>
sessionStorage.setItem("ProductionHostURL", '#System.Configuration.ConfigurationManager.AppSettings["ProductionHostURL"]');
</script>
}
<!DOCTYPE html>
Then in your main js file of the layout.htmlcs, you can use this a method liked this:
var urlBaseProduction;
var urlBaseDevelopment;
$(document).ready(function () {
configureHostEnvironment()
....
}
In that method, configure the variables to use in production and development, like this:
function configureHostEnvironment(){
HOST = sessionStorage.getItem("ProductionHostURL")
if (HOST.length <= 0) {
alert("Host not configured correctly")
} else {
urlBaseProduction= host + '/api/';
urlBaseDevelopment= host + port + '/api/';
}
}
If you have a suggestion or improvement to this method, please comment.

Custom keyboard / replace keys

I want to change behavior of my keyboard so when user on an input box press key a a = 97 it changes to b 97+1.
I want it for cross browser
jQuery.keypress will get you the event when the users types something, and String.fromCharCode gets you the character + 1. The tricky part is dealing with the selection.
To get the selection, I used the jQuery field selection plugin, and to make sure it doesn't keep jumping back to the end I used this answer to another question. Here is the final code:
$(function() {
$("#target").keypress(function (evt) {
if (evt.which >= 65 && evt.which <= 122) {
var sel = $(this).getSelection();
var val = $(this).val();
var out = val.substring(0, sel.start) + String.fromCharCode(evt.which+1) + val.substring(sel.end, val.length);
$(this).val(out);
$(this).selectRange(sel.start + 1, sel.start + 1);
return false;
}
});
});
jsFiddle
I restricted it to a-zA-Z but you can customize that however you want.
I tested the following in Firefox and Chrome. Using "keypress" allows the use of other keys, and using charCode allows using lower and uppercase letters:
document.getElementById("textbox").addEventListener("keypress",function(event){
event.preventDefault();
this.value+=(String.fromCharCode(event.charCode+1))
},false);
I just now saw the jQuery tag, so you could also do:
$("#textbox").bind("keypress",function(event){
event.preventDefault();
this.value+=(String.fromCharCode(event.charCode+1));
});

Categories

Resources