Related
I'm running a form which contains a textbox for the entry of a PIN code.
When typing the code in, each character is replaced with an * and the actual value entered is put into a new variable.
Click 'Submit' or 'Enter' and it works fine. (code below).
However, when I paste the code into the textbox, (id=user_pin_code) the characters are not replaced with * and the values are not entered to that other variable (PINcode), which means that, when I click 'Submit' or hit Enter key, the value is not passed to the next script.
It seems I need the onmouseup or onmouseout event to trigger the JS (to change the chars to ****** and to put the actual characters into 'PINcode' ) but, those two events don't seem to work which means the new variable is not populated.
Any guidance or pointers would be much appreciated.
<script>
\$(document).ready(function(e) {
var actualTextEntered = "";
\$("#user_pin_code").keyup(function(e) {
var x = document.getElementById("user_pin_code").value;
actualTextEntered += x.replace(/\\*/g,"");
//actualTextEntered += x.replace(/*/g,"");
addEventListener('keydown', function(event) {
const key = event.key; // const {key} = event; ES6+
//console.log( 'key = ' + key );
if ( key === "Backspace" ) {
// Do something
actualTextEntered = '';
x='';
}
if ( key === "Return" ) {
//console.log( 'key pressed = ' + key);
}
});
document.getElementById("user_pin_code").value = "";
for (var i=0;i<actualTextEntered.length;i++)
{
document.getElementById("user_pin_code").value += "*";
document.getElementById("PINcode").value = actualTextEntered;
}
});
});
</script>);
Check this code if it works:
<script>
\$(document).ready(function(e) {
var actualTextEntered = "";
\$("#user_pin_code").keyup(function(e) {
var x = document.getElementById("user_pin_code").value;
actualTextEntered += x.replace(/\\*/g,"");
//actualTextEntered += x.replace(/*/g,"");
\$("#user_pin_code").keydown(function(event) {
const key = event.key; // const {key} = event; ES6+
//console.log( 'key = ' + key );
if ( key === "Backspace" ) {
// Do something
actualTextEntered = '';
x='';
}
if ( key === "Return" ) {
//console.log( 'key pressed = ' + key);
}
});
document.getElementById("user_pin_code").value = "";
for (var i=0;i<actualTextEntered.length;i++)
{
document.getElementById("user_pin_code").value += "*";
document.getElementById("PINcode").value = actualTextEntered;
}
});
});
</script>);
I am constructing a query string in Javascript based on whether a checkbox is checked or not.
Some of the options in the checkboxes are
"Annual"
"Grass"
"Shrub (Evergreen)"
"Shrub (Deciduous)"
I found a function online that updates the url parameter:
function updateUrlParameter(uri, key, value) {
value = value.replace(/\s/g, "%20");
var i = uri.indexOf('#');
var hash = i === -1 ? '' : uri.substr(i);
uri = i === -1 ? uri : uri.substr(0, i);
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (!value) {
// remove key-value pair if value is empty
uri = uri.replace(new RegExp("([&]?)" + key + "=.*?(&|$)", "i"), '');
if (uri.slice(-1) === '?') {
uri = uri.slice(0, -1);
}
} else {
console.log("value is " + value)
uri = uri + separator + key + "=" + value;
}
return uri + hash;
}
Using the above function, if I check the checkboxes for the above four starting from top down, my query string becomes
?plantType=Annual&plantType=Grass&plantType=Shrub%20(Evergreen)&plantType=Shrub%20(Deciduous
Why is the function ignoring the last ')' in the string? Is there a work around this? I would like to keep the parenthesis in the query string because this will make querying the database easier.
I created a function to iterate through input checkboxes. If they are checked, then use the updateUrlParameter function to update the URI.
function getQueryString() {
var inputsContainerChildren = $('#floatingDivForFilter').children();
var input = document.createElement('input')
var uri = '';
for (var i = 0; i < inputsContainerChildren.length; i++) {
var currChild = inputsContainerChildren[i].firstElementChild;
if (currChild) {
if (currChild.tagName === 'INPUT') {
if (currChild.checked) {
var id = currChild.id;
console.log(uri)
uri = updateUrlParameter(uri, currChild.name, currChild.value);
}
}
}
}
console.log(uri);
}
The photo below shows a snapshot of the URL produced. I can't figure out why the last ')' is chopped off.
url photo
The issue you are seeing is just the Chrome developer tools trying to be too clever.
When logging the url to the console, Chrome will not recognize the full url as a link but exclude the closing ")". They probably do that because it will be very common that people write an url in braces and it is not expected that the closing brace is part of the url.
Since this is only an issue of the developer tools, you can ignore the issue. It will not affect the runtime behaviour of your code.
The issue will be solved when you correctly escape special characters in the parameters (as you should do anyway):
function updateUrlParameter(uri, key, value) {
// removed because escape will do that
// value = value.replace(/\s/g, "%20");
var i = uri.indexOf('#');
var hash = i === -1 ? '' : uri.substr(i);
uri = i === -1 ? uri : uri.substr(0, i);
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (!value) {
// remove key-value pair if value is empty
uri = uri.replace(new RegExp("([&]?)" + key + "=.*?(&|$)", "i"), '');
if (uri.slice(-1) === '?') {
uri = uri.slice(0, -1);
}
} else {
console.log("value is " + value)
// Use escape on key and value
uri = uri + separator + escape(key) + "=" + escape(value);
}
return uri + hash;
}
let s = "http://chrome.is.too.clever/";
s = updateUrlParameter(s, "plantType", "Annual");
s = updateUrlParameter(s, "plantType", "Grass");
s = updateUrlParameter(s, "plantType", "Shrub (Evergreen)");
s = updateUrlParameter(s, "plantType", "Shrub (Deciduous)");
console.log(s);
Fiddle
Instead of using a regular expression, just convert the params to an object, modify said object, and convert it back into params.
var url = 'https://x.y?plantType=Annual&plantType=Grass&plantType=Shrub%20(Evergreen)&plantType=Shrub%20(Deciduous)';
function updateUrlParameter(uri, key, value) {
let url = new URL(uri), object = deserializeQuery(url.search); // params to obj
object[key] = value; // modify obj
return url.origin + '?' + serializeQuery(object); // obj to url + params
}
console.log(updateUrlParameter(url, 'plantType', [ 'Pine', 'Palm', 'Rose (Red)' ]));
/** ======= Serialization / Deserialization functions below ======== */
// https://stackoverflow.com/a/47517503/1762224
function deserializeQuery(queryString, queryKey) {
let query = {}, pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('='), key = decodeURIComponent(pair[0]), value = decodeURIComponent(pair[1] || '');
value = (value.indexOf(',') === -1 ? value : value.split(','));
query[key] = query[key] ? (query[key].constructor === Array ? query[key].concat(value) : [query[key], value]) : value;
}
return typeof queryKey === 'undefined' ? query : query[queryKey];
}
// https://stackoverflow.com/a/53528203/1762224
function serializeQuery(params, keys = [], isArray = false) {
const p = Object.keys(params).map(key => {
let val = params[key];
if ("[object Object]" === Object.prototype.toString.call(val) || Array.isArray(val)) {
keys.push(Array.isArray(params) ? "" : key);
return serializeQuery(val, keys, Array.isArray(val));
} else {
let tKey = keys.length > 0 ? ((isArray ? keys : [...keys, key]).reduce((str, k) => "" === str ? k : `${str}[${k}]`, "")) : key;
if (isArray) {
return encodeURIComponent(tKey) + '=' + encodeURIComponent(val);
}
}
}).join('&');
keys.pop();
return p;
}
.as-console-wrapper {
top: 0;
max-height: 100% !important;
}
.as-console-row {
white-space: pre-wrap;
word-break: break-all;
}
I have a function that I use to pass over a table field name and its value. Depending on the name of the field, it either returns the contents as a link or it does not.
// Given a field name, check to see if its in our output. If so, return the formatted link
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for ( i = 0; i < keys.length; ++i ) {
key = keys[i];
if(field.toLowerCase() == key){
return ''+val+'';
}
}
return val;
}
Usage:
createLink('email', 'bob#stuff.com')
// returns bob#stuff.com
This also works for NTID. The issue I am having though is there are some field names that contain my values in the output such as Sup Email or Sup NTID and those are not transformed correctly.
Expected Result:
createLink('sup email', 'bob2#stuff2.com')
// returns bob#stuff.com
The Question:
How can I tweak my function to see if my field exists in the output array at all, even if it's not an exact match?
Change your function to
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if ((field.toLowerCase()).includes(key)) {
return '' + val + '';
}
}
return val;
}
console.log(createLink('sup email', 'bob2#stuff2.com') )
Notice the code if ((field.toLowerCase()).includes(key)) {
This will check for your key substring in the string
What you're implementing is the Strategy Pattern. The Strategy Pattern relies on some form of behaviour-switching depending on the inputs to the method. In your case, that switching is based on the first argument.
What you don't want to do is what your questions asks how to do. You don't want to assume every field name in your application which contains "email" or some other string is guaranteed to be an email address, handled by the same strategy.
Create a table of field names and strategies to use for the display of each of these fields; and use an "enum-ish" object as the definition of the strategies.
function create_link(field, val) {
const strategy = create_link.Field_Strategies[field];
if (typeof strategy === 'undefined') {
console.log("Using default strategy");
return val;
}
console.log("Using " + strategy);
switch (strategy) {
case create_link.Strategies.EMAIL:
return '' + val + '';
case create_link.Strategies.NTID:
return '<a href="https://web.internal/profile/' +
val + '" target="_blank">' + val + '</a>';
case create_link.Strategies.SOME_FIELD:
return '<a href="http://example.com/some/path/' +
encodeURIComponent(val) +
'" target="_blank">' + val + '</a>';
}
}
create_link.Strategies = {
EMAIL: "email strategy",
NTID: "ntid strategy",
SOME_FIELD: "somefield strategy"
};
create_link.Field_Strategies = {
"Sup email": create_link.Strategies.EMAIL,
"E-mail": create_link.Strategies.EMAIL,
"Email": create_link.Strategies.EMAIL,
"NTID": create_link.Strategies.NTID,
"Foobar baz": create_link.Strategies.SOME_FIELD
};
console.log(create_link("foo","foofoofoo"));
console.log(create_link("Sup email","supervisor#example.com"));
console.log(create_link("E-mail","foo#example.com"));
console.log(create_link("Email","bar#example.com"));
console.log(create_link("NTID","10983409509734"));
console.log(create_link("Foobar baz","Aleph null"));
You could use String.prototype.indexOf.
The indexOf() method returns the index within the calling String object of the first occurrence of the specified value...Returns -1 if the value is not found.
So your code would then look like:
// Given a field name, check to see if its in our output. If so, return the formatted link
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for ( i = 0; i < keys.length; ++i ) {
key = keys[i];
if(field.toLowerCase().indexOf(key) >= 0){ //CHANGE HERE
return ''+val+'';
}
}
return val;
}
I've been banging my head over this.
Using jquery or javascript, how can I toggle variables & values and then rebuild the query string? For example, my starting URL is:
http://example.com?color=red&size=small,medium,large&shape=round
Then, if the user clicks a button labeled "red", I want to end up with:
http://example.com?size=small,medium,large&shape=round //color is removed
Then, if the user clicks "red" again, I want to end up with:
http://example.com?size=small,medium,large&shape=round&color=red //color is added back
Then, if the user clicks a button labeled "medium", I want to end up with:
http://example.com?size=small,large&shape=round&color=red //medium is removed from list
Then, if the user clicks the labeled "medium" again, I want to end up with:
http://example.com?size=small,large,medium&shape=round&color=red //medium added back
It doesn't really matter what order the variable are in; I've just been tacking them to the end.
function toggle(url, key, val) {
var out = [],
upd = '',
rm = "([&?])" + key + "=([^&]*?,)?" + val + "(,.*?)?(&.*?)?$",
ad = key + "=",
rmrplr = function(url, p1, p2, p3, p4) {
if (p2) {
if (p3) out.push(p1, key, '=', p2, p3.substr(1));
else out.push(p1, key, '=', p2.substr(0, p2.length - 1));
} else {
if (p3) out.push(p1, key, '=', p3.substr(1));
else out.push(p1);
}
if (p4) out.push(p4);
return out.join('').replace(/([&?])&/, '$1').replace(/[&?]$/, ''); //<!2
},
adrplr = function(s) {
return s + val + ',';
};
if ((upd = url.replace(new RegExp(rm), rmrplr)) != url) return upd;
if ((upd = url.replace(new RegExp(ad), adrplr)) != url) return upd;
return url + (/\?.+/.test(url) ? '&' : '?') + key + '=' + val; //<!1
}
params self described enough, hope this help.
!1: changed from ...? '&' : '' to ... ? '&' : '?'
!2: changed from .replace('?&','?')... to .replace(/([&?]&)/,'$1')...
http://jsfiddle.net/ycw7788/Abxj8/
I have written a function, which efficiently results in the expected behaviour, without use of any libraries or frameworks. A dynamic demo can be found at this fiddle: http://jsfiddle.net/w8D2G/1/
Documentation
Definitions:
The shown example values will be used at the Usage section, below
- Haystack - The string to search in (default = query string. e.g: ?size=small,medium)
- Needle - The key to search for. Example: size
- Value - The value to replace/add. Example: medium.
Usage (Example: input > output):
qs_replace(needle, value)
If value exists, remove: ?size=small,medium > ?size=small
If value not exists, add: ?size=small > size=small,medium
qs_replace(needle, options) Object options. Recognised options:
findString. Returns true if the value exists, false otherwise.
add, remove or toggleString. Add/remove the given value to/from needle. If remove is used, and the value was the only value, needle is also removed. A value won't be added if it already exists.
ignorecaseIgnore case while looking for the search terms (needle, add, remove or find).
separatorSpecify a separator to separate values of needle. Default to comma (,).
Note : A different value for String haystack can also be defined, by adding it as a first argument: qs_replace(haystack, needle, value) or qs_replace(haystack, needle, options)
Code (examples at bottom). Fiddle: http://jsfiddle.net/w8D2G/1/:
function qs_replace(haystack, needle, options) {
if(!haystack || !needle) return ""; // Without a haystack or needle.. Bye
else if(typeof needle == "object") {
options = needle;
needle = haystack;
haystack = location.search;
} else if(typeof options == "undefined") {
options = needle;
needle = haystack;
haystack = location.search;
}
if(typeof options == "string" && options != "") {
options = {remove: options};
var toggle = true;
} else if(typeof options != "object" || options === null) {
return haystack;
} else {
var toggle = !!options.toggle;
if (toggle) {
options.remove = options.toggle;
options.toggle = void 0;
}
}
var find = options.find,
add = options.add,
remove = options.remove || options.del, //declare remove
sep = options.sep || options.separator || ",", //Commas, by default
flags = (options.ignorecase ? "i" :"");
needle = encodeURIComponent(needle); //URL-encoding
var pattern = regexp_special_chars(needle);
pattern = "([?&])(" + pattern + ")(=|&|$)([^&]*)(&|$)";
pattern = new RegExp(pattern, flags);
var subquery_match = haystack.match(pattern);
var before = /\?/.test(haystack) ? "&" : "?"; //Use ? if not existent, otherwise &
var re_sep = regexp_special_chars(sep);
if (!add || find) { //add is not defined, or find is used
var original_remove = remove;
if (subquery_match) {
remove = encodeURIComponent(remove);
remove = regexp_special_chars(remove);
remove = "(^|" + re_sep + ")(" + remove + ")(" + re_sep + "|$)";
remove = new RegExp(remove, flags);
var fail = subquery_match[4].match(remove);
} else {
var fail = false;
}
if (!add && !fail && toggle) add = original_remove;
}
if(find) return !!subquery_match || fail;
if (add) { //add is a string, defined previously
add = encodeURIComponent(add);
if(subquery_match) {
var re_add = regexp_special_chars(add);
re_add = "(^|" + re_sep + ")(" + re_add + ")(?=" + re_sep + "|$)";
re_add = new RegExp(re_add, flags);
if (subquery_match && re_add.test(subquery_match[4])) {
return haystack;
}
if (subquery_match[3] != "=") {
subquery_match = "$1$2=" + add + "$4$5";
} else {
subquery_match = "$1$2=$4" + sep + add + "$5";
}
return haystack.replace(pattern, subquery_match);
} else {
return haystack + before + needle + "=" + add;
}
} else if(subquery_match){ // Remove part. We can only remove if a needle exist
if(subquery_match[3] != "="){
return haystack;
} else {
return haystack.replace(pattern, function(match, prefix, key, separator, value, trailing_sep){
// The whole match, example: &foo=bar,doo
// will be replaced by the return value of this function
var newValue = value.replace(remove, function(m, pre, bye, post){
return pre == sep && post == sep ? sep : pre == "?" ? "?" : "";
});
if(newValue) { //If the value has any content
return prefix + key + separator + newValue + trailing_sep;
} else {
return prefix == "?" ? "?" : trailing_sep; //No value, also remove needle
}
}); //End of haystack.replace
} //End of else if
} else {
return haystack;
}
// Convert string to RegExp-safe string
function regexp_special_chars(s){
return s.replace(/([[^$.|?*+(){}\\])/g, '\\$1');
}
}
Examples (Fiddle: http://jsfiddle.net/w8D2G/1/):
qs_replace('color', 'red'); //Toggle color=red
qs_replace('size', {add: 'medium'}); //Add `medium` if not exist to size
var starting_url = 'http://example.com?color=red&size=small,medium,large&shape=round'
starting_url = qs_replace(starting_url, 'color', 'red'); //Toggle red, thus remove
starting_url = qs_replace(starting_url, 'color', 'red'); //Toggle red, so add it
alert(starting_url);
This is the solution for your task: http://jsfiddle.net/mikhailov/QpjZ3/12/
var url = 'http://example.com?size=small,medium,large&shape=round';
var params = $.deparam.querystring(url);
var paramsResult = {};
var click1 = { size: 'small' };
var click2 = { size: 'xlarge' };
var click3 = { shape: 'round' };
var click4 = { shape: 'square' };
var clickNow = click4;
for (i in params) {
var clickKey = _.keys(clickNow)[0];
var clickVal = _.values(clickNow)[0];
if (i == clickKey) {
var ar = params[i].split(',');
if (_.include(ar, clickVal)) {
var newAr = _.difference(ar, [clickVal]);
} else {
var newAr = ar;
newAr.push(clickVal);
}
paramsResult[i] = newAr.join(',');
} else {
paramsResult[i] = params[i];
}
}
alert($.param(paramsResult)) // results see below
Init params string
{ size="small, medium,large", shape="round"} // size=small,medium,large&shape=round
Results
{ size="small"} => { size="medium,large", shape="round"} //size=medium%2Clarge&shape=round
{ size="xlarge"} => { size="small,medium,large,xlarge", shape="round"} // size=small%2Cmedium%2Clarge%2Cxlarge&shape=round
{ shape="round"} => { size="small,medium,large", shape=""} //size=small%2Cmedium%2Clarge&shape=
{ shape="square"} => { size="small,medium,large", shape="round,square"} //size=small%2Cmedium%2Clarge&shape=round%2Csquare
productOptions is the only thing you need to modify here to list all the available options and their default state. You only need to use the public API function toggleOption() to toggle an option.
(function(){
//Just keep an object with all the options with flags if they are enabled or disabled:
var productOptions = {
color: {
"red": true,
"blue": true,
"green": false
},
size: {
"small": true,
"medium": true,
"large": true
},
shape: {
"round": true
}
};
//After this constructing query becomes pretty simple even without framework functions:
function constructQuery(){
var key, opts, qs = [], enc = encodeURIComponent, opt,
optAr, i;
for( key in productOptions ) {
opts = productOptions[key];
optAr = [];
for( i in opts ) {
if( opts[i] ) {
optAr.push( i );
}
}
if( !optAr.length ) {
continue;
}
qs.push( enc( key ) + "=" + enc( optAr.join( "," ) ) );
}
return "?"+qs.join( "&" );
};
//To toggle a value and construct the new query, pass what you want to toggle to this function:
function toggleOption( optionType, option ) {
if( optionType in productOptions && option in productOptions[optionType] ) {
productOptions[optionType][option] = !productOptions[optionType][option];
}
return constructQuery();
}
window.toggleOption = toggleOption;
})()
Example use:
// "%2C" = url encoded version of ","
toggleOption(); //Default query returned:
"?color=red%2Cblue&size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "color", "red" ); //Red color removed:
"?color=blue&size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "color", "blue" ); //Blue color removed, no color options so color doesn't show up at all:
"?size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "color", "blue" ); //Blue color enabled again:
"?color=blue&size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "shape", "round" ); //The only shape option removed
"?color=blue&size=small%2Cmedium%2Clarge"
I have tried this and this may give the desire result
<script>
var url='http://example.com?color=red&size=small,medium,large&shape=round';
var mySplitResult = url.split("?");
var domain=mySplitResult[0];
var qstring=mySplitResult[1];
var proparr=new Array();
var valarr=new Array();
var mySplitArr = qstring.split("&");
for (i=0;i<mySplitArr.length;i++){
var temp = mySplitArr[i].split("=");
proparr[i]=temp[0];
valarr[i]=temp[1].split(",");
}
function toggle(property,value)
{
var index;
var yes=0;
for (i=0;i<proparr.length;i++){
if(proparr[i]==property)
index=i;
}
if(index==undefined){
proparr[i]=property;
index=i;
valarr[index]=new Array();
}
for (i=0;i<valarr[index].length;i++){
if(valarr[index][i]==value){
valarr[index].splice(i,1);
yes=1;
}
}
if(!yes)
{
valarr[index][i]=value;
}
var furl=domain +'?';
var test=new Array();
for(i=0;i<proparr.length;i++)
{
if(valarr[i].length)
{
test[i]=valarr[i].join(",");
furl +=proparr[i]+"="+test[i]+"&";
}
}
furl=furl.substr(0,furl.length-1)
alert(furl);
}
</script>
<div>
<input id="color" type="button" value="Toggle Red" onclick="toggle('color','red')"/>
<input id="shape" type="button" value="Toggle shape" onclick="toggle('shape','round')"/>
<input id="size" type="button" value="Toggle Small" onclick="toggle('size','small')"/>
<input id="size" type="button" value="Toggle large" onclick="toggle('size','large')"/>
<input id="size" type="button" value="Toggle medium" onclick="toggle('size','medium')"/>
<input id="size" type="button" value="Toggle new" onclick="toggle('new','yes')"/>
</div>
I'm working on formatting a URL for the Facebook Feed Dialog. There's so many parameters though. I want to have a function for these dialogs, something like:
function generateDialogUrl(dialog, params) {
base = "http://www.facebook.com/dialog/" + dialog + "?";
tail = [];
for (var p in params) {
if (params.hasOwnProperty(p)) {
tail.push(p + "=" + escape(params[p]));
}
}
return base + tail.join("&")
}
Oh wow... I think I just answered my own question. Is that right? Is escape() the correct function to use?
I'm stuck in the Lovers source code.
UPDATE: Since, we're using jQuery, I rewrote the method using jQuery.each. I also replaced escape() with encodeURIComponent() as suggested by #galambalazs & #T.J. Crowder. Thanks, guys!
var generateDialogUrl = function (dialog, params) {
base = "http://www.facebook.com/dialog/" + dialog + "?";
tail = [];
$.each(params, function(key, value) {
tail.push(key + "=" + encodeURIComponent(value));
})
return base + tail.join("&");
}
It's working!
Better yet, use encodeURIComponent instead. See this article comparing the two:
The escape() method does not encode
the + character which is interpreted
as a space on the server side as well
as generated by forms with spaces in
their fields. Due to this shortcoming
and the fact that this function fails
to handle non-ASCII characters
correctly, you should avoid use of
escape() whenever possible. The best
alternative is usually
encodeURIComponent().
escape() will not encode: #*/+
There is a jQuery method to accomplish this: $.param. It would work like this:
var generateDialogUrl = function (dialog, params) {
base = 'http://www.facebook.com/dialog/' + dialog + '?';
return base + $.param(params);
}
const createQueryParams = (param, prefix = '') => {
let queryString = '';
if (param.constructor === Object) {
queryString = Object.keys(param).reduce((result, key) => {
const obj = param[key];
const queryParam = result ? `${result}&${prefix}` : prefix;
if (obj.constructor === Object) {
return `${queryParam}${createQueryParams(obj, `${key}.`)}`;
} else if(obj.constructor === Array) {
const qp= obj.map((item, index)=> {
if (item.constructor === Object || item.constructor === Array) {
const query = createQueryParams(item, `${key}[${index}].`);
return `${query}`;
} else {
return `${key}[${index}]=${item}`;
}
}).reduce((res, cur) => {
return res ? `${res}&${cur}`: `${cur}`;
}, '');
return `${queryParam}${qp}`;
} else {
return `${queryParam}${key}=${obj}`;
}
}, '');
} else if(param.constructor === Array) {
queryString = param.reduce((res, cur) => `${res},${cur}`);
} else {
queryString = param;
}
return encodeURI(queryString);
};
Example:
createQueryParams({"Context":{"countryCode":"NO"},"Pagination":{"limit":10,"offset":1},"AdditionalField":[{"name":"Policy Number","value":"Pol123"},{"name":"Policy Version","value":"PV1"}]});
convertJsonToQueryString: function (json, prefix) {
//convertJsonToQueryString({ Name: 1, Children: [{ Age: 1 }, { Age: 2, Hoobbie: "eat" }], Info: { Age: 1, Height: 80 } })
if (!json) return null;
var str = "";
for (var key in json) {
var val = json[key];
if (isJson(val)) {
str += convertJsonToQueryString(val, ((prefix || key) + "."));
} else if (typeof (val) == "object" && ("length" in val)) {
for (var i = 0; i < val.length; i++) {
//debugger
str += convertJsonToQueryString(val[i], ((prefix || key) + "[" + i + "]."));
}
}
else {
str += "&" + ((prefix || "") + key) + "=" + val;
}
}
return str ? str.substring(1) : str;
}
isJson = function (obj) {
return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
};
example:
convertJsonToQueryString({Name:1,Children:[{Age:1},{Age:2,Hoobbie:"eat"}],Info:{Age:1,Height:80}})
Result:
"Name=1Children[0].Age=1Children[1].Age=2&Children[1].Hoobbie=eatInfo.Age=1&Info.Height=80"