Javascript only runs last function

I have a playlist produced dynamically by a user from an sql database. I want to change the colour of the background from a button with onclick(). The idea of the div comes from the song name as a variable from sql. I have used the variable in the javascript and in the html div. Each time I click the button it is only the last name that is changed. I’m very much a newbie (62 yr old home coder) but trying to learn. Here is the code from the website: 2 records

<form>
            <table>
                <tr>
                    <td>
                        <div id="angelscall">angelscall</div>
                    </td>
                    <td>
                        <button id="allchange" type="button" onclick="changecolor()">Change Colour</button>
                </tr>
            </table>
            <script>

            function changecolor() {
                document.getElementById("angelscall").style.backgroundColor = "green";
            }
            </script>

            <table>
                <tr>
                    <td>
                        <div id="merkabah">merkabah</div>
                    </td>
                    <td>
                        <button id="allchange" type="button" onclick="changecolor()">Change Colour</button>
                </tr>
            </table>

            <script>

            function changecolor() {
                document.getElementById("merkabah").style.backgroundColor = "green";


            }
            </script>

        </form>

Here is my html/javascript coding: I use the php include so that all the ids and javascript are in the same place

<?php $track = strtolower(str_replace(' ', '', $row['wcpmusic']));?>
<?php echo $track;?>
Change Colour

This is the html where the above script is called testtrack.php :

<?php $etitle= $row['etitle'];?> <?php $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) or die('Error connecting to MySQL server.'); $query = "SELECT * FROM workshopcontrolpanel WHERE wcpevent = '$_POST[bevent]' ORDER BY wcpmusic ASC "; $result = mysqli_query($dbc, $query) or die('Error querying first database.'); while ($row = mysqli_fetch_array($result)) { ?> <?php include("testtrack.php"); ?> <?php } mysqli_close($dbc); ?>

I hope this makes sense. I tried to ask this question on stack overflow but all I got was criticism about how I code and not asking correctly! I’m hoping this place is a little more friendly.

Regards

Andrew

1 Like

You will certainly not find a friendlier community than this one! Welcome.

Well, I am not knowledgeable in technologies other than HTML, CSS and JS, but I can already see a small issue with the code. There are duplicate id’s, which are not acceptable in JS:

If you’re trying to create multiple buttons, that each change their respective div’s background-color, I would recommend giving each button a unique id, just as you did for the divs.

Also, all your JS can be inside one script tag — there’s no need to make multiple. Just make sure each function is unique. If you have one function called changeColor changing a div to green, and another function also called changeColor changing another div to green, the computer doesn’t know which function to choose when you call it, as both have the same name. Since you’re changing all the elements to green, you can use only one function for this, with a parameter for the element you’re changing. See my example:

function changeColor(element) {
  element.style.backgroundColor = "green";
}

See? Now you can reuse this function for whatever element you need to turn green, for example like this:

function changeColor(document.getElementById("merkabah"));

And it would be equivalent to doing this:

function changeColor(document.getElementById("merkabah")) {
 document.getElementById("merkabah").style.backgroundColor = "green";
}

I hope you understand. If you find yourself getting stuck very often over basic tasks, it might be a good idea to refresh some JS basics. Even an hour of some quick reading and practicing can make a huge difference if you focus. This is a rather helpful video from the fCC curriculum for the bare basics. There is further instruction and exercises later in the course:

Basically, if you see a lot of repetition in your code (such as changing divs to the color green over and over again), it might be time to work smarter instead of harder and build a handy function.

Hope you fix the issue. I don’t have your complete code running, so there might be a few more issues. But making sure there are no duplicate id’s is a good place to start.

Happy coding!

Hi Nicking

That you so much for that. I understand exactly what you are saying. It didn’t dawn on me that the unique ID applied to all elements not just the div I was working on. I’ll have a go at amend my code and let you now. Also thank you for the link to the vid. :slight_smile:

1 Like

I’m so glad you understood what I was saying, as I was afraid I was a bit hard to understand. Your welcome! And let us know if it works.

Good luck!

Good Day Nick

Thank you for your help yesterday. I thought I understood what you said but I still can’t get it to work. I have taken a screen shoot from the view source and part of the webpage. I removed the id from the button ( I will use class instead) the source window is not sowing errors now but when I click on the button it only changes the last div. The source code has unique ids and the function refers to the unique id. I can’t see what’s wring with the logic. Have a missed an instruction in the function. I have e tried putting return or exit but that made no difference. Can you see where I’ve gone wrong. Many thanks. Andrew

1 Like

My deepest apologies, @AndrewRHelme, for not responding earlier — I was swamped with work yesterday and was unable to thoroughly reply to you.

So, at first glance at your code, I see you are creating two functions with the same name. This is not acceptable in JS, since creating a function is practically creating a variable. And you can’t have two variables with the same name, right?

Now, I understand your thinking, that perhaps by putting them into two separate script tags, each underneath the respective table, the functions will run independently of one another. But unfortunately, the functions are defined globally, which means they’ll spill into any other script tag on the HTML document.

The solution? First of all, I’d remove the multiple script tags. Most often, especially for inline scripts like this, you only need one script tag, placed right before the closing tag of the body element. So I’d open a new script tag right before the closing tag of the body element, copy all the existing code inside your other script elements into there, and delete those other script elements.

Then, I’d make sure each function, in this case your two changecolor() functions, have unique names, since they’re doing different things. Something like changeColorAngelscall() and changeColorMerkabah(), or whatever else you’d like. As long as they’re unique. They must be, since they’re doing different things.

It should work, unless of course there is something else I missed in your code. But given that the first one works and not the second, I’m quite confident the only problem is your duplicate function name.

