About a month ago I introduced FogJS. On the main FogJS site, there are a couple of code examples that you can use to quickly start interacting with Blob Storage, Table Storage, or the Azure Service Bus. However, if you're new to using Azure from Node.js, then you may be wondering what other steps need to be done to get a dev environment up and running. While you can glean the steps by reading various How-To Guides provided on the Azure site, it can sometimes be helpful to have the process described in a slightly different way. In this post, I'll show you how to quickly get a Windows machine setup to interact with Emulator Table Storage using FogJS. I'll follow a similar structure as the Node.js Getting Started Guide and a few of the steps between this post and that guide overlap. Some of the key differences include the use of a WorkerRole rather than a WebRole, the use of the emulator, and of course the use of FogJS.
Setting up Your Windows Machine:
1. Install Node.js from http://nodejs.org/.
2. Install the Windows Azure SDK for Node.js (this may require a reboot).
3. Open a PowerShell command prompt and navigate to the parent location at which you wish to create a project. I'll use c:\Temp for this example.
4. Run the following command to create a couple of starter files for your project (note: FogJSExample should be replaced with the name of the project that you wish to create).
New-AzureServiceProject FogJSExample
6. Navigate to the FogJSExample directory and install FogJS with the command:
npm install fogjs
5. Create a worker role with the following command (note: TableStorageWorker should be replaced with the name of the worker that you wish to create).
Add-AzureNodeWorkerRole TableStorageWorker
7. Navigate to the TableStorageWorker directory, edit the server.js file, and replace the text within it with the following:
8. Set your environment to use the Azure Storage Emulator for Table Storage with the following command (note: You can verify that this command is set with the command ls env:EMULATED).
$env:EMULATED = "true"
9. Run the following command to start the Azure Emulator (note: The emulator does not support Service Bus interaction. For working with Azure Service Bus, you will need to setup environment variables as defined here).
Start-AzureEmulator
10. Open a browser and navigate to http://localhost:81. This will cause a request to go to your Node service. When that request is received, a record is created in Table storage, then retrieved and used to populate the output that will be displayed, and finally deleted.
That's all there is to it. You can find the source for FogJS on my GitHub.
Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts
Tuesday, December 17, 2013
Monday, November 18, 2013
Announcing FogJS for Windows Azure with Node.js
About a year and a half ago I announced a library named Fog (for F#) that had the goal of making it very easy to use F# to work with the Windows Azure API for .NET. Today, I'm proud to announce the release of FogJS, which has a similar goal for JavaScript/Node.js development.
FogJS:
FogJS currently supports 3 of the more popular Azure services: Blob Storage, Table Storage, and Service Bus. One of the most broad features in FogJS is that of support for promises. In fact, almost every function provided by the Azure SDK for Node.js has been replicated in Fog with the results returned as a promise (with the help of Q.js).
The second big feature is related to making it as easy as possible to interact with Azure. This is primarily accomplished with "simplified functions" that follow a convention over configuration approach.
Example:
Here's a quick example of one option for how to use Blob Storage with FogJS:
You can find examples for Table Storage and Service Bus interaction on the main FogJS site: http://fogjs.azurewebsites.net/.
As usual, the code and tests can be found on my GitHub.
FogJS:
FogJS currently supports 3 of the more popular Azure services: Blob Storage, Table Storage, and Service Bus. One of the most broad features in FogJS is that of support for promises. In fact, almost every function provided by the Azure SDK for Node.js has been replicated in Fog with the results returned as a promise (with the help of Q.js).
The second big feature is related to making it as easy as possible to interact with Azure. This is primarily accomplished with "simplified functions" that follow a convention over configuration approach.
Example:
Here's a quick example of one option for how to use Blob Storage with FogJS:
You can find examples for Table Storage and Service Bus interaction on the main FogJS site: http://fogjs.azurewebsites.net/.
As usual, the code and tests can be found on my GitHub.
Sunday, June 24, 2012
Functional JavaScript with LiveScript, Mocha, and ExpectThat
I've been playing with LiveScript a bit lately and have really been enjoying it! If you haven't heard of LiveScript, it's a "...fork of Coco, which is in turn derived from CoffeeScript..." (LiveScript Overview Page). It provides more features than Coco and CoffeeScript including several that assist in writing code in a more functional style.
Here's a quick example of a test written in LiveScript for Mocha and ExpectThat:
This shows off a couple of the features that help you write in a functional style with LiveScript. The first is the use of pattern matching within the isWeekend function. The second is the use of the pipe-forward operator when calling the isWeekend function.
The pattern matching syntax gives you a concise way of defining a basic switch statement in JavaScript. The pipe-forward operator allows you to compose things together. In the example above, the string 'sun' (which also could have been written in LiveScript as \sun) is being passed into the isWeekend function. This becomes even more powerful when the value to be passed into the next function is coming from another function, as shown in this example:
F# has these same concepts and many more, which makes LiveScript + F# a compelling combination!
There are a number of additional LiveScript features that assist in using a functional style. For more examples of LiveScript with Mocha and ExpectThat visit https://github.com/dmohl/expectThat/tree/master/example/mocha-LiveScript. To learn more about LiveScript, see a number of examples, and/or get setup for use, visit the LiveScript site at http://gkz.github.com/LiveScript/.
Here's a quick example of a test written in LiveScript for Mocha and ExpectThat:
This shows off a couple of the features that help you write in a functional style with LiveScript. The first is the use of pattern matching within the isWeekend function. The second is the use of the pipe-forward operator when calling the isWeekend function.
The pattern matching syntax gives you a concise way of defining a basic switch statement in JavaScript. The pipe-forward operator allows you to compose things together. In the example above, the string 'sun' (which also could have been written in LiveScript as \sun) is being passed into the isWeekend function. This becomes even more powerful when the value to be passed into the next function is coming from another function, as shown in this example:
F# has these same concepts and many more, which makes LiveScript + F# a compelling combination!
There are a number of additional LiveScript features that assist in using a functional style. For more examples of LiveScript with Mocha and ExpectThat visit https://github.com/dmohl/expectThat/tree/master/example/mocha-LiveScript. To learn more about LiveScript, see a number of examples, and/or get setup for use, visit the LiveScript site at http://gkz.github.com/LiveScript/.
Sunday, January 8, 2012
Introducing ExpectThat: A CoffeeScript Assertion Library
I'm a big fan of automated testing. In fact, on the rare occasions that I don't write tests, I find that I can't shake the thought that something has been missed.
As with all aspects of my coding efforts, I am constantly looking for ways to improve the process, make tests more readable, and reduce room for error. With these goals in mind, I'd like to introduce ExpectThat.
What is ExpectThat?
ExpectThat is an expressive, self-documenting, assertion library for CoffeeScript, that seeks to improve testing efforts with your favorite testing framework. It does this by providing a syntax similar to FsUnit (a library for F#) that makes assertions more readable and then automatically translates that readable code into descriptive test output. This ensures that your test names always stay in sync with your tests and allows your code to speak for itself. ExpectThat currently supports Pavlov, QUnit, and Jasmine. Overtime, support for additional testing frameworks will be added.
Let's See it in Action
The following example shows how to write tests with ExpectThat for Pavlov in CoffeeScript:
Other Testing Frameworks
As I mentioned, ExpectThat currently supports QUnit and Jasmine in addition to Pavlov. The following are examples for each of these.
QUnit:
There are a couple of ways to get started with ExpectThat. First, head over to the ExpectThat GitHub site and browse through the documentation. You can then clone the repo and grab any of the examples from the example folder. If you are writing an ASP.NET app in Visual Studio, another option is to install one of the available NuGet packages.
Available Assertions
ExpectThat currently provides the following assertions:
- equal
- stictlyEqual
- false
- true
- greaterThan
- greaterThanOrEqual
- lessThan
- lessThanOrEqual
- throwException
- 'to' and 'be' can be used in most cases to make tests more readable.
In addition to the out-of-the-box assertions, ExpectThat allows for the creation of custom assertions. Examples of this for each of the supported testing frameworks are available in the example folder on GitHub.
ExpectThat in JavaScript
While the syntax of ExpectThat works best with CoffeeScript, you can certainly use it in JavaScript as well. Simply add in the missing braces, parens, semi-colons, function keywords, etc. The following provides a simple example for Pavlov:
There are a lot of things left to do for ExpectThat and I'd love to hear your thoughts on direction, enhancements, etc. as well as have any help that anyone would like to offer. If you want to get involved, fork me on GitHub.
As with all aspects of my coding efforts, I am constantly looking for ways to improve the process, make tests more readable, and reduce room for error. With these goals in mind, I'd like to introduce ExpectThat.
What is ExpectThat?
ExpectThat is an expressive, self-documenting, assertion library for CoffeeScript, that seeks to improve testing efforts with your favorite testing framework. It does this by providing a syntax similar to FsUnit (a library for F#) that makes assertions more readable and then automatically translates that readable code into descriptive test output. This ensures that your test names always stay in sync with your tests and allows your code to speak for itself. ExpectThat currently supports Pavlov, QUnit, and Jasmine. Overtime, support for additional testing frameworks will be added.
Let's See it in Action
The following example shows how to write tests with ExpectThat for Pavlov in CoffeeScript:
pavlov.specify "Example Specifications", -> foo = "bar" describe "When testing 'should equal'", -> expectThat -> foo.should equal "bar" describe "When testing 'shouldnt equal'", -> expectThat -> foo.shouldnt equal "baz" describe "When testing for 'true'", -> expectThat -> (foo is "bar").should be true expectThat -> (foo is "baz").shouldnt be true describe "When testing for 'false'", -> expectThat -> (foo is "baz").should be false expectThat -> (foo is "bar").shouldnt be false describe "When testing 'greater than'", -> expectThat -> (9.1).should be greaterThan 9 expectThat -> (9.1).shouldnt be greaterThan 10 expectThat -> 10.shouldnt be greaterThan 10Here's a screenshot of the result:
Other Testing Frameworks
As I mentioned, ExpectThat currently supports QUnit and Jasmine in addition to Pavlov. The following are examples for each of these.
QUnit:
module "Example QUnit Specifications" foo = "bar" module "When testing should equal" expectThat -> foo.should equal "bar" module "When testing shouldnt equal" expectThat -> foo.shouldnt equal "baz" module "When testing for true" expectThat -> (foo is "bar").should be true expectThat -> (foo is "baz").shouldnt be true module "When testing for false" expectThat -> (foo is "baz").should be false expectThat -> (foo is "bar").shouldnt be falseJasmine:
describe "Example Jasmine Specifications", -> foo = "bar" describe "When testing should equal", -> expectThat -> foo.should equal "bar" describe "When testing shouldnt equal", -> expectThat -> foo.shouldnt equal "baz" describe "When testing for throw", -> expectThat -> (-> throw "test exception").should throwException expectThat -> (-> throw "test").should throwException "test" describe "When testing for less than", -> expectThat -> 10.should be lessThan 11 expectThat -> (10.1).shouldnt be lessThan 10Getting Started with ExpectThat
There are a couple of ways to get started with ExpectThat. First, head over to the ExpectThat GitHub site and browse through the documentation. You can then clone the repo and grab any of the examples from the example folder. If you are writing an ASP.NET app in Visual Studio, another option is to install one of the available NuGet packages.
Available Assertions
ExpectThat currently provides the following assertions:
- equal
- stictlyEqual
- false
- true
- greaterThan
- greaterThanOrEqual
- lessThan
- lessThanOrEqual
- throwException
- 'to' and 'be' can be used in most cases to make tests more readable.
In addition to the out-of-the-box assertions, ExpectThat allows for the creation of custom assertions. Examples of this for each of the supported testing frameworks are available in the example folder on GitHub.
ExpectThat in JavaScript
While the syntax of ExpectThat works best with CoffeeScript, you can certainly use it in JavaScript as well. Simply add in the missing braces, parens, semi-colons, function keywords, etc. The following provides a simple example for Pavlov:
pavlov.specify("expectThat Specifications", function() { describe("When testing should equal", function() { var foo = "bar"; expectThat(function() { foo.should(equal("bar")); }); expectThat(function() { (foo + "test").should(equal("bartest")); }); }); });Getting Involved
There are a lot of things left to do for ExpectThat and I'd love to hear your thoughts on direction, enhancements, etc. as well as have any help that anyone would like to offer. If you want to get involved, fork me on GitHub.
Labels:
CoffeeScript,
ExpectThat,
Jasmine,
JavaScript,
Pavlov,
QUnit
Tuesday, November 29, 2011
Getting Setup for JavaScript Testing with Pavlov
I've talked about testing CoffeeScript with Pavlov in a previous post. Today, I'm going to talk about a couple of ways to quickly get started with Pavlov--a BDD API that sits on top of QUnit--in an ASP.NET web app.
In the past, whenever I wanted to start creating Pavlov specs, I would go out to the Pavlov GitHub site, grab the appropriate files, and add them to my web app. While this process isn't all that time consuming, there is now a better way. Now I can simply install the Pavlov NuGet package using the NuGet Visual Studio Extension. This package adds a folder named Specs under the Scripts folder that includes a barebones html file and pavlov.js.
An example of what the file structure looks like after this package is installed is shown below:
If I prefer to have a simple example to start with, I can alternatively install the Pavlov.Sample package. This adds the same files as the Pavlov package, but also includes an example.specs.js file with the code from the example on the Pavlov GitHub site.
Lastly, I've been writing a fair amount of CoffeeScript lately, so I may prefer to have the sample specs written in CoffeeScript. All that is needed for this is to make sure that Mindscape Web WorkBench Visual Studio Extension is installed (this is a onetime install) and then install the Pavlov.Coffee NuGet package. The files are then added to the project including a example.specs.coffee file that looks like this:
In the past, whenever I wanted to start creating Pavlov specs, I would go out to the Pavlov GitHub site, grab the appropriate files, and add them to my web app. While this process isn't all that time consuming, there is now a better way. Now I can simply install the Pavlov NuGet package using the NuGet Visual Studio Extension. This package adds a folder named Specs under the Scripts folder that includes a barebones html file and pavlov.js.
An example of what the file structure looks like after this package is installed is shown below:
If I prefer to have a simple example to start with, I can alternatively install the Pavlov.Sample package. This adds the same files as the Pavlov package, but also includes an example.specs.js file with the code from the example on the Pavlov GitHub site.
Lastly, I've been writing a fair amount of CoffeeScript lately, so I may prefer to have the sample specs written in CoffeeScript. All that is needed for this is to make sure that Mindscape Web WorkBench Visual Studio Extension is installed (this is a onetime install) and then install the Pavlov.Coffee NuGet package. The files are then added to the project including a example.specs.coffee file that looks like this:
Sunday, August 14, 2011
Another CoffeeScript and jQuery UI Example
In a previous post, I showed a few examples of jQuery UI demos ported to CoffeeScript. While I prefer the approach that was shown in that post, there is another way that I could have done it. In this post, I'll show a different jQuery UI example (one of the the Slider demos) written using the CoffeeScript class structure.
You can find the full example (F# + ASP.NET MVC + CoffeeScript + jQuery UI) on my GitHub: https://github.com/dmohl/FsCoffeeScriptjQueryUIExample.
You can find the full example (F# + ASP.NET MVC + CoffeeScript + jQuery UI) on my GitHub: https://github.com/dmohl/FsCoffeeScriptjQueryUIExample.
class Slider constructor: -> $('#master').slider value: 60 orientation: "horizontal" range: "min" animate: true $('#eq > span').each -> value = parseInt $(this).text(), 10 $(this).empty().slider value: value range: "min" animate: true orientation: "vertical" window.slider = new Slider()
Labels:
ASP.NET MVC 3,
CoffeeScript,
JavaScript,
jQuery UI
Sunday, July 31, 2011
jQuery UI Examples in CoffeeScript
Recently, I've been playing with CoffeeScript and have found it to be a lot of fun. I'm a big fan of JavaScript and CoffeeScript has only added to the enjoyment of writing client-side code by taking away a few of the "bad parts" and reducing syntactic noise. To help learn the language, I took a few of the jQuery UI examples and re-wrote them in CoffeeScript. You can find the full solution (F# + ASP.NET MVC (Razor) + CoffeeScript) at https://github.com/dmohl/FsCoffeeScriptjQueryUIExample. (Note: You will need to install the Mindscape Web Workbench Visual Studio 2010 extension to make the CoffeeScript aspects work correctly. Visit this post by Scott Hanselman for information on getting started with this extension).
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:
The CoffeeScript Version:
This simple Photo Manager example comes from the jQuery UI demo found at http://jqueryui.com/demos/droppable/#photo-manager.
The JavaScript Version:
The CoffeeScript Version:
This simple User Manager example comes from the jQuery UI demo found at http://jqueryui.com/demos/dialog/#modal-form.
The JavaScript Version:
The CoffeeScript Version:
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 {}
Labels:
ASP.NET MVC 3,
CoffeeScript,
F#,
JavaScript,
jQuery UI
Subscribe to:
Posts (Atom)