document.getElementById(" ").src not working? - javascript

I want to be able to choose the Battery 9 inside the dropdownlist.
I want the image of Battery 9 to show in the img tag.
Am I doing something wrong?
HEAD
function checkBatteryLife(){
if(document.getElementById('batterylifes').value == 'batterylife9'){
document.getElementsByTagName('batteryID').src = 'battery9.png';
}
BODY
<img alt="" src="" name="batteryID" onclick="checkBatteryLife()">
</br>
<select id="batterylifes" onchange="checkBatteryLife()">
<option name="batteryIMG" value="batterylife9">Battery 9</option>
</select>

The getElementsByTagName method will return a collection of tags by name, such as IMG or SELECT. Passing in the name attribute of a tag will not yield any results.
You should probably use getElementById and pass in the id of the element:
function checkBatteryLife() {
if(document.getElementById('batterylifes').value == 'batterylife9')
{
document.getElementsById('batteryID').src = 'battery9.png';
}
}
..
<img alt="" src="" id="batteryID" onclick="checkBatteryLife()" />
<br />
<select id="batterylifes" onchange="checkBatteryLife()">
<option name="batteryIMG" value="batterylife9">Battery 9</option>
</select>
You can also use getElementsByName which will return a collection of DOM elements with the specified name property, and then iterate through it to find the correct one.

You need .getElementsByName() function instead of .getElementByTagName():
document.getElementsByName('batteryID')[0].src = 'battery9.png';
As .getElementsByName() function returns list,and not a single element, for accessing list's element you need to use [] square brackets.Specifically you need first matched element with name="batteryID", that's why you should use[0].

Firstly, it is not cross-browser compatible to get the value of the selected option by simply reading the value of the select. Instead, first detect the selected option then read ITS value.
var sel = document.getElementById('batterylifes');
if (sel.options[sel.options.selectedIndex].value == 'batterylife9') {
//your code here...
}
Secondly, as many have pointed out, you are mistakenly using getElementsByTagName to reference a single element by its name. You need getElementsByName(), though this is not cross-browser compatible either. Other options:
use jQuery or some other library
if you don't care about old browsers, use the new document.querySelector() method to select the element via CSS syntax
give the image an ID and use getElementById()

Related

Why does jQuery return more than one element when selecting by type and ID? [duplicate]

I fetch data from Google's AdWords website which has multiple elements with the same id.
Could you please explain why the following 3 queries doesn't result with the same answer (2)?
Live Demo
HTML:
<div>
<span id="a">1</span>
<span id="a">2</span>
<span>3</span>
</div>
JS:
$(function() {
var w = $("div");
console.log($("#a").length); // 1 - Why?
console.log($("body #a").length); // 2
console.log($("#a", w).length); // 2
});
Having 2 elements with the same ID is not valid html according to the W3C specification.
When your CSS selector only has an ID selector (and is not used on a specific context), jQuery uses the native document.getElementById method, which returns only the first element with that ID.
However, in the other two instances, jQuery relies on the Sizzle selector engine (or querySelectorAll, if available), which apparently selects both elements. Results may vary on a per browser basis.
However, you should never have two elements on the same page with the same ID. If you need it for your CSS, use a class instead.
If you absolutely must select by duplicate ID, use an attribute selector:
$('[id="a"]');
Take a look at the fiddle: http://jsfiddle.net/P2j3f/2/
Note: if possible, you should qualify that selector with a type selector, like this:
$('span[id="a"]');
The reason for this is because a type selector is much more efficient than an attribute selector. If you qualify your attribute selector with a type selector, jQuery will first use the type selector to find the elements of that type, and then only run the attribute selector on those elements. This is simply much more efficient.
There should only be one element with a given id. If you're stuck with that situation, see the 2nd half of my answer for options.
How a browser behaves when you have multiple elements with the same id (illegal HTML) is not defined by specification. You could test all the browsers and find out how they behave, but it's unwise to use this configuration or rely on any particular behavior.
Use classes if you want multiple objects to have the same identifier.
<div>
<span class="a">1</span>
<span class="a">2</span>
<span>3</span>
</div>
$(function() {
var w = $("div");
console.log($(".a").length); // 2
console.log($("body .a").length); // 2
console.log($(".a", w).length); // 2
});
If you want to reliably look at elements with IDs that are the same because you can't fix the document, then you will have to do your own iteration as you cannot rely on any of the built in DOM functions.
You could do so like this:
function findMultiID(id) {
var results = [];
var children = $("div").get(0).children;
for (var i = 0; i < children.length; i++) {
if (children[i].id == id) {
results.push(children[i]);
}
}
return(results);
}
Or, using jQuery:
$("div *").filter(function() {return(this.id == "a");});
jQuery working example: http://jsfiddle.net/jfriend00/XY2tX/.
As to Why you get different results, that would have to do with the internal implementation of whatever piece of code was carrying out the actual selector operation. In jQuery, you could study the code to find out what any given version was doing, but since this is illegal HTML, there is no guarantee that it will stay the same over time. From what I've seen in jQuery, it first checks to see if the selector is a simple id like #a and if so, just used document.getElementById("a"). If the selector is more complex than that and querySelectorAll() exists, jQuery will often pass the selector off to the built in browser function which will have an implementation specific to that browser. If querySelectorAll() does not exist, then it will use the Sizzle selector engine to manually find the selector which will have it's own implementation. So, you can have at least three different implementations all in the same browser family depending upon the exact selector and how new the browser is. Then, individual browsers will all have their own querySelectorAll() implementations. If you want to reliably deal with this situation, you will probably have to use your own iteration code as I've illustrated above.
jQuery's id selector only returns one result. The descendant and multiple selectors in the second and third statements are designed to select multiple elements. It's similar to:
Statement 1
var length = document.getElementById('a').length;
...Yields one result.
Statement 2
var length = 0;
for (i=0; i<document.body.childNodes.length; i++) {
if (document.body.childNodes.item(i).id == 'a') {
length++;
}
}
...Yields two results.
Statement 3
var length = document.getElementById('a').length + document.getElementsByTagName('div').length;
...Also yields two results.
What we do to get the elements we need when we have a stupid page that has more than one element with same ID? If we use '#duplicatedId' we get the first element only. To achieve selecting the other elements you can do something like this:
$("[id=duplicatedId]")
You will get a collection with all elements with id=duplicatedId.
From the id Selector jQuery page:
Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM. This behavior should not be relied on, however; a document with more than one element using the same ID is invalid.
Naughty Google. But they don't even close their <html> and <body> tags I hear. The question is though, why Misha's 2nd and 3rd queries return 2 and not 1 as well.
If you have multiple elements with same id or same name, just assign same class to those multiple elements and access them by index & perform your required operation.
<div>
<span id="a" class="demo">1</span>
<span id="a" class="demo">2</span>
<span>3</span>
</div>
JQ:
$($(".demo")[0]).val("First span");
$($(".demo")[1]).val("Second span");
Access individual item
<div id='a' data-options='{"url","www.google.com"}'>Google</div>
<div id='a' data-options='{"url","www.facebook.com"}'>Facebook</div>
<div id='a' data-options='{"url","www.twitter.com"}'>Twitter</div>
$( "div[id='a']" ).on('click', function() {
$(location).attr('href', $(this).data('options').url);
});
you can simply write $('span#a').length to get the length.
Here is the Solution for your code:
console.log($('span#a').length);
try JSfiddle:
https://jsfiddle.net/vickyfor2007/wcc0ab5g/2/

How to access a hidden input with javascript

What I am attempting to do is is access hidden object in a div. What happends is a user will click on button that will then perform some task such as delete a user. This may be easier if I show what I have.
<div class="mgLine">
<input type="hidden" name="tenentID" value="1">
<p class="mgName">James Gear</p>
<input type="text" class="mgBill" value="" placeholder="Post Bill Link Here">
Submit Bill
Not Paid
Change Password
Delete User
</div>
What I want the system to do is alert the value of one which it gets from the hidden field when the "submit bill" is pressed.
function alertTest(e){
//e.parentNode
window.alert(e.parentNode.getElementsByTagName("tenentID")[0]);
}
I am attempting to use JavaScript DOM to access the element. I hope this made at least some sense. There will be many of these entries on the page.
You need to use getElementsByName instead of getElementsByTagName
function alertTest(e){
//e.parentNode
window.alert(document.getElementsByName("tenentID")[0]);
}
getElementsByTagName is for selecting elements based on its tag say div, input etc..
getElementsByName
getElementsByTagName
Realizing that you might have multiple div section and your hidden input is the first child you could use these:-
e.parentNode.getElementsByTagName("input")[0].value;
or
e.parentNode.firstElementChild.value;
if it is not the firstCHild and you know the position then you could use
e.parentNode.children(n).value; //n is zero indexed here
Fiddle
The modern method would be to use querySelector.
e.parentNode.querySelector("[name=tenentID]");
http://jsfiddle.net/ExplosionPIlls/zU2Gh/
However you could also do it with some more manual DOM parsing:
var nodes = e.parentNode.getElementsByTagName("input"), x;
for (x = 0; x < nodes.length; x++) {
if (nodes[x].name === "tenentID") {
console.log(nodes[x]);
}
}
http://jsfiddle.net/ExplosionPIlls/zU2Gh/1/
Try this:
function alertTest(e){
alert(e.parentNode.getElementsByName("tenentID")[0].value);
}
I usually set an id attribute on the hidden element, then use getElementById.
<input type="hidden" id="tenentID" name="tenentID" value="1">
then I can use...
var tenentValue = document.getElementById("tenentID").value;
In general, your best bet for accessing a specific element is to give it an ID and then use getElementById().
function alertTest(ID){
alert(document.getElementById(ID).value);
}
Names can be duplicated on a page, but the ids have to be unique.

Exclude Element from .html()

I have to remove a specific element (button with #add_phone) from .html() of jquery.
So here's the thing. At first there are field(phone number) + select(phone type) + button(#add_phone), and all three are enclosed in div as a container. And when I click the button, it will recreate that through .html().
The JS is as follows:
$('#add_phone').click(function() {
$('div.multiple_number:last').after('<div id="phone_div_id' + phone_div_id + '" class="multiple_number">'+ $('div.multiple_number').html() +'</div>');
...
//append a remove [-] button, etc...
});
and here's the html:
<div class="multiple_number" id="phone_div_id0">
<label>Phone Number(s):</label>
<input name="phone" id="phone[]" placeholder="Phone Number"/>
<select name="phone_type[]" id="phone_type">
<option value="1">Mobile</option>
<option value="2">Home</option>
<option Value="3">Office</option>
<option Value="3">Fax</option>
</select>
<input type="button" name="add_phone" class="add_phone_class" id="add_phone" value="ADD MORE" />
</div>
So in effect, I am creating multiple phone numbers for a form. But, here's the problem. Inside is an input type="button" (#add_phone button). And I would want to exclude it from .html().
I have tried:
$('div.multiple_number:not(#add_phone)').html()
$('div.multiple_number:not(input#add_phone)').html()
$('div.multiple_number:not(#add_phone)').not(#add_phone).html()
$('div.multiple_number:not(#add_phone)').not(input#add_phone).html()
And the class name counterpart instead of using id name. I wouldn't also want to place the #add_phone button outside the div, for aesthetics reason.
I'm a little bit unclear about what you're looking for, but I assume that when the #add_phone button is clicked, you want the form to be duplicated and added below it with the exception of the #add_phone button itself.
Working off that assumption, the following should work
$('#add_phone').click(function() {
var numberForms = $('div.multiple_number');
var newNumberForm = numberForms.eq(0).clone(true);
newNumberForm.find('#add_phone').remove();
newNumberForm.attr('id', 'phone_div_id' + numberForms.length);
numberForms.last().after(newNumberForm);
});
Here's a live jsfiddle demo to show it working.
Your initial attempts didn't work for a few reasons. The main one being that :not() selector and .not() methods only operate on the element being selected. It doesn't filter based on child elements. Those methods would only work if the element you were selecting <div class="multiple_number" /> also had the ID add_phone.
Also, it is not recommended to use .html() as a way of cloning methods. Using string manipulation as an alternative to direct DOM manipulation can cause problems later on. Using .html() will force you to have to re-bind event handlers to the newly created DOM elements. The strategy I've provided above should be more future-proof, since it will also clone event handlers for any elements being copied. There are also cases where certain browsers will not replicate the original elements exactly when calling .html(), which is another reason to avoid it unless you have a specific reason for serializing your DOM elements as a string.
Try this instead :
var innerHTML = $("div.multiple_number").html()
.replace($("div.multiple_number input#add_phone").html(), "");
Good Luck

How can I get an HTML5 data value from a select option?

Is it possible to use jquery to get an html5 data attribute from a select option?
<select id="change-image">
<option value="cool" data-image="myimage.jpg">Cool</option>
</select>
$("#pet-tag-id").change(function() {
var src = $("#change-image").data("image");
$("#image-preview").attr("src", src);
});
<img id="image-preview">
Yes.
You even did it in the correct manner. jQuery will pull HTML5 data attributes into its internal expando data object for elements. So you can access them just by name.
The only thing that is incorrect is, that you don't call .data() on the correct element. You're calling it on the <select>, but you need to grab the selected option element. Like
var src = $("#change-image option:selected").data("image");
$("#change-image").change(function() {
var data_image = $(this).children('option:selected').attr('data-image');
});
​

Obtain a HTML elements hidden value

I have a HTML element like so:
<select>
<option id="a" hidden"1">Abcdefgh</option
</select>
And, using javascript, I want to retreive the hidden value from the option element.
How do I do this?
var hiddenVal = document.getElementById( "a" ).hidden; // this doesnt work
Not all attributes map directly to properties. You should be able to use the native .getAttribute() to get the value of custom attributes.
var hiddenVal = document.getElementById( "a" ).getAttribute('hidden');
<select>
<option id="a" hidden="1">Abcdefgh</option>
</select>
Well first off your mark up on your HTMl is all off. You are missing an end tag on the element and you would need to put hidden="1" with the equals and quotes. But is hidden even a valid attribute for an option element?? I dont think it is.

Categories