Search code examples
javascripthtmlparametersget

Adding more than one GET value in the href


I got this HTML with several unordered lists.

<ul>
    <h3>Staff</h3>
    <li><a href="?staff=Mike">Mike</a></li>
    <li><a href="?staff=John">John</a></li>
    <li><a href="?staff=Kyle">Kyle</a></li>
</ul>
<ul>
    <h3>Category</h3>
    <li><a href="?category=Food">Food</a></li>
    <li><a href="?category=Sports">Sports</a></li>
    <li><a href="?category=News">News</a></li>
    <li><a href="?category=Games">Games</a></li>
    <li><a href="?category=GIFs">GIFs</a></li>
</ul>

As can be seen, all of them contains with params values in each of its hrefs. My question is: using Javascript, how can I append a new value in a param in the href if one of them are actives in the URL.

IE: The URL is www.site.com/?category=Food.

So the lists should be valued as:

<ul>
    <h3>Staff</h3>
    <li><a href="?category=Food&staff=Mike">Mike</a></li>
    <li><a href="?category=Food&staff=John">John</a></li>
    <li><a href="?category=Food&staff=Kyle">Kyle</a></li>
</ul>
<ul>
    <h3>Category</h3>
    <li><a href="?category=Food">Food</a></li>
    <li><a href="?category=Food,Sports">Sports</a></li>
    <li><a href="?category=Food,News">News</a></li>
    <li><a href="?category=Food,Games">Games</a></li>
    <li><a href="?category=Food,GIFs">GIFs</a></li>
</ul>

Solution

  • What you can do is

    1. Parse the current query string into an URLSearchParams object
    2. For each <a> element, parse the href into an URL object
    3. Iterate the query params from step #1 and...
      1. Check if the param already exists
      2. If it does not, simply append it
      3. If it does, then parse the current list into a Set, add the value from the query string, then write the value back into the URL
    4. Write the URL into the <a> href property

    //const query = location.search
    const query = "?category=Food" // this is for the snippet
    
    // Parse any CSV values into arrays and store in a `Map`
    const params = new Map()
    for (let [ key, val ] of (new URLSearchParams(query))) {
      params.set(key, val.split(","))
    }
    
    const links = document.querySelectorAll("ul li a[href]")
    
    links.forEach(link => {
      const url = new URL(link.href)
      
      // Loop the page query params
      for (let [ param, values ] of params) {
        if (url.searchParams.has(param)) {
          // Split the current value on "," and parse to a `Set`
          const linkParams = new Set(url.searchParams.get(param).split(","))
          
          // Add the query string value then write the param back into the URL
          values.forEach(v => linkParams.add(v))
                
          url.searchParams.set(param, [...linkParams].join(","))
        } else {
          // Simply append the param value 
          url.searchParams.append(param, values.join(","))
        }
      }
      link.href = url
    })
    /* This just makes it easy to see the URLs in the demo */
    a[href]:after {
      content: " - " attr(href);
      font-size: .8;
      color: grey;
    }
    <ul>
        <h3>Staff</h3>
        <li><a href="?staff=Mike">Mike</a></li>
        <li><a href="?staff=John">John</a></li>
        <li><a href="?staff=Kyle">Kyle</a></li>
    </ul>
    <ul>
        <h3>Category</h3>
        <li><a href="?category=Food">Food</a></li>
        <li><a href="?category=Sports">Sports</a></li>
        <li><a href="?category=News">News</a></li>
        <li><a href="?category=Games">Games</a></li>
        <li><a href="?category=GIFs">GIFs</a></li>
    </ul>