Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

JavaScript Insert classes using JavaScript

I basically know no JavaScript at all yet i need it for my current project i am working on to learn scss and html. I have a set of radio buttons an what i need is if a radiobutton is checked, that its label and the labels bofre it get a extra class inserted. (e.g. if radiobutton 4 was checked, the labels of the buutons 1-4 should have the extra class)

HTML:
<div class="container">
        <input name="test" type="radio" class="radio" id="1">
        <input name="test" type="radio" class="radio" id="2">
        <input name="test" type="radio" class="radio" id="3">
        <input name="test" type="radio" class="radio" id="4">
        <input name="test" type="radio" class="radio" id="5">
        <label for="1" class="label">Label</label>
        <label for="2" class="label">Label</label>
        <label for="3" class="label">Label</label>
        <label for="4" class="label">Label</label>
        <label for="5" class="label">Label</label>
</div>

This is the html code Iused to try figure it out myself but just couldn't get it to work.

HTML:
<div class="container">
        <input name="test" type="radio" class="radio" id="1">
        <input name="test" type="radio" class="radio" id="2">
        <input name="test" type="radio" class="radio" id="3">
        <input name="test" type="radio" class="radio" id="4" checked>
        <input name="test" type="radio" class="radio" id="5">
        <label for="1" class="label active">Label</label>
        <label for="2" class="label active">Label</label>
        <label for="3" class="label active">Label</label>
        <label for="4" class="label active">Label</label>
        <label for="5" class="label">Label</label>
</div>

This is an example of how it should look like if radiobutton 4 were selected.
 
Solution
D
Right, that was the 3rd mistake I was going to tell you.
The second mistake I w3as going to tell you explains why glass 10 is selected when you click any glass it should not. It's because you are comparing strings here :

