Reputation: 47
I have two buttons that call the same JavaScript function but with a different argument. When I test them independently, they work fine. However, when they're together, only the "next" button works. I'm not sure what I'm doing wrong.
if (fbResults.collection.links[p].prompt == "Previous") {
var linkBack = "" + fbResults.collection.links[p].href;
nextBtnDiv.innerHTML += "<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>";
document.getElementById("prevBtn").onclick = function () { findImages(linkBack); };
}
if (fbResults.collection.links[p].prompt == "Next") {
var linkForward = "" + fbResults.collection.links[p].href;
nextBtnDiv.innerHTML += "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";
document.getElementById("nextBtn").onclick = function () { findImages(linkForward); };
}
Upvotes: 1
Views: 714
Reputation: 1075
Read on if you want specifics about why you're getting this behavior. If you want a quick solution, try creating and appending DOM elements instead of directly manipulating innerHTML
:
const prevBtn = document.createElement("a");
prevBtn.id = "prevBtn";
prevBtn.name = "prevBtn";
prevBtn.class = "button1";
prevBtn.type = "button";
prevBtn.innerHTML = "Previous";
const nextBtn = document.createElement("a");
nextBtn.id = "nextBtn";
nextBtn.name = "nextBtn";
nextBtn.class = "button1";
nextBtn.type = "button";
nextBtn.innerHTML = "Next";
for (let p = 0; p < 2; p++) {
if (fbResults.collection.links[p].prompt == "Previous") {
var linkBack = "" + fbResults.collection.links[p].href;
prevBtn.onclick = function () { findImages(linkBack); };
nextBtnDiv.appendChild(prevBtn);
}
if (fbResults.collection.links[p].prompt == "Next") {
var linkForward = "" + fbResults.collection.links[p].href;
nextBtn.onclick = function () { findImages(linkForward); };
nextBtnDiv.appendChild(nextBtn);
}
}
A few things going on here. First, type="button"
is not a valid type in an <a>
tag. It is for describing the media type you're linking to. So you would usually use a <button>
for that type of function call (which I'm assuming is for pagination).
Second, when playing around with your code I realized I made a mistake that you might have made as well: I gave the <div>
surrounding the buttons an id="nextBtn"
, then called the variable I found using that nextBtnDiv
, like you did. The problem with that is that HTML expects id
s to be unique, and when you use document.getElementById
to get an element in the DOM, you will get the first element that matches that id
at best, and undefined behavior at worst. See this question for more info on that.
So if both anchor tags end up triggering the "Next" link, it is because you're probably giving the whole <div>
(which contains both buttons), rather than the next button itself, the onclick
handler.
Finally, if you fix that issue, you'll still see that your previous button does nothing when clicked. Here's why:
nextBtnDiv.innerHTML += "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";
This line basically means "make nextBtnDiv.innerHTML
be equal to nextBtnDiv.innerHTML
plus "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>"
". The problem is a bit tricky. It is recreating both <a>
tags, not just adding the "next" one, to the <div>
. That's because of the +=
semantics and how they work, but basically once you have new buttons the previous one gets overwritten and you lose the onclick
handler you attached to it.
One of the ways to get around this is to recreate the "previous" click behavior once you create the behavior for the "next" button. Like in the following snippet:
const nextBtnDiv = document.getElementById("nextBtnDiv");
const fbResults = {
collection: {
links: [
{ prompt: "Previous", href: "previous" },
{ prompt: "Next", href: "next" },
],
},
};
for (let p = 0; p < 2; p++) {
if (fbResults.collection.links[p].prompt == "Previous") {
var linkBack = "" + fbResults.collection.links[p].href;
nextBtnDiv.innerHTML += "<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>";
document.getElementById("prevBtn").onclick = function () { findImages(linkBack); };
}
if (fbResults.collection.links[p].prompt == "Next") {
var linkForward = "" + fbResults.collection.links[p].href;
nextBtnDiv.innerHTML += "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";
document.getElementById("prevBtn").onclick = function () { findImages(linkBack); };
document.getElementById("nextBtn").onclick = function () { findImages(linkForward); };
}
}
function findImages(link) { console.log(`Clicked ${link} button`); }
<div id="nextBtnDiv"></div>
Upvotes: 2
Reputation: 3563
You are overwriting your first assigned a-tag node:
nextBtnDiv.innerHTML +=
"<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>";
is creating new nodes. So at the second time
nextBtnDiv.innerHTML +=
"<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";
it is the same as
nextBtnDiv.innerHTML =
"<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>"
+ "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";
but now you are removing the first assigned node and its listeners
It is better to create a node and append it like:
let a = document.createElement('a');
// set a attr ...
nextBtnDiv.appendChild(a);
Upvotes: 1