-1

I have the following (partial) code:

<input type="checkbox" id="myCheck">
span class="checkmarkz"></span>

<a href="test.zip" class="download" onclick="return ifchecked()">One-time download!</a>

<script>
        function ifchecked() {
            if (document.getElementById('myCheck').checked) {
                return true;
            } else {
                let warning = document.getElementById('warning');
                warning.style.display = "block";
                return false;
            }
        }
</script>

I would need that after the download, the user is redirect to success.php.

NOTE: I know there are other questions were users ask for redirect after download link, but in this case I have already onclick="return ifchecked()", then I don't know how to or where I could add a redirect since I need to check the checkbox first. Please consider this before giving me -1 or -2 or -3. Please be kind. Thank you.

Red
  • 63
  • 6

1 Answers1

3

Don't use inline HTML event attributes in the first place as this is a 25+ year old event wiring technique that just will not die because people just keep copying other people's code.

Instead, use the modern approach, which is .addEventListener(). With this method, you can register multiple event listeners to the same event and the listeners will fire in the order that you've registered them.

Here's an example:

const btn = document.querySelector("button");

btn.addEventListener("click", foo1); // Register 1st handler
btn.addEventListener("click", foo2); // Register 2nd handler
btn.addEventListener("click", foo3); // Register 3rd handler

function foo1(){
  console.log("foo1");
}

function foo2(){
  console.log("foo2");
}

function foo3(){
  console.log("foo3");
}
<button type="button">Click Me</button>

But, in your use case, you don't seem to need multiple callbacks. You'd do something like this:

// Get DOM references just once, not everytime the function runs
const label = document.querySelector("label");
const chk = document.getElementById('myCheck');
const warning = document.getElementById('warning');
const link = document.querySelector(".download");
const success = document.querySelector("#success");

// Set up the event callback
link.addEventListener("click", ifChecked);

function ifChecked(event) {
  event.preventDefault();  // Cancel the click event on the link
  
  // Check to see if the checkbox is checked
  if (chk.checked) {
    link.click();  // Begin the download
    warning.classList.add("hidden");    // Hide the warning
    label.classList.add("hidden");      // Hide the checkbox and link
    success.classList.remove("hidden"); // Show the success message
  } else {
    warning.classList.remove("hidden");  // Unhide the warning
    chk.focus();   // Set the focus on the checkbox
  }  
}
.hidden { display:none; }
<label>
  <input type="checkbox" id="myCheck">
  <a href="test.zip" class="download">One-time download!</a>
</label>
<span id="warning" class="warning hidden">You must agree by checking the checkbox.</span>
<span id="success" class="hidden">Congrats!</span>

Keep in mind that this code won't actually prevent someone from downloading the file more than once if they really want to. All they'd have to do is look at the source code of the page and see the path and file name of the download file and then manually navigate to that location. If you really want to secure the file, you'd need some kind of server-side validation.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Thank you Scott! That was very instructive. I'm trying, but I can't manage to understand how to make addEventListener check if the checkbox is checked (if not make appears the warning) and if checked to let the download start. Can't manage sorry. – Red Mar 16 '23 at 17:48
  • @Red I've updated my answer to show your use case. – Scott Marcus Mar 16 '23 at 18:55
  • Hi Scott, Thank you very much for your code that actually will be a good reference for me for the future. I'm using your code and the download does not start, I click on the checkbox, I click on the link, and "Congrats" appear, but no download, why is that? About what you said, my download page will be active until the user download the file, once the user download the file the page will be inactive (because of a value in mysql) and the file will be deleted. – Red Mar 17 '23 at 10:53
  • Hi @Scott I think I will do in this way: if the checkbox is checked, I redirect the user to success.php, in success.php I will let the download automatically start with "document.getElementById('download').click();" and I will update the database mysql accordingly. – Red Mar 17 '23 at 11:34