javascriptjqueryquery-string

Toggle query string variables


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.


Solution

  • 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/