0

I'm trying to use JavaScript to add parameters to the current URL in order to filter WordPress posts. Example: http://domain.com/houses/?rooms=1,2&bath=1&yard=yes

I have successfully done this with one of the parameters, but I'm failing in understanding how to add on multiple parameters. What is the proper way of getting this one?

Also, is using window.location.assign(), the proper way for adding the parameters to the URL? Is using AJAX better/safer?

Below is my code

HTML

<div id="filter-rooms">
       <ul>
           <li>
               <input type="checkbox" value="1" id="rooms" />1 Room</li>
           <li>
               <input type="checkbox" value="2" id="rooms" />2 Rooms</li>
           <li>
               <input type="checkbox" value="3" id="rooms" />3 Rooms</li>
           <li>
               <input type="checkbox" value="4" id="rooms" />4 Rooms</li>
      </ul>
</div>

<div id="filter-bath">
    <ul>
        <li>
            <input type="checkbox" value="1" id="bath" />1 Bathrooms</li>
        <li>
            <input type="checkbox" value="2" id="bath" />2 Bathrooms</li>
        <li>
            <input type="checkbox" value="3" id="bath" />3 Bathrooms</li>
    </ul>
</div>

<div id="filter-yard">
    <ul>
        <li>
            <input type="radio" name="yard" value="yes" id="yard" />Yes</li>
        <li>
            <input type="radio" name="yard" value="no" id="yard" />No</li>
    </ul>
</div>

JavaScript

$('#filter-rooms').on('change', 'input[type="checkbox"]', function () {

    var $ul = $(this).closest('ul'),
        vals = [];

    $ul.find('input:checked').each(function () {

        vals.push($(this).val());

    });

    vals = vals.join(",");

    window.location.assign('?rooms=' + vals);

});

Now, in the JavaScript displayed above, I managed to get the rooms parameter successfully working, but when I duplicate this for the other parameters, it replaces the URL with the rooms parameter instead of adding it on to the end of the URL like so - &bath=1&yard=yes

jsFiddle: http://jsfiddle.net/g9Laforb/1/ (Note: window.location.assign() is missing because jsFiddle doesn't allow it.)

Any advice on this would be greatly appreciated.

iammikerodriguez
  • 379
  • 1
  • 5
  • 16

3 Answers3

3

First, do not use the same id on multiple elements. See Why is it a bad thing to have multiple HTML elements with the same id attribute?

Your problem is with this line

 window.location.assign('?rooms=' + vals);

You need to dynamically update the query string.

Using this method

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  }
  else {
    return uri + separator + key + "=" + value;
  }
}

from add or update query string parameter

and custom attributes like

<ul data-type="rooms">

you can do

window.location.href = updateQueryStringParameter(window.location.href, $ul.attr('data-type'), vals);

instead of

window.location.assign('?rooms=' + vals);
Community
  • 1
  • 1
