Today We will be dealing with URL query parameters. I will show you how you can save search parameters based on the values provided by a user and then construct a URL with such parameters.
We won't actually be needing a form for this.
LET'S BEGIN
I will start with a fake URL that allows me to pull up { x } number of records using the parameter (limit), search through { x } number of records using the parameter (filter), and filter through the records by their respective Id's using the parameter (id).
So I have my fake base URL as
And the query URL as
So I'll show you how to construct the query URL, still retaining the values of the other parameters.
Input Elements
We have 3 input elements that will enable us to get values from users based on how they want to filter the data.
<!-- limit -->
<select id="select_limit">
<option value="">Select One </option>
<option value="50">50 records</option>
<option value="100">100 records</option>
</select>
<!-- search input -->
<input type="search" id="inp_filter">
<!-- id -->
<input type="text" id="inp_id">
Now we will create a variable that will store the user's query along with its default values.
This variable will help us to retrieve a new set of filtered data because we will store the value of the other parameters.
let userQuery = {
"limit" : 50,
"filter" : "",
"id" : 1
}
If your page does not send the request through Ajax, you need to store the value of userQuery in the browser's local storage and then retrieve that value on page reload.
//check if it exists and rewrite the variable
let userQuery = (localStorage.getItem('userQuery')) ?
JSON.parse(localStorage.getItem('userQuery')) :
{ "limit" : 50,"filter" : "","id" : 1 };
//save user query
localStorage.setItem('userQuery', JSON.stringify(userQuery));
Build Your Query
Now let's create a function that will loop through our object, build our query parameter and return the URL for us to send.
function buildQuery(){
//store query parameters in a temporary variable
var query = [];
//loop through user query object
for (var key in userQuery) {
//encode the keys and values this is most necessary for search inputs
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(userQuery[key]));
}
//construct new URL
let new_url = "https://api.test.com/users"+ (query.length ? '?' + query.join('&') : '');
return(new_url);
}
When dealing with a search form, it is necessary to encode the search value using encodeURICompenent and decode on the backend.
Listen for changes
Now we will listen for changes in the input elements, and rebuild the query parameter.
We will also create a variable that will store the value of these input elements to prevent sending duplicate requests.
//handle limit change
let limitNo;
document.querySelector("#select_limit").addEventListener('change', function(){
//check if value is not empty and has not been used before
if((this.value !== "") && (limitNo !== this.value)){
//set the variable to contain this value( this means that is used)
limitNo = this.value;
//build userQuery
userQuery["limit"] = limitNo;
//do something with the url
let url = buildQuery();
//window.location.assign(url);
}
})
//handle search input
let searchTxt;
document.querySelector("#inp_filter").addEventListener('change', function(){
//check if search value has not been used before
if(searchTxt !== this.value){
//set the variable to contain this value( this means that is used)
searchTxt = this.value;
//build userQuery
userQuery["filter"] =searchTxt;
//do something with the url
let url = buildQuery();
//window.location.assign(url);
}
})
//handle id input
let inpID;
document.querySelector("#inp_id").addEventListener('change', function(){
//check if search value has not been used before
if((this.value !== "") && (inpID !== this.value)){
//set the variable to contain this value( this means that is used)
inpID = this.value;
//build userQuery and format the value to number
userQuery["id"] = parseInt(inpID);
//do something with the url
let url = buildQuery();
//window.location.assign(url);
}
})
So anytime any input element changes value, we will rebuild the query parameter and return the URL which we can send to the browser.
Here's the full script
//check if it exists and rewrite the variable
let userQuery = (localStorage.getItem('userQuery')) ?
JSON.parse(localStorage.getItem('userQuery')) :
{ "limit" : 50,"filter" : "","id" : 1 };
//save user query
localStorage.setItem('userQuery', JSON.stringify(userQuery));
//build your query
function buildQuery(){
//store query parameters in a temporary variable
var query = [];
//loop through user query object
for (var key in userQuery) {
//encode the keys and values this is most necessary for search inputs
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(userQuery[key]));
}
//construct new URL
let new_url = "https://api.test.com/users"+ (query.length ? '?' + query.join('&') : '');
return(new_url);
}
//handle limit change
let limitNo;
document.querySelector("#select_limit").addEventListener('change', function(){
//check if value is not empty and has not been used before
if((this.value !== "") && (limitNo !== this.value)){
//set the variable to contain this value( this means that is used)
limitNo = this.value;
//build userQuery
userQuery["limit"] = limitNo;
//do something with the url
let url = buildQuery();
//window.location.assign(url);
}
})
//handle search input
let searchTxt;
document.querySelector("#inp_filter").addEventListener('change', function(){
//check if search value has not been used before
if(searchTxt !== this.value){
//set the variable to contain this value( this means that is used)
searchTxt = this.value;
//build userQuery
userQuery["filter"] =searchTxt;
//do something with the url
let url = buildQuery();
//window.location.assign(url);
}
})
//handle id input
let inpID;
document.querySelector("#inp_id").addEventListener('change', function(){
//check if search value has not been used before
if((this.value !== "") && (inpID !== this.value)){
//set the variable to contain this value( this means that is used)
inpID = this.value;
//build userQuery and format the value to number
userQuery["id"] = parseInt(inpID);
//do something with the url
let url = buildQuery();
//window.location.assign(url);
}
})
You can modify the code to suit your app's logic.
The reason I decided not to use a form for this is because of a web page structured like this
You can see the input and select elements responsible for filtering the records are beautifully structured and not under a single form, so using the approach above will help users filter records with ease, retaining the previous query parameters.
USING THE URL() OBJECT CONSTRUCTOR
We can make things very easy for us by using the url() object constructor, to construct the URL.
To begin, I will create a function doQuery that will have just 2 parameters.
The first parameter is a URL (this URL can have a search query already).
The second parameter is an object that contains the user's search query.
Then we will use the set() method to either set new parameters from the userQuery object or rewrite the existing parameters.
function doQuery(url, userQuery){
//construct a new url
let res = new URL(url);
//check if userquery contians properties
if(Object.keys(userQuery).length !== 0){
//loop through object
let ind = 0;
while (ind < Object.keys(userQuery).length){
//get the parameter
const param = Object.keys(userQuery)[ind];
//get the value
const value = userQuery[param];
//set or replace the parameter
res.searchParams.set(param, value);
//increment counter
ind++;
}
}
//return the full URL
return ( res.href );
}
To use this function, just pass in your URL as the first argument, then the userQuery object as the second argument.
const userQuery = {
uname : "Simon",
pass : "OctaHenryX6D"
}
//store url
let url = doQuery('http://mywebsite.com/check-record', userQuery);
//send to the browser
window.location.href=url;
This is what the return value looks like with a URL without a search query.
What if we attached a search query to the URL?
The values of the search parameters will be rewritten with the one from the userQuery object!
You've reached the end of my article.
EXTRA
I recently launched a JavaScript package that validates your HTML forms using validation rules, regular expressions, and form input attributes.
I will appreciate it if you spared a few seconds to check it out.
Thank You
Top comments (0)