jQuery addClass when value of hidden input changes dyamically - javascript

I have a contact form that sends a value to a hidden input on successful completion of the sendmail function. I want to detect this value change and then use it to apply a class to a div/paragraph.
I asked a similar question recently and I'm aware that this requires the script to continually check the doc after DOM is loaded but even after adding .change() it just doesn't seem to want to add the class.
Here's the jQuery:
$(document).ready(function() {
$("#acf_success_sent").change(function(){
if ($("#acf_success_sent").val() == "1"){
$("#acf_verified").addClass('gone');
}
});
});
any help would be great. here's a link to a test version of form in case you're interested, everything works except the verified symbol doesn't disappear after a successful send http://seeshell.me/forms/contact.php

There'll be no "change" event fired when code updates the value of your <input> element, so the handler you've registered won't run. What you could do however is fire "change" from a watchdog:
var watchdog = setInterval(function() {
if ($('#acf_success_sent').val() !== originalValue)
$('#acf_success_sent').trigger('change');
}, 100);
How you set up "originalValue" depends on your application. You could, for example, keep a separate ".data()" value, and watch for whenever your saved value differs from the current "value" attribute. Or you could keep the value in a closure variable:
var watchdog = (function() {
var $acfSuccessSent = $('#acf_success_sent'), cachedValue = $acfSuccessSent.val();
return function() {
if (cachedValue !== $acfSuccessSent.val())
$acfSuccessSent.trigger('change');
};
})();

Related

Can I catch a js triggered change event?