AmmarCSE
  • 30,079
  • 5
  • 45
  • 53
  • AmmarCSE, thanks for the advice. I actually didn't realize I was using the same ID on multiple elements. As far as the JavaScript, I'm a little confused as how this works. I tried implementing this and the the URL did not update at all. Should the first parameter inside the updateQueryStringParameter method be window.location or window.location.assign? – iammikerodriguez May 28 '15 at 05:02
  • @iammikerodriguez, sorry, my mistake. Use window.location.href – AmmarCSE May 28 '15 at 05:05
  • AmmarCSE, Unfortunately, it's still not adding the parameters to the URL. – iammikerodriguez May 28 '15 at 05:12
  • 1
    @iammikerodriguez, try window.location.href = updateQueryStringParameter(..... instead of updateQueryStringParameter(.... by itself – AmmarCSE May 28 '15 at 05:16
  • AmmarCSE, that worked in getting the page to reload, but instead I'm getting this when the URL changes: /rooms?1=undefined instead of /?rooms=1 – iammikerodriguez May 28 '15 at 05:19
  • @iammikerodriguez, this is because the `vals` you are passing in is undefined – AmmarCSE May 28 '15 at 05:21
  • AmmarCSE, When I console.log the `vals`, I'm successfully getting the defined values. The format of the added parameters is wrong. I'm should be getting `domain.com/houses/?rooms=1` but instead I'm getting `domain.com/houses/rooms?1=` – iammikerodriguez May 28 '15 at 05:25
  • @iammikerodriguez, can you reproduce it in a fiddle? – AmmarCSE May 28 '15 at 05:26
  • AmmarCSE, jsFiddle filters out the window.location line, but here is a fiddle of the rest of the code http://jsfiddle.net/p73zvnaL/2/ CodePen, doesn't filter it out, however. http://codepen.io/anon/pen/waoLyz – iammikerodriguez May 28 '15 at 05:34
  • @AmmarCSE - console.log is correctly spitting out the values. Here is the updated jsFiddle link: http://jsfiddle.net/p73zvnaL/3/ – iammikerodriguez May 28 '15 at 06:01
  • @iammikerodriguez, no I mean, see the console.log(test) at the end of http://jsfiddle.net/p73zvnaL/2/ it is correctly changing the url – AmmarCSE May 28 '15 at 06:22
  • @AmmarCSE Sorry, there isn't any console.log statement at the end of http://jsfiddle.net/p73zvnaL/2/ I think jsFiddle is removing it – iammikerodriguez May 28 '15 at 06:24
  • 1
    @iammikerodriguez, wow your right! sorry. Ok, put this at the end: var test = window.location.href = updateQueryStringParameter(window.location.href, $ul.attr('data-type'), vals); console.log(test); – AmmarCSE May 28 '15 at 06:26
  • Thanks for that. It's showing the URL now. Just have to work out some bugs on it. – iammikerodriguez May 28 '15 at 06:39
  • @iammikerodriguez, ok, let me know if you get stuck – AmmarCSE May 28 '15 at 06:39
1

Try this : define variables to store rooms, bath and yard selected values and create url accordingly in each change handler of inputs.

roomVal = '';
bathVal = '';
yardVal = '';

$('#filter-rooms').on('change', 'input[type="checkbox"]', function () {
     roomVal = $(this).closest('ul').find('input[type="checkbox"]:checked').map(function(i,v){
        return $(this).val();
    }).get();

    window.location.assign('?rooms=' + roomVal + '&bath='+bathVal+"&yard="+yardVal);
});

$('#filter-bath').on('change', 'input[type="checkbox"]', function () {
     bathVal = $(this).closest('ul').find('input[type="checkbox"]:checked').map(function(i,v){
        return $(this).val();
    }).get();

    window.location.assign('?rooms=' + roomVal + '&bath='+bathVal+"&yard="+yardVal);
});

$('#filter-yard').on('change', 'input[type="radio"]', function () {
     yardVal = $(this).closest('ul').find('input[type="radio"]:checked').map(function(i,v){
        return $(this).val();
    }).get();

    window.location.assign('?rooms=' + roomVal + '&bath='+bathVal+"&yard="+yardVal);
});

JSFiddle Demo

Bhushan Kawadkar
  • 28,279
  • 5
  • 35
  • 57
  • This method works, but it keeps replacing the clearing the URL parameters every time new parameter is added on. – iammikerodriguez May 28 '15 at 04:57
  • 1
    To avoid this, you can just assign values to `roomsVal`, `bathVal` and `yardVal` in each change handler and when you do ajax call that time create your `window.location.assign` using these variables. – Bhushan Kawadkar May 28 '15 at 05:02
0

You can simply do it with window.location.href If you have any value stored in a variable, you can use the + symbol to concatenate the value.

var somedata = somedata;

window.location.href = "http://www.yourwebsite.com?data1=somedata&data2="+somedata;
Abhinav
  • 8,028
  • 12
  • 48
  • 89