Multiple append Javascript [duplicate] - javascript

How can I get a collection of elements by specifying their id attribute? I want to get the name of all the tags which have the same id in the html.
I want to use ONLY getElementById() to get an array of elements. How can I do this?

I know this is an old question and that an HTML page with multiple identical IDs is invalid. However, I ran into this issues while needing to scrape and reformat someone else's API's HTML documentation that contained duplicate IDs (invalid HTML).
So for anyone else, here is the code I used to work around the issue using querySelectorAll:
var elms = document.querySelectorAll("[id='duplicateID']");
for(var i = 0; i < elms.length; i++)
elms[i].style.display='none'; // <-- whatever you need to do here.

The HTML spec requires the id attribute to be unique in a page:
[T]he id attribute value must be unique amongst all the IDs in the element's tree
If you have several elements with the same ID, your HTML is not valid.
So, document.getElementById should only ever return one element. You can't make it return multiple elements.
There are a couple of related functions that will return a list of elements: getElementsByName or getElementsByClassName that may be more suited to your requirements.

Why you would want to do this is beyond me, since id is supposed to be unique in a document. However, browsers tend to be quite lax on this, so if you really must use getElementById for this purpose, you can do it like this:
function whywouldyoudothis() {
var n = document.getElementById("non-unique-id");
var a = [];
var i;
while(n) {
a.push(n);
n.id = "a-different-id";
n = document.getElementById("non-unique-id");
}
for(i = 0;i < a.length; ++i) {
a[i].id = "non-unique-id";
}
return a;
}
However, this is silly, and I wouldn't trust this to work on all browsers forever. Although the HTML DOM spec defines id as readwrite, a validating browser will complain if faced with more than one element with the same id.
EDIT: Given a valid document, the same effect could be achieved thus:
function getElementsById(id) {
return [document.getElementById(id)];
}

document.querySelectorAll("#yourId"); returns all elements whose id is yourId

It is illegal to have multiple elements with the same id. The id is used as an individual identifier. For groups of elements, use class, and getElementsByClassName instead.

The id is supposed to be unique, use the attribute "name" and "getelementsbyname" instead, and you'll have your array.

As others have stated, you shouldn't have the same ID more than once in your HTML, however... elements with an ID are attached to the document object and to window on Internet Explorer. Refer to:
Do DOM tree elements with ids become global variables?
If more than one element with the same ID exists in your HTML, this property is attached as an array. I'm sorry, but I don't know where to look if this is the standard behavior or at least you get the same behavior between browsers, which I doubt.

Class is more than enough for refering anything you want, because it can have a naming with one of more words:
<input class="special use">
<input class="normal use">
<input class="no use">
<input class="special treatment">
<input class="normal treatment">
<input class="no special treatment">
<input class="use treatment">
that's the way you can apply different styles with css (and Bootstrap is the best example of it) and of course you may call
document.getElementsByClassName("special");
document.getElementsByClassName("use");
document.getElementsByClassName("treatment");
document.getElementsByClassName("no");
document.getElementsByClassName("normal");
and so on for any grouping you need.
Now, in the very last case you really want to group elements by id. You may use and refer to elements using a numerically similar, but not equal id:
<input id=1>
<input id="+1">
<input id="-1">
<input id="1 ">
<input id=" 1">
<input id="0x1">
<input id="1.">
<input id="1.0">
<input id="01.0">
<input id="001">
That way you can, knowing the numeric id, access and get an element by just adding extra non-invalidating numeric characters and calling a function to get (by parsing and so on) the original index from its legal string identifying value. It is useful for when you:
Have several rows with similar elements and want to handle its events
coherently. No matter if you delete one or almost all of them.
Since numeric reference is still present, you can then reuse them and
reassign its deleted format.
Run out of class, name and tagname identifiers.
Although you can use spaces and other common signs even when it's a not a requirement strictly validated in browsers, it's not recommended to use them, specially if you are going to send that data in other formats like JSON. You may even handle such things with PHP, but this is a bad practice tending to filthy programming practices.

This is my solution:
<script type="text/javascript">
$(document).ready(function () {
document.getElementsByName("mail")[0].value = "ex_mail1";
document.getElementsByName("mail")[1].value = "ex_mail2";
});
</script>
Or you can use for-loop for that.

You shouldn't do that and even if it's possible it's not reliable and prone to cause issues.
Reason being that an ID is unique on the page. i.e. you cannot have more than 1 element on the page with the same ID.

you can use
document.document.querySelectorAll("#divId")

we can use document.forms[0].Controlid

If you're using d3 for handling multiple objects with the same class / id
You can remove a subset of class elements by using d3.selectAll(".classname");
For example the donut graph here on http://medcorp.co.nz utilizes copies of an arc object with class name "arc" and there's a single line of d3, d3.selectAll(".arc").remove(); to remove all those objects;
using document.getElementById("arc").remove(); only removes a single element and would have to be called multiple times (as is with the suggestions above he creates a loop to remove the objects n times)

Related

How to use querySelectorAll with a variable?

