Catch only keypresses that change input? - javascript

I want to do something when a keypress changes the input of a textbox. I figure the keypress event would be best for this, but how do I know if it caused a change? I need to filter out things like pressing the arrow keys, or modifiers... I don't think hardcoding all the values is the best approach.
So how should I do it?

In most browsers, you can use the HTML5 input event for text-type <input> elements:
$("#testbox").on("input", function() {
alert("Value changed!");
});
This doesn't work in IE < 9, but there is a workaround: the propertychange event.
$("#testbox").on("propertychange", function(e) {
if (e.originalEvent.propertyName == "value") {
alert("Value changed!");
}
});
IE 9 supports both, so in that browser it's better to prefer the standards-based input event. This conveniently fires first, so we can remove the handler for propertychange the first time input fires.
Putting it all together (jsFiddle):
var propertyChangeUnbound = false;
$("#testbox").on("propertychange", function(e) {
if (e.originalEvent.propertyName == "value") {
alert("Value changed!");
}
});
$("#testbox").on("input", function() {
if (!propertyChangeUnbound) {
$("#testbox").unbind("propertychange");
propertyChangeUnbound = true;
}
alert("Value changed!");
});

.change() is what you're after
$("#testbox").keyup(function() {
$(this).blur();
$(this).focus();
$(this).val($(this).val()); // fix for IE putting cursor at beginning of input on focus
}).change(function() {
alert("change fired");
});

This is how I would do it: http://jsfiddle.net/JesseAldridge/Pggpt/1/
$('#input1').keyup(function(){
if($('#input1').val() != $('#input1').attr('prev_val'))
$('#input2').val('change')
else
$('#input2').val('no change')
$('#input1').attr('prev_val', $('#input1').val())
})

I came up with this for autosaving a textarea. It uses a combination of the .keyUp() jQuery method to see if the content has changed. And then I update every 5 seconds because I don't want the form getting submitted every time it's changed!!!!
var savePost = false;
jQuery(document).ready(function() {
setInterval('autoSave()', 5000)
$('input, textarea').keyup(function(){
if (!savePost) {
savePost = true;
}
})
})
function autoSave() {
if (savePost) {
savePost = false;
$('#post_submit, #task_submit').click();
}
}
I know it will fire even if the content hasn't changed but it was easier that hardcoding which keys I didn't want it to work for.

Related

Javascript Run function on all input fields on focus

I want to execute a function when any of the text field is focused.
Something like this, BUT purely in Javascript - NOT IN JQUERY
$("input").focus(function() {
alert("Hello World");
});
I am trying:
document.getElementById("text1").onfocus = alert(1);
But this only shows the alert after loading page, nothing else.
Thanks
Get elements by tag name & loop("Iterate") on them for attaching focus.
http://www.w3schools.com/jsref/met_doc_getelementsbytagname.asp
var x=document.getElementsByTagName("input");
EDIT : Put this at the end of page
<script>
var x=document.getElementsByTagName("input");
for(i=0;i<x.length;i++)
{
x[i].addEventListener('focus',function(){
alert("focus");
});
}
</script>
Yet another way with document.querySelectorAll for new browser
var inputs = document.querySelectorAll('input');
and then in loop for example use addEventListener
for(var i=0,len=inputs.length;i<len;i++){
inputs[i].addEventListener('focus',function(){
//handle event
})
}
If you like some aspects of jQuery, but do not want to include the entire library in your project, you can check out You Might Not Need jQuery. You can set the minimum version of IE that you support, in the settings at the top of the page.
function addEventListener(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, function(){
handler.call(el);
});
}
}
function addEventListeners(selector, type, handler) {
var elements = document.querySelectorAll(selector);
for (var i = 0; i < elements.length; i++) {
addEventListener(elements[i], type, handler);
}
}
addEventListeners('input', 'focus', function(e) {
if (this.value !== this.placeholder) {
this.value = this.placeholder;
} else {
this.value = '';
}
});
input {
display: block;
}
<input type="text" placeholder="One" />
<input type="text" placeholder="Two" />
<input type="text" placeholder="Three" />
I know I am probably late to this, but I just wanted to add my 2 cents, as I see a lot of Stackoverflow answers like this still using JQuery and many people have moved on from JQuery, and might want another option
You could either use the focusin event or capture the focus in the Capturing phase from the top down, in either JQuery or JS, If It works in JS, it should work in the other, as I dont use JQ
let form = document.forms.myForm;
form.addEventListener('focus', (event) => {
console.log('Focused!');
console.log(event.target);
}, true);
//Work around focusin
form.addEventListener('focusin', (event) => {
console.log('Focused In!');
console.log(event.target);
});
This one supports input elements that are loaded asynchronously too.
document.addEventListener("focusin", inputBoxListener)
function inputBoxListener(event) {
if (event.target.tagName === "INPUT") {
console.log("focused on input")
}
}
https://developer.mozilla.org/en-US/docs/Web/API/Element/focusin_event

