All Marked Up

A tasty brew of web standards and internet culture.

jQuery URL Toolbox *beta*

I have been working on a jQuery plugin (well actually a self-contained set of plugins) that extends the capabilites of my jQuery URL Parser. I’m calling it a ‘URL Toolbox’ as it does everything the URL parser does (i.e. retrieving various bits of any URL string) but also allows you to set parts of URL strings, link hrefs, form actions etc, amongst other things.

UPDATE (22.01.10) – I have now removed the $.observeUrl() function as I felt it was not really in line with the core idea behind the plugin. For those needing similar functionality I would highly recommend Ben Alman’s hashchange plugin. New version also includes a number of bugfixes (thanks to Pavol, Eugene et al.). Proper demos and docs coming soon I hope! :-)

It also includes a function, $.observeUrl(), that once called ‘listens’ for changes to the document URL hash fragment, and triggers a custom jquery event, ‘hash:change’ whenever the hash portion of the URL changes. The plugin includes a somewhat modified version of the jQuery History Plugin to enable full back/forwards/history support for hash changes, and will hopefully make it pretty trivial to include full bookmarking and history support in AJAX based apps/sites .

The plugin is still very beta, but I thought I would link to the current version of it here anyway for those that are feeling brave and want to have a play around.

Download the jQuery URL Toolbox beta

Some very quick pointers on how to use it are included below – once I have tested it further I will move it over to the projects area of my site and get some proper documentation together.

General usage:

  1. Use  var myUrl = $(element).url() to grab an element’s  URL and return a special ‘URL’ object. (a, form, img, base, link and iframe elements are supported, and using ‘document’ (no quotes) as the selector will return a URL object based on the current page’s URL)
  2. Then use myUrl.attr('theAttr') to return any part of the URL, where ‘theAttr’ can be any one of: source, protocol, host, port, query, file, hash or path.
  3. If you include a second argument to the attr() method – i.e. something like myUrl.attr('path', '/myNewPath/'), then it will set the value of that part of the URL to the value of the second argument. Whatever the URL of element the initial url() function was called on will be updated accordingly. If the document URL was used (via $(document).url()) then the location will be changed accordingly, normally resulting in a page refresh.
  4. Doing a .toString() on the URL object at any time will return the current string representation of the URL.
  5. The .segment(i) method (where ‘i’ is the segment number, starting from zero) will return the corresponding segment from the URL. Including a second parameter will set that segment.
  6. The .param('key') method (where ‘key’ is the query string key) will return the corresponding value of the suppied key in the URL query (GET) string, if there is one. Including a second parameter will set that parameter.
  7. If you have a hash fragment that consists of segments, like ‘#/part1/part2/’ then you can get/set those segments using the hashSegment() method, which works exactly like the segment() one.
  8. Similarly if you have a hash fragment that looks like a query string, the parts can be get/set using the hashParam() method.

Watching for hash changes in the document’s URL:

  1. Calling the $.observeUrl() function in your code will result in a custom ‘hash:changed’ event being triggered on the document any time the URL hash fragment is updated.
  2. It will also ensure that any changes to the URL hash fragment are correctly recorded in the browser’s history (‘fixed’ for all browsers) so that the back/forwards buttons can be used correctly.
  3. You can then set up you app to respond to hash changes by listening out for the hash:change event on the document, eg. $(document).bind('hash:change', function(e, hash){ doSomething() }

A lot to take in but I will try to get together some more comprehensive and less confusing documentation in the near future!

Any bugs, suggestions or otherwise please email me at mark[at]allmarkedup.com for now.

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a comment or trackback from your own site.

11 Responses to “jQuery URL Toolbox *beta*”

  1. 4rn0 says:

    I’m quite happy with this development! I use jquery.urls.js together with jquery.observehashchange.js (http://finnlabs.github.com/jquery.observehashchange/) in a lot of projects. Having one jQuery URLtoolbox makes a lot of sense to me!

    Thanks for the efforts!

  2. eli dupuis says:

    Excellent feature additions… Looking forward to testing this beta out. Thanks a bunch!

  3. Mark says:

    @4rn0 – Thanks! I hadn’t seen the observehashchange.js function, looks good, I will definitely check it out….

    @eli dupuis – great, let me know if you find any bugs or have any issues!

  4. Kasper Garnaes says:

    Sounds great, Mark!

    I especially appreciate the efforts into working with the #hash.

    Have you considered moving the code for the plugin to an open repository like GitHub or Google Code?

  5. Eugene says:

    I’e just found a bug:

    else if ( ! isObj( source ) )
    {
    // just a URL string
    sourceType = ’str’;
    var url = loc.href;
    }

    should be

    else if ( ! isObj( source ) )
    {
    // just a URL string
    sourceType = ’str’;
    var url = source;
    }

  6. Eugene says:

    Here is also a function for getting all query keys by regular expression – quite useful staff for me:

    // get query string parameters by regexp
    find_param : function(regexp) {
    var params = [];
    for (var key in parsed.params) {
    if (!regexp.test(key)) continue;
    params.push(key);
    }
    return params;
    }

  7. Mark says:

    @Kasper – Yes I have, and when I have a bit more time I will be probably be porting all my repos for stuff like this over to Github.

    @Eugene, thanks, I’ll take a look at that bugfix – i have a few other amends to make as well when I have a spare second :-)

  8. Flo says:

    Wow I’m so amazed this thing’s already been invented.

  9. Haukur says:

    This is almost what I’ve been looking for.

    I need to be able to change a param but without redirecting (refreshing) the page.

    I have an ajax functionality where I’m changing values and therefore want to change the parameters as well.

    Will this be possible in the release?

  10. Jason C says:

    It might be nice to have a removeParam function.

    Here is a really rough implementation:

    function removeParam(key) {
    re = new RegExp(“(“+key+”=.*?)(?:&|$)”);
    newUrl = url.toString().replace(re, ”).replace(/[\?&]$/, ”);
    document.location = newUrl;
    }

  11. rob says:

    Mark, I’m using this script in Titanium.app which is like adobe AIR, and runs a version of webkit. It works perfect the first time it’s called, but after a jQuery ajax call it returns an error:

    TypeError: Result of expression ‘$.url’ [undefined] is not a function.

    It’s probaby something I’m doing wrong, but when I instead do some string manipulation on the url I was passing to $.url everything is peachy.

    I’ll keep trying to track down what’s happening in the app, but I’m wondering, could this be some type of namespace error?

Leave a Reply