dinsdag 12 mei 2009

jQuery :data() selector filter

Jump to actual plugin
I have been using jQuery for quite some time now and one of the thing I really like about it is the .data() function. Using this function you can easily add data to elements without cluttering the DOM. I.e. if we want to store the old value of a textbox before updating it with some auto completed value, we can do the following:

$('#textboxId').data('oldValue', $('#textboxId').val() ).updateWithAutocomplete();

Then we can easily get the old value back like this:

$('#textboxId').data('oldValue');

For when the user decides that the autocomplete suggestion is wrong or something. You can even add objects as data:

$('#someElem').data('anObject', {aKey: 23, inner:{ foo: 'bar' } });

However jQuery does not provide a method to query objects for data. If you want to check which elements have certain data specified or have it with a certain value you will have to loop over all elements and check them using an if statement. With this plugin this is no longer necessary. You can add a :data() filter to the selector and only elements matching the selector will be returned. The filter works very similar to the [attribute] filter. The following syntax is supported:

$('selector:data("foo")'); //Matches all elements that have .data('foo') defined.
$('selector:data("foo=bar")'); //Matches all elements that have .data('foo')=='bar'
$('selector:data("foo!=bar")'); //Matches all elements that have .data('foo')!='bar' NOTE that it still only matches elements that have .data('foo') defined.
$('selector:data("foo^=bar")'); //Matches all elements whos value for .data('foo') starts with 'bar'. i.e. .data('foo')=='barfoo' is matched but .data('foo')=='qwertbarfoo' not
$('selector:data("foo$=bar")'); //Matches all elements whos value for .data('foo') ends with 'bar'. i.e. .data('foo')=='foobar' is matched but .data('foo')=='foobarqwerty' not
$('selector:data("foo*=bar")'); //Matches all elements whos value for .data('foo') contains 'bar'. i.e. .data('foo')=='foobarqwerty' is matched


Becuase .data() can also hold objects you can also query for dataobject properties. You can use all the same selectors as above and specify object properties as dataKey.property.property etc. i.e.

$('selector:data("foo.bar")'); //Matches all elements that have .data('foo').bar defined.
$('selector:data("foo.bar.x^=hai")'); //Matches all elements whos value for .data('foo').bar.x starts with 'hai'
//Etc. =. !=,$= and *= are also supported


You can download and view the source of this plugin at my google code project.

maandag 11 mei 2009

stringQuery plugin

Quite often I find myself in the position that I need to check some simple thing on strings. Does it start/end with a certain string? Does it contain a certain string. SO i decided to code up this little plugin for jQuery. It's not much, but it just makes things a little easier.

$.stringQuery.startsWith(haystack, needle)

This function checks if string haystack starts with string needle.
$.stringQuery.startsWith('foobar', 'foo') === true;
$.stringQuery.startsWith('foobar', 'af') === false;

$.stringQuery.endsWith(haystack, needle)

This function checks if string haystack ends with string needle.
$.stringQuery.endsWith('foobar', 'bar') === true;
$.stringQuery.endsWith('foobar', 'bara') === false;

$.stringQuery.contains(haystack, needle)

This function checks if string haystack contains string needle.
$.stringQuery.contains('foobar', 'bar') === true;
$.stringQuery.contains('foobar', 'ob') === true;
$.stringQuery.contains('foobar', 'hai') === false;


This is just something I find myself testing a lot and I thought it would be nice to make the checks a little easier.

Here is the source code (Note how the License is about two times as big as the actual code)

/*
Copyright (c) 2009, Pim Jager
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name Pim Jager may not be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY Pim Jager ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Pim Jager BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
(function($){
    $.stringQuery = {};
    $.stringQuery.startsWith = function(haystack, needle){
        //checks if haystack starts with needle i.e. startsWith('foobar','foo') //true
        return haystack.indexOf(needle) === 0;
    }
    $.stringQuery.endsWith = function(haystack, needle){
        //checks if haystack ends with needle i.e. endsWith('foobar','bar') //true
        return haystack.substr(haystack.length - needle.length) === needle;
    }
    $.stringQuery.contains = function(haystack, needle){
        //checks if haystack contains needle i.e. contains('foobar','ob'); //true
        return haystack.indexOf(needle) !== -1;
    }
})(jQuery);

zondag 10 mei 2009

Licenses

On this blog I plan to host code snippets and jQuery plugins (hence the url). But first I will need a license to publish these snippets in. It will offcourse be an opensource license, but there are so many licenses out there that I was a bit overwhelmed.

At first I thought I should take the MIT-license which boils down to: "Do whatever you like with this software/code as long as you keep this license above it."
But I wanted something which offered more protection, so I decided to use the BSD-license. It boils down to: "Do whatever you like with this code/software as long as you keep this license above it. Oh and please do not sue us, using this code is your own responsibility"

Here is the license as I will post it on top of the code here. I have changed a few things, like removing the need for a company name as I don't have one.

Copyright (c) <year>, Pim Jager
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name Pim Jager may not be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY Pim Jager ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Pim Jager BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


I shall post code samples soon once I have found a nice client-side javascript syntax highlighter.