I can use jquery to easily catch a change event of a select option when a user clicks it, however if javascript changes the select value, the 'change' event never triggers and needs to be manually triggered.
Is it possible to catch the value changing without manually having to trigger('change')?
Example fiddle here: https://jsfiddle.net/1fhbha4o/1/
Is it possible to catch the value changing without manually having to trigger('change')?
No. No event is fired when JavaScript code sets the value of a select. So your options are:
Have a common function you call both in response to a change event and also whenever your code changes the value (perhaps centralize changing the value so you don't forget to call it).
.trigger('change')
Polling the value to see if it changes (blech).
Re #1 and #2, you could give yourself a valWithNotify:
$.fn.valWithNotify = function(arg) {
if (arguments.length == 0) {
return this.val();
}
return this.each(function() {
$(this).val(arg).trigger("js-change"); // or just "change", but I'm not a
// fan of synthetic user events
});
};

checking the ace editor in the onbeforeunload to see if changes were made

I'm trying to use the $(window).on('beforeunload', function(){}); and editor.session.getUndoManager().isClean(); in the ace editor to check if the user made changes to a document but didn't click the submit button but for some reason it doesn't work Here's the code:
editor.on('change', function(Isclean ) {
var Isclean = editor.session.getUndoManager().isClean();
});
var submitting = false;
$(window).on('beforeunload', function(){
if (submitting == false && Isclean == false) {
return "You have made some changes in the editor.";
};
});
But for whatever reason Isclean always returns a boolean of true.
There are a couple of problems with the code. In your 'change' event handler, the function argument and the local variable are both called Isclean.
Secondly, the Isclean variable is not visible to your 'beforeunload' event handler.
In order to accomplish this task I did:
$(window).bind("load", function() {
editor.session.getUndoManager().markClean();
});
I was pre-loading some Json into the editor so unless i called editor.session.getUndoManager().markClean(); as the last thing to load (and it HAS to be the last thing to load), it would always boolean to false.

Avoid user changed data being overwritten?

I have an app where you can enter some information about a customer. I have the problem that this information easily can be overwritten by other changes in the app.
I want:
A textarea showing the information
The message shown should update as changes are made to it in other places in the app
If the user has changed the message in the textarea, the message in the textarea should NOT be overwritten by server side changes or other changes in the app
When a save button is pressed, the model is updated
Simply doing this:
<textarea ng-model="customer.info"></textarea>
<button ng-click="save(customer)">Save</button>
won't work, because if something is changed to the customer object on the server, the information field will be reset and the user's changes will be overwritten.
Update:
In response to your comment/updated question: I'd simply track the state of the textarea using a couple of event listeners, that check if the user changed the value. If so: the textarea is no longer kept in sync with the server data.
I also check if the textarea has focus, if that is the case, the value should not be updated, because the user might be editing its contents.
Lastly, I've attached a blur event handler, that checks the value again, in case the user "undoes" changes. If a user adds a char by accident, and removes it later on, the textarea's value might be the same as the last known value that came from the server, in which case, the textarea's value should be kept in-sync again.
I've set up a simple fiddle that uses an interval to do all this. Replace the interval-related code with your worker, ajax callback or whatever it is you're using. If it's a worker, unsetting the interval should be replaced with unbinding the onmessage handlers with a handler function that syncs the textarea or doesn't sync the textarea. Alternatively use a single function that checks the changed flag whenever it wants to change the textarea's value. Plain and simple.
Here's the fiddle
And here's the code (the fiddle version contains some actual comments that explain various bits and pieces):
(function (txt)
{
var initialValue = txt.value,
changed = false,
id,
callback = function()
{
if (changed === false)
initialValue = (txt.value += ' Server-sync');
else
{
clearInterval(id);
id = null;
}
};
txt.addEventListener('change', function()
{
if (this.value !== initialValue)
changed = true;
}, false);
txt.addEventListener('focus', function()
{
changed = true;
}, false);
txt.addEventListener('blur', function()
{
if (this.value !== initialValue)
changed = true;
else
{
changed = false;
id = setInterval(callback, 5000);
}
}, false);
id = setInterval(callback,5000);
}(document.querySelector('#foo')));
Initial answer
Like I said in my comment:
<textarea ng-model="customer.info" id='foo' readonly></textarea>
prevents the value of the textare from being altered by the user, but you can still set/change its value in your JS code:
var changeTxt = (function(txt)
{
return function(addVal)
{
txt.value += addVal;
};
}(document.querySelector('#foo')));
Demo
To keep the value of the textArea in sync, you could perform an AJAX call prior to making any changes to the value client side, or create a worker "thread" that polls the server for changes that have been made since the value was last fetched.
Seeing as you're using angular.js, I must admit that I don't have any experience with how angular can be best used to solve your issue, but a quick google search lead me to 3-way data binding, which does look rather promising.

How to capture change in text when that change is through javascript function. Javascript change event is not working in this case

My Code is as below.
$(document).ready(function($)
{
var form = $("#video_detail_form");
var name = $("#videoTitle");
var nameInfo = $("#valid_videoTitle");
function validateName(){
//if it's NOT valid
var titleValue=$.trim(name.val());
if(titleValue.length == 0){
nameInfo.text("Please Enter Title");
return false;
}
//if it's valid
else{
nameInfo.text("");
return true;
}
}
name.blur(validateName);
name.keyup(validateName);
name.change(validateName);
$('#editVideoCancel').click(function(){
cancelVideoDetailAjaxCall( '/video/cancelVideoDetail', callBackCancelVideoDetail);
});
});
My cancelVideoDetailAjaxCall function changes text of the videoTitle input box. But my this code is not capturing that event by name.change.
If I change manually then it captures it. So when dynamically my callback function is changing the text then change event is not capturing it.
How should I capture that change?
You can actually extend your value change catching to all changes coming from some script using the jQuery val method, by setting a custom setter in jQuery.valHooks.
Imagine you change the input type to myCustomType, then you will implement jQuery.valHooks.myCustomType.set method which will be called each time val is used to set the input value, and you will include your specific call here. But I insist : it is not a best practice.
You will surely find explicit code on the web for that hooks.
As comments have mentioned, if you programmatically change the value via jQuery you must also trigger that change programmatically, if you want anything subscribed to it to register that change.
You can always make up your own events and trigger them accordingly if you don't want to "interfere" with other things already subscribed to regular events:
$el.on('mycustomevent', function() { ... })
$el.trigger('mycustomevent');
You can even subscribe with the same callback for the 'regular event' and your 'custom event':
$el.on('change', myChangeCallback);
...
$el.on('mycustomevent', myChangeCallback);
If you don't want to keep typing $el.val('...').trigger('mycustomevent') repeatedly, then declare a helper function that does that for you:
// helper function for changing the value
function changeInput(newVal) {
if(!this.$target) this.$target = $('#text'); // stash the target for reuse
this.$target
// programmatically change the value; does not fire 'change' event
.val(newVal)
// now trigger your custom action that behaves
.trigger('customaction'); // add extra parameters, etc
}
Full example: https://jsfiddle.net/drzaus/ds6g745s/8/

real time validation of username using javascript and ajax

I've written a script for my registration form that if there's a keyup event on the username input field, then javascript checks if the username entered is valid and if it's then an ajax function is called to check its availability.
It's working fine. But username can be entered without doing a key up, what to do for those cases? E.g. username can be entered by clicking the input field and selecting a name suggested by the browser, Or by using an auto-form filler. There's no "keyup" in these cases, so what to do for these cases?
And if I am missing some case then pls tell.
Bind the callback to the change event too.
Instead of $('username_input').keyup or $('username_input').bind('keyup', callback) use
$('username_input').bind('keyup change blur', function () {
//
})
[UPDATE]
If you are not using jQuery try
function checkUserName() {
// Ajax validation code
}
userinput = document.getElementById('yourusernameinputid');
userinput.onclick = userinput.onchange = userinput.onblur = checkUserName;
on a side note, you should try learning jQuery. It could save you a lot of time, and help you make better sites in less time.
[UPDATE 2]
It looks like there is no way to detect change via autofill using events. You need to set a timer to automatically check your input at fixed interval and check with you last value.
(function() {
// It is always better to use a closure to prevent the value from
// getting overwritten by another piece of code
var value = '';
setInterval(2000, function() {
if (userinput.value != value) {
checkUserName();
value = userinput.value;
}
});
})();
Test the username when:
The blur event occurs (when the text field loses its focus), and
Before the user sumits the form, or
The change event occurs (I think this is the best).
setInterval is the only way.
Sources:
I want to trigger an event every single time data changes in an HTML text input field regardless of focus
jQuery: What listener do I use to check for browser auto filling the password input field?

Categories