Viewing Category: JavaScript  [clear category selection]

User Interface Elements

The way that myOpenID does user feedback on pages with forms is understated and functional. In their HTML source, they give this content the “alert box” class, and have a link to dismiss the message at the upper right. This seems very Facebook-esque, which leads me to believe it's a widely seen/used/understood user interface element. Not too long ago, I coded a site that had UI messages very similar to this, with a jQuery timer that hid the message after a few seconds. I'd bet that no matter how many seconds it waited to remove the message, it was wrong. It also slid content up the page without a user input — another no-no.

I should note that the green trim around the main content area is clipped weirdly because of my screenshot dimensions, not due to their design. It looks much better with the rest of the site chrome.

Dynamic favicon Loading

It hadn't occurred to me previously, but today I wanted to dynamically the change the favicon file used on a site/page. It's been possible using JavaScript in Firefox and Opera for at least three years, and there is a really clean library by Michael Mahemoff that makes the task trivial. This method doesn't work in Microsoft Internet Explorer or Safari. There might be another mechanism to dynamically add and remove link elements to the document head, but I haven't seen it yet.

While searching for information, I happened upon DEFENDER of the favicon -- a classic arcade game played through a 16x16 pixel portal. Crazy.

jQuery Messaging Plugin Screencast

I've been working on an enterprise information management application. One of the requirements on the form validation is to gracefully handle client-side and server-side validation. The form uses the jQuery Validate and Form plugins. The plugin I wrote handles the receipt of server-side validation messages, and updates the UI in the same was as the client-side validation. A screencast showing how it works is now available on Vimeo.

The plugin is short, so I'll just post it here:

(function($) { $.extend({ messaging : function(action, data) { var defaults = { feedback: "#feedback", status: "#status", form: "form", validator: "validator" }; if (action == undefined || action == "") { action = "config"; } if (action == "config") { this.settings = $.extend({}, defaults, data); var $status = $(this.settings.status).hide().removeClass("hidden"); var $feedback = $(this.settings.feedback); $().ajaxStart(function() { $status.show(); }).ajaxStop(function() { $status.hide(); }).ajaxError(function(ajaxError, XMLHttpRequest, ajaxOptions, errorText) { $status.hide(); $feedback.removeClass().addClass("error").text("An error occurred while posting the form."); }); } if (action == "receive") { var $message = $("message", data); var $feedback = $(this.settings.feedback); var $form = $(this.settings.form); var errors = new Object(); if ($message.children("status").text() == "success") { $feedback.removeClass().addClass("success").text($message.children("text").text()); } else { $feedback.removeClass().addClass("error").text($message.children("text").text()); $message.find("validationMessages message").each(function() { var $msg = $(this); errors[$msg.attr("fieldName")] = $msg.text(); }); if ($message.children("validationMessages").attr("count") > 0) { $form.data(this.settings.validator).showErrors(errors); } } } } }) })(jQuery);

Here is the call to configure the plugin from the main document:

$.messaging("config", { form: "#accountForm" });

The integration with the Validator seems a little kludgey, but after trying many ways, I settled on this.

$form.data("validator", $form.validate(validationOptions));

The callback from the AJAX submit passes the XML to the messaging plugin:

var validationOptions = { submitHandler: function(form) { $(form).ajaxSubmit({ dataType: "xml", success: function(data, status) { $.messaging("receive", data); } }); } };

I hope that's useful. I'll keep updating the plugin and post a link to its Subversion repository.

jQuery UI Dialog Widget Screencast

I just uploaded a screencast showing how I use jQuery UI to implement a simple “popup” window that allows the user to verfiy the password of an account in an LDAP server. While working in it, I didn't see many examples showing the best practice for passing data from a link in the page to the dynamically created dialog widget. View the screencast with the following link to Vimeo.

Consider the following link that might exist for each user in a group of records:

<a href="#username:fred" class="verify-password">Verify Password</a>

In the jQuery code executed when the page is loaded, it wires up the click event for the link:

$("a.verify-password").click( function() { var username = this.hash.split(':')[1]; $("#verifyPassword").dialog("open").data("username", username); return false; } );

Notice the call to the jQuery.data() method. This is the connection between the link and the dialog widget created by its click event. Here's the simple container that is wrapped up within the dialog widget:

<div id="verifyPassword"> <form name="passwordForm" onsubmit="return false;"> <input type="password" name="password"/> </form> <p class="result"></p> </div>

To put it all together, here is the code that configures the dialog widget. Notice that the Verify button makes use of the username data.

$("#verifyPassword").dialog({ title: "Verify Password", buttons: { "Verify": function() { $.ajax({ data: { var $v = $("#verifyPassword"); username: $v.data("username"), password: $v.find("input[name='password']").val() }, success: function(data, status) { // Do some interesting things with data } }); }, } });

The actual implementation has a whole lot more detail. I tried to strip out everything that wasn't necessary to communicate the dialog widget usage.

Offline Warning with JavaScript

The requirement is to check whether an HTML file has been loaded from a local source, say a CD-ROM, or from a website. It's possible to test the document.location.protocol value and act accordingly. This doesn't actually check to see if a valid network connection exists -- that would require a different test to attempt loading something from a remote site. The handleLinkClick function just evaluates the protocol to be used when a link from a local file is clicked.

<script> function handleLinkClick(link) { if (document.location.protocol == "file:" && link.protocol != "file:") { return confirm("This link requires Internet access.\nClick cancel if you're not online."); } return true; } </script>

In the body of the local document, the links would be updated with the onclick attribute. Technically, only the remote links need to be changed, but if a global search-and-replace didn't differentiate, that would be fine.

<a href="http://www.google.com" onclick="return handleLinkClick(this);">Remote Site</a><br/> <a href="file.html" onclick="return handleLinkClick(this);">Local File</a>

Unfortunately, if the user doesn't follow the instructions, and clicks OK when they don't actually have Internet access, they'll get an error from their web browser about being unable to access the page. Can't help you there...