Here are the before and after examples:
This simple Portlets example comes from the jQuery UI demo found at http://jqueryui.com/demos/sortable/#portlets.
The JavaScript Version:
(function (portlets, undefined) { portlets.init = function() { $(".column").sortable({ connectWith: ".column" }); $(".portlet") .addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all") .find(".portlet-header").addClass("ui-widget-header ui-corner-all") .prepend("<span class='ui-icon ui-icon-minusthick'></span>") .end().find(".portlet-content"); $(".portlet-header .ui-icon").click(function () { $(this).toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick"); $(this).parents(".portlet:first").find(".portlet-content").toggle(); }); $(".column").disableSelection(); }; } (window.portlets = window.portlets || {}));
The CoffeeScript Version:
((portlets) -> portlets.init = -> $(".column").sortable(connectWith: ".column").disableSelection() $(".portlet") .addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all") .find(".portlet-header").addClass("ui-widget-header ui-corner-all") .prepend("<span class='ui-icon ui-icon-minusthick'></span>") .end().find ".portlet-content" $(".portlet-header .ui-icon").click -> $(this).toggleClass("ui-icon-minusthick").toggleClass "ui-icon-plusthick" $(this).parents(".portlet:first").find(".portlet-content").toggle() ) window.portlets = window.portlets or {}
This simple Photo Manager example comes from the jQuery UI demo found at http://jqueryui.com/demos/droppable/#photo-manager.
The JavaScript Version:
(function (pictureManager, undefined) { pictureManager.init = function() { var $gallery = $("#gallery"), $trash = $("#trash"); $( "li", $gallery ).draggable({ cancel: "a.ui-icon", revert: "invalid", containment: $( "#demo-frame" ).length ? "#demo-frame" : "document", helper: "clone", cursor: "move" }); $trash.droppable({ accept: "#gallery > li", activeClass: "ui-state-highlight", drop: function( event, ui ) { deleteImage( ui.draggable ); } }); $gallery.droppable({ accept: "#trash li", activeClass: "custom-state-active", drop: function( event, ui ) { recycleImage( ui.draggable ); } }); $("ul.gallery > li").click(function (event) { var $item = $(this), $target = $(event.target); if ($target.is("a.ui-icon-trash")) { deleteImage($item); } else if ($target.is("a.ui-icon-zoomin")) { viewLargerImage($target); } else if ($target.is("a.ui-icon-refresh")) { recycleImage($item); } return false; }); var recycle_icon = "<a href='link/to/recycle/script/when/we/have/js/off' title='Recycle this image' class='ui-icon ui-icon-refresh'>Recycle image</a>"; function deleteImage($item) { $item.fadeOut(function () { var $list = $("ul", $trash).length ? $("ul", $trash) : $("<ul class='gallery ui-helper-reset'/>").appendTo($trash); $item.find("a.ui-icon-trash").remove(); $item.append(recycle_icon).appendTo($list).fadeIn(function () { $item .animate({ width: "48px" }) .find("img") .animate({ height: "36px" }); }); }); } var trash_icon = "<a href='link/to/trash/script/when/we/have/js/off' title='Delete this image' class='ui-icon ui-icon-trash'>Delete image</a>"; function recycleImage($item) { $item.fadeOut(function () { $item .find("a.ui-icon-refresh") .remove() .end() .css("width", "96px") .append(trash_icon) .find("img") .css("height", "72px") .end() .appendTo($gallery) .fadeIn(); }); } function viewLargerImage($link) { var src = $link.attr("href"), title = $link.siblings("img").attr("alt"), $modal = $("img[src$='" + src + "']"); if ($modal.length) { $modal.dialog("open"); } else { var img = $("<img alt='" + title + "' width='384' height='288' style='display: none; padding: 8px;' />") .attr("src", src).appendTo("body"); setTimeout(function () { img.dialog({ title: title, width: 400, modal: true }); }, 1); } } }; } (window.pictureManager = window.pictureManager || {}));
The CoffeeScript Version:
((pictureManager) -> pictureManager.init = -> $gallery = $("#gallery") $trash = $("#trash") recycle_icon = "<a href='link/to/recycle/script/when/we/have/js/off' title='Recycle this image' class='ui-icon ui-icon-refresh'>Recycle image</a>" trash_icon = "<a href='link/to/trash/script/when/we/have/js/off' title='Delete this image' class='ui-icon ui-icon-trash'>Delete image</a>" deleteImage = ($item) -> $item.fadeOut -> $list = if $("ul", $trash).length then $("ul", $trash) else $("<ul class='gallery ui-helper-reset'/>").appendTo $trash $item.find("a.ui-icon-trash").remove() $item.append(recycle_icon).appendTo($list).fadeIn -> $item.animate(width: "48px").find("img").animate height: "36px" recycleImage = ($item) -> $item.fadeOut -> $item.find("a.ui-icon-refresh").remove().end() .css("width", "96px").append(trash_icon).find("img") .css("height", "72px").end().appendTo($gallery).fadeIn() viewLargerImage = ($link) -> src = $link.attr "href" title = $link.siblings("img").attr "alt" $modal = $("img[src$='#{src}']") if $modal.length $modal.dialog "open" else img = $("<img alt='#{title}' width='384' height='288' style='display: none; padding: 8px;' />") .attr("src", src).appendTo "body" setTimeout (-> img.dialog title: title width: 400 modal: true ), 1 $("li", $gallery).draggable cancel: "a.ui-icon" revert: "invalid" containment: if $("#demo-frame").length then "#demo-frame" else "document" helper: "clone" cursor: "move" $trash.droppable accept: "#gallery > li" activeClass: "ui-state-highlight" drop: (event, ui) -> deleteImage ui.draggable $gallery.droppable accept: "#trash li" activeClass: "custom-state-active" drop: (event, ui) -> recycleImage ui.draggable $("ul.gallery > li").click (event) -> $item = $(this) $target = $(event.target) if $target.is "a.ui-icon-trash" deleteImage $item else if $target.is "a.ui-icon-zoomin" viewLargerImage $target else recycleImage $item if $target.is "a.ui-icon-refresh" false ) window.pictureManager = window.pictureManager or {}
This simple User Manager example comes from the jQuery UI demo found at http://jqueryui.com/demos/dialog/#modal-form.
The JavaScript Version:
(function (userManager, undefined) { userManager.init = function () { $("#dialog:ui-dialog").dialog("destroy"); var name = $("#name"), email = $("#email"), password = $("#password"), allFields = $([]).add(name).add(email).add(password), tips = $(".validateTips"); function updateTips(t) { tips .text(t) .addClass("ui-state-highlight"); setTimeout(function () { tips.removeClass("ui-state-highlight", 1500); }, 500); } function checkLength(o, n, min, max) { if (o.val().length > max || o.val().length < min) { o.addClass("ui-state-error"); updateTips("Length of " + n + " must be between " + min + " and " + max + "."); return false; } else { return true; } } function checkRegexp(o, regexp, n) { if (!(regexp.test(o.val()))) { o.addClass("ui-state-error"); updateTips(n); return false; } else { return true; } } $("#dialog-form").dialog({ autoOpen: false, height: 300, width: 350, modal: true, buttons: { "Create an account": function () { var bValid = true; allFields.removeClass("ui-state-error"); bValid = bValid && checkLength(name, "username", 3, 16); bValid = bValid && checkLength(email, "email", 6, 80); bValid = bValid && checkLength(password, "password", 5, 16); bValid = bValid && checkRegexp(name, /^[a-z]([0-9a-z_])+$/i, "Username may consist of a-z, 0-9, underscores, begin with a letter."); bValid = bValid && checkRegexp(email, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i, "eg. ui@jquery.com"); bValid = bValid && checkRegexp(password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9"); if (bValid) { $("#users tbody").append("<tr>" + "<td>" + name.val() + "</td>" + "<td>" + email.val() + "</td>" + "<td>" + password.val() + "</td>" + "</tr>"); $(this).dialog("close"); } }, Cancel: function () { $(this).dialog("close"); } }, close: function () { allFields.val("").removeClass("ui-state-error"); } }); $("#create-user") .button() .click(function () { $("#dialog-form").dialog("open"); }); }; } (window.userManager = window.userManager || {}));
The CoffeeScript Version:
((userManager) -> userManager.init = -> name = $("#name") email = $("#email") password = $("#password") allFields = $([]).add(name).add(email).add password tips = $(".validateTips") updateTips = (t) -> tips.text(t).addClass "ui-state-highlight" setTimeout (-> tips.removeClass "ui-state-highlight", 1500 ), 500 checkLength = (o, n, min, max) -> if o.val().length > max or o.val().length < min o.addClass "ui-state-error" updateTips "Length of #{n} must be between #{min} and #{max}." false else true checkRegexp = (o, regexp, n) -> unless regexp.test o.val() o.addClass "ui-state-error" updateTips n false else true $("#dialog-form").dialog autoOpen: false height: 300 width: 350 modal: true buttons: "Create an account": -> bValid = true allFields.removeClass "ui-state-error" bValid = bValid and checkLength name, "username", 3, 16 bValid = bValid and checkLength email, "email", 6, 80 bValid = bValid and checkLength password, "password", 5, 16 bValid = bValid and checkRegexp name, /^[a-z]([0-9a-z_])+$/i, "Username may consist of a-z, 0-9, underscores, begin with a letter." bValid = bValid and checkRegexp email, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i, "eg. ui@jquery.com" bValid = bValid and checkRegexp password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9" if bValid $("#users tbody").append "<tr>" + "<td>" + name.val() + "</td>" + "<td>" + email.val() + "</td>" + "<td>" + password.val() + "</td>" + "</tr>" $(this).dialog "close" Cancel: -> $(this).dialog "close" close: -> allFields.val("").removeClass "ui-state-error" $("#dialog:ui-dialog").dialog "destroy" $("#create-user").button().click -> $("#dialog-form").dialog "open" ) window.userManager = window.userManager or {}