Jquery Articles

RSS Feed - Tag Jquery

jQuery Enlightenment is a Worthy Purchase

Category: JavaScript & jQuery Tags: jQuery, Books | Written on Oct 26, 2009

If you haven't heard of or read jQuery Enlightenment, then you probably should go subscribe to more jQuery blogs, this one has been posted everywhere. Simply because this book is an excellent read with excellent examples, worth the $15 purchase. It has live links to code examples you might need down the road.

And no, I wasn't paid to do this post. All the dough goes straight to Cody Lindley on this self-published e-book, and he deserves every penny. Go Cody go! *cheers*

jQuery Tools vs jQuery UI

Category: JavaScript & jQuery Tags: jQuery, jQuery UI | Written on Jun 05, 2009

  VS

A new library has come out called, "jQuery Tools" that is packed with some visually appealing plugins built on top of jQuery. Here is their opening line to grab your interest:

Let's face it: do you really need drag-and-drop, resizables, selectables or sortable tables in your web applications? Websites are not desktop applications. They are different.

This is obviously a jab at jQuery UI, but before we dismiss what they have to say let's read on...

What you really need are tabs, tooltips, accordions, overlays, smooth navigation, great visual effects and all those "web 2.0" goodies that you have seen on your favourite websites.

This library contains six of the most useful JavaScript tools available for today's website. The beauty of this library is that all of these tools can be used together, extended, configured and styled. In the end, you can have hundreds of different widgets and new personal ways of using the library.

While there is some truth to the fact that you don't need each component that jQuery UI provides in most websites. You still have to keep in mind that jQuery UI's focus is to bring a set of components to the table that you can pick and chose from.

I agree with what the jQuery Tools author in saying that everybody needs overlays and visual effects that this library provides. I just don't understand the arrogance of attacking jQuery UI right off the bat, instead of augmenting the library and working together with them. 

Note: the author says he isn't attacking the jQuery UI library (in comments). But I think he should still be looking for ways to add the good parts of his plugins onto jQuery UI.

From an outside perspective, this library shines and has great potential. However as I dig deeper into the API and intensions it just looks bad.

Note: Tero from jQuery Tools has updated the API to fix this issue I'm pointing out here. You can see the result of the update in the jQuery Tools release notes. This type of thing should be sorted out behind the scenes from now on, but it was a good learning experience for me personally about where the public / private line should be.

Tooltip

Demo (hover over box):

Definition of Pride

Tooltip Implimentation

HTML:
  1. <!-- trigger element -->
  2. <a href="#" id="trigger">
  3.     Move the mouse over this box to see the tooltip in action.
  4. </a>
  5.  
  6. <!-- tooltip element -->
  7. <div class="tooltip">
  8.     <h3>The Tooltip</h3>
  9.  
  10.     <p>
  11.         <strong>A great tool for designing better layouts and more intuitive user-interfaces.</strong>
  12.     </p>
  13.  
  14.     <p>
  15.         Tooltips can contain any HTML such as links, images, forms and tables.
  16.         This tooltip is vertically centered on the top edge of the trigger element.
  17.     </p>
  18. </div>
JavaScript:
  1. $('#tooltip').tooltip();

It doesn't make sense within the context of jQuery.

So apparently, you have to grab the tooltip div, then turn it into a tooltip? Um... what? How do I get multiple tooltips on the page?

Quick, here is the philosophy behind jQuery:

  1. Find element(s) on the page
  2. Do something to them

Is the tooltip on the page? nope, not yet. Ok, failed #1. Where do we go from here? Typically you would grab elements on the page and then attach the tooltips to them. This is just common jQuery sense.

Note: After reading this article, the author of jQuery Tools updated his tooltip API.

As I dive into more examples of the tooltip, it continues to make no sense. The form example have no way to target inputs that you desire with custom classes or ids. You have to modify the markup before page load to change tooltips. After you load up the tooltips, you are stuck and cannot ditch tooltips, or make new ones from within the JavaScript.

Please, just use the jQuery Tooltip plugin or ClueTip.

Non-jQuery API

So now look at the API where it talks about returning the API instead of a jQuery object by passing api: true .... WHAT?! We are now forced to exit out of jQuery into a seperate jQuery Tools API by passing a variable?

JavaScript:
  1. var api = $("#myDiv").scrollable({size: 3, api: true});
  2. api.onClick = function(){ ...

Contrast this to using jQuery UI, you can stay within' jQuery and modify all settings.

JavaScript:
  1. var $myDiv = $("#myDiv").accordion({ 'header': 'h3' });

Then if later we want to change an option we can use that same div jQuery object.

JavaScript:
  1. $myDiv.accordion('option', 'changestart', function(){ ... });

With jQuery UI, all the plugins work with jQuery and it's philosophy. Working with John Resig's supervision and incite. Working together. Returning a seperate API has some potential, but not the way it is implimented here.

jQuery Tools flying solo

All this means (from what I've seen) is that the author did not take the time to learn the why behind jQuery and decided to go his own route, then flame jQuery UI and give you some shiny effects. The effects have potential, but the author needs to open up the code and start collaborating instead of going it solo.

Note: discussion has been opened up between jQuery UI and jQuery Tools teams.

Keep it real, y'all

jQuery and Google Maps #2: AJAX Storing and Retrieving Points

Category: JavaScript & jQuery Tags: jQuery, Google Maps | Written on Apr 28, 2009

Note on April 30th: This article was updated do to feedback from Google Maps API team to use the Client Geocoder instead of encoding on the server.

Continuing the series on jQuery and Google Maps, I will teach you how to store and retrieve points with using AJAX and a server-side language. This tutorial will use PHP/MySQL on the server, but it is basic enough that re-writing in another language should not be difficult.

View Final Demo

Google maps add point with jQuery

First, let me share with you the design-pattern behind the tutorial. My design pattern has two steps. The first is to use a simple HTML form to create new locations by posting the data to the server via AJAX. The second step is to fetch those locations from the server also via AJAX. Sound simple? Well, then lets get started...

Note: This tutorial builds on the first tutorial's code, so all code I am showing you here will be added onto it.

Step #1: Create the, "Add Location" Form

To allow users to add locations to the map, let's create a basic form. This will include the parts of an address, as well as the name of the location.

HTML:
  1. <form id="add-point" action="map-service.php" method="POST">
  2.     <input type="hidden" name="action" value="savepoint" id="action">
  3.     <fieldset>
  4.         <legend>Add a Point to the Map</legend>
  5.         <div class="error" style="display:none;"></div>
  6.         <div class="input">
  7.             <label for="name">Location Name</label>
  8.             <input type="text" name="name" id="name" value="">
  9.         </div>
  10.         <div class="input">
  11.             <label for="address">Address</label>
  12.             <input type="text" name="address" id="address" value="">
  13.         </div>
  14.         <button type="submit">Add Point</button>
  15.     </fieldset>
  16. </form>

A couple things to note about the form:

  • The form's action is pointed to map-service.php, which is where we will process the form data.
  • A hidden input <input type="hidden" name="action" value="savepoint" id="action"> will be used on the server to flag that we want to save a point to the database. This is just a personal preference on how to do things, there are many other ways to flag the intended action.
  • An empty div with class error <div class="error" style="display:none;"></div> is placed in the form to be used in a later step to display errors.

Step #2: Add Styles to the Form

By adding a few CSS rules to our page, we will set our form next to the map and spruce up the form a bit.

Css:
  1. #add-point { float:left; }
  2. div.input { padding:3px 0; }
  3. label { display:block; font-size:80%; }
  4. input, select { width:150px; }
  5. button { float:right; }
  6. div.error { color:red; font-weight:bold; }

Step #3: Geoencode Address Before Submiting Data

3a) Override default form submit

At this point we'll override the form's default submit action by selecting the form $("#add-point"), then using jQuery's submit event method. This method accepts a function that will run on submit of the form.

JavaScript:
  1. $("#add-point").submit(function(){
  2.     geoEncode();
  3.     return false;
  4. });

3b) Add GeoCoder