Now, even if this works, it might be worth asking, is this the best way to go about this? You’re basically defining a new function for every new element you want to change green upon click. You could create a reusable function to accomplish this, as I showed in my earlier post. This would mean less redundant code, which is something coders should always strive for, not to mention better readability. However, if this is one of your first-ever projects and you just want to wet your feet, so to speak, in JS, technically, it will work if you keep it as it is and define new functions for every element. So don’t worry about it, but consider venturing out there and seeing if you can make a reusable function. Once you do it a couple of times, you’ll really get the hang of it and understand the power of programming to accomplish a lot in only a few lines of code.

Also, just a small thing, define your functions and variables with camelCase. It’s good practice, and makes things much more readable.

Hope you find my suggestions successful. Do let me know if you have any questions.

Nicolas

Hi Nicholas

Sorry for the delay in getting back . Storm Eowyn hit the UK on Friday and took out our power and broadband. We only just got power back last night but the broadband is still out - I’m running on 10mb mini hub which links into the local 3/4G - bit slow but better than nothing.

Thanks so much for getting back to me and being patient enough to explain. I think I got it this time as it worked when I added the variable to the function name both at the onclick position and the function name. However, if I keep the script with the include statement (testtrack.php) the colour change works but if I put the script at the bottom of the page (attendance register.php) I’m back to only having the last div change colour.

I started down this route as a test for myself to try and access each instance of the button with javascript. What I really want to do is add an auto fade button to the HTML Audio tag. As you might have guessed the variable names are songs and the user wants to be able to fade the song. I was having great difficulty especially with all other (play/pause/volume/seek etc) associated audio code. I think I will end up using the audio control and adding the fade button as an extra.

I started to watch some of the video links you sent but got lost with the jargon so I’ve been going though the w3schools javascript lessons. It’s beginning to make sense :slight_smile:

Many thanks again for your help and I promise not to pester you with anymore questions. I shall just post to the community (if that’s the correct process). Have a good week and don’t work too hard :slight_smile:

Regards

Andrew

1 Like

Hello again, Mr. @AndrewRHelme!

No problem about the delay. I’m offline on Sundays anyway!

I’m so glad to hear it worked (kind of). It can be tricky to deal with all those user interactions with JS, especially if there’s a lot of them. DOM manipulation (basically manipulating HTML elements with JS is what that means) is decidedly inefficient in many respects. It requires a lot of attention to detail to get it right.

So, I don’t perfectly understand your file structure on the document, and I don’t have any experience with PHP, but in general, the order of succession for all these technologies on a single webpage should be as following:

  1. HTML first. It’s like the structure of your webpage in the most fundamental way. Every browser needs it as a foundation to use any other technology or language.

  2. The load the PHP. It should come from the server, and many times generates dynamic content that will be manipulated with the JS. This is why it is paramount that PHP comes before the JS, as the JS cannot manipulate content that hasn’t been loaded yet.

  3. JS should come last. That’s why it should be at the very bottom of your body element, right before the closing tag. Adding individual script tags in between different elements in the body is likely to cause some issues.

  4. If you really need to, for some reason, put your JS in the head element, you should put all your code inside an event listener that will wait for all the elements to load before executing your JS. That’s quite easy to do:

document.addEventListener('DOMContentLoaded', () => {
    // All your JavaScript logic here
});

That might explain some of the strange behavior you’re seeing by moving around the order of succession of the different parts of your code. Just a guess. It could also be duplicate variables again, or duplicate IDs. They sneak up on the best of us!

It looks like you’re making a fully functional audio player web app with all the controls needed for audio playback plus an auto-fade feature. I think this is a really cool project idea! Also, I don’t know if you know this already or not, but you’ll probably need to use the Web Audio API for this. According to MDN,

The Web Audio API provides a powerful and versatile system for controlling audio on the Web, allowing developers to choose audio sources, add effects to audio, create audio visualizations, apply spatial effects (such as panning) and much more.

I think it’s exactly what you need. And it’s built into vanilla JS already, so there’s no installations or anything to worry about. Just pure JS functions just waiting to be put to use.

I found it rather complicated to use, and I’m sure you’ll have some difficulty figuring out how to set up audio manipulation in JS. However, once you do, it’s powerful enough to do practically anything from a basic music player to a DJ controller. It’s most certainly worth the headache.

One good way to get introduced to this kind of project is a small practice project using this very API in the fCC curriculum. Here’s a link to it:

It will really help you with DOM interaction, such as button clicks, event listeners and element removal, as well as show you the basics of the Web Audio API and how to perform basic functions on an audio track. It will teach you everything as you code, instructing you step by step. I think it’s the perfect project for you. Don’t worry about not understanding many parts. Neither did I, but the idea is to get a picture of how to build such applications. I recommend checking terminology and different functions in the wonderful MDN Docs. They 99% of the time have the answer to every question you have, and are always professional and high-standard.

They might be a bit technical, no doubt, so feel free to use W3Schools too, especially at the beginning, as they’re more beginner-friendly. Just keep in mind the MDN is more professional and detailed.

I get lost in web dev jargon every day, and I’ve been coding for almost a year now. Have no fear. We all experience it, and I promise that if you stick with it, the jargon will actually start to make sense. With studying programming, progress is slow, but inevitable.

Ask as many questions as needed! You’re not pestering any of us. It’s what we’re here for. And yes, don’t hesitate to create a new topic for any new issue that arises. That is the correct process :slight_smile:

Also don’t forget that a little study goes a long way with JS. Even the most gigantic coding projects still use basic functions and conditionals. Master the basics, and the sky is the limit.

All the best to you on your coding journey,

Nicolas

1 Like