Issues adding and removing classes with javascript - javascript

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>

Related

Target/style an element’s attributes with JavaScript

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.

select html object without id

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

Javascript to change class of an Element

This is heavily trimmed down source code from a webpage I'm working on right now.
<!--// GRID ENTRY //-->
<li class="entry" id="sjDDulC8wt">
<div class="entry_actions">
<ul class="entry_actions">
<li class='have_it'>
<a href='javascript: haveItem("name", "id", "none")' target='_self' title='Have It' class='have_it'>%</a></li>
</ul>
</div>
</li>
Inside the haveItem() function I'm trying to change the class of the <a> element from 'have_it' to 'have_it selected' to change the appearance of the element. The reason for the id is because I have dozens of these elements on the page. The javascript I'm currently using is:
var targetA = document.getElementbyID(sjDDulC8wt).getElementsbyTitle("Have_it");
targetA.removeClass("have_it").addClass("have_it selected");
When I click the link, the haveItem() function runs, but it doesn't change the class. How can I change my script so that clicking the link will change the class?
I am assuming you are using jQuery since you are using removeClass() and addClass. Otherwise, I would recommend you link to jQuery so that the code below works, or stick with only JavaScript.
var targetA = $('#sjDDulC8wt .have_it');
targetA.addClass('selected');
For future reference, here are some things about your code that you can improve:
getElementById() accepts the id of the element you want to retrieve as a string. Basically, you should wrap your ID in ' or "
Be careful where you are putting spaces and underscores. They are not the same thing. Your list item has the title Have It, while your JavaScript has Have_it.
Capitalization matters. Have_It is not the same thing as Have_it. Be careful with this when you try to get elements by ID.
A class with spaces in it is actually multiple classes. have_it selected actually has both the have_it class and the selected class. Therefore it not necessary to remove have_it and then add have_it selected - you can go straight to adding the selected class.
The function getElementbyTitle() does not currently exist in JavaScript. Also, be careful again about capitalization. Typically, the first letter of every word in a function is capitalized. Thus, if it did exist it would be called getElementByTitle() (notice the B instead of b).
Here:
var anchor = document.querySelector( '#sjDDulC8wt [title="Have It"]' );
if ( anchor ) anchor.classList.add( 'selected' );
Live demo: http://jsfiddle.net/UZfnh/
(Won't work in older browsers.)
This should do the task for you:
<a title="Have It" class="have_it" onclick="this.className+=' selected'">%</a>
However, you should learn about the DOM. None of the methods you used (getElementbyID, getElementsbyTitle, removeClass and addClass) exists.
When you successfully find the element, you can do one of these:
element.classList.add("selected");
It uses a fairly new classList feature available for FF 3.6, IE 10, Chrome 8, Opera 11.50, Safari 5.1 and above. It the the most preferred way to do it once you are sure your clients will have one of those browsers (near future).
element.className += " selected";
className doc. This works and is probably the easiest way. Not so nice as the classList thing, but available for all browsers.
If you can't use jQuery then you can change the classname of an element using className:
var element = document.getElementById("elementId");
element.className = "have_it selected";
Note also this function: getElementsByClassName (HTML5).
As has been pointed out, you have some other issues selecting your element. From your example, it looks like you want to use:
var element = document.getElementById("sjDDulC8wt");
var children = element.getElementsByClassName("have_it");
children[0].className = "have_it selected";
Note that there's no error handling/null checks here. And this handles a simple case of only changing the first child with the specified class, assuming that it exists.
But prefer jQuery if you can use that. From your use of addClass/removeClass it appears that you already expect jQuery.

Javascript/jQuery .each and syntax issue

I'm having some trouble writing a function to change a background image on a div on document.ready
I haven't made a jsfiddle as i think the problem is just my poor (but improving) jQuery skills. Please let me know if you think one is needed.
Background Info ->
I have a collection of div's with a class of portlet-visible or portlet-hidden, each of these div's will have another class of red-arrow (or a different color, but once i have one color it should be easy to extrapolate). When the page loads i would like a function that can find all divs with a class of portlet-hidden or portlet-visible and see if those have a class of red-arrow. If they do then change the background image src to a different value.
Im really struggling to work this one out, and any help is much appreciated.
My HTML
<div class="portlet-visible red-arrow"></div>
My CSS
div.portlet-visible
{
position:absolute;
top:12px;
right:10px;
background-image:url(../images/red-arrow-up.png);
width:14px;
height:14px;
}
And finally my javascript
$(document).ready(function() {
$(".portlet-hidden" && ".portlet-visible").each(function() {
if ($("this").hasClass(".red-arrow")) {
$(this).css(background-image, url('"url(../images/blue-arrow-up.png)"')
};
});
});
Multiple selectors should be separated by a comma(,) and also css method takes a string or a map. Try this.
$(document).ready(function() {
$(".portlet-hidden, .portlet-visible").each(function() {
if ($(this).hasClass("red-arrow")) {
$(this).css('background-image', "url('../images/blue-arrow-up.png')")
};
});
});
I would have written the selector this way
$(".portlet-hidden, .portlet-visible")
Unless there's a specific reason you want to do this with jQuery you should just use CSS...
div.portlet-visible
{
background-image:url(../images/red-arrow-up.png);
width:14px;
height:14px;
}
div.portlet-visible.red-arrow
{
background-image:url(../images/blue-arrow-up.png);
}
Any div with the class "portlet-visible" is defined in the first block, and any div with the classes "portlet-visible" and "red-arrow" will use the same css, but also apply the new background image.
http://jsfiddle.net/johncmolyneux/gcm5b/
First... Archer's answer is spot on-- what you're trying to do with jQuery can be done with CSS alone.
But if for some reason you do need jQuery, a few things are wrong here.
First, as justtkt said in his answer, your selector is wrong. There is no need (and is syntactically wrong) to use conditional operators like && or || in a jQuery selector. This is simply because there is already conditional syntax built in to CSS, upon which jQuery selectors are directly based.
.this-class.that-class
Selects all elements with both .this-class, and .that-class.
#this-id.that-class
Is a very (possibly overly) specific declaration that select an element (there should only be one ID per page) with both #this-id and .that-class
For more on selectors, please read this very thorough, complete, and educational link http://www.w3.org/TR/selectors/
Additionally and importantly
This line:
$("this").hasClass(".red-arrow")
Is wrong! hasClass does not require a selector (the ".") because it only takes a class. It should be
$("this").hasClass("red-arrow")
Also!!
$(this).css(background-image, url('"url(../images/blue-arrow-up.png)"')
This line has some errors... should be:
$(this).css("background-image", "url(../images/blue-arrow-up.png)")
although I think the following syntax is easier:
css({'background-image' : 'url(../images/blue-arrow-up.png)'})
Your selector is just incorrect. If you want to match things with both classes, it'd be:
$('.portlet-hidden.portlet-visible').each( ...
If you want to match either of the classes:
$('.portlet-hidden, .portlet-visible').each( ...
The expression ".portlet-hidden" && ".portlet-visible" will always evaluate to just ".portlet-visible".
Instead of && two selectors together, use the multiple selector like $(".portlet-hidden, .portlet-visible") or the .add() method to build up your jQuery.
Your current line is actually anding the two strings together, which I believe will return boolean true in Javascript.
if ('$("this").hasClass(".red-arrow")') { <--- this condition is a string here
Should be:
if ($(this).hasClass(".red-arrow")) {
change in selector ".portlet-hidden,.portlet-visible"
change if condition to boolean from string
change in css.
$(".portlet-hidden,.portlet-visible").each(function(){
if ($("this").hasClass("red-arrow")){
$(this).css("background-image", "url('../images/blue-arrow-up.png')");
}
});

how to append a css class to an element by javascript?

Suppose a HTML element's id is known, so the element can be refereced using:
document.getElementById(element_id);
Does a native Javascript function exist that can be used to append a CSS class to that element?
var element = document.getElementById(element_id);
element.className += " " + newClassName;
Voilà. This will work on pretty much every browser ever. The leading space is important, because the className property treats the css classes like a single string, which ought to match the class attribute on HTML elements (where multiple classes must be separated by spaces).
Incidentally, you're going to be better off using a Javascript library like prototype or jQuery, which have methods to do this, as well as functions that can first check if an element already has a class assigned.
In prototype, for instance:
// Prototype automatically checks that the element doesn't already have the class
$(element_id).addClassName(newClassName);
See how much nicer that is?!
Adding class using element's classList property:
element.classList.add('my-class-name');
Removing:
element.classList.remove('my-class-name');
classList is a convenient alternative to accessing an element's list of classes.. see http://developer.mozilla.org/en-US/docs/Web/API/Element.classList.
Not supported in IE < 10
When an element already has a class name defined, its influence on the element is tied to its position in the string of class names.
Later classes override earlier ones, if there is a conflict.
Adding a class to an element ought to move the class name to the sharp end of the list, if it exists already.
document.addClass= function(el, css){
var tem, C= el.className.split(/\s+/), A=[];
while(C.length){
tem= C.shift();
if(tem && tem!= css) A[A.length]= tem;
}
A[A.length]= css;
return el.className= A.join(' ');
}
You should be able to set the className property of the element. You could do a += to append it.
addClass=(selector,classes)=>document.querySelector(selector).classList(...classes.split(' '));
This will add ONE class or MULTIPLE classes :
addClass('#myDiv','back-red'); // => Add "back-red" class to <div id="myDiv"/>
addClass('#myDiv','fa fa-car') //=>Add two classes to "div"
you could use setAttribute.
Example:
For adding one class:
document.getElementById('main').setAttribute("class","classOne");
For multiple classes:
document.getElementById('main').setAttribute("class", "classOne classTwo");

Categories

Resources