I have multiple forms on my page with the following function:
$('#pageContainer').on('input propertychange change', '#form1', function() {}
Within this function, I make 11 function calls that formats text for 11 different textarea box's. I don't need to call all 11, just the one's that have changed that need formatting.
Is there a way to figure out what part of the form has been changed that made the function call so that I can call the correct (1 of 11) functions, or none at all?
So basically, if textarea 1-11 has been the input that calls the .on(), call that specific function. If not, don't call anything.
You can use event.target to find out which element caused the change event.
$('#pageContainer').on('input propertychange change', '#form1', function(e) {
var elementId = e.target.id;
//Do you actions based on this
}
I don't think there's a nice handy function to check these things, but you could assign an event handler on the onChange event, this could add $(this).attr("id") to an array. You could then construct a selector based on that array?
for example
var changes = [];
$("input").on('change', function() {
changes.push($(this).attr(id));
});
function yourFormattingFunction() {
var selector = "#" + changes.splice(", #");
$(selector).each(function() {
//...Do your formatting here
});
}
Obvious improvements like making sure the list is unique etc can be done to improve this...
Related
I am trying to create some calculations using a wordpress forms plugin that a customer insists on using (due to integrations with other plugins). I have created the code which fires on an onchange field event. I want to be able to trigger the code from multiple form fields events however.
See below - item meta[76] onchange fires the scrip. How can i modify this to enable other fields to fire the script as well (ie item meta[34] || item meta[43]). Is it possible in the select one statement? The strange IDs are due to the plugin. Thank you in advance.
<script type="text/javascript">
jQuery(document).ready(function($){
$('select[name="item_meta[76]"]').change(function(){
var val1 = $("select[name='item_meta[76]']").val();
var myArea = $("#field_f4wns").val() * $("#field_ymo4z").val();
var myTotalArea = $("#field_xuyzx").val();
var myToolPrice = "#field_8v27o";
var myBoardPrice = "#field_ku0w8";
if (val1 == "One Layer"){
if (myArea > 0 && myArea < 5000) {
$(myToolPrice).val(20);
}...... and many other calculations follow.
Use a delegate listener with an appropriate selector and make use of the this variable.
You have one function, and N elements that need the logic performed. Don't attach a listener to every single element. That means lots of extra memory and code tracking (and potential source of bugs) for your web app. Instead, use a delegate listener:
// "bad" (not wrong; could be better)
jQuery('select[name=a],select[name=b],sele...').change(...
// "good" (the specific scenario dictates best)
jQuery('body').on('change', 'select[name=a],select[name=b],sele...', function (evt) {
The first example attaches a copy of the function to the change event of every single element matched in the selector. In the example above, any <select name="a"> or <select name="b">. The second example attaches a single listener to the change event on the body element, but only actually executes if one of the selectors matches. Same effect, much less memory, much less churn for your JS engine, and presumably now only a single place for you to worry about generating your comma-separated selector.
Understand how jQuery abuses the this keyword. Whenever jQuery calls back to an event listener, it sets the this variable to the actual element of the event. So, in your code above, you have this:
$('select[name="item_meta[76]"]').change(function(){
var val1 = $("select[name='item_meta[76]']").val();
That is wholly too much work. Consider:
$('select[name="item_meta[76]"]').change(function(){
var val1 = $(this).val();
With this last tidbit, you should be able to write a single, more general, delegate listener that works for you and is easier to alter as appropriate.
You can define multiple selector in for calling function on event as:
$('selector1','selector2','selector3',...).change(function(){
// your code
});
Or you can give common class to all the element and define the jQuery function as:
$('.common_class').change(function(){
// your code
});
Additionally, inside the function, you are using that selector again to get value:
var val1 = $("select[name='item_meta[76]']").val();
So in this case, you can replace your static selector with this keyword as:
var val1 = $(this).val();
This question already has answers here:
Attaching jQuery plugin calls to dynamically loaded elements via jQuery,on()
(3 answers)
Closed 9 years ago.
I have an HTML page, which contains many select boxes, to beautify those boxes I have used "select2", What I have done is:
$(document).ready(function() { $("select").select2(); });
This makes all of the select boxes to get transform like "select2".
But now I am generating the tables on a button click(after the document is ready), therefore the newly generated select boxes doesn't looks like "select2", Please help me if there is any function that detects the change in document?
Something like:
$(document).change(function() { $("select").select2(); });
In at least some browsers (not any current version of IE, though), you can do this, via a MutationObserver (this is the new DOM4 thing, not the old DOM3 mutation events, which you want to stay away from).
But I don't recommend it, just call select2 again after your code that appends the new selects.
Another option is to use a timer: Get a NodeList of all select elements on the page:
var allSelects = document.getElementsByTagName('select');
...and poll checking its length (NodeLists are live, you don't have to re-query):
var lastLength = 0;
setInterval(function() {
if (allSelects.length !== lastLength) {
lastLength = allSelects.length;
// Hook up the new ones here
}
}, 1000); // 1000ms = 1 second
You could put a class on them to keep track of which ones are already done (if select2 doesn't already do that).
But again, you have code adding select elements, just re-trigger there.
You can try something like this:
function checkDocumentChange() {
// Run a simple task to check whether any new "selects" were added
var old_value = checkDocumentChange.num_selects || 0;
var new_value = $("select").length;
if (old_value != new_value) {
$("select:not(.already_done)").select2();
}
checkDocumentChange.num_selects = new_value;
setTimeout(checkDocumentChange, 100);
}
DOM events are not recommended to use since those are deprecated.
Better approach would be, of course, to call .select2() right after you insert select into DOM. So that you will not have to delegate this to some checker or event.
You can try DOMNodeInsertedIntoDocument
$(document).on('DOMNodeInsertedIntoDocument', function() {
}
Or mutation observer
use this id or class
in this code
var id = document.getelementbyid("id for select 1 or 2");
//here the code
How can I detect if the value of a textarea changes using jQuery? I'm currently using keyup() but this triggers every key stroke of course, I dont want my code to run if it's an arrow key that was pressed or any other key that doesn't have an impact on the value of the textarea.
Take a look:
$('textarea').keyup(function() {
if (content was changed)
// Do something
});
I hope you understand. How can I do this the best way? I don't want to compare the current value to an old value to check for changes, I hope that's not the only way.
By all means the easiest way is to store old values to data and do the check every keyup. The solution is quite short and will work in any case. No need to reinvent the wheel.
$("textarea").data("oldValue", function() {
return this.value;
}).keyup(function() {
var $this = $(this);
if (this.value !== $this.data("oldValue")) {
// Do something
$this.data("oldValue", this.value);
}
});
DEMO: http://jsfiddle.net/vvbSj/
$('textarea').blur(function() {
//This will be invoked when the focus is removed
});
$('textarea').change(function() {
//Same as the blur
});
Is this what you want
Got a question for you javascript gurus out there. I'm creating a sidebar tool that is comprised of a few different text input fields. The purpose of this tool is to edit copy on a template. I've tried to pass the data entered into the field onchange, but I'm running into problems dumping the data into my js object. This is somewhat what I have in mind:
$('myInputField').(function(){
$(this).onChange(){
// write to variable X
}
});
Essentially I want to have what I'm typing in the input be mimicked live and then I can parse the changes to my database.
$('#myInputField').(function(){
$(this).onkeyup(){
x = this.value;
}
});
or more succinctly:
$('#myInputField').onkeyup(){
x = this.value;
});
You're just looking for the value that's in myInputField within that event handler? Something like this?:
$('myInputField').(function(){
$(this).onChange(){
x = $(this).val();
}
});
I don't remember off the top of my head if this is already a jQuery object. If it is, then this should work and perhaps skip a little bit of overhead:
x = this.val();
Additionally, you can explicitly reference the field with a normal jQuery selector if this is ever overridden with a different context, or if you want to reference other fields as well, etc.:
x = $('myInputField').val();
The problem is, on IE, the onchange event doesn't work on INPUT elements. Thus, you have to use the onkeypress or the onblur event depending on what you want to do.
JS way:
document.getElementById('myInputField').onblur = function() {
var x = this.value
}
jQuery way:
$('#myInputField').blur(function() {
var x = this.value
})
Wouldn't a simply keyup event on the input fields be sufficient?
jQuery:
$('textarea').keyup(function() {
$('#foo').html($(this).val());
});
HTML:
<textarea></textarea>
<div id="foo"></div>
jsFiddle example.
I have written this code in javascript however I have to make it work using JQuery, I have included both the javascript function and the jquery attempt but i can't figure out what is wrong with my jquery attempt could someone please help me?
Javascript working:
function done()
{
var valid = document.getElementById("text2").value.length;
if (valid > 5)
{
document.getElementById('one').innerHTML += "<div class='done rotateone wiggler'></div>";
document.getElementById('one').className += "grey";
}
Jquery attempt:
$(document).ready(function(){
//Validates the title field is at least 5 characters long.
$("#text2").done(function(){
var value = $(this).val();
if (value.length >= 5)
{
$("#one").append("<div class='done'></div>");
}
});
Looks like you want to execute your function right away? (look at the edit to see why I added the .blur() event handler) Well, here is how I'd do it:
$(document).ready(function() {
$('#text2').blur(function() { // Listen to the "onblur" event on the element
if (this.value.length > 5) { // No need for jQuery there
$('#one')
.append('<div class="done"></div>')
.addClass('grey')
}
})
})
See how I use one call only to the DOM by chaining functions on a single element? That's practical and efficient.
Btw, innerHTML is bad for many reasons (including performance), prefer .append() in jQuery and .appendChild() in javascript.
Edit: looks like you want this to activate on the onblur event. I edited my code.
You can use your done() function and just add small changes to adapt jQuery
function done()
{
var valid = $("#text2").val().length;
if (valid > 5)
{
$('#one').append("<div class='done'></div>");
$('#one').addClass("grey");
}
}