Recursive jQuery function to amend select option values - javascript

I have a form that I am trying to alter with jQuery. Basically, my form has two elements and I need to change the value of the first option in each of them. However, there is an "add more" option that uses AJAX to dynamically generate another element that also needs changed. This add more button can be clicked an unlimited amount of times.
Right now I have this:
$(document).ready(function(){
$("#myname-0-field option:first").val("None");
$("#myname-1-field option:first").val("None");
});
This works fine, but once the "add more" button is clicked, I have more elements called "#myname-2-field", "#myname-3-field", "#myname-4-field" etc. These obviously aren't affected by adding another line into my jQuery as the document has already loaded when they are added.
So the real question is, can someone point me in the right direction of writing a function that can react when the new element is added and change it. If possible, I'm also looking for the function to be aware and look for "#myname-X-field option:first" for tidyness.

use live() function
Then using each function set value

From the jQuery API look live function
Maybe you could add class to your element, so that finding particular element would be easier and it would not add event to other similar elements.
In the example I have a Li with class
$('li.myClass').live('click', function() {
$(this).val(); // this is the getter for clicked value
$(this).val("some_value_here"); // this is the setter for clicked value
});
Now you can add more elements (that has myClass class) and it will have a click event.
Btw. if you know that all elements are inside some container (div for example) then you can write more efficient jQuery using delegate.
$('#container_id').delegate('li.myClass', 'click', function () {
});
This is more efficient because it looks your new elements only under "containter" not from the whole DOM structure.

Related

Assigning JQuery On Click Function in For Loop

I have a function that dynamically creates div elements based upon whatever input is given, and lets them choose certain items by clicking on each div. I have it so that if the div is clicked, a function (named checkToggle) is called that makes it looks like it is selected and adjusts some related variables. There is a checkbox in the div element that is toggled by this function (hence its name). Long story short, I had to jump through some hoops to get it to work, most of which I don't even remember. Please don't ask me about that.
The point of this question is this. I initially used the following JavaScript code to run the function when the checkbox was clicked. It was assigned by the main function, which created these div elements using a for loop.
document.getElementById(`${itemID}-checkbox`).onclick = function() {
checkToggle(`${itemID}-checkbox`);
};
This works, but I wanted to try to convert all of my onClick functions to JQuery. Here is the JQuery alternative I created.
$(`${itemID}-checkbox`).on(`click`, function() {
checkToggle(`${itemID}-checkbox`);
});
While the code itself seems to be fine, it does not work. It seems as if JQuery functions cannot be created like this in a for loop or something. It is applied after the element is created and put in its place, so I don't think it has anything to do with the element not being ready. I am also having the same issue with 2 other similar cases. Any idea as of why this isn't working?
Let me know if more information is needed and if so, what kind of information is needed.
You need to update the selector to Target HTML id using the # character. Simply prepend the character to the query:
$(`#${itemID}-checkbox`).on(`click`, function() { checkToggle(`${itemID}-checkbox`); });
It would also apply to DOM methods querySelector or querySelectorAll as well.
Hopefully that helps!

JQuery not working on inserted/inject DOM element

I am still a bit new to JS & JQuery, so please excuse what may be a simple and stupid question.
Background:
I have a div on my page that holds several divs (#idle-variable). On click of the top level div, it basically shows the other divs (#addvariable). Nothing more than display: none; and .show(). Easy. On another action within that div (change of drop down), I essentially want to inject/insert that top level div (#idle-variable) underneath the first instance.
Issue:
Essentially, the .click function is not working on my newly inserted div. This may be because the two div's share the same ID, BUT I have a sneaky suspicion that it's not recognized in the DOM. A friend of mine said something about I have to "re-run" my jquery in order for it to be readable in the DOM.
Question:
How can i make this work properly? I want to be able to add a dynamic number of these idle-variables to the page and I need to make sure my .click function works for all added DIVS.
$(function(){
$('#idle-variable').click(function(event) {
$("#addvariable").show(400);
});
});
//create variable in db & show value entry
$("#variabletype").change(function() {
$("#varholder").css("display", "inline-block");
$.ajax({
type: "POST",
url: "/myphpfile.php",
data: {"variabletype": $("#variabletype").val()},
success: function(){
$( "#idle-variable" ).after("<div id="#idle-variable>content</div>");
}
});
});
Well to make the code work it would need to use on and ids are only supposed to be on one element. If it can be on the page multiple times you need to use classes.
$(document).on("click,'#idle-variable', function(event) {
$("#addvariable").show(400);
});
you should be using classes
$(document).on("click,'.idle-variable', function(event) {
//$("#addvariable").show(400); //not sure how this relates to the clicked element.
$(this).find(".addvariable").show(400); //if it is a child
});
You also have a typo in your code with quotes.
The ID based selector will be applied to the first element only.
See the example here http://jsfiddle.net/9GN2P/2/
If you are looking to bind same event handler to multiple elements, definitely go with the class based approach, instead of ID based approach.
And, you are expecting event handler to work with dynamically created elements as well. If you are using older versions of jquery, use the live method like
$('yourselector').live('click',function(){
});
Since live is deprecated and if you are in a new version, use the 'on' method
$('containerselector').on('click','yourselector',function(){
});
Editing to answer your comment:
To create dynamic element and append to DOM, you can follow the bellow pattern. Here, I will create a DIV with id "newID", class "newClass", content "NEW DIV!!" and a click event handler for it. And it will be pushed into another div with id 'containerID'
$('<div />',{
id:'newID',
'class':'newClass',
text:'NEW DIV!!',
click:function(){alert('hi');}
})
.appendTo('div#containerID');
This is just a demo.