Then, inside the submit we will post the form data with AJAX using jQuery's ajax post method.

JavaScript:
  1. var geo = new GClientGeocoder();
  2.                
  3. var reasons=[];
  4. reasons[G_GEO_SUCCESS]            = "Success";
  5. reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address";
  6. reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address.";
  7. reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address";
  8. reasons[G_GEO_BAD_KEY]            = "Bad API Key";
  9. reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries";
  10. reasons[G_GEO_SERVER_ERROR]       = "Server error";

3c) Get geocode from address

JavaScript:
  1. function geoEncode() {
  2.     var address = $("#add-point input[name=address]").val();
  3.     geo.getLocations(address, function (result){
  4.         if (result.Status.code == G_GEO_SUCCESS) {
  5.             geocode = result.Placemark[0].Point.coordinates;
  6.             savePoint(geocode);
  7.         } else {
  8.             var reason="Code "+result.Status.code;
  9.             if (reasons[result.Status.code]) {
  10.                 reason = reasons[result.Status.code]
  11.             }
  12.             $("#add-point .error").html(reason).fadeIn();
  13.             geocode = false;
  14.         }
  15.     });
  16. }

Step #4: Submit Data to Server

JavaScript:
  1. function savePoint(geocode) {
  2.     var data = $("#add-point :input").serializeArray();
  3.     data[data.length] = { name: "lng", value: geocode[0] };
  4.     data[data.length] = { name: "lat", value: geocode[1] };
  5.     $.post($("#add-point").attr('action'), data, function(json){
  6.         $("#add-point .error").fadeOut();
  7.         if (json.status == "fail") {
  8.             $("#add-point .error").html(json.message).fadeIn();
  9.         }
  10.         if (json.status == "success") {
  11.             $("#add-point :input[name!=action]").val("");
  12.             var location = json.data;
  13.             addLocation(location);
  14.             zoomToBounds();
  15.         }
  16.     }, "json");
  17. }

The $.post method accepts parameters.

  1. URL to post data to: $(this).attr('action') will get the action attribute from the form that was submitted in the previous step.
  2. Data in name, value pairs i.e. { name: "inputname", value: "inputvalue" } we will get all the inputs using the :input selector in jQuery, then use the serialize array function to turn those inputs into name, value pairs. Then add the two geocode name/value pairs to the data object.
  3. Function to run after AJAX response is received. This function has one parameter which contains the response of the AJAX request.
  4. Type of data to be returned (optional). In this case we will use JSON.

Step #5: Use PHP on the Server to Process the Form

Once the data is posted with jQuery, we can handle it on the server with PHP.

5a) Check the action and validate the name

Let's simply check if the action variable is posted as, "savepoint". Then validate that the name has the proper characters with a regular expression and also that it is not empty. If any data is invalid, let's call a fail method (defined in next sub-step) with the message we want to show to the user.

PHP:
  1. <?php
  2. if ($_POST['action'] == 'savepoint') {
  3.     $name = $_POST['name'];
  4.     if(preg_match('/[^\w\s]/i', $name)) {
  5.         fail('Invalid name provided.');
  6.     }
  7.     if(empty($name)) {
  8.         fail('Please enter a name.');
  9.     }
  10. }
  11. ?>

Save the file as map-service.php or whatever you named your form's action attribute.

5b) Output the error message as a JSON object

Our fail function will use PHP's die method to stop the script from executing and output an error message to the client. Since the front-end (jQuery) is expecting a JSON object, we want to make sure to always send back a JSON response. To output JSON with PHP, you simply pass an array into the json encode method (json_encode is PHP 5.2+ only, if you are using less than 5.2 then use the JSON PHP library).

PHP:
  1. function fail($message) {
  2.     die(json_encode(array('status' => 'fail', 'message' => $message)));
  3. }

For the JSON array we want to use the JSEND specification for sending back a response. Basically, you have a key/value pair of status equals success or fail. That way the response can easily be checked on the front-end. I'm deviating from the JSEND spec a little bit by only sending a string back instead of a key/value pair of messages.

Using Firebug and Firefox, we can inspect the Ajax requests easily within the browser.

You can see here I submitted the form without entering a name and it sent me back an error message in the form of JSON.

Step #6: Display the Error Messages with jQuery

Hopping back to the jQuery code, we will write the error handling.

Inside the post code, we will first use the hide method to hide the error div in case it is already displaying. Then check if json.status is showing, "fail". If it is, we'll place the json.message inside the error div with jQuery's html attribute method and then fade it in with the fade in method.

JavaScript:
  1. $("#add-point .error").hide();
  2. if (json.status == "fail") {
  3.     $("#add-point .error").html(json.message).fadeIn();
  4. }

Step #7: Create a Database and Store the Locations

Using SQL, create a database table named locations which has a "name", "latitude", "longitude" and an "id" in it. If you need help with this, you will have to consult w3schools php and mysql for more help.

7a) Create the table with SQL

