0

I am making a checklist form and currently i am able to append the value of the selected boxes to the url in I feel an inefficient way and the main issue is that the state of the checkbox doesnt save either so a user cant see what they checked or uncheck.

This is the html code

<form id="carForm" method="get">
    <label>BMW</label>
    <input type="checkbox"  value="bmw" onChange="checkboxChanged()">
    <label>mercedes</label>
    <input type="checkbox"  value="mercedes" onChange="checkboxChanged()">
    <label>honda</label>
    <input type="checkbox"  value="honda" onChange="checkboxChanged()">
    <label>toyota</label>
    <input type="checkbox"  value="toyota" onChange="checkboxChanged()">
</form>

This is the script to make the url

let form = document.getElementById("carForm")

        let checkboxes = document.getElementsByTagName("input")
       var vals = "";

       let formSubmit = () => {               
           for (var i=0, n=checkboxes.length;i<n;i++) 
           {
               if (checkboxes[i].checked) 
               {
                   vals = checkboxes[i].value
                   // append checkbox values to url   
                   var url = window.location.href; 
                    if (url.indexOf('?') > -1){
                    // if a paramter already exists, append using 
                    url += `&make=${vals}`
                    }else{
                    url += `?make=${vals}`
                    }
                    window.location.href = url;
                }
                console.log(vals);
            }
    }

    function checkboxChanged() {
        formSubmit()
        }     
</script>

So for instance if kia and honda were selected the url would be

/inventory?make=kia&make=honda

So if this is inefficient whats a better way of doing this and how do i ensure the checkbox state is persisted after the page is reloaded I am using nodejs/expressjs on server side and ejs

Potato
  • 509
  • 1
  • 6
  • 17

4 Answers4

1
var makes=[];
...
for (var i=0;i<checkboxes.length;i++) {
  if (checkboxes[i].checked) makes.push(checkboxes[i].value);
}
...
url+='&makes='+makes.join(',');

This will give you a comma delimited list; you can string split it on the server side.

Ian Heisler
  • 111
  • 6
1

You should take a look at URLSearchParams. Using it, you could do something like this:

const searchParams = new URLSearchParams(location.search);
document.querySelector('input[type=checkbox]').forEach(cb => {
  if (cb.checked) {
    searchParams.append('make', cb.value)
  }
});
location.href = location.href.replace(location.search, '?' + searchParams.toString())
Titus
  • 22,031
  • 1
  • 23
  • 33
0

I think that you should not define all the parametres of the url as make=..., but with ${vals}=checked. Then you can read it easily with php and just check the names that are defined, but you will have to define a name for your chackboxes.

Sorry for my approximative english, I am swiss and speak french.

niaou suzanne
  • 43
  • 1
  • 9
0

If you have access to a server-side language, like PHP, use that to check the URL and auto-check the boxes when the page loads. Something along these lines:

<?php
$bools = [
 "kia" => isset($_GET['kia']),
 "bmw" => isset($_GET['bmw']),
 "mercedes" => isset($_GET['mercedes']),
 "toyota" => isset($_GET['toyota'])
];
?>
<form id="carForm" method="get">
  <label>BMW</label>
  <input type="checkbox" value="bmw" onChange="checkboxChanged()" <?= $bools['bmw'] ? 'checked' : '' ?>>
  <label>mercedes</label>
  <input type="checkbox" value="mercedes" onChange="checkboxChanged()" <?= $bools['mercedes'] ? 'checked' : '' ?>>
  <label>honda</label>
  <input type="checkbox" value="honda" onChange="checkboxChanged()" <?= $bools['honda'] ? 'checked' : '' ?>>
  <label>toyota</label>
  <input type="checkbox" value="toyota" onChange="checkboxChanged()" <?= $bools['toyota'] ? 'checked' : '' ?>>
</form>

Protip: In PHP, you can use value="car[]" in order to submit an array of values which will already be an array type in PHP!


If you don't have access to server-side, or you don't wish to use it, then check the URL on page-load:

window.onload = () => {
  for (const el of checkboxes) {
    // Check the URL's params:
    // From link below
    const urlParams = new URLSearchParams(window.location.search);
    const myParam = urlParams.get(el.value);

    if (myParam != null) {
      el.checked = true;
    }
  }
}

(Get URL params reference, there are more options with better support than what I used. I just used the simplest option)

matthew-e-brown
  • 2,837
  • 1
  • 10
  • 29
  • I am using nodejs/express.js and EJS, do you know what the equivalent solution would look like then, do i just pass the values back from server side into the ejs template and then do something similar?And would this type of solution work when a user unchecks ? Also is the way i appended to the url a good solution? – Potato Nov 18 '19 at 21:13
  • I'm not too familiar with Express, but in the small tinkering I've done I know you can pass variables to EJS and do things that way. Something like `res.render('page.ejs', { kia: true, bmw: true });` (don't quote me on that). See this: https://stackoverflow.com/a/14201112/10549827. -- Your code could be optimized a little bit, but as for your actual method of setting the URL, it's pretty good. There are more modern solutions (https://stackoverflow.com/a/58922710/10549827) but using them will reduce your browser support. Your's is solid and should work well. Maybe try some `for of` loops. – matthew-e-brown Nov 18 '19 at 21:19