David Wheeler - HTTP.Query-0.03

Documentation | Source

Name

HTTP.Query - Easy GET query string management

Synopsis

  JSAN.use('HTTP.Query');

  var query = new HTTP.Query(location.search);

  query.set('from', 'me@example.com');
  query.add('to', 'you@example.com');
  query.add('to', 'him@example.com');

  location.search = query.toString();

Description

This class parses a GET query string, pulling out its argument keys and values and unescaping their encodings, and arranges them into an object. If a given query key is specified multiple times, then all of its values will be stored in an array for that key.

Constructor

  var query = new HTTP.Query;
  var query = new HTTP.Query(queryString);

Returns a new HTTP.Query object that has parsed the queryString passed as the single argument. If no query argument is passed and HTTP.Query is running in a Web browser, window.document.location.search will be used, instead. To initialize an empty HTTP.Query object, pass a null or empty string to the constructor.

get()

  var value = query.get(key);

Gets the value stored for a given key in the table. If the key has multiple values, they will all be returned in an array object.

set()

  query.set(key, value);

Sets the value for a key. Any previous value or values for that key will be discarded.

unset()

  query.unset(key);

Takes a single key argument and deletes that key from the query object, so that none of its values will be in the object any longer.

clear()

  query.clear();

Clears the query object of all values.

add()

  query.add(key, value);

Adds a new value to the query object. This method is the best interface for adding mutiple values for a single key. Once a key has multiple values, those values will be returned from a call to get() as an array.

act()

  query.act(function (key, value) {
      document.write(key + ' => ' + value);
      return true;
  });

Pass a function to this method to have it iterate over all of the key/value pairs in the query object. Keys with multiple values will trigger the execution of the function multiple times: once for each value. The function should expect two arguments: a key and a value. Iteration terminates when the code reference returns false, so be sure to have it return a true value if you want it to iterate over every value in the query object.

toString()

  alert(qry.toString());
  location.search = query.toString('&');
  alert(qry);

Overrides the default toString() method inherited from Object to return a properly-formatted and encoded GET query string. By default, it uses ";" as the query argument delimiter. Pass in "&" as the single argument to toString() for it to be used as the argument delimiter. Of course, when the HTTP.Query object itself is used in a string context, thus implicitly calling toString() ";" will be the delimiter; call toString("&") explicitly to use "&" as the delimiter.

Author

David Wheeler <david@kineticode.com>

Copyright and License

Copyright 2005 by David Wheeler.

This program is free software; you can redistribute it and/or modify it under the terms of the Perl Artistic License or the GNU GPL.

See http://www.perl.com/perl/misc/Artistic.html and http://www.gnu.org/copyleft/gpl.html.

// # $Id: Kinetic.pm 1493 2005-04-07 19:20:18Z theory $

// Set up namespace.
if (typeof HTTP == 'undefined') HTTP = {};
HTTP.Query = function (qry) {
    this.query = [];
    // Do nothing with empty query strings.
    // Use the current browser document location search if there is no query.
    if (!arguments.length && typeof window != 'undefined')
        qry = window.document.location.search;
    if (qry == null || qry == '') return;
    var pairs = qry.substring(1).split(/[;&]/);
    for (var i = 0; i < pairs.length; i++) {
        var parts = pairs[i].split('=');
        if (parts[0] == null) continue;
        var key = unescape(parts[0]), val = unescape(parts[1]);
        if (this.query[key] == null) {
            this.query[key] = unescape(val);
        } else {
            if (typeof this.query[key] == 'string') {
                this.query[key] = [this.query[key], unescape(val)];
            } else this.query[key].push(unescape(val));
        }
    }
};

HTTP.Query.VERSION = '0.03';

HTTP.Query.prototype = {
    get:   function (key)      { return this.query[key] },
    set:   function (key, val) { this.query[key] = val },
    unset: function (key)      { delete this.query[key] },
    clear: function ()         { this.query = [] },

    add:   function (key, val) {
        if (this.query[key] != null) {
            if (typeof this.query[key] != 'string') this.query[key].push(val);
            else this.query[key] = [this.query[key], val];
        } else {
            this.query[key] = val;
        }
    },
    act:    function (fn) {
        for (var k in this.query) {
            if (typeof this.query[k] == 'string') {
                if (!fn(k, this.query[k])) return;
            } else {
                // XXX What if someone has changed Array.prototype or
                // Object.prototype??
                for (var i in this.query[k])
                    if (!fn(k, this.query[k][i])) return;
            }
        }
    },
    toString: function (sep) {
        var ret = '';
        if (sep == null) sep = ';';
        this.act(function (k, v) {
             ret += sep + escape(k) + '=' + escape(v);
             return true;
        });
        return ret.replace(/^[;&]/, '?');
    }
};