JavaScript, loop all selects? - javascript

Well im new to javascript but why does this not work, all i want to do is to get a list of all selects on the page.
var elements = document.getElementsByTagName("select");
alert("there are " + elements.length + " select's");
for (i = 0; i < elements.length; i++)
{
alert(elements[i].getAttribute('Id'));
}
Edit: the error is that it does not find any selects at all, elements.length is allways zero!

You'r saying that elements.length is always returning 0 for you, this could be because:
You are running the JS code in the beginning of your page, thus the DOM is not fully available yet

Try using .id instead of of getAttribute('Id').

I guess the part of getting id attribute doesn't work for you. Probably it's because you typed there "Id" instead of "id".

The usual cause for getElementsByTagName returning zero results in a document with matching elements is that it is being run before the elements appear in the document (usually in the section and not inside a function that is called onload or onDomReady).
Move the element to just before the (END of body!) tag, or use an event handler that fires after the HTML has all been processed.

Well, as far as I can see is that perhaps the selects on your page don't have Id's (the alerts in the loop show null)

Related

Iterating over jQuery selector with variable, using closures

[First time on stackoverflow.] I am trying to dynamically add html buttons to my page and then give them a javascript function to run when they are clicked, using jQuery's click. I want to have one button for each element in an array, so I used a for loop. My code looks like this (simplified)
for (var i = 0; i < results.length; i++) {
$("#" + place[i].place_id).click(function(){console.log("Test");})
$("#" + place[i].place_id).click();
}
(I inject buttons with the right id's in the same loop.) This code, when run, console logs "Test" the right number of times, but afterwards, only the last button responds "Test" when clicked. (This situation is a little absurd.) So, I think the event handler ends up using only the final value of i to assign the event handler. I think the problem has to do with closures, but I am not sure how to make a closure out of a jQuery Selector (and in general am not familiar with them).
In contrast, as a hack solution, I "manually" wrote code like the below right below and outside the for loop, and it works as expected, in that clicking causes the console log.
$("#" + place[0].place_id).click(function(){console.log("Test"););
$("#" + place[1].place_id).click(function(){console.log("Test");});
etc.
(Of course, this all occurs within a larger context - specifically a Google Maps Places API call's callback.)
First, am I understanding the problem correctly? Second, what would work? Should I take a different approach altogether, like use a .each()?
(I later would want to display a property of place[i] when clicked, which I would think would need another callback
My final hack code looks like this:
$("#" + place[0].place_id).click(function(){google.maps.event.trigger(placeMarkers[0], "click"); repeated 20 times
To do this, you can simply create a self executing function inside the for loop, like this:
for (var i = 0; i < results.length; i++) {
(function(index) {
$("#" + place[index].place_id).click(function() {
//Do something with place[index] here
});
})(i);
}

jQuery for loops not running function

I'm trying to make a loop in jQuery that finds all 'img' elements and places a caption below them, according to the value of the element's 'caption' attribute. Whenever I run the loop below, I am left with no captions under any of the images.
for (var i = 0; i < $('.myimage').length; i++) {
$('.myimage')[i].after('<h6>' + $('.myimage').attr('caption') + '</h6>');
};
However, when I run this code
$('.myimage').after('<h6>TEST</h6>');
the word 'TEST' appears below all of the images. Therefore I know my html is correct, I have no typos, and the selector is working, I just cannot get the for loop to work... What have I done wrong?
$('.myimage')[i] returns a DOM element (not a jQuery object) so there is no after method. If you want to loop, simply use .each
$(".myimage").each(function() {
//this refers to each image
$(this).after('<h6>' + $(this).attr('caption') + '</h6>');
});
You can loop through the .myimage elements like this, using .after()'s callback function
$('.myimage').after(function(){
return '<h6>' + $(this).attr('caption') + '</h6>';
});
One minor note, don't make up your own attributes. use the custom data attribute instead, like data-caption="something".
jsFiddle example

document.getelementbyid returns null in a loop

The code below, produces the same annoying error. It will return the button element in the first pass of the loop but it only returns null thereafter. Any ideas?
<script>
function Check_Submission()
{var Entry = [];
for(var i = 0; i < 14; i++)
{
for(var j = 0; j < 10; j++)
{
Entry[i] = document.getElementById('Add');
document.write(Entry + '<br>');
}
}
}
</script>
<button id = 'Add' onclick = "Check_Submission()" >Click me.</button>
You can not use document.write after the page load. When you do that it wipes away the page content.
First loop it finds the element
You write to the page, it removes the button
other iterations can not find it since it was removed.
You need to use DOM methods to add new content or use the console for debugging.
When you do document.write() to an already loaded document, it clears the current document and starts writing a new empty document.
So, as soon as you call the first document.write() in your loop, it clears the current document and then document.getElementById('Add') will no longer find the former content.
Probably what you should do is to use DOM insertion methods such as .appendChild() or .insertBefore() to add new content to an existing loaded page.
It seems to me like the first time you run your for loop, you use document.write. That will clear everything, so the document.getElementById('Add') will return nothing. what you really want to do is something like 'appendChild' or modifying the innerHTML of the element.
document.write will clear everything each time it is executed.
Try writing,
document.getElementById('divid').innerHTML+=Entry+'<br>';
<div id='divid'></div>

Loop Elements in JQuery

I am trying to run a loop over a few elements in JQuery. Before anyone says it, I do not need .each(). I am trying to run through the elements as a genuine loop- once a successful iteration runs, the loop will break and prevent the same action being done on other elements. I looked briefly at the straight JavaScript version, with the .getElement... methods, but it is my understanding that this won't satisfy my other requirement- the list of elements to be iterated over is created via a partial-string JQuery identifier:
rows = $('tr[id^="am_assetRow_' + parentAsset.replace(/ /, "_") + '_' + type + '"]');
Does anyone know of anything that might help me get this working?
EDIT: Just a bit more information on the application: I am checking to see if a value can be inserted into an existing row of a table, and if not, creating a new row and inserting it there. Thus, I need the loop to exit if a suitable fit is found, and after the loop terminates, I need to know whether it terminated in success (placing the value) or failure (no available locations- time to create a new row).
In jquery, if you want a $.each() loop to end immediately, just return false from the function call.
Do do a normal loop without using each() but still using jquery to select the items based on partial string etc...
rows = $('tr[id^="am_assetRow_' + parentAsset.replace(/ /, "_") + '_' + type + '"]');
for (var i = 0; i < rows.length; ++i) {
rows[i]; // The raw element at this index.
$(rows[i]); // jquery collection for this one element.
if (someCondition) {
break; // Break the loop early.
}
}

Why would .append randomly fail in jquery?

I'm using jquery to add elements to a blank list.
on the page I have:
<ul id="myList">
</ul>
and I go through a loop like this in the script that's called from a dynamically created event handler. (It's "onDrop" of a list item having been sorted with a drag operation)
var myListItemHTML;
for (var i = 0 ; i < 5 ; i++)
{
myListItemHTML += '<li id=listItem'+i+'>This is item number'+i+'</li>';
}
$('#myList').append(myListItemHTML);
and if I check after...
if ($('#myList li').length == 0 )
{
alert('Going to crash now since I'm expecting list items')
}
roughly 95% of the time the list is populated, but about 5% of the time I hit my alert that's going to cause an exception later.
Has anyone run into this? Is there a callback or way to know when/if the append really happens?
var myListItemHTML;
for (var i = 0 ; i < 5 ; i++)
{
$('#myList').append('<li id=listItem'+i+'>This is item number'+i+'</li>');
}
Try just appending inside the for loop.
if ($('#myList li').length == 0 )
{
alert('Going to crash now since I\'m expecting list items')
}
You need a \ before the ' so it doesn't conflict.
edit: jsfiddle that shows "undefined" http://jsfiddle.net/gyEre/1/
This is a bit of a longshot, because I'm making an assumption about your code beyond what was posted. Here goes:
I had a problem with some code once, which worked perfectly in all Browsers except Chrome, wherein it would fail randomly and seemingly without cause.
My problem, ultimately, was that Chrome was actually executing my JavaScript too fast, and that it was throwing off some of the timing in some of the AJAX calls that were being made earlier.
My code was such that AJAX event A triggered, which then passed data to AJAX event B. In Chrome only, though, I found that event B was on occasion occurring before event A, and that was the error condition.
If I recall, I think the solution was to force one key AJAX request to be made synchronously, though that should be used with care. Please see: http://api.jquery.com/jQuery.ajaxSetup/
I hope that's not too vague to be helpful. Good luck!
What I've learned is that I can't trust jquery for DOM manipulation called through dynamically created events. I welcome someone to prove me wrong, but this approach:
addListItem = function (itemID, itemText)
{
var li = document.createElement('li');
li.setAttribute("id", itemID);
var liText = document.createTextNode(itemText);
li.appendChild(goalTextNode);
document.getElementById('myList').appendChild(li);
}
for (var i = 0 ; i < 5 ; i++)
{
addListItem('listItem'+i, 'Item Text'+i);
}
will work 100% of the time and never fail.
In my experience, if the script in which the prepend function is used in the -tag, it will not work because the script is loaded before the DOM is ready.
To avoid this kind frustration, is a good habit to place your javascript before the tag.

Categories