Alert when backspace is pressed inside textbox

I have a grid with three read-only columns. Whenever user goes in there and try to edit by pressing backspace, I need to alert by giving a message. I am using this script and it doesn't work? Can anyone correct me?
$(document).ready(function () {
$('#txtCode').bind('keypress', function (e) {
if (e.which == 8) {
alert('The column is read-only and is not editable');
}
}
});
instead of keypress try with keyup or keydown with .on() method:
$('#txtCode').on('keyup keydown', function (e) {
You can bind multiple events like this too.
and one more thing closing of $('#txtCode') seems to be missing });
$(document).ready(function () {
$('#txtCode').on('keyup keydown', function (e) {
if (e.which == 8) {
alert('The column is read-only and is not editable');
}
}); //<----");" this is the closing you misssed this
});
See the fiddle in action
If this is all the code you are testing, you weren't closing the function properly, annotated in my posted code. Also use keyup instead of keypress
$(document).ready(function () {
$('#txtCode').bind('keyup', function (e) {
if (e.which == 8) {
alert('The column is read-only and is not editable');
}
}); /*<-- You weren't closing your function properly*/
});
Fiddle
You do indeed need to add a return false statement to ensure the character doesn't get deleted anyway. I also took it a step further and extended jQuery with a preventKeyUsage method.
$(document).ready(function () {
$.fn.preventKeyUsage = function (key, message) {
return this.each(function () {
$(this).on('keydown', function (e) {
return (e.keyCode === key) ? (function () {
alert(message);
return false;
})() : true;
});
});
};
$('#txtCode').preventKeyUsage(8, 'The column is read-only and is not editable');
});
New Fiddle
Working code is:
Java Script Code:
$(document).ready(function () {
$('#txtCode').bind('keypress keydown', function (e) {
if (e.which == 8) {
alert('The column is read-only and is not editable');
}
});
});
Here is the updated code
<input type="text" id="txtCode" />
$(document).ready(function () {
$('#txtCode').bind('keydown', function (e) {
if (e.which == 8) {
alert('The column is read-only and is not editable');
return false;
}
});
});
Fiddle Demo
Try this
$(document).ready(function () {
$('#txtCode').on('keyup', function (e) {
if (e.which == 8) {
alert('The column is read-only and is not editable');
}
});
});
DEMO (Working on Firefox & Chrome)
$('#textbox').keydown(function(event){
if(event.keyCode == 8){
alert("Backspace not allowed..");
return false;
}
});
http://jsfiddle.net/xF9jL/1/
You are missing }); of keypress. google chrome have issues with keypress, u can try keydown instead
$(document).ready(function () {
$('#txtCode').bind('keydown', function (e) {
if (e.which == 8) {
alert('The column is read-only and is not editable');
}
});
});
To use delete ,arrows, backspace keys in Chrome you must use keydown. keypress on these keys work only in Firefox and Opera.
DEMO
You can probably solve the underlying issue by either not using an element that accepts input, or by using the disabled attribute:
<textarea name="example" disabled>Some text</textarea>
If you are posting back to the sever, you should assume the user has edited the field, no matter what you do to prevent it.
keypress event won't give keycodes for all keys in all browsers . Better use keyup or keydown event which gives keycode for all keys in all browsers
In order to understand the difference between keydown and keypress, it is useful to understand the difference between a "character" and a "key". A "key" is a physical button on the computer's keyboard while a "character" is a symbol typed by pressing a button. In theory, the keydown and keyup events represent keys being pressed or released, while the keypress event represents a character being typed. The implementation of the theory is not same in all browsers.