I have two HTML elements that are alternatives of each other and I am trying to write a JS function that removes one if the other is present (they originated as words within <sic> and <corr> beneath <choice> in a TEI document). In my transformation, they are both assigned a code (not an #id: #id is randomly generated and has to remain so for other purposes) with a unique prefix:
<a id="abc" choicePOS="sic0">Element1</a>
<a id="xyz" choicePOS="corr0">Element2</a>
In a JS function that 'belongs' to Element1, I want to select Element2 so as to remove it. This is what I have tried (el is element1):
var choicePOS = el.getAttribute("choicePOS").slice(3); // produces 0
var corrID = "corr" + choicePOS; // produces corr0
var corr = document.querySelectorAll("a[choicePOS=corrID]");
This fails, presumably because the corrID variable in the last line is in quote marks and is being taken as a string. I have read various tutorials on CSS selectors and can't find any guidance on how to use them with a variable attribute value. Is this possible? If so, how? If not, any alternatives?
EDIT: A number of other questions relating how to concatenate strings with variables in JS have been suggested as duplicates of this one. To clarify, I am asking specifically about querySelectorAll, as I cannot find any examples this being used with variables. If the answer is that its selector is to be treated as any other JS string (i.e. variables can be concatenated in), then that is perfectly satisfactory.
Use template literals to evaluate that
var corr = document.querySelectorAll(`a[choicePOS=${corrID}]`);

How to find a value of an attribute of an element

Here is a piece of code
<span class="balance themecolor" data-balance="2800">
I'm looking for a way to extract the value of data-balance and set it as variable x, but I have absolutely no idea how to do it. I know of the existence of .val() but I don't know if I can apply it to this code. I'm looking a for a one line long solution.
If you're using jQuery (as you've mentioned .val()):
var x = $("[data-balance]").attr("data-balance");
Or if you aren't:
var x = document.querySelector("[data-balance]").getAttribute("data-balance");
In both cases, the [data-balance] is a CSS selector for the element; adjust as needed. For instance, with that element, and assuming no other elements with either of its classes, you could use .balance, .themecolor, or even .balance.themecolor.
jQuery will find all elements matching the selector (you can change that if it's an issue, usually it isn't), but then only give you the attribute value for the first one.
querySelector will stop with the first one. If you want to find them all and get a list, use querySelectorAll (and then index into it to get the individual ones).

jQuery selector cannot find an element that exists

This doesn't work
var name= "#443.selected:first";
selectedEntity = $(name).attr('entityId');
This works
var name= "li.selected:first";
selectedEntity = $(name).attr('entityId');
selectedEntity is undefined but an element does exist with id="443" class="selected".
Why doesn't the first example work?
You can use the attribute selector:
$('[id="443"].selected:first')
See this jsFiddle demo
Though in HTML other than HTML5 IDs which start with a number are not allowed, your selector should work (working Demo). You must have an error elsewhere in your code and/or markup.
There are several issues you should address:
IDs must be unique otherwise your HTML is invalid
overqualifying the ID-Selector is bad for performance and due to 1) even not necessary
ID-Selectors only return the first element so using :first is useless (and also affected by point 1)
Don't use custom attributes like entityId. Instead use the data- prefix. Then you can use jQuerys data method to get/set those attributes. (Beware however that you cannot use camelCase).

javascript, how to take value from an input by class?

I use this code to get value from an input box:
var suggest_type = document.getElementById('ac-type').value;
Now I need to apply my js code on several other pages. I heard that it's not nice to repeat an ID on one website. So, I'm thinking to change to use class like this:
var suggest_type = document.getElementByClass('ac-type').value;
This doesn't get the value. How can I use class to get value?
You should stick with using ID's - they only have to be unique within a page.
If you must use classes, you need to use getElementsByClassName():
var elems = document.getElementsByClassName('ac-type');
var value = elems[0].value;
However this function is not well supported on older browsers, which is another good reason to stick with IDs.
Its absolutely fine to repeat ids across a website just not on a single html document.
ID's should be unique within one html page.
It's actually :
var suggest_type = document.getElementsByClassName('ac-type')[0].value;
But I agree with Jon Taylor, ID's can be the same within a website, as long they are not duplicated on the same page.
try using this:
var elements = document.getElementsByClassName('ac-type'); // this is an array containing all matched elements
Use jquery just by using -
$('.ac-type').val();
you will get value.

javascript copying element value, where element name has a period

If an html element id has no period in it, then copying between elements is of course trivial, e.g.:
var theForm = document.paymentForm;
theForm.BillStreet1.value = theForm.ShipStreet1.value;
I've got a case where I need to have period in my ids, namely id="bill.street1" and id="ship.street1", and the following doesn't work :-(
theForm.bill.street1.value = theForm.ship.street1.value;
Can you please let me know how to handle the period? Does jquery make this simpler?
jQuery makes everything simplier by using css selectors to access elements. However, if you don't want to use jQuery, you can access the element this way, I believe.
theForm['bill.street1'].value = theForm['ship.street1'].value;
I haven't tested this, but it should work because periods are an alternate method to access an array, iirc.
Be sure to use theForm['bill.street1'].value = theForm['ship.street1'].value;
and not theForm.['bill.street1'].value = theForm.['ship.street1'].value;. The extra periods make the format invalid, in the same way using array.[2] instead of array[2] would invalidate it.
theForm['bill.street1'].value
theForm['ship.street1'].value

Categories