How to detect when a textarea value is changed by a script? - javascript

I would like to check a textarea when the value inside it is changed by program.
The code is quite complex so I would rather use an event listener instead of looking for the exact line of code.
Here is how I check:
$(".edit.btn.btn-default").on("click", function(){
alert($("#attribute_fabric_en").val());
$("#attribute_fabric_en").on("input propertychange",function(){
alert("test");
});
});
The result: alert($("#attribute_fabric_en").val()); prints an empty string, but the textarea later on will be assigned a value by script; but the listener is not triggered.
At least Chrome tested is not work to capture the event

There is an event for that, in jQuery you can use $('.textareaId').on('change', console.log($('#textareaId').html()), It is that simple !
EDIT:
Maybe you don't want to use jQuery, click event is for textarea, contentediatble divs, etc and input event is for form elements such as
textArea.addEventListener('change', function(e){ ... }, false);\n
inputElement.addEventListener('input', function(e) { ... }, false);

Related

My change event listener not tracking changes as expected [duplicate]

When using jquery .change on an input the event will only be fired when the input loses focus
In my case, I need to make a call to the service (check if value is valid) as soon as the input value is changed. How could I accomplish this?
UPDATED for clarification and example
examples: http://jsfiddle.net/pxfunc/5kpeJ/
Method 1. input event
In modern browsers use the input event. This event will fire when the user is typing into a text field, pasting, undoing, basically anytime the value changed from one value to another.
In jQuery do that like this
$('#someInput').bind('input', function() {
$(this).val() // get the current value of the input field.
});
starting with jQuery 1.7, replace bind with on:
$('#someInput').on('input', function() {
$(this).val() // get the current value of the input field.
});
Method 2. keyup event
For older browsers use the keyup event (this will fire once a key on the keyboard has been released, this event can give a sort of false positive because when "w" is released the input value is changed and the keyup event fires, but also when the "shift" key is released the keyup event fires but no change has been made to the input.). Also this method doesn't fire if the user right-clicks and pastes from the context menu:
$('#someInput').keyup(function() {
$(this).val() // get the current value of the input field.
});
Method 3. Timer (setInterval or setTimeout)
To get around the limitations of keyup you can set a timer to periodically check the value of the input to determine a change in value. You can use setInterval or setTimeout to do this timer check. See the marked answer on this SO question: jQuery textbox change event or see the fiddle for a working example using focus and blur events to start and stop the timer for a specific input field
If you've got HTML5:
oninput (fires only when a change actually happens, but does so immediately)
Otherwise you need to check for all these events which might indicate a change to the input element's value:
onchange
onkeyup (not keydown or keypress as the input's value won't have the new keystroke in it yet)
onpaste (when supported)
and maybe:
onmouseup (I'm not sure about this one)
With HTML5 and without using jQuery, you can using the input event:
var input = document.querySelector('input');
input.addEventListener('input', function()
{
console.log('input changed to: ', input.value);
});
This will fire each time the input's text changes.
Supported in IE9+ and other browsers.
Try it live in a jsFiddle here.
As others already suggested, the solution in your case is to sniff multiple events.
Plugins doing this job often listen for the following events:
$input.on('change keydown keypress keyup mousedown click mouseup', handler);
If you think it may fit, you can add focus, blur and other events too.
I suggest not to exceed in the events to listen, as it loads in the browser memory further procedures to execute according to the user's behaviour.
Attention: note that changing the value of an input element with JavaScript (e.g. through the jQuery .val() method) won't fire any of the events above.
(Reference: https://api.jquery.com/change/).
// .blur is triggered when element loses focus
$('#target').blur(function() {
alert($(this).val());
});
// To trigger manually use:
$('#target').blur();
If you want the event to be fired whenever something is changed within the element then you could use the keyup event.
There are jQuery events like keyup and keypress which you can use with input HTML Elements.
You could additionally use the blur() event.
This covers every change to an input using jQuery 1.7 and above:
$(".inputElement").on("input", null, null, callbackFunction);

trigger Jquery function after an auto focus

is it possible to trigger a function after an autofocus? I tried but when my textarea get the autofocus i need to click away then to click again on my textarea to trigger the function
my code is :
$('#test').focus();
$('#test').focus(function() {
alert('ok');
});
Try swapping the code around. You're event wasn't attached to the test element the first time you call focus()
$('#test').focus(function() {
alert('ok');
});
$('#test').focus();
This is because you are setting the trigger after you set the focus.
Rearrange your code and this will work fine.
The .focus() method has two different meanings based on the parameters it is passed.
In your first statement.
$('#test').focus();
This is setting the focus to the element with ID test.
Your second statement though
$('#test').focus(function() {
alert('ok');
});
What is happening here is jQuery is attaching an event handler to the focus event of the element. I suggest adding your event handlers when the DOM is loaded, then calling the .focus() event when required (which will trigger the alert).
$(function(){
$('#test').focus(function() {
alert('ok');
});
});

jQuery using event.preventDefault() with on('input')

I'm catching paste events with $('selector').on('input', function(event) { ... });
Then I'm trying to test what's been pasted and if it doesn't pass validation, cancel the paste with event.preventDefault(). Unfortunately, by the time the listener function is executed, the text has already been pasted and event.preventDefault() does nothing.
So what's a good way to catch paste events, and if what's been pasted doesn't validate, undo/prevent the paste?
I know I can use .on('paste', function(event) { ... }), but that doesn't give me the text that's been pasted or the contents of the input element after the paste, unless I use setTimeout() with some minute wait time, and I'd like to avoid using setTimeout().
First of all some background on event trigger order for the input element:
keydown -> keypress -> paste -> input -> keyup -> change
Whenever you call preventDefault it stops the chains, like nothing happened.
So my suggestion is to catch the paste event, prevent its default behavior and do your logic there.
I know I can use .on('paste', function(event) { ... }), but that
doesn't give me the text that's been pasted or the contents of the
input element after the paste
Actually you can retrieve the content of the clipboard. See this doc. Support is all major browser (but only IE11+). I do not know if by the time of the writing of the question this functionality was available or not.
Fiddle example
$('#myInput').on('paste', function(e) {
// Cancel the event - this prevents the text from being entered into the input and stops the event chain
e.preventDefault();
// Get the content of the clipboard
let paste = (event.clipboardData || window.clipboardData).getData('text');
// Validate what it is pasted
if (paste == "text to paste") {
// If condition is satisfied manually set the value of the input
$(this)
.val(paste)
// Manually trigger events if you want
.trigger('input')
.trigger('change');
}
});
Notes on the code:
This solution does not include setTimeout. Whenever you make it with setTimeout you see for a very short time the text being pasted, like a blinking effect.
If text meets condition I manually set it in the input. However this does not trigger input and change events. If you need them, just manually trigger them
Similar approach is to first check the text and if it does not meet requirements then call preventDefault, otherwise do nothing. This way you avoid manually setting value in the input and triggering events afterward.
Try using .change event of jquery.
Set value to blank if value doesn't satisfy your condition.
Using
$('selector').on('input', function(event) { ... });
and in case the validation does not pass deleting the pasted text seems to work for me.
Sadly accessing the clipboard has some flaws (browser asking if it is allowed to inspect the clipboard, cross browser compatibility, etc.)
If you are okay with saving the last value of the input, the pasted text can be calculated anyway.
Here is my approach for calculating the pasted text
https://jsfiddle.net/f710o9qd/2/
I hope this helps you :)
(Feel free to refine the calculation of the pasted text if you find any flaws)
My understanding from the question is, we must not allow any data to be pasted inside the text box until and unless it pass a specific validation. Instead of using event.preventDefault(), we can capture the value when user input any content, using on('input') listener and validate it against the specific condition and if the validation gets failed, empty the text box value.
(This is the workaround if we still need to use on('input') event listener)
Sample Code (I am using console.log() for printing the pasted value):
HTML:
<input type='text' id="selector" />
JS:
$(document).ready(function() {
$('#selector').on('input', function (e){
if(e.target.value !== "myValue"){
$('#selector').val('');
}
else{
console.log(e.target.value);
}
});
});

paste event gets fired before text is in textbox

events: { "paste .youtube-url" : "addUrl" }
addUrl: function(){
console.log(this.$(".youtube-url").val());
So lets say I paste "bad" into the textbox first time
console output: (an empty string)
then if I paste append something like "coder"
console output: bad
instead of whats inside the box "badcoder", I guess this i because the pseudo paste event is fired before the text is inserted.
Instead of using the paste event you could use the keyup event which fires if someone pastes but also only fires after the value for the input has been updated.
UPDATE
Good comment from #Micah (and #JohnnyO). Here's a fix I found to work:
$('input').on('paste', function () {
var that = this;
setTimeout(function () {
alert(that.value);
}, 0);
});​
This sets a timeout so the code that reads the input's value is only run after the rest of the code in the stack has been run. I've only tested in Chrome 21 but the zero-time-timeout seems to do the trick.
Demo: http://jsfiddle.net/H4K4R/
The answer by #Jasper only works when pasting by keyboard. When using the mouse and the context menu to paste, you won't get a keyup event. The best event to watch for is the 'input' event. Unfortunately, for IE versions before 9, you'll need to watch for the 'propertychange' event instead because they don't support 'input'. 'propertychange' doesn't bubble, so you won't be able to wire up this event like you're doing using Backbone, and instead will need to bind it directly to the '.youtube-url' element.

jQuery keypress event not firing

I have a form that when the user hits edit, it changes the field from text to a textbox with a class of cat_name_edit.
The following code does not trigger when pressing any key in the textbox. Could it have something to do with the fact that I've already changed the text into a textbox?
$(".cat_name_edit").keypress(function() {
alert("hi");
});
I've also tried .click() and .keydown() with no luck. Any ideas?
Ok, apparently I had to use .live()
I think the elements are not present on page load so the events are not attached. Try using jQuery live.
$(".cat_name_edit").live('keypress', (function() {
alert("hi");
});
I put this into a fiddle keypress() works fine:
$(".cat_name_edit").keypress(function(e) {
$(this).replaceWith("<textarea class=\"cat_name_edit\"></textarea>");
$("textarea.cat_name_edit").focus();
});
keyup() would have worked too.
I've also gone to the liberty of making the function that replaces the input with a textarea.
or you could also use EventDelegation. Attach your click event to the parent which contains these textboxes, and in the function check if the target that was clicked has the class cat_name_edit and then perform your operation.

Categories

Resources