3

I am getting stuck on this. I want to make query string on dyanmic filters. Right now i have added to types of filter Select your favorite sports and Select your favorite food: .. So in future it will be more filters and it will be in check boxes type and selectbox only. So i want to make it fully dynamic. Here is my html code:-

<body>
    <select class="getfilterchange" name="hobby">
        <option value="">Select</option>
        <option value="Chess">Chess</option>
         <option value="Hockey">Hockey</option>
    </select>
    <h3>Select your favorite sports:</h3>
    <label><input class="getfilter" type="checkbox" value="football" name="sport"> Football</label>
    <label><input class="getfilter" type="checkbox" value="baseball" name="sport"> Baseball</label>
    <label><input class="getfilter" type="checkbox" value="cricket" name="sport"> Cricket</label>
    <label><input class="getfilter" type="checkbox" value="boxing" name="sport"> Boxing</label>
    <label><input class="getfilter" type="checkbox" value="racing" name="sport"> Racing</label>
    <label><input class="getfilter" type="checkbox" value="swimming" name="sport"> Swimming</label>
    <br>
    <h3>Select your favorite food:</h3>
    <label><input class="getfilter" type="checkbox" value="choclate" name="food"> Choclate</label>
    <label><input class="getfilter" type="checkbox" value="biscuits" name="food"> Biscuits</label>
    <label><input class="getfilter" type="checkbox" value="candy" name="food"> Candy</label>
    <label><input class="getfilter" type="checkbox" value="Cake" name="food"> Cake</label>
    <br>
</body>

Here i have some try to jquery code :-

<script type="text/javascript">
$(document).ready(function() {
    var names = [];
    $(".getfilter").click(function(){
        if(jQuery.inArray($(this).attr('name'), names )=='-1'){
            names.push($(this).attr('name')); 
        }
        var favorite = [];
        $.each($("input[name='"+$(this).attr('name')+"']:checked"), function(){
            favorite.push($(this).val());
        });
        console.log(names);
        console.log(favorite);
    });
});

See image

My expected output is like below

?sport=football~baseball~cricket&food=choclate~biscuits

If user has selected food first then it should be like this :-

?food=choclate~biscuits&sport=football~baseball~cricket

Please help me how can i achieve this type of functionality note :- My filters will be dynamic means if i add more filters it will automatically embedded to query string. In image it's showing Getvalues button.. I want to get query string on click on checkbox. Forget about there is no button. Thanks

5
  • Just use form as a container for your controls and .serialize() method. Commented Jul 8, 2018 at 10:24
  • yes seralize is good method but i want query string to add in url aslo Commented Jul 8, 2018 at 10:26
  • What's problem? You could create query string using form serialization, then use strings concatenation to add the query string to url. Commented Jul 8, 2018 at 10:33
  • Can you post your answer by taking example of my question? Commented Jul 8, 2018 at 10:42
  • Chocolate*..... Commented Jul 9, 2018 at 3:17

2 Answers 2

3

Submit form

The simplest way to build and send request with filter parameters is to submit form that contains the filter's controls to your server that is defined by the form's action attribute value. If you need to apply the filter every time the filter is changed, then just call .submit() method in the form change event handler.

Serialize form

If you need to build request URL manualy, then you could use .serialize() method. Just place your controls to a form, and it will be possible to get query string by the form serialization.