if (glass.id <= id){

and "10" is smaller than "2" or "9".

Change this to

if (Number(glass.id) <= Number(id)){

and it works fine.

So you need only 10 glasses. Easy enough to cdreate the HTML for that. But just imagine you'd need 1000, then you'd want to create them dynamically:

JavaScript:
var numGlasses = 1000;
function init()
{
    for (let count = 1; count <= numGlasses; count++)
    {
        var glass = document.createElement('img');
        glass.classList.add('glass')...
<label> and <input> tags should always come in pairs. Coding it like you did makes no sense, as it displays like this
a.jpg
which I'm pretty sure is not what you want.

When you say you "just couldn't get it to work" what does that mean ? What did you try and where exactly did it fail ?
 
I am working on a survey site about ones physical health and one question is how much water one drinks. So my idea was that there are water cups and you could select the amount of glasses you drink a day. But if i for example want to select 4 glasses i'd click on glass 4 but all the glasses 1-4 should be colored in and that what i can't figure out. (I've built it with <img> elements to show you what it should look like)
But thanks for the html tip! :)
1674822153409.png
 
Ok, it's clear what you want to do. Will you have the radio buttons underneath the glasses, or do you want to make the glasses themselves clickable ? In any case, no labels I suppose ?
 
Ok. That is easy enough but the policy here is not to provide people with complete code for their their problem. You'll need to do some work on it yourself and learn from it. You can hardly learn html and (s)css without also getting into Javascript (well perhaps there is a CSS only solution, I don't know but others here might).
Using JS, the idea is to define 5 <img> elements with the same class (so you can loop through them all) but different id's (so you can tell them apart). Set a click event handler on each image (the same handler for all). In the event handler, get the id of the clicked element. Then loop through the images using document.getElementsByClassName() and set the image to a full or empty glass, depending in whether the index (1..5) is less than the id you have or not. I hope this gets you going. Anything unclear, do ask.
 
I think I have figured out how to add an event listener but I don't know how to move on from here. I tried a few things but haven't arrived anywhere that's close to working. Here is the code I have so far:

<div class="container"> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="1"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="2"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="3"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="4"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="5"></a> </div> <script> <div class="container"> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="1"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="2"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="3"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="4"></a> <a class="anchor"><img src="Glass-std.svg" class="waterglas" id="5"></a> </div> </script>

I used a youtube tutorial to write the JavaScript but it wasn't for the exact same use so I had to change it, not sure whats wrong with it because I only get an output in the terminal when I click the first image.
 
Why do you have the same piece of HTML twice, the second time inside <script> where it has no business being ?
And why put an anchor around each image ? That just complicates matters. You can add an even listener to any element. Where's your code for that anyway ?
 
Sorry I copied the wrong code into the html file because in VSC i have seperate files for html and JavaScript. Regarding the <a>, I've tried it without them first but it didnt work. But here's the code I have so far:

JavaScript:
const glas = document.querySelector('.glas-a')

glas.addEventListener('click', e => {
    console.log(e.target);
})

I've put the console.log in there to see if it worked, but as alraedy mentioned, it only worked on the first element.
 
I'm not sure where the selector glas-a suddenly comes from ? You may want to make a habit of posting complete code.
But, if you read the documentation on document.querySelector, you see that it only returns the first element with the specified selector.

I used this

HTML:
<body onLoad="init()">
<img class="glass" id="1"><img>
<img class="glass" id="2"><img>
<img class="glass" id="3"><img>
<img class="glass" id="4"><img>
<img class="glass" id="5"><img>
</body>

and

JavaScript:
function init()
{
    for (var glass of document.getElementsByClassName('glass') )
    {
        glass.src = "glass_empty.jpg";
        glass.addEventListener("click", set);
    }
}

The event listener here is called set(). I never use those awful anonymous arrow functions.
This should hopefully get you a bit further.
 
I'm completely lost here. I've been searching the internet for possible solutions for another two hours but if I click a <img> nothing happens. I think I'll just use something simpler like a range input for now and start the JavaScript course on FreeCodeCamp and then come back to this when I know some basic JavaScript. I still appreciate your help a lot! Anyway, here's the code I ended up with:

HTML:
<div class="container" onload="init()">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="1">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="2">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="3">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="4">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="5">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="6">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="7">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="8">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="9">
    <img src="/Pictures/glass_empty.jpg" class="glass" id="10">
</div>

JavaScript:
function init(){
    for (var glass of document.getElementsByClassName('glass'))
    {
        glass.src = "glass_empty.jpg";
        glass.addEventListener("click", set);
    }
}

function set(){
    var id = this.id;
    for (var glass of document.getElementsByClassName('glass')){
        if (glass.id <= id){
            glass.src = "/Pictures/glass_full.jpg";
        }
        else{
            glass.src= "/Pictures/glass_empty.jpg";
        }
    }
}

I hope I havn't forgotten any code this time but if I have: I've uploaded the entite project onto GitHub
 
You are on the right track, but why have you put the onload="init()" in your container div ? It's never going to be called - a div does not have an onload event. Look at the code I provided you. It's supposed to go in the <body>. Here's a tip : whenever you first write a function, put an alert() or console.log() statement at the beginning so you know for sure whether it is being called or not. There are two other mistakes here but we'll do one at a time.
 
I've put the onload="init()" on the body but now I have two new problems:

1. When the page is loaded the first time, the images don't load and in the google chrome console is the error message:
1675280753267.png

2. The last glass isn't doing what it is supposed to do. It is selected even though it shouldn't be and if I want to select the 10nth glass only the first and last glass get selected.
Here's a video to show you what I mean: Google Drive


The code is still the one from my previous post except the onload="init()"
 
I've fixed both problems now:

1. The pictures didn't load because I defined the wrong path
(i used
JavaScript:
glass.src="glass_empty.jpg"
but should have used
JavaScript:
glass.src="/Pictures/glass_empty.jpg"
)

2. The <img> element now have the IDs from 0 to 9 instead of 1 to 10 and now it works properly. But once I add an 11nth glass I run into the same problem but I don't really care because I only need ten glasses anyway. But I still wonder why once the ID gets to 10 it just doesn't work anymore.

But huge thanks to you, without your help I couldn't have done it!
 
Right, that was the 3rd mistake I was going to tell you.
The second mistake I w3as going to tell you explains why glass 10 is selected when you click any glass it should not. It's because you are comparing strings here :

if (glass.id <= id){

and "10" is smaller than "2" or "9".

Change this to

if (Number(glass.id) <= Number(id)){

and it works fine.

So you need only 10 glasses. Easy enough to cdreate the HTML for that. But just imagine you'd need 1000, then you'd want to create them dynamically:

JavaScript:
var numGlasses = 1000;
function init()
{
    for (let count = 1; count <= numGlasses; count++)
    {
        var glass = document.createElement('img');
        glass.classList.add('glass');
        glass.src   = "glass_empty.jpg";
        glass.id    = count;
        glass.addEventListener("click", set);
        container.appendChild(glass);
    }
}


HTML:
<body onLoad="init()">
<div id="container">
</body>
 

Attachments

  • a.jpg
    a.jpg
    232.8 KB · Views: 2
Solution

Buy us a coffee!

Back
Top Bottom