I'm attempting to change the style of the div element below using JavaScript, but by using its attribute as the selector instead of the class:
<div class="radio-wrapper" data-option-method="Option-A">
For example, I'm able to achieve the desired effect with the following CSS:
.radio-wrapper[data-option-method="Option-A"] { display: none; }
But I'm not having any luck when I attempt the same in the JS:
document.getElementsByClassName(".radio-wrapper[data-option-method="Option-A"]").style.display = "none";
I'm sure this is a fairly simple one, but I'm struggling to research a clear answer, greatly appreciate any suggestions!
First of all, you have a clear syntax error. Your browser console is undoubtedly pointing this out to you. Always check the console for errors.
Since your string contains double-quotes, use single-quotes for the string itself:
'.radio-wrapper[data-option-method="Option-A"]'
Aside from that, document.getElementsByClassName is the wrong function to use here. What you have isn't a class name, it's a more complex selector. document.querySelector can find the element based on that:
document.querySelector('.radio-wrapper[data-option-method="Option-A"]').style.display = "none";
Alternatively, if there are multiple matching elements and you want to target all of them, use querySelectorAll and iterate over the results:
let elements = document.querySelectorAll('.radio-wrapper[data-option-method="Option-A"]');
for (let el of elements) {
el.style.display = "none";
}
The problem is that isn't the class name. ([data-option-method="Option-A"] is an attribute)
Try it with:
document.querySelector('.radio-wrapper[data-option-method="Option-A"]')
If you want to select multiple, use querySelectorAll but bare in mind that returns an array.
Also watch out for the `, ", and ' in strings, either escape them with a " or combine them as I did.
Related
I'm trying to have javascript add or remove the hidden class from contact_form_top when the button contact_form_btn is pressed, but I have not been able to make it work.
function hide_unhide_btn() {
if (document.getElementId("contact_form_top").classList.contains("hidden");{
document.getElementById("contact_form_top").classList.remove("hidden");
}
else {
document.getElementById("contact_form_top").classList.add("hidden");
}}
On a quick glance I see 5 problems in your code:
element.className is a String.
You can add a class to it with element.className += " hidden". Note the space before the "hidden" word.
Without the space you will get className = "contact_form_tophidden" (one word = one class) instead of "contact_form_top hidden" (two classes)
Also you can't subtract a string by using -=, subtraction is for numbers only.
Instead of manipulating the String className, I suggest you use classList which is an array-like list of classes that you can add and remove. If you want to be backward compatible with old browsers its best to use a framework such as jQuery or follow the className manipulation techniques described in https://stackoverflow.com/a/196038/519995
Also you need to use getElementsByClassName (uppercase C)
getElementsByClassName returns a collection of elements, you need to iterate them with a for loop and modify the class of each, one at a time. Again, if you'd use a framework such as jQuery this would be much easier.
Also the if statement you are using will always enter the first part and never the second part, since the content is always "closed" when the function runs.
Instead of using .className i suggest to use classList to easily mantain the add/remove classes, e.g :
if(content == "closed"){
document.getElementsByClassName("contact_form_top")[0].classList.remove("hidden");
content = "open";
}else if(content == "open"){
document.getElementsByClassName("contact_form_top")[0].classList.add("hidden");
content = "closed";
}
Hope this helps.
You can use the classList API for adding classes, which is very straightforward.
Here is an (unobtrusive) approach to adding and removing classes:
function hide_unhide_btn() {
this.parentNode.classList.toggle('hidden');
}
var contactFormButton = document.getElementsByClassName('contact_form_btn')[0];
contactFormButton.addEventListener('click',hide_unhide_btn,false);
.hidden {opacity: 0.1;}
<form class="contact_form_top">
<input type="button" value="Contact Me" class="contact_form_btn" />
</form>
I am writing a small library where I am in need of selecting a relative element to the targeted element through querySelector method.
For example:
HTML
<div class="target"></div>
<div class="relative"></div>
<!-- querySelector will select only this .target element -->
<div class="target"></div>
<div class="relative"></div>
<div class="target"></div>
<div class="relative"></div>
JavaScript
var target = document.querySelectorAll('.target')[1];
// Something like this which doesn't work actually
var relativeElement = target.querySelector('this + .relative');
In the above example, I am trying to select the .relative class element relative only to the .target element whose value is stored in target variable. No styles should apply to the other .relative class elements.
PS: the selectors can vary. So, I can't use JavaScript's predefined methods like previousElementSibling or nextElementSibling.
I don't need solution in jQuery or other JavaScript libraries.
Well it should be ideally:
var relativeElement = target.querySelector('.relative');
But this will actually try to select something inside the target element.
therefore this would only work if your html structure is something like:
<div class="target">
<div class="relative"></div>
</div>
Your best bet would probably in this case be to use nextElementSibling which I understand is difficult for you to use.
You cannot.
If you insist on using the querySelector of the subject element, the answers is there is no way.
The spec and MDN both says clearly that Element.querySelector must return "a descendant of the element on which it is invoked", and the object element you want does not meet this limitation.
You must go up and use other elements, e.g. document.querySelector, if you want to break out.
You can always override Element.prototype.querySelector to do your biddings, including implementing your own CSS engine that select whatever element you want in whatever syntax you want.
I didn't mention this because you will be breaking the assumption of a very important function, easily breaking other libraries and even normal code, or at best slowing them down.
target.querySelector('.relative');
By using querySelector on the target instead of document, you scope the DOM traversal to the target element.
It is not entirely clear from your explanation, but by related i assume you mean descendant?
To get all target elements you can use
document.querySelectorAll('.target')
And then iterate the result
I found a way which will work for my library.
I will replace "this " in the querySelector with a unique custom attribute value. Something like this:
Element.prototype.customQuerySelector = function(selector){
// Adding a custom attribute to refer for selector
this.setAttribute('data-unique-id', '1');
// Replace "this " string with custom attribute's value
// You can also add a unique class name instead of adding custom attribute
selector = selector.replace("this ", '[data-unique-id="1"] ');
// Get the relative element
var relativeElement = document.querySelector(selector);
// After getting the relative element, the added custom attribute is useless
// So, remove it
this.removeAttribute('data-unique-id');
// return the fetched element
return relativeElement;
}
var element = document.querySelectorAll('.target')[1];
var targetElement = element.customQuerySelector('this + .relative');
// Now, do anything with the fetched relative element
targetElement.style.color = "red";
Working Fiddle
Looping through all the elements of the class, I see the code below only affecting the first element in the array yet the console log logs every one of them.
del = $('<img class="ui-hintAdmin-delete" src="/images/close.png"/>')
$('.ui-hint').each(function(){
console.log($(this));
if ($(this + ':has(.ui-hintAdmin-delete)').length == 0) {
$(this).append(del);
}
});
The elements are all very simple divs with only text inside them. They all do not have the element of the class i am looking for in my if statement, double checked that. Tried altering the statement (using has(), using children(), etc). Guess i'm missing something very simple here, haha.
Will apperciate input.
I think what you need is (also if del should be a string, if it is a dom element reference then you need to clone it before appending)
$('.ui-hint').not(':has(.ui-hintAdmin-delete)').append(function(){
//you need to clone del else the same dom reference will be moved around instead of adding new elements to each hint
return del.clone()
});
You can do this:
$('.ui-hint:not(:has(.ui-hintAdmin-delete))').append(del);
without even using the each loop here. As jquery code will internally loop through all the descendant of the ui-hint class element and append the del element only to the descendant not having any .ui-hintAdmin-delete elements.
While it would probably help to see your HTML as well, try changing your conditional to
if (!$(this).hasClass('ui-hintAdmin-delete')) {
$(this).append(del);
}
Edit: one missing piece of information - I can't use the class selector because there are more divs with the same class. I already thought of that, but I forgot to mention it. I have no idea why my post got downvoted, but it seems awfully silly considering I provided a lot of information, gave it honest effort, and tried to be verbose with code examples. People on this forum are ridiculous sometimes.
I'm trying to set the id of a div that doesn't have one and there's no way I can give it one upon generation of the page. I've tried using jquery (.each, .contains, .find, .filter, etc.) and I can't seem to get it right. I know a ton of people have asked this question, but none of the answers made sense to me.
I have the ability to set the text (html?) of the div, but nothing else. It ends up looking like this:
<div class="dhxform_note" style="width: 300px;">Remaining letters: 500</div>
I want a handle to the div object so I can show the user how many more letters they can type by updating the text.
Using this:
$("div")
returns a list of all divs on the page. I can see the target div in the list, but I can't get jquery to return a single object.
I know it can also be done with something like this:
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++) {
if( /^Remaining letters/.test(divs[i].innerText) )
divs[i].id = "kudosMsgNote"
}
}
but I was hoping to complete this with a cleaner looking solution involving jquery. I also simply want to know how to do it with jquery, aesthetics not withstanding.
Use a class selector.
var theDivViaTheClass = $(".dhxform_note");
Class Selector (“.class”)
Description: Selects all elements with the given class.
version added: 1.0
jQuery( ".class" )
class: A class to search for. An
element can have multiple classes; only one of them must match.
For class selectors, jQuery uses JavaScript's native
getElementsByClassName() function if the browser supports it.
You seem to be targeting the <div> by its text. Try using the :contains selector:
$("div").filter(':contains("Remaining letters")').first().attr("id", "kudosMsgNote");
The .first() is to make sure you don't set the same id for multiple elements, in case multiple elements contain the text "Remaining letters".
Here's the docs for the :contains selector: http://api.jquery.com/contains-selector/
Be careful, the text you're looking for is case sensitive when using :contains!
Is that div the only one with the class dhxform_note? If so, you can use the class selector:
$('.dhxform_note').html();
With jQuery, you can specify any css selector to get at the div:
$(".dhxform_note").attr("id", "kudosMsgNote");
will get you this element as well.
Selecting on inner text can be a bit dicey, so I might recommend that if you have control over the rendering of that HTML element, you instead render it like this:
<div name="remainingLetters" class="dhxform_note" style="width: 300px">Remaining Letters: 500</div>
And get it like this:
$("[name=remainingLetters]").attr("id", "kudosMsgNote");
However, it's possible that you really need to select this based on the inner text. In that case, you'll need to do the following:
$("div").each(function() {
if ( /^Remaining letters/.test($(this).html()) ) {
$(this).attr("id", "kudosMsgNote");
}
});
If you cannot set id for whatever reason, I will assume you cannot set class either. Maybe you also don't have the exclusive list of classes there could be. If all those assumptions really apply, then you can consider down your path, otherwise please use class selector.
With that said:
$("div").filter(function() {
return /^Remaining letters/.test($(this).text())
}).attr('id', 'id of your choice');
For situations where there are multiple divs with the class dhxform_note and where you do not know the exact location of said div:
$("div.dhxform_note").each(function(){
var text = $(this).text();
if(/^Remaining letters/.test(text)){
$(this).attr("id", "kudosMsgNote");
}
});
EXAMPLE
If, however, you know that the div will always be the 2nd occurrence of dhxform_note then you can do the following:
$("div.dhxform_note").get(1).id = "kudosMsgNote";
EXAMPLE
Or do a contains search:
$("div.dhxform_note:contains('Remaining letters')").first().attr("id", "kudosMsgNote");
EXAMPLE
How can I select all elements that have a specific CSS property applied, using jQuery? For example:
.Title
{
color:red;
rounded:true;
}
.Caption
{
color:black;
rounded:true;
}
How to select by property named "rounded"?
CSS class name is very flexible.
$(".Title").corner();
$(".Caption").corner();
How to replace this two operation to one operation. Maybe something like this:
$(".*->rounded").corner();
Is there any better way to do this?
This is a two year old thread, but it was still useful to me so it could be useful to others, perhaps. Here's what I ended up doing:
var x = $('.myselector').filter(function () {
return this.style.some_prop == 'whatever'
});
not as succinct as I would like, but I have never needed something like this except now, and it's not very efficient for general use anyway, as I see it.
Thank you, Bijou. I used your solution, but used the jQuery .css instead of pure javascript, like this:
var x = $('*').filter(function() {
return $(this).css('font-family').toLowerCase().indexOf('futura') > -1
})
This example would select all elements where the font-family attribute value contains "Futura".
You cannot (using a CSS selector) select elements based on the CSS properties that have been applied to them.
If you want to do this manually, you could select every element in the document, loop over them, and check the computed value of the property you are interested in (this would probably only work with real CSS properties though, not made up ones such as rounded). It would also would be slow.
Update in response to edits — group selectors:
$(".Title, .Caption").corner();
Similar as Bijou's. Just a little bit enhancement:
$('[class]').filter(function() {
return $(this).css('your css property') == 'the expected value';
}
).corner();
I think using $('[class]') is better:
no need to hard code the selector(s)
won't check all HTML elements one by one.
Here is an example.
Here is a clean, easy to understand solution:
// find elements with jQuery with a specific CSS, then execute an action
$('.dom-class').each(function(index, el) {
if ($(this).css('property') == 'value') {
$(this).doThingsHere();
}
});
This solution is different because it does not use corner, filter or return. It is intentionally made for a wider audience of users.
Things to replace:
Replace ".dom-class" with your selector.
Replace CSS property and value with what you are looking for.
Replace "doThingsHere()" with what you want to execute on that
found element.
Good luck!
Custom CSS properties aren't inherited, so must be applied directly to each element (even if you use js to dynamically add properties, you should do it by adding a class), so...
CSS
.Title
{
color:red;
}
.Caption
{
color:black;
}
HTML
You don't need to define a rounded:true property at all. Just use the presence of the 'Rounded' class:
<div class='Title Rounded'><h1>Title</h1></div>
<div class='Caption Rounded'>Caption</div>
JS
jQuery( '.Rounded' ).corner();