Mysql:
  1. CREATE TABLE `locations` (
  2.   `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  3.   `name` VARCHAR(100) DEFAULT NULL,
  4.   `lat` FLOAT(15,11) DEFAULT NULL,
  5.   `lng` FLOAT(15,11) DEFAULT NULL,
  6.   PRIMARY KEY  (`id`)
  7. )

7b) Insert name and location into the database with PHP and MySQL

We will use PHP and MySQL to insert the new location into the database. Directly after, we will either flag a success or fail message to the user.

PHP:
  1. $query = "INSERT INTO locations SET name='$_POST[name]', lat='$lat', lng='$lng'";
  2. $result = map_query($query);
  3.  
  4. if ($result) {
  5.     success(array('lat' => $_POST['lat'], 'lng' => $_POST['lng'], 'name' => $name));
  6. } else {
  7.     fail('Failed to add point.');
  8. }

If you noticed, I created a custom function called map_query to abstract out the database stuff. Here is the function definition. Make sure to update the, "MYSQL" stuff with your credentials.

PHP:
  1. function map_query($query) {
  2.     mysql_connect('MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD')
  3.         OR die(fail('Could not connect to database.'));
  4.     mysql_select_db ('MYSQL_DATABASE');
  5.     return mysql_query($query);
  6. }

I also created a similar method to "fail" called "success" which looks like:

PHP:
  1. function success($data) {
  2.     die(json_encode(array('status' => 'success', 'data' => $data)));
  3. }

An example of a succesful response in firebug:

Step #8: Map the New Point

Going back to the jQuery code, we can now add the success response handling. The response is a JSON object with "lat", "lng" and "name" properties. I'll give you the code inside the success handling, then later show you what each custom function is doing.

JavaScript:
  1. if (json.status == "success") {
  2.     $("#add-point :input[name!=action]").val("");
  3.     var location = json.data;
  4.     addLocation(location);
  5.     zoomToBounds();
  6. }

After a location is successfully added to the database, we want to clear the form to prevent duplicate entry. Do this by selecting the inputs with the :input selector. Then we need to filter out the  action input, do this by using the attribute not equal selector [name!=action].

My addLocation(location) function is simply our code from the last tutorial placed into a function to be reusable later.

JavaScript:
  1. function addLocation(location) {
  2.     var point = new GLatLng(location.lat, location.lng);       
  3.     var marker = new GMarker(point);
  4.     map.addOverlay(marker);
  5.     bounds.extend(marker.getPoint());
  6.    
  7.     $("<li />")
  8.         .html(location.name)
  9.         .click(function(){
  10.             showMessage(marker, location.name);
  11.         })
  12.         .appendTo("#list");
  13.    
  14.     GEvent.addListener(marker, "click", function(){
  15.         showMessage(this);
  16.     });
  17. }

It has a few things you might want to note:

  • using location.name, location.lat and location.lng means that we will be passing in a location object with those properties to the function.
  • Ignore bounds.extend(marker.getPoint()); and zoomToBounds for now or skip to #13 quickly to find out what they do.

Step #9: Load and Display the Locations from in the Database

When the page initially loads, we want to load all of our stored points. The simplest way to do this (in my opinion) is to do a GET request to fetch a JSON object from the server after the page loads.

To make a, "GET" request to the server, we can use jQuery's getJson method. We will send the server a, "get" variable called action with value, "listpoints".

JavaScript:
  1. $.getJSON("php/map-service.php?action=listpoints", function(json) {
  2.     // do stuff in step #11
  3. });

Step #10: Get the Locations from the Database

Simply check the, "GET" action in the PHP and run this code to fetch the locations records. Pretty straight-forward code here. We are creating an array of points and then sending them back to the client as JSON.

PHP:
  1. if ($_GET['action'] == 'listpoints') {
  2.     $query = "SELECT * FROM locations";
  3.     $result = map_query($query);
  4.     $points = array();
  5.     while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
  6.         array_push($points, array('name' => $row['name'], 'lat' => $row['lat'], 'lng' => $row['lng']));
  7.     }
  8.     echo json_encode(array("Locations" => $points));
  9.     exit;
  10. }

Step #11: Display the Locations

Iterate through the JSON object that contains the locations inside the getJson response function.

jQuery Essentials Presentation at MinneWebCon

Category: JavaScript & jQuery Tags: jQuery, Conference | Written on Apr 07, 2009

At the University of Minnesota's web conference, MinneWebCon I gave a talk on, "jQuery Essentials" and it seemed well-received. I enjoyed giving the presentation and I particularly enjoyed it because I finally was able to present in my home state of Minnesota!

Enjoy the slides! Keep it real, y'all.

jQuery and Google Maps Tutorial: #1 Basics

Category: JavaScript & jQuery Tags: jQuery, Google Maps | Written on Mar 04, 2009

There are many times I want to leverage jQuery's strengths to create a custom Google Maps mashup. In this tutorial, I will walk you through how to get started using jQuery inside the Google Maps environment. I will assume nothing, and explain each piece in detail.

View Final Demo

If you are already familiar with Google Maps API, skip to step #5, or so.

Step #1: Get API key

First, grab yourself an API key for Google Maps, you will need this in the next step.

Step #2: Load Google Maps and jQuery

We want to load up jQuery and Google Maps with the Google AJAX Libraries API.

JavaScript:
  1. <script type="text/javascript" src="http://www.google.com/jsapi?key=YOUR_API_KEY_HERE">
  2. <script type="text/javascript" charset="utf-8">
  3.     google.load("maps", "2.x");
  4.     google.load("jquery", "1.3.1");
  5. </script>

Make sure to replace YOUR_API_KEY_HERE with your API key. By using the Google AJAX Libraries API, it allows you to load the JavaScript libraries you need right from Google's servers. This increases the chance that your users will be able to load the scripts faster from their browser cache, as well as shuffle the jQuery script loading off your server.

Step #3: Create the Google Map

Google Maps Basic

To create our Google Map, we need to create a container div and use CSS to give it a width and a height.

HTML:
  1. <div id="map"></div>
Css:
  1. <style media="screen" type="text/css">
  2.     #map { width:500px; height:500px; }
  3. </style>

Use the GMap2 function to make a map instance. Then, set the center of the map. I wrapped this code block in jQuery's document ready function so that the code is run after the page has loaded.

JavaScript:
  1. $(document).ready(function(){
  2.     var map = new GMap2(document.getElementById('map'));
  3.     var burnsvilleMN = new GLatLng(44.797916,-93.278046);
  4.     map.setCenter(burnsvilleMN, 8);
  5. });

Here, I used Burnsville, MN's latitude and longitude because it is where I live right now. There are many ways to get the latitude and longitude of an address, like this simple service by iTouchMap.

The second parameter for setCenter is the zoom level, which is a number. I set the zoom level to "8" here because it is about in the middle.

At this point we should have a simple map.

Step #4: Load the Google Maps Example

To have some points to work with, let's paste in the google maps example.

JavaScript:
  1. // setup 10 random points
  2. var bounds = map.getBounds();
  3. var southWest = bounds.getSouthWest();
  4. var northEast = bounds.getNorthEast();
  5. var lngSpan = northEast.lng() - southWest.lng();
  6. var latSpan = northEast.lat() - southWest.lat();
  7. var markers = [];
  8. for (var i = 0; i < 10; i++) {
  9.     var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
  10.         southWest.lng() + lngSpan * Math.random());
  11.     marker = new GMarker(point);
  12.     map.addOverlay(marker);
  13.     markers[i] = marker;
  14. }

Note that I added a markers array to the example code. This will be used in the next step.

Step #5: Loop Through Markers and Add Basic Click Event to Markers

In this step, we start to use jQuery and Google Maps together. We want to be careful to use Google Map's built-in API as much as possible, leaving jQuery only for what it is best at.

Let's take that array of markers and loop through them with jQuery's each method.

JavaScript:
  1. $(markers).each(function(i,marker){
  2.     GEvent.addListener(marker, "click", function(){
  3.         map.panTo(marker.getLatLng());
  4.     });
  5. });

Inside the loop, let's use Google Maps's GEvent namespace to attach a click event to each marker. Then, we will add a panTo behavior to center the map on the marker. marker.getLatLng(); returns the latitude and longitude of the marker, while map.panTo(GLatLng) allows us to center the map on that latitude and longitude.

Step #6 - Make a Clickable List of Markers

Let's add a clickable list next to the map. Insert a ul.

HTML:
  1. <ul id="list"></ul>

Then let's style it up a bit by floating the map left and float our list element next to it. We also want to add a hover effect to the list items to give visual feedback to the user that they can click on each item in the list.

Css:
  1. <style type="text/css" media="screen">
  2.     #map { float:left; width:500px; height:500px; }
  3.     #list { float:left; width:200px; background:#eee; list-style:none; padding:0; }
  4.     #list li { padding:10px; }
  5.     #list li:hover { background:#555; color:#fff; cursor:pointer; cursor:hand; }
  6. </style>

In our jQuery each loop from last step, let's append the clickable list items to the list.

JavaScript:
  1. $("<li />")
  2.     .html("Point "+i)
  3.     .click(function(){
  4.         map.panTo(marker.getLatLng()); 
  5.     })
  6.     .appendTo("#list");

Here I am just setting the content to "Point (the count)", adding that same panTo action from before, then appending the list item to our list.

Step #7 - Add a Custom Message

When I create a Google Maps mashup, I usually want to replace the built-in info window with something custom. With jQuery, we can add any arbitrary HTML in place of the info window. This is great when you want complete control over what the info window looks like.

Add a message div with some test text.

HTML:
  1. <div id="message" style="display:none;">
  2.     Test text.
  3. </div>

Then add some basic styling to the message.

Css:
  1. #message { position:absolute; padding:10px; background:#555; color:#fff; width:75px; }

We have to place the message div inside the map. To do this, we can use jQuery to append it to an object. The map view is seperated into panes. Each pane is a div layered on top of the other. To get the div object that we want to attach our message div to, we can use map.getPane(PANE). The G_MAP_FLOAT_SHADOW_PANE is the layer that I find works best for attaching custom messages.

JavaScript:
  1. $("#message").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE));

To show the message div in place of the info window, we need to separate the click action into a separate function. Replace the map.panTo(marker.getLatLng(); with displayPoint(marker, i);, a call to the new displayPoint function shown below.

JavaScript:
  1. function displayPoint(marker, i){
  2.     map.panTo(marker.getPoint());
  3.    
  4.     var markerOffset = map.fromLatLngToDivPixel(marker.getPoint());
  5.     $("#message").show().css({ top:markerOffset.y, left:markerOffset.x });
  6. }

We put the panTo action in our new function. Then the magic function here is the map.fromLatLngToDivPixel(GLatLng); which converts the latitude/longitude of the marker into a pixel on the map div.  This returns a  object containing x (amount of pixels from the left of the map) and y (amount of pixels from the top of the map).

Final Step #8 - Add Some Spice

To finish up, we will add an event when the map stops panning. We can do this by attaching the "movend" event map object. This way, after panning to the marker you've clicked on we can use jQuery's fadeIn method to add some spice.

JavaScript:
  1. function displayPoint(marker, index){
  2.     $("#message").hide();
  3.    
  4.     var moveEnd = GEvent.addListener(map, "moveend", function(){
  5.         var markerOffset = map.fromLatLngToDivPixel(marker.getLatLng());
  6.         $("#message")
  7.             .fadeIn()
  8.             .css({ top:markerOffset.y, left:markerOffset.x });
  9.    
  10.         GEvent.removeListener(moveEnd);
  11.     });
  12.     map.panTo(marker.getLatLng());
  13. }

There you have it. We've come a long ways by adding our own custom click event, a clickable list and a custom info window. In the next tutorial, I'll show you how to store and retrieve points with a server-side language.

View Final Demo

Resizable WYMEditor with jQuery UI Resizable

Category: JavaScript & jQuery Tags: jQuery UI | Written on Jan 14, 2009

I took pyjax's WYMEditor resizable plugin and turned it into something that works for me using jQuery UI 1.6.

To use this, include jQuery, jQuery UI core and resizable, WYMEditor, then this. In that order.

JavaScript:
  1. WYMeditor.editor.prototype.resizable = function(options) {
  2.     var wym = this;
  3.     // Define some default options
  4.     var default_options = {
  5.             start: function(e, ui) {
  6.                 jQuery(wym._box).data("wym_height",
  7.                     jQuery(wym._box).find("iframe").height()
  8.                 );
  9.             },
  10.             stop: function(e, ui) {
  11.                 jQuery(wym._box).data("wym_height",
  12.                     jQuery(wym._box).find("iframe").height()
  13.                 );
  14.             },
  15.             // resize is called by the jQuery resizable plugin whenever the
  16.             // client area was resized.
  17.             resize: function(e, ui) {
  18.                 var diff = ui.size.height - ui.originalSize.height;
  19.                 jQuery(wym._box).find("iframe").height(jQuery(wym._box).data("wym_height") + diff);
  20.                 // If the plugin has horizontal resizing disabled we need to
  21.                 // adjust the "width" attribute of the area css, because the
  22.                 // resizing will set a fixed width (which breaks liquid layout
  23.                 // of the wymeditor area).
  24.                 if( !ui.options.handles['w'] && !ui.options.handles['e'] ) {
  25.                     ui.size.width = "inherit";
  26.                 }
  27.             },
  28.             handles: "s,e,se",
  29.             minHeight: 250,
  30.             maxHeight: 600
  31.         };
  32.  
  33.     // Merge given options with default options. Given options override
  34.     // default ones.
  35.     var final_options = jQuery.extend(default_options, options);
  36.  
  37.     jQuery(wym._box).resizable(final_options);
  38.  
  39. };

From this point, you can use a resizable WYMEditor by adding this to your postInit setting when you create a WYMEditor on the page.

JavaScript:
  1. wymeditor({postInit: function(wym) {
  2.         wym.hovertools(); // other plugins&hellip;
  3.         wym.resizable({handles: &ldquo;s,e&rdquo;,
  4.         maxHeight: 600});
  5.     }
  6. })

Go ahead and view the demo.

5 Tips for Better jQuery Code

Category: JavaScript & jQuery Tags: jQuery, Tutorial | Written on Nov 14, 2008

I've been coding using jQuery since shortly after it came out, and well -- I've been using it almost every work day. Here is a few tips that have saved me time.

#1: Use data method instead of storing data inside the DOM.

The mistake I see people making all the time is this:

JavaScript:
  1. $('selector').attr('alt', 'this is the data that I am storing');
  2. // then later getting that data with
  3. $('selector').attr('alt');

Why is this a bad thing?  Because "alt" has absolutely no meaning whatsoever, as well as HTML is not meant to store data.

Instead use the data method in jQuery. It allows you to associated data with an element on the page. 

JavaScript:
  1. $('selector').data('meaningfullname', 'this is the data I am storing');
  2. // then later getting the data with
  3. $('selector').data('meaningfullname');

This allows you to store data with meaningful names and as much data as you want on any element on the page. It is a really amazing utility and something I've come to rely on.

#2: Take advantage of jQuery's built-in custom selectors.

jQuery has a plentiful amount of selectors that are beyond basic CSS selectors, so use them. Some that I use are:

  • :input   example: get all the inputs on the page regardless if they are checkbox, textarea or select list - use :input
  • [attribute=value]   example: find an input with the name, "container" - use input[name='container']
  • :eq(index)  example: get the fourth table on the page - use table:eq(3)

#3: If you are Manipulating the DOM a lot, use livequery.

Note on March 21st, 2009: New in jQuery 1.3, the live method has adopted many of the same events of livequery into the core of jQuery.

Note on November 16th, 2008: If you understand event delegation, use it as an alternative to using livequery for attaching events.

When you add elements to the page a lot, attaching events to them and running functions on them then use Brandon Aaron's livequery plugin. This way you can do things like:

JavaScript:
  1. $('div.edit').livequery('click', function(){
  2. //go into edit mode
  3. });

Then whenever you add a div to the page with class "edit" it will attach that click event. This works for all other events, as well as if you want to run a function on an element right when it is added you can do this:

JavaScript:
  1. $('span.flag').livequery(function(){
  2. // run this function when a span with class "flag" is added to the page
  3. });

#4: Use jQuery form plugin to submit files via Ajax.

If you use Mike Alsup's jQuery form plugin you can use it to submit files via Ajax. It uses a trick with an iframe to submit the data. Just put in an input type file, then use $(form).ajaxSubmit(); and you are good to go.

#5: Use classes as flags.

If you aren't storing data, but need to set a flag on an element use a class. What do I mean by a flag? Well, for instance if you are in "edit mode" of a form you might use the class, "editing".  With jQuery you can add a class with the addClass method and then check later if an element has the class with the hasClass method.

 

Top Commenters Page

Category: Marc Grabanski's Work Tags: My Work, jQuery, CakePHP, MySQL | Written on Aug 19, 2008

An addition to my website is the top commenters page.  Even though the page doesn't look that complex, there is still a bit going on behind the scenes.

To get the top commenter count I have to thank Ryan Peterson in helping me write this custom MySQL query.  I used Group By to lump the results together based on the commenter's email address.  Then use count(*) to count the number of records in the group. Also used the NOT function in MySQL to filter my email address.

Mysql:
  1. SELECT `Comment`.`author`, `Comment`.`id`, `Comment`.`url`, count(*) AS `count` FROM `cake_comments` AS `Comment` WHERE 1 = 1 AND NOT(`Comment`.`email`=\'m@marcgrabanski.com\') GROUP BY `Comment`.`email` ORDER BY `count` DESC LIMIT 0, 10

Since I didn't want to load all of the related comments at once, I decied to use a little jQuery and Ajax to show comments that they have made.

First, I put a span tag around the comment count, because without JavaScript you won't see this functionality. On page load I swapped the spans into links with $(this).replaceWith('<a>' + $(this).html() + '</a>');

Instead adding behavior later after append, I used a jQuery object inside replaceWith  so I can attach behavior to the link and I like how the code looks.

JavaScript:
  1. $(this).replaceWith(
  2.     $('<a>' + $(this).html() + '</a>').click(function(){
  3.         //code here
  4.     })
  5. );

Using CakePHP's JavaScript object generator, $javascript->object($data); it was easy to send JSON back to the client and parse with jQuery. Here is the full source of the JavaScript file.

JavaScript:
  1. $(document).ready(function(){
  2.     $('.get_comments').each(function(){
  3.         $(this).replaceWith(
  4.             $('<a>'+$(this).html()+'</a>').click(function(){
  5.                 link = $(this);
  6.                 $.post('comments/get/comments', {
  7.                     'data[Comment][id]': $(this).siblings('.author').attr('id')
  8.                 }, function(data){
  9.                     out = '';
  10.                     for (i in data) {
  11.                         prefix = data[i].Article.type ? 'article/' : 'answers/';
  12.                         out += '<li><a href="' + prefix + data[i].Article.slug + '#c' + data[i].Comment.id + '">' + data[i].Article.title + '</a>' +
  13.                             data[i].Comment.created + '</li>';
  14.                     }
  15.                     $('<ol>' + out + '</ol>').hide().appendTo(link.parents('li:first')).slideDown();
  16.                     $(link).replaceWith( $(link).html() );
  17.                 }, 'json');
  18.             })
  19.         );
  20.     });
  21. });

 

Update: I think I'll post the CakePHP code just in case someone is interested. Here is the controller, I use the RequestHandler component var $components = array('RequestHandler'); and the Time helper var $helpers = array('Time'); in the top of the controller.

PHP:
  1. function get($type = null)
  2. {
  3.     if ($this->RequestHandler->isAjax()) {
  4.         Configure::write('debug', 0);
  5.         if ($type == 'comments') {
  6.             $comment = $this->Comment->read(array('Comment.email'), $this->data['Comment']['id']);
  7.             $results = $this->Comment->find('all', array(
  8.                 'conditions' => array('email' => $comment['Comment']['email']),
  9.                 'fields' => 'Article.title, Article.slug, Article.type, Comment.id, Comment.created'
  10.             ));
  11.             $this->set(compact('results'));
  12.         }
  13.     }
  14. }

I also turn debug off with Configure::write('debug', 0);. Also, I only use $type  so that I can setup my code to get types of data if I want later - more of a design pattern I typically follow.

Then in my view I use the time helper and output a JSON object.

PHP:
  1. <?php
  2. if ($result):
  3.         if (isset($result['Comment']['created'])):
  4.             $results[$key]['Comment']['created'] =
  5.                 $time->timeAgoInWords($result['Comment']['created']);
  6.         endif;
  7.     endforeach;
  8.     echo  $javascript->object($results);
  9. ?>

 

To see in action, click the comments count next to someone's name on the top commenters page.

jQuery UI Datepicker Themes

Category: JavaScript & jQuery Tags: jQuery, JavaScript, My Work | Written on Aug 08, 2008

Note on March 9th, 2010: The datepicker themes are customizable through the jQuery UI Themeroller.

jQuery Tip - Getting Select List Values

Category: JavaScript & jQuery Tags: jQuery, Tutorial | Written on Jul 22, 2008

Chris Hartjes asked me a simple question today, but it is worth noting because I have asked the same before, "How do you get the current value from a select list?"

To get the current value is very simple using val().

JavaScript:
  1. $('#selectList').val();

But sometimes you may need to get the selected option's text. This is not as straight forward. First, we get the selected option with :selected selector. Then once we have the option, we can get the text with the function, text().

JavaScript:
  1. $('#selectList :selected').text()

View Demo:

Note on July 23 @9:14AM: HoyaSaxa93 wrote in to ask how to get values from select multiples. I will create the demo and code below. This would be how to set a select multiple to an array called, "foo".

JavaScript:
  1. var foo = [];
  2. $('#multiple :selected').each(function(i, selected){
  3.     foo[i] = $(selected).text();
  4. });

Make a "Scroll To Next Article" Button with jQuery

Category: JavaScript & jQuery Tags: jQuery | Written on Jul 18, 2008

If you view my articles page, you will see a, "next" button on the bottom left of the browser window that looks like this:
Click the arrow, and it will take you to the next article on the page.

To create this, first lets setup the CSS.  The key in here is the position: fixed; bottom: 2%; left: 2%; statement.  This pins the arrow to the bottom left of the browser window.  Since position fixed doesn't work in IE6, I just hide the div with the * html hack - I know I'm bad ;)  Since Apple dropped support for IE6, I might as well for the advanced features.

Css:
  1. #next_arrow {
  2.     width: 50px;
  3.     padding-top: 50px;
  4.     background: url(../img/structure/backgrounds/next_arrow.gif) no-repeat top left;
  5.     text-align: center;
  6.     position: fixed;
  7.     bottom: 2%;
  8.     left: 2%;
  9.     z-index: 999;
  10. }
  11. * html #next_arrow {
  12.     display: none;
  13. }
  14. #next_arrow:hover {
  15.     cursor: pointer;
  16. }

Using the scrollTo plugin, this is a fairly straight forward task to make the window scroll to the next article.  Here is the code I am using:

JavaScript:
  1. jQuery(function($){
  2.        
  3.     $('<div id="next_arrow">Next</div>')
  4.         .prependTo("body") //append the Next arrow div to the bottom of the document
  5.         .click(function(){
  6.             scrollTop = $(window).scrollTop();
  7.             $('#content h2').each(function(i, h2){ // loop through article headings
  8.                 h2top = $(h2).offset().top; // get article heading top
  9.                 if (scrollTop < h2top) { // compare if document is below heading
  10.                     $.scrollTo(h2, 800); // scroll to in .8 of a second
  11.                     return false; // exit function
  12.                 }
  13.             });
  14.         });
  15.    
  16. });

If you read my comments in the code, you should be able to know what's going on here. The only thing you have to worry about is changing the selector #content h2 to your article heading selector.

That's it, now you have a skip to next article button!

Tutorial - CakePHP Ajax "Quick Save" with jQuery

Category: PHP & CakePHP Tags: CakePHP, jQuery | Written on Jul 15, 2008

When you are in an administration panel, sometimes you want a "quick save" feature that allows you to save without leaving the page.  Here is how to accomplish this with CakePHP and jQuery.

To start, download jQuery and the jQuery Form Plugin JavaScript.  Include them in your view with the JavaScript helper:

PHP:
  1. $javascript->link(array('jquery', 'form'), false);

Include the RequestHandler in your controller detect an Ajax save attempt.  Also include the JavaScript helper if you haven't already.

PHP:
  1. var $helpers = array('Javascript');
  2. var $components = array('RequestHandler');

Next we want to override our save function with the ajax quick save.  Put this right before your $this->Model->save($this->data) in your save action.

PHP:
  1. if ($this->RequestHandler->isAjax()) {
  2.     if ($this->Article->save($this->data)) {
  3.         echo 'success';
  4.     }
  5.     Configure::write('debug', 0);
  6.     $this->autoRender = false;
  7.     exit();
  8. }

This detects if the request is ajax, then saves the data.  Then it sends back a simple, "success" message to let you know things went fine.  It also writes debug to 0 and doesn't render anything, then exits.

Lastly, lets create and include a JavaScript file that performs the quick save.

JavaScript:
  1. jQuery(function($){
  2.     $('<input type="button" value="Quick Save" />')
  3.         .click(function(){
  4.             $(this).parents("form:first").ajaxSubmit({
  5.                 success: function(responseText, responseCode) {
  6.                     $('#ajax-save-message').hide().html(responseText).fadeIn();
  7.                     setTimeout(function(){
  8.                         $('#ajax-save-message').fadeOut();
  9.                     }, 5000);
  10.                 }
  11.             });
  12.             return false;
  13.         })
  14.         .appendTo('form div.submit');
  15. });

This adds a button called, "Quick Save" to each form on the page where a div with class="submit" exists (you may want to switch this to the id of the form you want to add quick save to). Then It also attaches a click event to the button that submits the form via the jQuery Form Plugin.

In a few simple steps, we've created a quick save feature that saves your data whenever you want without leaving the page.

Published on LearningjQuery.com - Introduction to jQuery UI

Category: JavaScript & jQuery Tags: jQuery, jQuery UI | Written on Jul 02, 2008

I published an article on learningjquery.com titled, "Introduction to jQuery UI" - I hope you enjoy the article!

As a member of the jQuery UI team, I felt compelled to write this introduction because I didn't see any tutorials starting from the ground level.  I'm hoping the article will help people get their feet wet with jQuery UI.

Version 2 of MarcGrabanski.com Launched!

Category: Marc Grabanski's Work Tags: My Work, CakePHP, jQuery | Written on Jun 25, 2008

CakePHP Logo  jQuery Logo 

Note on June 27th: The website is now usable on IE6 and IE7.

Rebuilt from scratch on top of CakePHP and jQuery, version 2 of MarcGrabanski.com has been launched!

The first version was on top of PHP and HTML, which turned into a mess to maintain. This time I really thought long and hard on how to code the website from the ground-up. It is a psuedo CMS, blog and takes advantage of much of CakePHP's strengths.  The code is 100% hand written in a text editor, as well as the design was done in illustrator. I purchased the computer/face, then heavily modified it and illustrated all of the items around the monitor and keyboard. I enjoy illustrating but don't get to do it very often (too much coding). 

Finally I feel like I have a website to be pleased about - despite the compliments on the old website by far and wide audiences, I was never too happy with it.  But, this one I enjoy and am pleased with.  Which is ultimately what matters.  With this website I will be able to post more (hopefully) and definately have a much easier time maintaining.

Enjoy the new website, I know I will!

P.S. Please report any bugs you find in the new site to m@marcgrabanski.com

jQuery Plugin Actions vs Utilities

Category: JavaScript & jQuery Tags: jQuery | Written on Jan 24, 2008

Jonathan Snook posted about developing a jQuery plugin. I started a comment and it turned into a post.

One question I've gotten from people moving to jQuery from other libraries is, "How do you extend a native object?" This is something you never do in jQuery, in fact it is against the philosophy of jQuery. One of the goals with jQuery is to be as unobtrusive to the native JavaScript language as possible - that way it plays nicely with other libraries and code. In this case you would want to create a utility plugin instead of an action plugin. Here is an example of using a utility plugin:

JavaScript:
  1. $.formatDate(new Date(), 'm d Y')

This would return a string, not an object for chaining. So now if we want to perform an action with it... such as insert the value into a div we would use:

JavaScript:
  1. $('#myDiv').html($.formatDate(new Date(), 'm d Y'));

I just wanted to point out a common pitfall when making a plugin. Some are utilities, and some are actions. A utility plugin returns a result, but an action plugin is something that returns an object for chaining. Take the method attachDatepicker, for instance:

JavaScript:
  1. $('#myInput').datepicker().val('select a date');

It can be chained because it returns the input with the datepicker attached. You can see more examples of actions vs utilities in the Datepicker Documentation or look at the jQuery Utilities (example of utilities) vs jQuery Manipulation (example of actions).

Google Uses UI Datepicker

Category: Google & Yahoo Tags: jQuery, JavaScript, My Work | Written on Dec 28, 2007

Google let me know that they are using jQuery UI Datepicker on Google Code (http://code.google.com/events/calendar/add/). This is great news, Google is actually adopting something I wrote! Here is a screenshot:

Google Code using UI Datepicker

Google did a nice job of changing the colors to match their site (refer to the screenshot above). I think the simple skin provides an easy way to adopt the datepicker's look and feel into web applications, but I think that we need new skins for the datepicker. If anyone wants to contribute designs please let me know.

I can't leave this post without mentioning Keith Wood, thanks for all the great work. And to everyone who has sent me emails and feedback, thanks again!

Getting jQuery into Big Corporations

Category: JavaScript & jQuery Tags: jQuery, JavaScript, Business | Written on Dec 05, 2007

Corporation Buildings

Big Corporation IT

Big corporations are typically resistant to adopting change - and for good reason. They have to work at keeping stable a large amount of applications in one environment. Internal IT teams will usually only adopt something if it doesn't interfere with their jobs or make them more difficult. You must have a really good reason to bring something new in. I understanding that, so how do you get them to approve you using a relatively new library like jQuery?

The Easy Way

The simplest way I've found to get jQuery into projects is use it for doing something very specialized. Creating tabbed panes, graphing data, or maybe some simple animation effects that are normally created in Flash. Either way, from that point on you can use it in the application. But what if you want to build a project from the get-go, from scratch in jQuery?

Big Corporation Project, Built on jQuery

Currently I am building a Google Maps application for one of the biggest banks in the world, HSBC. It is almost done, and I used jQuery to build the application with my manager's approval. As expected, when we handed the code off to HSBC's internal IT team in India they asked why we used jQuery:

"Is there any advantage of using jquery as google is already providing Ajax api for the same purpose. Also please clarify whether there is any licensing issues with jquery. If it is free, then can we use in commercial projects?"

My response:

jQuery is used is for parsing XML and adding behavior to the page elements in a faster and more compatible way. jQuery eliminates the problems that JavaScript has with inconsistent rendering between browsers and jQuery also improves the rendering speed / performance of the application. The code is arguably easier to maintain because it reduces the overall code size of the application because you do not have to code in different ways depending on the browser.

jQuery is dual licensed under the MIT and GPL licenses (http://docs.jquery.com/License), which means that it is 100% free for commercial use.

Note that jQuery is used by: Google, NBC, MSNBC, Bank of America, Amazon, Intel, BBC, Newsweek, AOL and Intuit - just to name a few. Full list: http://docs.jquery.com/Sites_Using_jQuery

A very vibrant and active community surrounds jQuery and it will continue to be well documented and maintained.

My response was very well received - feel free to use that explanation in your own corporation. I have to say though it has been much easier to get accepted since Google uses jQuery. My feeling is that internally to use jQuery you really only need your manager's approval. Once you sell him and your immediate team around you on the idea, you shouldn't have a problem using jQuery for projects. After all, it makes all of our lives easier. jQuery has saved me countless hours and the client's work is going to be better because of it. Thanks, John and the jQuery team.

jQuery Makes Parsing XML Easy

Category: JavaScript & jQuery Tags: jQuery, JavaScript, XML | Written before Dec, 2007

I am building a Google Maps project and jQuery is making my life so much easier when parsing XML.

Regular JavaScript XML Parsing

JavaScript:
  1. var xmlDoc = request.responseXML;
  2. try // Build Markers, if available
  3. {
  4.     var markers = xmlDoc.getElementsByTagName("marker") ;
  5.     for ( var i = 0; i < markers.length ; i++ )
  6.     {
  7.         var point = {
  8.             markers[i].getAttribute("lat")),
  9.             markers[i].getAttribute("lng")
  10.         };
  11.     }
  12. } catch(e) {}

jQuery XML Parsing

JavaScript:
  1. $(request.responseXML).find("marker").each(function() {
  2.     var marker = $(this);
  3.     var point = {
  4.         marker.attr("lat"),
  5.         marker.attr("lng")
  6.     };
  7. });

The jQuery code is so much easier to read and understand. This is a basic example, but imagine when things get complex. After writing a few complex statements, you will realize the jQuery code will still be understandable, where as the JavaScript code will become hard to maintain. Thank you jQuery for making my job easier and more fun.

List of Useful jQuery Plugins

Category: JavaScript & jQuery Tags: jQuery, JavaScript | Written before Dec, 2007

I viewed each of the jQuery plugins in the jQuery plugins repository. I couldn't believe how many there were! So I decided to make this master list to weed out any plugins that were either broken or I didn't find any practical application for. You will notice I added, "EXCELLENT" to the plugins that I thought were exceptional.

  • Accessibility Stylesheet and text size switcher.
  • Accordion Accordion interface with a few variations.
  • AlphaNumeric Prevent users from inputing special characters.
  • Ajax File Upload Loading graphic displays while file is uploaded.
  • appendDom Write HTML with JavaScript, great for displaying Ajax results.
  • appendText Converts text into post friendly html.
  • blockUIEXCELLENT Create a message overlay while blocking user interaction on elements or the entire page.
  • BogoFolders View text through a 'file menu' interface.
  • BogoTabs Basic tabbed interface.
  • Bubble Demo highlights selected table rows in groups of tables..
  • Calendar Aids date entry.
  • Checkbox manipulation Select, unselect and toggle checkboxes.
  • ChiliEXCELLENT Syntax highlighting for displaying code on webpages.
  • Choose Component Select data from a table row through a modal window.
  • Click Menu Generates dropdown menus.
  • clueTip Tooltips with many variations.
  • Color Animations Add color animations to div backgrounds.
  • Color Picker Pass in color choices and attach custom events to each color block.
  • columnHover Highlight table rows and columns.
  • columnManager Add, remove and toggle table columns.
  • ContextMenu - Menus that show when you right click specified elements.
  • Confirmer Adds a listener to check if user confirms their action.
  • CycleEXCELLENT Add flash-like image effects to rotating image galleries.
  • date picker Aids date entry.
  • Delicious Read delicious bookmarks from a user to display on a webpage.
  • Dimensions Get accurate window and document attributes across browsers.
  • Equalize Columns Make columns the same height as the longest column.
  • FCKEditor Plugin Adds a rich text editor to a textarea.
  • Field Expand the ability to retrieve and set values in forms.
  • FormEXCELLENT Change HTML forms to submit via Ajax.
  • Gallery Viewer JavaScript image gallery.
  • getUrlParam Function to get url parameters.
  • Google Feed Plugin Display any RSS feed to a webpage.
  • Gradient Adds a gradient to a div without needing an image.
  • Grid Column Sizing Table column draggable resizing.
  • Grid Row Sizing Expand and collapse table rows.
  • hoverIntent Prevents unintended hover events.
  • idTabs Add tabbed interface to a website.
  • Impromptu Create modal windows and messages.
  • jQuery Localisation Applies localisation packages based on the user's language preference.
  • jBox UI dialog widget.
  • jCalendar Aids selecting of dates inline on a page.
  • jCarousel Lite Simple carousel for images and HTML content.
  • jCodeViewer Syntax highlighting for displaying code on webpages.
  • jdMenu Hierarchical Menu Generates dropdown menus.
  • jEditable Live editing of elements on a webpage.
  • jFeed XML feed parser.
  • jPanView Replaces big images with a zoom viewer in HTML.
  • jqDnR Drag'n'Resize elements on a page.
  • jQMaps Interact with Google maps.
  • jqModal Display notices, dialogs, and modal windows in a web browser.
  • Treetable Make a tree view out of an HTML table.
  • Tree ViewEXCELLENT Tree view controls.
  • Suggest Add autocomplete to input fields.
  • YAV Form validation library.
  • jqUploader Provides a status bar for uploading images.
  • jScrollPane Customize your scrollbars.
  • jTagEditor EXCELLENT Turn a textarea into a tag editor.
  • jVariations Create a control panel to manipulate elements on a page.
  • Keyboard Navigation Dynamically determine which element to focus on based on it's position on the screen.
  • labelOver Overlay labels over an input field.
  • LavaLamp Navigation menu with a 'lava' effect.
  • Lazy Load Only load images that are in the current window.
  • Live Query Adds event listeners to elements.
  • Masked Input Add mask to inputs to aid user data entry (phone numbers, etc).
  • Media EXCELLENT Unobtrusive conversion of standard markup into rich media content.
  • Extra selectors for JQuery Add more selectors to jQuery.
  • Mousewheel Mousewheel event handler.
  • Mousehold Event Add repeating event as the user holds down the mouse.
  • Multiple File Upload Select multiple files one by one as it adds to a queue list.
  • newsticker Create a fading news ticker.
  • Password Strength Meter Indicator to show the strength of a users password.
  • PopupWindow Creates an preview popup of destination link.
  • Query String Object Useful for sending URL parameters.
  • Select box manipulation Remove and add options from a select list or dropdown in many ways.
  • selectCombo Tool for making dependant dropdowns with Ajax.
  • Star Rating Generates star rating from input fields
  • Grid Dynamic ajax grid control.
  • slideViewer Image gallery as slides.
  • Spoilers Hide content behind an image until user action is taken.
  • tableHover Row and column highlighting with variations.
  • tableFilter Search box is added to each column header to filter table.
  • tablesorter Client side table sorting.
  • Taconite EXCELLENT Easily make multiple DOM updates using the results of a single AJAX call.
  • Textgrad Add gradients to whole blocks of text.
  • Time Entry Sets an input field up to accept a time value.
  • Tooltip Add tooltips from title page.
  • Validation EXCELLENT Add live validation to forms.
  • WYMeditor EXCELLENT Web-based XHTML WYSIWYM editor.
  • Zoomi Zoomable thumbnails.
  • XSLT Transform XML/XSL from JavaScript.
  • XAP Ajax library.

Other Reading - Categories