Event fired when clearing text input on IE10 with clear icon

On chrome, the "search" event is fired on search inputs when user clicks the clear button.
Is there a way to capture the same event in javascript on Internet Explorer 10?
The only solution I finally found:
// There are 2 events fired on input element when clicking on the clear button:
// mousedown and mouseup.
$("input").bind("mouseup", function(e){
var $input = $(this),
oldValue = $input.val();
if (oldValue == "") return;
// When this event is fired after clicking on the clear button
// the value is not cleared yet. We have to wait for it.
setTimeout(function(){
var newValue = $input.val();
if (newValue == ""){
// Gotcha
$input.trigger("cleared");
}
}, 1);
});
The oninput event fires with this.value set to an empty string. This solved the problem for me, since I want to execute the same action whether they clear the search box with the X or by backspacing. This works in IE 10 only.
Use input instead. It works with the same behaviour under all the browsers.
$(some-input).on("input", function() {
// update panel
});
Why not
$("input").bind('input propertychange', function() {
if (this.value == ""){
$input.trigger("cleared");
}
});
I realize this question has been answered, but the accepted answer did not work in our situation. IE10 did not recognize/fire the $input.trigger("cleared"); statement.
Our final solution replaced that statement with a keydown event on the ENTER key (code 13). For posterity, this is what worked in our case:
$('input[type="text"]').bind("mouseup", function(event) {
var $input = $(this);
var oldValue = $input.val();
if (oldValue == "") {
return;
}
setTimeout(function() {
var newValue = $input.val();
if (newValue == "") {
var enterEvent = $.Event("keydown");
enterEvent.which = 13;
$input.trigger(enterEvent);
}
}, 1);
});
In addition, we wanted to apply this binding only to the "search" inputs, not every input on the page. Naturally, IE made this difficult as well... although we had coded <input type="search"...>, IE rendered them as type="text". That's why the jQuery selector references the type="text".
Cheers!
We can just listen to the input event. Please see the reference for details. This is how I fixed an issue with clear button in Sencha ExtJS on IE:
Ext.define('Override.Ext.form.field.ComboBox', {
override: 'Ext.form.field.ComboBox',
onRender: function () {
this.callParent();
var me = this;
this.inputEl.dom.addEventListener('input', function () {
// do things here
});
}
});
An out of the box solution is to just get rid of the X entirely with CSS:
::-ms-clear { display: none; } /* see https://stackoverflow.com/questions/14007655 */
This has the following benefits:
Much simpler solution - fits on one line
Applies to all inputs so you don't have to have a handler for each input
No risk of breaking javascript with bug in logic (less QA necessary)
Standardizes behavior across browsers - makes IE behave same as chrome in that chrome does not have the X
for my asp.net server control
<asp:TextBox ID="tbSearchName" runat="server" oninput="jsfun_tbSearchName_onchange();"></asp:TextBox>
js
function jsfun_tbSearchName_onchange() {
if (objTbNameSearch.value.trim() == '')
objBTSubmitSearch.setAttribute('disabled', true);
else
objBTSubmitSearch.removeAttribute('disabled');
return false;
}
ref
MSDN onchange event
- tested in IE10.
... or to hide with CSS :
input[type=text]::-ms-clear { display: none; }
The above code was not working in my case and I have changed one line and introduced $input.typeahead('val', ''); which works in my case..
// There are 2 events fired on input element when clicking on the clear button:// mousedown and mouseup.
$("input").on('mouseup', function(e){
var $input = $(this),
oldValue = $input.val();
if (oldValue === ''){
return;
}
// When this event is fired after clicking on the clear button // the value is not cleared yet. We have to wait for it.
setTimeout(function(){
var newValue = $input.val();
if (newValue === ''){
$input.typeahead('val', '');
e.preventDefault();
}
}, 1);
});