using jQuery to change, only the elements that were loaded via ajax

For each checkbox on the web page, I replace it with a slider that I borrowed from jsfiddle.net/gnQUe/170/
This is done by going through the elements when the document is loaded.
Now the problem is that when more content is loaded via ajax, the new checkboxes are not transformed.
To solve the problem, I used AjaxComplete event to go through all the elements again and replace the checkboxes with sliders.
Now the problem happens that elements that were already replaced, get two sliders. To avoid that I check if the checkbox is hidden and next element is div of class "slider-frame", then don't process the re-process the element.
But I have a lot of other such controls as well, and I am presume I am not the only one that has this problem. Is there another easy way around it?
There exists jQuery live/on( http://api.jquery.com/on/ ) event but it requires an event as an argument? whereas I would like to change the look of my controls when they are rendered.
Another example of the same problem is to extend some controls that are loaded via ajax with jQuerys autocomplete plugin.
Is there a better way to accomplish this other than changing some attributes on the element.
To summarize, on document load I would like to process every element in DOM, but when more elements are loaded via ajax then I want to change only the new elements.
I would assume that when the element's are transformed into a slider, a class is added to them. So just add a not clause.
$(".MySelector").not(".SomeClassThatSliderAddsToElement").slider({});
So in the case of your code do something like this
$('.slider-button').not(".sliderloaded").addClass("sliderloaded").toggle(function(){
$(this).addClass('on').html('YES');
$('#slider').val(true);
},function(){
$(this).removeClass('on').html('NO');
$('#slider').val(false);
});
Since you said you do not want to add anything else, how about you change the toggle function to click.
$(document).on("click", ".slider-button", function(){
var elem = $(this);
elem.toggleClass("on");
var state = elem.hasClass("on");
elem.text(state?"YES":"NO");
elem.parent().next().val(state);
});
Running fiddle: http://jsfiddle.net/d9uFs/

JQuery Ajax not updating DOM (I think)

I have a problem, in my page, I have a div that contains lets say two hidden fields with the value 0 and 2. I have a button that trigger an ajax query and change the div contents with the same hidden fields but with the value 1 and 2 respectively. The problem is that it seems like my javascript (using JQuery) is not aware of theses changes. When I inspect my page to see the html source code I see the values have changed but in the script when I'm doing:
$("#btn").click(function() {
alert($("#hidden1").val());
alert($("#hidden2").val());
});
It still show me the old value (0 and 2) like if the DOM hasn't been updated. Can someone help me please or tell me if it is normal and how to fix it.
Thanks for your time
Me!
Try this:
$("#btn").on('click', function() {
alert($("#hidden1").val());
alert($("#hidden2").val());
});
It's not that the DOM is not being updated, it's probably because your jQuery event is bound to the particular element at the time .click() is called. Since the DOM changed(you likely removed and added a new element of the same id), the function returns the values of the elements you discarded(because it remains bound to it even if removed from DOM).
Use the live() method or on() as a replacement for your click() handler. This method provided by jQuery will not bind to a particular DOM element at the time it is called, but does a dynamic lookup every time a click is detected.

JQuery - Appended Links don't work

I have created a dynamic list picker script using Jquery 1.3 and PHP that sends a JSON AJAX request and returns a list of items to choose from. The AJAX call works perfectly returning an array of items that I use Jquery to append them as an unordered list to an empty container DIV. That portion of the process works as expected.
The problem comes from the fact that from that list of items, I'm drawing them as links whose clicks are handled by a rel attribute. Here's an example:
<a rel="itemPick" id="5|2" href="#">This is the link</a>
The JQUERY handler looks like:
$('a[rel=itemPick]').click(function () {
code here...
});
These links and click handlers work fine when the page loads, but when they are appended to the container DIV, the click event does not get picked up. I don't want to have to refresh the entire HTML page again, so is there something I need to do in addition to append() to get JQUERY to recognize the newly added links?
When you use the jQuery.click method, it's looking for all of the "a" elements that currently exist on the page. Then, when you add a new "a" element, it has no knowledge of that click event handler.
So, there's a new event model in jQuery that allows you to bind functions to all current and future elements called Live Events. You can use Live Events the same way that you use normal event binding, but they will work for all future elements specified. So, you can simply switch your binding logic to:
$('a[rel=itemPick]').live('click', function () {
//code here...
})
$('a[rel=itemPick]').live("click", function (){ code here... });
Do you bind the event after adding the links?

Categories