jQuery Sparkle is a simple but powerful DRY Plugin/Effect Framework aimed to simplify your jQuery development such that you no longer have to repeat yourself.
It already includes such extensions as:
But at it's core it is mostly just a framework to allow you to develop faster, utilising the Don't-Repeat-Yourself ideology.
This demo shows it in action, as well as providing you with tutorials and examples on how YOU can write great jQuery plugins which are configurable, extensible and translatable in minutes instead of hours.
jquery-sparkle
and move all the files and directories into that to continue.jquery-sparkle
which has a whole bunch of stuff in it, then that is fine and you can continue onto the next step.jquery-sparkle
then you must rename it to jquery-sparkle
to continue.jquery-sparkle
directory to somewhere on your webserverBe sure to always keep the entire jquery-sparkle
directory intact; this means if you were to only move some of the files instead of moving the entire directory, then you would run into problems due to the cross directory references would no longer be working.
If your page already has already included jQuery then you should skip this step.
<!-- Include jQuery (Sparkle Requirement) --> <script type="text/javascript" src="http://www.yoursite.com/somewhere/on/your/webserver/jquery-sparkle/scripts/jquery-1.4.2.min.js"></script>
<!-- Include Sparkle (Production) --> <script type="text/javascript" src="http://www.yoursite.com/somewhere/on/your/webserver/jquery-sparkle/scripts/jquery.sparkle.min.js"></script> <link href="http://www.yoursite.com/somewhere/on/your/webserver/jquery-sparkle/styles/jquery.sparkle.min.css" media="screen" rel="stylesheet" type="text/css" >
<textarea id="sparkle-demo-queryStringToJSON-input">file.js?a=1&b.c=3.1&b.d=four&a_false_value=false&a_null_value=null</textarea> <textarea id="sparkle-demo-queryStringToJSON-result"></textarea> <button id="sparkle-demo-queryStringToJSON-update">Update Result</button>
$(function(){ var $input = $('#sparkle-demo-queryStringToJSON-input'), $result = $('#sparkle-demo-queryStringToJSON-result'), $update = $('#sparkle-demo-queryStringToJSON-update'); $update.click(function(){ var val = new String($input.val()); $result.val(JSON.stringify(val.queryStringToJSON())); }).trigger('click'); });
<textarea id="sparkle-demo-toSlug-input"> This is a post about special chars: !@#$%^*()+</textarea> <textarea id="sparkle-demo-toSlug-result"></textarea> <button id="sparkle-demo-toSlug-update">Update Result</button>
$(function(){ var $input = $('#sparkle-demo-toSlug-input'), $result = $('#sparkle-demo-toSlug-result'), $update = $('#sparkle-demo-toSlug-update'); $update.click(function(){ var val = new String($input.val()); $result.val(val.toSlug()); }).trigger('click'); });
<textarea id="sparkle-demo-enter-input"></textarea> <textarea id="sparkle-demo-enter-result"></textarea> <button id="sparkle-demo-enter-clear">Clear Result</button>
$(function(){ var $input = $('#sparkle-demo-enter-input'), $result = $('#sparkle-demo-enter-result'), $clear = $('#sparkle-demo-enter-clear'); //$input.enter(function(){ $input.bind('enter', function(){ $result.val("Enter was pressed.\n"+$result.val()); }); $clear.click(function(){ $result.val(''); }); });
<textarea id="sparkle-demo-cancel-input"></textarea> <textarea id="sparkle-demo-cancel-result"></textarea> <button id="sparkle-demo-cancel-clear">Clear Result</button>
$(function(){ var $input = $('#sparkle-demo-cancel-input'), $result = $('#sparkle-demo-cancel-result'), $clear = $('#sparkle-demo-cancel-clear'); //$input.cancel(function(){ $input.bind('cancel', function(){ $result.val("ESC was pressed.\n"+$result.val()); }); $clear.click(function(){ $result.val(''); }); });
<button id="sparkle-demo-lastclick-input">Click Me</button> <textarea id="sparkle-demo-lastclick-result"></textarea> <button id="sparkle-demo-lastclick-clear">Clear Result</button>
$(function(){ var $input = $('#sparkle-demo-lastclick-input'), $result = $('#sparkle-demo-lastclick-result'), $clear = $('#sparkle-demo-lastclick-clear'); //$input.lastclick(function(){ $input.bind('lastclick', function(){ $result.val("lastclick performed.\n"+$result.val()); }); $clear.click(function(){ $result.val(''); }); });
<button id="sparkle-demo-firstclick-input">Click Me</button> <textarea id="sparkle-demo-firstclick-result"></textarea> <button id="sparkle-demo-firstclick-clear">Clear Result</button>
$(function(){ var $input = $('#sparkle-demo-firstclick-input'), $result = $('#sparkle-demo-firstclick-result'), $clear = $('#sparkle-demo-firstclick-clear'); //$input.firstclick(function(){ $input.bind('firstclick', function(){ $result.val("firstclick performed.\n"+$result.val()); }); $clear.click(function(){ $result.val(''); }); });
<button id="sparkle-demo-singleclick-input">Click Me</button> <textarea id="sparkle-demo-singleclick-result"></textarea> <button id="sparkle-demo-singleclick-clear">Clear Result</button>
$(function(){ var $input = $('#sparkle-demo-singleclick-input'), $result = $('#sparkle-demo-singleclick-result'), $clear = $('#sparkle-demo-singleclick-clear'); //$input.singleclick(function(){ $input.bind('singleclick', function(){ $result.val("Singleclick performed.\n"+$result.val()); }); $clear.click(function(){ $result.val(''); }); });
The major benefits of using BalClass is that you can easily work with multiple configurations for your plugin, as well as making it easily extensible by other developers. For example we can do this to have our plugin easily translatable:
if ( !($.HiBye||false) ) { $.HiBye = $.HiBye.create({ // Configuration config: { "default": { "hi": "Hello", "bye": "Goodbye" }, "english": { // Same as default }, "french": { "hi": "Salut", "bye": "Au Revoir" } }, // Functions fn: function(mode, options) { // Prepare var Me = $.HiBye; // where you have placed your instantiated/created class var config = Me.getConfigWithDefault(mode,options); var $this = $(this); // Say Hi then Bye $this.hide().html(config.hi).fadeIn('slow',function(){ $this.html(config.bye).fadeOut('slow'); }); // Chain return this; }, built: function(){ // Prepare var Me = this; // Attach $.fn.hibye = Me.fn; // Return true return true; } }); } else { console.warn("$.HiBye has already been defined..."); }
We can then trigger your plugin using different configurations like so:
<p id="hibye-example"></p> <script type="text/javascript"> // onDomReady $(function(){ $('#hibye-example').hibye(); // uses the default language $('#hibye-example').hibye('english'); // uses the english language $('#hibye-example').hibye('french'); // uses the english language $('#hibye-example').hibye('french',{ 'hi': 'Salut :-)' }); // uses the french language with a override on hi to include a smiley face $('#hibye-example').hibye({ 'hi': 'Ciao', 'bye': 'Ciao' }); // uses the default language with a override on hi and bye so that they are italian }); </script>
Now that is pretty nifty isn't it! Now say if an Italian developer is using our plugin calls the hibye jquery function ($.fn.hibye) a fair bit, instead of doing the following (which is a bit redundant):
$('#hibye-example1').hibye({ 'hi': 'Ciao', 'bye': 'Ciao' }); $('#hibye-example2').hibye({ 'hi': 'Ciao', 'bye': 'Ciao' });
They could do this:
var hibye_italian = { 'hi': 'Ciao', 'bye': 'Ciao' }; $('#hibye-example1').hibye(hibye_italian); $('#hibye-example2').hibye(hibye_italian);
But that could possibly unleash a plague of scope issues down your alleyway. A much better solution is to add the Italian language directly to HiBye's configuration! We can do this easily with:
$.HiBye.addConfig("italian", { 'hi': 'Ciao', 'bye': 'Ciao' }); $('#hibye-example1').hibye("italian"); $('#hibye-example2').hibye("italian");
Now isn't that sweet and tastes like honey. Mmmm. honey...
For our HiBye example, what could make it even better is if we use sparkle! Sparkle really saves us a lot of time, instead of having to do all those lengthy jQuery fn calls whenever we want to instantiate something, we can just add a CSS class and Sparkle will handle it automagically! Wow!
This has huge benefits especially for AJAX loaded in content, as say datepickers and timepickers for example will be instantiated automatically for their AJAX content without us having to instantiate each and every one manually! This is a serious life saver at times!
So let's see how we can do this. Firstly we want to modify our example to no longer use an id
attribute, but instead a CSS class
.
<p class="sparkle-hibye"></p>
You don't need to prefix the CSS classname with sparkle-
but we like to as it has become a kinda convention and standard with other sparkle extensions. So now that that's done, all we need to do is add our sparkle extension. We can do this with:
$.Sparkle.addExtension({ // Extension Name name: "hibye", // Extension Configuration config: { selector: '.sparkle-hibye', // the selector which will be used hibyeMode: 'default', // the mode to be used for hibye hibyeConfig: {} // the configuration to be used for hibye } // Extension Function extension: function(Sparkle, config){ var $this = $(this); var $item = $this.findAndSelf(config.selector); return $item.hibye(config.hibyeMode, config.hibyeConfig); } });
Now that's all there is to it, now wherever there is a element with the class sparkle-hibye
they will automatically be hibye'd onDomReady
. If you are loading in AJAX content, you can use $ajax_content.sparkle()
to sparkleify the ajax content.
But what if we are on a French website, we would want all the HiBye's to be in French! We can do this easily with:
$.Sparkle.applyExtensionConfig("hibye",{ "hibyeMode": "french" });
And bang, just like that, all the sparkle instantiated HiBye's are now in french! As well as any future sparkled content!
// Define our Function function checkMeaningOfLife ( decimal, success ) { if ( parseInt(decimal,10) === 42 ) { window.console.log(success); } }; // Define our Variables var str = 'The meaning of life is true', decimal = 42.00; // Fire our Function checkMeaningOfLife(decimal,success);
the html:
<div id="eventCal"></div> <div id="eventsInfo"></div>
the javascript:
$(function(){ var $eventCal = $('#eventCal'), $eventsInfo = $('#eventsInfo'); var now = new Date(); $eventCal.EventCalendar({ // Ajax Variables /** The JSON variable that will be return on the AJAX request which will contain our entries */ //ajaxEntriesVariable: 'entries', /** The AJAX url to request for our entries */ //ajaxEntriesUrl: '', /** The JSON Object to send via POST to our AJAX request */ //ajaxPostData: {}, /** Whether or not to Cache the AJAX data */ //ajaxCache: true, // Data Variables /* If you are not using AJAX, you can define your entries here */ calendarEntries: [ { id: 1, title: "My First Entry", start: "2010-"+(now.getMonth()+1).padLeft('0',2)+"-14 11:11:00", finish: "2010-"+(now.getMonth()+1).padLeft('0',2)+"-14 14:23:18", user: { name: "Joe" } }, { id: 2, title: "My Second Entry", start: "2010-"+(now.getMonth()+1).padLeft('0',2)+"-14 11:11:00", finish: "2010-"+(now.getMonth()+1).padLeft('0',2)+"-15 14:23:18", user: { name: "Joe" } }, { id: 3, title: "My Third Entry", start: "2010-"+(now.getMonth()+2).padLeft('0',2)+"-11 11:11:00", finish: "2010-"+(now.getMonth()+2).padLeft('0',2)+"-12 14:23:18", user: { name: "Joe" } }, { id: 4, title: "My Fourth Entry", start: "2010-"+(now.getMonth()).padLeft('0',2)+"-15 11:11:00", finish: "2010-"+(now.getMonth()).padLeft('0',2)+"-15 14:23:18", user: { name: "Joe" } } ], // Customisation Variables /** The CSS class which will be assigned to the Event Calendar */ calendarClass: 'hasEventCalendar', /** The CSS class which will be assigned to day when the day contains a entry */ dayEventClass: 'ui-state-active hasEvent', /** The standard options to send to the datepicker */ datepickerOptions: { firstDay: 1 /* Monday */ }, /** Whether or not to disable the datepicker date selection click */ disableClick: true, /** * The domEvents option contains all the events which you would like to assign to a $day * * It will send the following arguments back to you: * - domEvent * - details * * The details of the details argument contains the following: * - {Number} year * - {Number} month * - {Number} day * - {String} date * - {Array} dayEntries * - {Array} monthEntries * - {Element} datepicker */ domEvents: { mouseenter: function(domEvent, details) { // Prepare var $day = $(this), dayEntries = details.dayEntries; // Output $.each(dayEntries,function(i,entry){ $eventsInfo.append( '<p>'+ '<strong>'+entry.title+'</strong> ~'+entry.user.name+'<br/>'+ '<em>'+entry.start.toLocaleDateString()+'</em> to <em>'+entry.finish.toLocaleDateString()+'</em>'+ '</p>' ); }); }, mouseleave: function(domEvent, details) { // Clear $eventsInfo.empty(); } } }); });
./eventcalendar.json
{ "entries": [ { "id": 1, "title": "My First Entry", "start": "2010-07-14 11:11:00", "finish": "2010-07-14 14:23:18", "user": { "name": "Joe" } }, { "id": 2, "title": "My Second Entry", "start": "2010-07-14 11:11:00", "finish": "2010-07-15 14:23:18", "user": { "name": "Joe" } }, { "id": 3, "title": "My Third Entry", "start": "2010-08-11 11:11:00", "finish": "2010-08-12 14:23:18", "user": { "name": "Joe" } }, { "id": 4, "title": "My Fourth Entry", "start": "2010-06-15 11:11:00", "finish": "2010-06-15 14:23:18", "user": { "name": "Joe" } } ] }
the html:
<div id="eventCalAjax"></div> <div id="eventsInfoAjax"></div>
the javascript:
$(function(){ var $eventCal = $('#eventCalAjax'), $eventsInfo = $('#eventsInfoAjax'); var now = new Date(); $eventCal.EventCalendar({ // Ajax Variables /** The JSON variable that will be return on the AJAX request which will contain our entries */ ajaxEntriesVariable: 'entries', /** The AJAX url to request for our entries */ ajaxEntriesUrl: './eventcalendar.json', /** The JSON Object to send via POST to our AJAX request */ ajaxPostData: {}, /** Whether or not to Cache the AJAX data */ ajaxCache: true, // Data Variables /* If you are not using AJAX, you can define your entries here */ //calendarEntries: [], // Customisation Variables /** The CSS class which will be assigned to the Event Calendar */ calendarClass: 'hasEventCalendar', /** The CSS class which will be assigned to day when the day contains a entry */ dayEventClass: 'ui-state-active hasEvent', /** The standard options to send to the datepicker */ datepickerOptions: { firstDay: 1 /* Monday */ }, /** Whether or not to disable the datepicker date selection click */ disableClick: true, /** * The domEvents option contains all the events which you would like to assign to a $day * * It will send the following arguments back to you: * - domEvent * - details * * The details of the details argument contains the following: * - {Number} year * - {Number} month * - {Number} day * - {String} date * - {Array} dayEntries * - {Array} monthEntries * - {Element} datepicker */ domEvents: { mouseenter: function(domEvent, details) { // Prepare var $day = $(this), dayEntries = details.dayEntries; // Output $.each(dayEntries,function(i,entry){ $eventsInfo.append( '<p>'+ '<strong>'+entry.title+'</strong> ~'+entry.user.name+'<br/>'+ '<em>'+entry.start.toLocaleDateString()+'</em> to <em>'+entry.finish.toLocaleDateString()+'</em>'+ '</p>' ); }); }, mouseleave: function(domEvent, details) { // Clear $eventsInfo.empty(); } } }); });
If anything isn't working the way you want it to, or if you would like to request a feature or provide praise or general feedback then be sure to click the feedback button to the right, or the "Get Support" link up the top of this page.
This work is powered by coffee and distributed for free. Donations are how we afford our coffee. Coffee is how we stay awake after our day job hours to work on things like this free open-source project which you're looking at. So go ahead, and get that warm fuzzy feeling knowing you just helped some poor fellow working after hours for free to buy his coffee. You only need to spare a few dollars, or as much as you feel this piece of work is worth. Thanks so much. Alternatively; if you are not in a donating mood, then spreading the word about this project on twitter, your blog, or whatever is just as good. You can also give praise by clicking the feedback button or visiting our "Get Support" link. Thanks a bunch, we appreciate the help deeply.
This work is licensed under a GNU Affero General Public License.