ExtJs simulate TAB on ENTER keypress

I know it is not the smartest idea, but I still have to do it.
Our users want to use ENTER like TAB.
So, the best I came up with is this:
Ext.override(Ext.form.field.Base, {
initComponent: function() {
this.callParent(arguments);
this.on('afterrender', function() {
var me=this;
this.getEl().on('keypress',function (e){
if(e.getKey() == 13) {
me.nextNode().focus();
}
});
});
}
});
But it still does not work exactly the same way as TAB.
I mean, it works OK with input fields, but not other controls.
May be there is some low-level solution.
Any ideas?
In the past I've attached the listener to the document, something like this:
Ext.getDoc().on('keypress', function(event, target) {
// get the form field component
var targetEl = Ext.get(target.id),
fieldEl = targetEl.up('[class*=x-field]') || {},
field = Ext.getCmp(fieldEl.id);
if (
// the ENTER key was pressed...
event.ENTER == event.getKey() &&
// from a form field...
field &&
// which has valid data.
field.isValid()
) {
// get the next form field
var next = field.next('[isFormField]');
// focus the next field if it exists
if (next) {
event.stopEvent();
next.focus();
}
}
});
For Ext.form.field.Text and similar xtypes there is a extra config enableKeyEvents that needs to be set before the keypress/keydown/keyup events fire.
The enableKeyEvents config option needs to be set to true as it's default to false.
ExtJS API Doc
Disclaimer: I'm not an expert on ExtJs.
That said, maybe try something like:
if (e.getKey() === 13) {
me.blur();
return false; // cancel key event to prevent the [Enter] behavior
}
You could try this
if (e.getKey() === 13) {
e.keyCode = Ext.EventObject.TAB
this.fireEvent(e, {// any additional options
});
}
Haven't really tried this ever myself.

Onsubmit validate change background requried fields?

Anyone know of a good tutorial/method of using Javascript to, onSubmit, change the background color of all empty fields with class="required" ?
Something like this should do the trick, but it's difficult to know exactly what you're looking for without you posting more details:
document.getElementById("myForm").onsubmit = function() {
var fields = this.getElementsByClassName("required"),
sendForm = true;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ff0000";
sendForm = false;
}
else {
//Else block added due to comments about returning colour to normal
fields[i].style.backgroundColor = "#fff";
}
}
if(!sendForm) {
return false;
}
}
This attaches a listener to the onsubmit event of the form with id "myForm". It then gets all elements within that form with a class of "required" (note that getElementsByClassName is not supported in older versions of IE, so you may want to look into alternatives there), loops through that collection, checks the value of each, and changes the background colour if it finds any empty ones. If there are any empty ones, it prevents the form from being submitted.
Here's a working example.
Perhaps something like this:
$(document).ready(function () {
$('form').submit(function () {
$('input, textarea, select', this).foreach(function () {
if ($(this).val() == '') {
$(this).addClass('required');
}
});
});
});
I quickly became a fan of jQuery. The documentation is amazing.
http://docs.jquery.com/Downloading_jQuery
if You decide to give the library a try, then here is your code:
//on DOM ready event
$(document).ready(
// register a 'submit' event for your form
$("#formId").submit(function(event){
// clear the required fields if this is the second time the user is submitting the form
$('.required', this).removeClass("required");
// snag every field of type 'input'.
// filter them, keeping inputs with a '' value
// add the class 'required' to the blank inputs.
$('input', this).filter( function( index ){
var keepMe = false;
if(this.val() == ''){
keepMe = true;
}
return keepMe;
}).addClass("required");
if($(".required", this).length > 0){
event.preventDefault();
}
});
);

Categories