Find elements using part of ID - javascript

I have, the div's where id looks like this_div_id_NUMBER, all div's has the different NUMBER part. How I find all div's just using this_div_id part of id ?

you can use querySelectorAll to hit partial attribs, including ID:
document.querySelectorAll("[id^='this_div_id']")
the ^ next to the equal sign indicates "starts with", you can use * instead, but it's prone to false-positives.
you also want to make sure to use quotes (or apos) around the comapare value in attrib selectors for maximum compatibility on querySelectorAll; in jQuery and evergreen browsers it doesn't matter, but in vanilla for old browsers it does matter.
EDIT: late breaking requirement needs a more specific selector:
document.querySelectorAll("[id^='this_div_id']:not([id$='_test_field'])");
the not() segment prevents anything ending with "_test_field" from matching.
proof of concept / demo: http://pagedemos.com/partialmatch/

querySelectorAll
querySelectorAll takes CSS selectors and returns a HTMLNodeList (a kind of array) of all the elements matching that css selector.
The css selector ^ (starts with) can be used for your purpose. Learn more about it in this article.
For your case, it would be document.querySelectorAll("[id^='this_div_id']");
Note that querySelectorAll doesn't return a live node list. That means, any changes to the dom would not be updated live in the return value of the function.
Another method would to assign all your elements a specific class and then you can use getElementsByClassName (which is much faster than querySelector).
var divs = document.getElementsByClassName("divClass");

Try this selector:
[id^="this_div_id_"]
Pure JavaScript: (reference)
document.querySelectorAll('[id^="this_div_id_"]')
jQuery: (reference)
$('[id^="this_div_id_"]')
CSS: (reference)
[id^="this_div_id_"] {
/* do your stuff */
}
Why is this working?
With the [] in the selector, you can select attributes. Use '=' to match exactly the value or use the '^=' to check if the value starts with. Read more about this here.

Using attribute selectors:
div[id^="this_div_id"]

It is better to use classes.
But there is one solution that you need (assuming you use jQuery):
$("*[id^='this_div_id']")

Just using attribute selector like below:
$("[id^='this_div_id_']")

Related

Why are directly assigned attributes ignored by document.querySelector()?

I've recently discovered a very fundamental difference between the 2 methods of setting custom DOM attributes in Javascript. The difference is in how the HTML5 Selectors API interacts with those attributes (ie, in document.querySelector() and friends).
<button id="b3">View</button>
<script>
document.getElementById('b3').shape = 'square';
console.log( document.querySelector('*[shape]') ); // FAIL: returns null
document.getElementById('b3').setAttribute('shape','square');
console.log( document.querySelector('*[shape]') ); // WORKS: returns element
</script>
So basically if you apply attributes to an element without using .setAttribute() then you cannot later select the element by the attribute name.
BTW. This behaviour is consistent across browsers which makes me think it might be addressed by the standard, however I can't see it:
http://www.w3.org/TR/css3-selectors/#attribute-selectors
http://www.w3.org/TR/selectors-api/
The selectors API standard doesn't appear to care:
Selectors allow the representation of an element's attributes. When a
selector is used as an expression to match against an element,
attribute selectors must be considered to match an element if that
element has an attribute that matches the attribute represented by the
attribute selector.
The entire attribute matching rule seems to boil down to "if the element has an attribute" and you would think that someElement.someAttribute = something would meet the criteria of "having an attribute" but for whatever reason it doesn't.
My question is basically why the difference? Is it actually part of a standard or just an identical implementation quirk in all the major browsers (IE11, FF38 and Chrome 43)?
The reason is very simple - getElementById and all of those kind return an Element Object (see specs: http://www.w3schools.com/jsref/met_document_getelementbyid.asp)
Which means you set property shape on an object. Then you try to do a query selector, but you haven't modified the html that's queried. They are different things.

javascript alternative for jquery element addressing

What is Javascript alternative for this:
$('#clientDetailModal #heightValue')
I need it because in my code this works:
document.getElementById('heightValue').checkValidity()
but this doesn't:
$('#clientDetailModal #heightValue').checkValidity()
And I need to select only heightValue within clientDetailModal div.
Try $('#clientDetailModal #heightValue')[0].checkValidity()
The reason you need to do the [0] is, (as per the jquery id selector documentation)
Calling jQuery() (or $()) with an id selector as its argument will
return a jQuery object containing a collection of either zero or one
DOM element
Since you'll get a collection with 1 DOM element (assuming you don't have multiple ids), you need to then explicitly "select" that element using the [0].
You could use get to get the DOM element :
$('#clientDetailModal #heightValue').get(0).checkValidity()
Just to be sure, as your question might be a little ambiguous : only one element can have a given ID in HTML. So if your element is either absent or inside #clientDetailModal, then you could as well use
$('#heightValue').get(0).checkValidity()
It would also be faster. But in that case, there would be nothing wrong in using document.getElementById.
Since document.getElementById('heightValue').checkValidity() works, it means your function checkValidity() is attached on native DOM elements. This means, you can do:
$('#clientDetailModal #heightValue')[0].checkValidity()
Plus: If your HTML is valid with no duplicate IDs, you can simply do
$('#heightValue')[0].checkValidity()
Since the OP asked for a JavaScript alternative. On modern browsers,
document.querySelector ('#clientDetailModal #heightValue')
will return the element you are asking for.
The direct equivalent would be
document.querySelectorAll ('#clientDetailModal #heightValue')
which returns an array of elements matching the selector requested, do yrou will need to add the [0] as per the other answers.
I presume this is what you're looking for :
document.getElementById('clientDetailModal').getElementById('heightValue').checkValidity();