var staticUrl = '/the/path/of/request';
$("#filter").change(function() {
  var queryString = $(this).serialize();
  var url = !queryString ? staticUrl : staticUrl + '?' + queryString;
  console.log(url);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<form id="filter">
  <h3>Select your favorite sports:</h3>
  <label><input class="getfilter" type="checkbox" value="football" name="sport"> Football</label>
  <label><input class="getfilter" type="checkbox" value="baseball" name="sport"> Baseball</label>
  <label><input class="getfilter" type="checkbox" value="cricket" name="sport"> Cricket</label>
  <label><input class="getfilter" type="checkbox" value="boxing" name="sport"> Boxing</label>
  <label><input class="getfilter" type="checkbox" value="racing" name="sport"> Racing</label>
  <label><input class="getfilter" type="checkbox" value="swimming" name="sport"> Swimming</label>
  <br>
  <h3>Select your favorite food:</h3>
  <label><input class="getfilter" type="checkbox" value="choclate" name="food"> Choclate</label>
  <label><input class="getfilter" type="checkbox" value="biscuits" name="food"> Biscuits</label>
  <label><input class="getfilter" type="checkbox" value="candy" name="food"> Candy</label>
  <label><input class="getfilter" type="checkbox" value="Cake" name="food"> Cake</label>
</form>

The result query string is standard. It should be parsed correctly by PHP server. But if you need any special format, you could transform the string using regular expressions. For example, use following to separate several values of same field by ~ character:

var staticUrl = '/the/path/of/request';
var delimiter = '~';
$("#filter").change(function() {
  var queryString = $(this).serialize().replace(/(?<=([^\?\&\=]+=)([^\&\=]+))(\&\1)/g, delimiter);
  var url = !queryString ? staticUrl : staticUrl + '?' + queryString;
  console.log(url);
});

You could see the transformation result using the regex101 snippet.

Note, a zero-width positive lookbehind assertion is used in the regular expression. It requires to browser support ES2018.

Build query string form array

If it is not possible to use a zero-width positive lookbehind assertion, then you could use classical way: transform a set of form elements to an array of names and values using serializeArray method and then build query string from the array.

The serializeArray creates an item for each control. It is possible to group form values by field name using reduce method.

var staticUrl = '/the/path/of/request';
var delimiter = '~';
$("#filter").change(function() {
  var query = $(this)
    // Create array
    .serializeArray()
    // Group array by key name
    .reduce(function(grouped, field) {
      grouped[field.name] = grouped[field.name] || [];
      grouped[field.name].push(field.value);
      return grouped;
    }, {});
  // Build query string
  var queryString = $
    .map(query, function(values, name) {
      return name + '=' + values.join(delimiter);
    })
    .join('&');
  // Build URL
  var url = queryString ? staticUrl + '?' + queryString : staticUrl;
  console.log(url);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="filter">
  <h3>Select your favorite sports:</h3>
  <label><input class="getfilter" type="checkbox" value="football" name="sport"> Football</label>
  <label><input class="getfilter" type="checkbox" value="baseball" name="sport"> Baseball</label>
  <label><input class="getfilter" type="checkbox" value="cricket" name="sport"> Cricket</label>
  <label><input class="getfilter" type="checkbox" value="boxing" name="sport"> Boxing</label>
  <label><input class="getfilter" type="checkbox" value="racing" name="sport"> Racing</label>
  <label><input class="getfilter" type="checkbox" value="swimming" name="sport"> Swimming</label>
  <br>
  <h3>Select your favorite food:</h3>
  <label><input class="getfilter" type="checkbox" value="choclate" name="food"> Choclate</label>
  <label><input class="getfilter" type="checkbox" value="biscuits" name="food"> Biscuits</label>
  <label><input class="getfilter" type="checkbox" value="candy" name="food"> Candy</label>
  <label><input class="getfilter" type="checkbox" value="Cake" name="food"> Cake</label>
</form>

Sign up to request clarification or add additional context in comments.

3 Comments

you are awesome man. Its working very fine thanks a lot... I am unable to give upvote you because i have 13 reputation. If you upvote my question then i will able to upvote your answer
@kunal, the third way has been added.
1

Your html code is perfect and you need some modification in javascript code to get it work.

You also need to push state of updated url with new query string in history. So, you can update url of browser without page load.

$(document).ready(function() {
    var queryStringObject = {};
    $(".getfilter").click(function(){
		var name = $(this).attr('name');
		queryStringObject[name] = [];
        $.each($("input[name='"+$(this).attr('name')+"']:checked"), function(){
            queryStringObject[name].push($(this).val());
        });
		if(queryStringObject[name].length == 0){
			delete queryStringObject[name];
		}
		var queryString = "";
		for (var key in queryStringObject) {
			if(queryString==''){
				queryString +="?"+key+"=";
			} else {
				queryString +="&"+key+"=";
			}
			var queryValue = "";
			for (var i in queryStringObject[key]) {
				if(queryValue==''){
					queryValue += queryStringObject[key][i];
				} else {
					queryValue += "~"+queryStringObject[key][i];
				}
			}
			queryString += queryValue;
		}
        console.log(queryStringObject);
        console.log(queryString);
		if (history.pushState) {
			var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + queryString;
			window.history.pushState({path:newurl},'',newurl);
		}
    });
});
<body>
    <h3>Select your favorite sports:</h3>
    <label><input class="getfilter" type="checkbox" value="football" name="sport"> Football</label>
    <label><input class="getfilter" type="checkbox" value="baseball" name="sport"> Baseball</label>
    <label><input class="getfilter" type="checkbox" value="cricket" name="sport"> Cricket</label>
    <label><input class="getfilter" type="checkbox" value="boxing" name="sport"> Boxing</label>
    <label><input class="getfilter" type="checkbox" value="racing" name="sport"> Racing</label>
    <label><input class="getfilter" type="checkbox" value="swimming" name="sport"> Swimming</label>
    <br>
    <h3>Select your favorite food:</h3>
    <label><input class="getfilter" type="checkbox" value="choclate" name="food"> Choclate</label>
    <label><input class="getfilter" type="checkbox" value="biscuits" name="food"> Biscuits</label>
    <label><input class="getfilter" type="checkbox" value="candy" name="food"> Candy</label>
    <label><input class="getfilter" type="checkbox" value="Cake" name="food"> Cake</label>
    <br>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

3 Comments

one thing more can we reduce the jquery code more??
You can replace the query value formation through 'join()' function. For example: var queryValue = queryStringObject[key].join('~');
Thanks Saravanakumar

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.