Strange ie behaviour with jquery inArray

Hello this seems to be working on IE8 :
var clsName = link.parents("div.fixed_column").attr("class").split(" ");
if($.inArray("column_one", clsName)
While this one reports error (Object expected errror in jquery).
var clsName = link.parents("div.fixed_column").attr("class");
What is the right way to do this? I thought purpose of inArray was that jquery will handle cross browser issues.
Unfortunately, this is indirectly answering your question, but... You seem to be looking to detect if an element has a class, and since you're already using jQuery, just use the hasClass method - http://api.jquery.com/hasClass/
For your specific code, try:
if (link.parents("div.fixed_column").hasClass("column_one")) {
// It has the "column_one" class
}
The more immediate answer to your question is that link.parents("div.fixed_column").attr("class") returns a single string. When the jQuery selector (div.fixed_column) returns multiple elements, which is very possible when using classes, using jQuery methods that get information (like .attr, using one parameter...to "get" the value) return the first matched element's value only.
So say the selector matches 3 elements:
["<div id='div30' class='fixed_column div30_class'></div>",
"<div id='div2' class='fixed_column div2_class'></div>",
"<div id='div17' class='fixed_column div17_class'></div>"]
Then the value returned from .attr("class") will be: fixed_column div30_class because it's the first matched element.
I'm not sure, but I think you're expecting jQuery to return an array of all the matched elements' values, which it just doesn't. So that doesn't mean jQuery isn't handling cross-browser issues, it just means you need to look up what the method does/returns.
I could've sworn that jQuery 2.0 has options for doing what you want - directly from calling the getters (or something similar), but I can't find it anymore :( Maybe I'm remembering incorrectly. Anyways, you could easily use $.each and/or $.map to look at every matched element, but it depends on what you were really trying to do with it.
You can't read the attributes of multiple elements into an array with .attr("class"). But why don't you just target the desired class in the selector like this?
var cols = link.parents("div.fixed_column.column_one");
Then change your conditional to check for an empty set:
if(cols.length) { ...

Hiding multiple tag with same name or class

I have using prototype 1.5. Can you please tell me, how can i hide/show the div tag with same name or class.
Element.hide('indicate')
But, the above line only satisfy to hide the first element only. "indicate" is the id.
As pointed out, the $$ function is required. It returns an array so you need to invoke hide on all items.
$$('.indicate').invoke('hide');
Or, for bonus showing off points, you can use the function directly as an object:
var hideFunc = Element.hide;
$$('.indicate').each(hideFunc);
The advantage of this technique means you can easily swap the function for another, such as a Scriptaculous effect.
hideFunc = Effect.SwitchOff;
Having the same id for two elements isn't supported in HTML, so there's no methods in Javascript to handle it. No matter what framework you're using.
Prototype provides the $$() function which you can use to query any CSS selector.
So if you have multiple items with a single class, you can query them like this:
$$('.indicate');
See the Prototype manual: http://www.prototypejs.org/api/utility/dollar-dollar
By the way, since you're using Prototype 1.5, I could also mention that it gives you a .getElementsByClassName() function as well. However, this has now been deprecated in more recent versions since its functionality is already covered by $$(), and to avoid confusion, since modern browsers implement a native function with the same name, but different syntax.
So don't use it, but for the sake of completeness, here is the manual link: http://www.prototypejs.org/api/element/getElementsByClassName
ID's have to be unique. Select with a class instead.
$$('div.indicate').hide();
or with its name attribute
$$('div[name=indicate]').hide();

Is there a preferred approach to setting an item's class using jQuery

Before jQuery I would have used something like the following code to set a class on an element:
document.getElementById("MyElementID").className = 'MyClassName';
This has the intended behaviour of replacing anything that was there before my new class name MyClassName
In jQuery the equivalent seems to be:
$('#MyElementID').attr('class', 'MyClassName')
But, we also have the in-built class functions, addClass(), removeClass() and toggleClass(). So to achieve the same effect, I would say:
$('#MyElementID').removeClass().addClass('MyClassName');
Obviously, the first jQuery example is more concise and requires just one function call (to attr, instead of addClass() and removeClass())
Can we also work on the assumption that I can't use prop as its an earlier (and currently unchangeable) version that I'm working with.
So what would you say is the preferred approach? Does the second sample give me anything over and above the first?
Many thanks in advance.
The addClass(), removeClass() and has() methods of jQuery use the className property of the element. The big advantage they offer is that they allow you to add or remove a class without affecting the other class names set.
The attr() method uses something like this:
document.getElementById("MyElementID")[name] = value;
For cases that you only need one class name, the attribute method will be probably faster. I personally however find the addClass method more elegant and easier to adapt if you need to add more class names in the future.
I think you should check the performance of all these functions. personally i think prop method is fastest ( introduced in v1.6)
see here the performance jQuery().attr vs jQuery().data vs jQuery().prop
http://jsperf.com/jquery-data-vs-jqueryselection-data/8
The difference is in this guy:
<div class="a_class another_class a_third_class">
attr('class','no_other_classes_now') <-- will replace everything in the class attribute even if there are multiple space separated classes. It's probably the lightest-weight of JQ methods for doing this since it's just using DOM methods that already worked properly across browsers for over a decade now.
.removeClass('a_third_class') will remove a class, leaving other classes intact.
.addClass('a_fourth_class') will add a space-separated class without replacing other classes.
^^ These two would have to do more work for a simple class overwrite than attr since they need to do find/replace type operations.
Prop is for changing properties of DOM elements that don't have HTML representatives like the window object (not likely to be useful very often due to other convenience methods) or that would be confusing because different attribute strings can mean different things. Like simply having the attribute "checked" without an equal sign or value being equivalent to checked="checked" or checked="true" as far as the boolean (true/false only) JS property is concerned in certain flavors of HTML. With prop you'll get the javascript property and not necessarily whatever is considered to be between the quotes of the actual HTML element.
When you're not in that type of situation, I would stick with the attr method. The whole point of prop seems to be to take work from the old attr method so I'd be surprised if it was faster in most cases. More importantly it's common and easy to read.

Categories