Using jQuery to Send Email with Web Services

Just to make sure we are all up to speed, a quick concept in extreme layman’s terms

- jQuery is a front-end thing, meaning it gets your browser to do stuff, like move stuff around and change stuff after it’s already been loaded from the server.

- Sending email is a back-end thing, meaning it requires talking to the server to send stuff.

Now that we are all up to speed, including my 5-month-old daughter, I think it’s clear that jQuery alone can’t do this, at least not without help.  How does jQuery get help from the server? It uses an AJAX Post method to talk to a server, in our case, a web service, to send something and then get something back in return, like a result, which could be ignored by not specifying it in the AJAX Post call.

For this exercise, because I prefer .NET to PHP, I will be using a very simple .NET web service to send out the email, but this task can be accomplished by any server that accepts HTTP Post commands, like a CGI script.

Let’s review the steps that we will take to accomplish this task:

  1. Validate form data
  2. Send data to web service
  3. Interpret & display results from web service

Validating Form Data

jQuery has a great validation plugin that is very easy to use out of the box – jQuery Validate.  To demonstrate just how simple it is, we can validate an email form by using a css class “required” and a simple $(“emailform”).validate() in the $(document).ready function.  The other cool thing about this plugin is you won’t have to write your own Google for a regular expression on validating email addresses.  Check out the code example below that I borrowed from the jQuery page for this plugin (http://docs.jquery.com/Plugins/Validation)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <script type="text/javascript" src="http://jzaefferer.github.com/jquery-validation/jquery.validate.js"></script>
<style type="text/css">
* { font-family: Verdana; font-size: 96%; }
label { width: 10em; float: left; }
label.error { float: none; color: red; padding-left: .5em; vertical-align: top; }
p { clear: both; }
.submit { margin-left: 12em; }
em { font-weight: bold; padding-right: 1em; vertical-align: top; }
</style>
  <script>
  $(document).ready(function(){
    $("#commentForm").validate();
  });
  </script>

</head>
<body>

 <form class="cmxform" id="commentForm" method="get" action="">
 <fieldset>
   <legend>A simple comment form with submit validation and default messages</legend>
   <p>
     <label for="cname">Name</label>
     <em>*</em><input id="cname" name="name" size="25" class="required" minlength="2" />
   </p>
   <p>
     <label for="cemail">E-Mail</label>
     <em>*</em><input id="cemail" name="email" size="25"  class="required email" />
   </p>
   <p>
     <label for="curl">URL</label>
     <em>  </em><input id="curl" name="url" size="25"  class="url" value="" />
   </p>
   <p>
     <label for="ccomment">Your comment</label>
     <em>*</em><textarea id="ccomment" name="comment" cols="22"  class="required"></textarea>
   </p>
   <p>
     <input class="submit" type="submit" value="Submit"/>
   </p>
 </fieldset>
 </form>
</body>
</html>

Send Data To Web Service

This step is a bit more tricky, at least if you want it to be cross-browser compatible. The jQuery method is $.ajax, with type POST that looks something like the code below:

$.ajax({
  type: 'POST',
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

That’s the basic skeleton of an AJAX POST, but we will need to modify it to look like this:

 $.ajax({
            type: "POST",
            url: "/services/Mail.asmx/SendMail",
            cache: false,
            contentType: "application/json; charset=utf-8",
            data: "{ 'body':'"  + messageBody + "'," +
                      "'to': '" + msgTo + "'," +
                      "'from': '" + msgFrom + "'," +
                      "'subject': " + msgSubject + "'" +
                  "}",
            dataType: "json",
            complete: function (transport) {  if (transport.status == 200) $("#formcontainer").html("Success"); else alert("Please try again later"); }
        });

So here is what’s happening, and BTW – the above code uses some different variable names than the validation code above, but I am sure you can deduce that msgSubject is a variable that has the value from a textbox containing the subject :

  • type – POST (becasuse we are doing an HTTP POST)
  • url – since we are using ASP.NET Web services, it follows the servicepage.asmx/webmethodname format
  • cache – false (we want to make sure to send fresh form results every time)
  • contentType – this is where we set up our communication type.  We can do SOAP, or JSON, the latter being a lot more lightweight.
  • data – this is where your parameters get passed in.  Since we are using JSON, we will want to format the parameters with the correct string delimiters -
    { ‘variable1′:’value1′,’variable2′,’value2′}
  • dataType – same as contentType, just a different way of specifying the format
  • complete - we can listen for success, error, and complete.

Interpret & Display Results

The reason you don’t see the success or error events up above is because, while cross-browser testing, even when the sending of the mail was successful, it was firing both success and error events.   The way to guarantee correct execution is to poll for the HTTP status after the web service executes. That’s why we are checking for transport.status being equal to 200, which is a successful HTTP code.

To display different results, we just need to inject the desired HTML formatted results into the div or another HTML container that houses your results by using the $(“#formcontainer”).html(“Your result”) method.

Other Notes

You will need to get your submit button to fire off the AJAX POST call.  You can give the button an id or class and fire up the onclick event using jQuery like  $(“imgsubmitbutton”).click(function {}); – just make sure to return false as the last line of the function, otherwise the page will refresh.

Demo

Of course, no post on jQuery would be complete without a demo, so I’ve put together on jsFiddle here - http://jsfiddle.net/aM7PR/55 .  Couple of notes about it:

  • With jsFiddle, you can make mock JSON calls, so it will always come back successful.
  • If this is a “Contact Us” form, you don’t really want to have both a From and a To field, because you will be a spam magnet, so you can hard code the To email address in your web service.

Inside Look at a Real World Web Project – Planning, Strategy, Design, and Implementation

My team and I just deployed a high-profile, albeit small website for one of our brands. This article will give you an inside look at each step of this real world project, which you may not necessarily be able to find in a WROX publishing book. I will cover the project framework, overall design strategy, and working with Sitecore. In a cross-post, one of my teammates, @kaidez [http://www.kaidez.com], go into the detail of front-end code and some of the invaluable tools that simplified the general development of this project.

Project Framework

For our framework, we chose SCRUM. In a 4-person web team, all sitting within reach of each other, we have found that over the years, this works best for us. The designers know what the developers are doing and vice versa. Like SCRUM, we are fast and efficient. In fact, I am very proud of my team. As a 4-person standalone web design shop, I think we’d do rather well, assuming we wouldn’t have to pay for our own healthcare.

In the role of ScrumMaster, the first thing I did was set up a storyboard in scrumy.com (pronounced scruh-mee, not screw-me, which is a completely different NSFW site). If you haven’t used this tool before, give it a try. Its drag-and-drop interface lets you create stories, associate tasks with a user, and drag-and-drop them from column to column (to-do, in progress, verify, complete). Maintaining a storyboard like this, not only puts your project manager at ease, who may be in a remote location, but also keeps the team sane when you need to get out of the coding zone and get a perspective on the project progress.

Design Strategy

If you only get one takeaway from this, it’s that no matter how small the project, proper design and planning will always serve a benefit.

Since we adopted Sitecore as the official CMS tool, our design was already partially established. With this being a small product informational site, our Sitecore template design was not unlike the Sitecore demo project. The difference between our solution and the demo project is the level of OOP design.

What I have seen with novice Sitecore developers is as soon as they start developing a site, they completely abandon n-tier architecture and OOP best practices. Sitecore does not and should not replace a good OOP design.

Take the Product entity as an example. A Product may have a name, image, link, and a description. In a 3-tier (DAL/BLL/UI) architecture, you would create a class for it in the Business Logic Layer. In our case, we display products in a category page and in a product page. If you care about your code, there should be an alarm that goes off that detects duplicate functionality and tells you to extract it to one common place; hence, the need for our BLL assembly.

If you are still not seeing the benefit, consider the readability and general elegance of binding an asp:repeater to a List of products with dot notation and intellisense, as opposed the ugly DataBinder.Eval() function.

<asp:Repeater ID="rptProducts" runat="server">
	<ItemTemplate>
		<a href="<%#((Product)Container.DataItem).Link)" %>
			<%#((Product)Container.DataItem).Image) %><br/>
			<%#((Product)Container.DataItem).Name) %>
		</a>
	</ItemTemplate>
</asp:Repeater>

As another best practice, you will want a Core assembly to keep track of static constants and variables. In our case, it holds the URL to our CDN which is different from environment to environment.

Team Development Environment

After the design is knocked out, I have to make sure everyone’s development environment is properly set up and wired up to TFS. I’ve seen developers skip this step until the project is complete, but I cannot stress this enough – these shortcuts will only make your life more difficult. Set up TFS before you start development and don’t forget to check in changes to avoid having other developers overwrite your changes or hearing the never-old “well… it works on my machine” phrase.

The Sitecore templates were done during the design phase in a true Agile environment – in a locked conference room with the entire team, so at this point, it was safe for everyone’s environment to be pointed at the same Sitecore database environment since the templates weren’t really changing.  I created the solution with by including the Sitecore files and assemblies, created BLL/Core projects, and checked everything into TFS, after which everyone did a GLV (get latest version).

Sitecore Deployment

We build this site using Sitecore v6.4. With this version, there is no staging module that you have install like with v6.1, so I thought that after I take care of the checklist in Sitecore’s Configuring Production Environments handbook, I’d be home free, but not so. If you want the cache to automagically clear after publish, you will have to set the EnableEventQueues property to “true” in your web.config

Takeaways

A little planning and preparation before will save you a lot of fan cleaning later. No matter how small the project, if you are in a real world environment, chances are it will at some point grow or will probably need maintenance. Following best practices in the beginning, you will avoid cursing yourself and/or your team when it’s time to do that maintenance or expansion.

  • Remember to use a project framework that will fit your team and organization, whether it’s SCRUM or something else. If it’s something else, you will still find scrumy.com to be useful for simple task management.
  • Use TFS, or something else if you don’t have TFS, for source control early on before development kicks off.
  • Do not disregard a good n-tier design just because you are working in a CMS.

Check out @kaidez’s cross-blog on this topic here: www.kaidez.com.

Liveblog from Microsoft Mix 11 – Keynote

[10:29] New in Windows Azure – Access Control Service, Caching, CDN, Traffic Manager.
We saw Facebook & Twitter icons around ACS. Hopefully, it wasn’t just clipart and they are supported.

[10:26] Umbraco CMS demo. Another .NET based open source project. The twist – running on Windows Azure cloud. Currently used by mainstream sites like vogue.co.uk.
Allows you to scale the instances and looks like it gives you a lot of control on the cloud.

[10:12] Orchard CMS Demo. Open Source project that Microsoft is contributing to.  It’s no Sitecore, but still worth taking a look at.

[10:10] WebMatrix helpers

[9:58] Microsoft WebMatrix Demo. It’s your basic website in a box. TemplateMonster sells WebMatrix templates. You set up your site by choosing the packages you want. Packages are like WordPress plugins.

[9:51] Looking at a demo with MVC3.  Awesome integration with HTML5.  Didn’t see the need during MVC v1 or v2, but this may be worth taking a look at.

[9:45] ASP.NET MVC3 Tools Update

[9:43] Scott Gurthrie. Starting off with a bang?? Charlie Sheen #WINNING/tigerblood joke. really? Talking about the Microsoft Web Platform

[9:41]IE10 Recap Slide

[9:39] Looking at SVG canvas video performance on IE10 vs. Chrome. IE10 does it faster.

[9:37] Microsoft PDC announced – Anaheim, CA – Sep 13-16, 2011.

[9:31] CSS3 columns, “Strict”, CSS gradients – all looks great on IE10.  What happened to IE9? More markup needed to do the same on Chrome than IE10, even though Chrome can do it.

[9:27] Looking at IE10 demo.  I need to call my QA team ASAP and get them to start cross-browser testing.  Another jab at Chrome not being able to support video hardware acceleration.

[9:26] It’s not about how many releases there are. It’s about how much progress is made.

[9:23] Wow. Xtranormal animation mocking Chrome and Websockets. Yes. This is really happening.

[9:21] Native experiences are better.  IE9 delivers that. Browsers that optimize for the operating system are better. IE9 with Windows 7 is better.  Browsers that spread themselves over multiple OS’s can’t concentrate on optimization (really? This guy is telling Chrome to go eff itself)

[9:18] IE9 vs. Chrome – IE9 has hardware graphics acceleration.  Painball demo is much faster.

[9:13] Looking at some great HTML5 sites.

[9:07]  Dean Hachamovitch, Corporate VP, Internet Explorer. Fan and Evangelist of HTML5.

  • Native Experiences – best experiences
  • Web experiences – most important experiences.
  • Best web experience – IE9 with HTML5

LiveBlog from Microsoft Mix 11 – jQuery Bootcamp

UPDATE [4/18/2011] – Joe posted the slides on his website: http://joemarini.com/downloads/Presentations/jQueryBootCampMIX11.zip

64,000 ft. View of jQuery

  • It’s awesome
  • It hides browser-specific functionality, meaning you don’t have to write a function for each browser that does the same thing.  This is done for you.
  • It’s a library, not a framework.

8 elements of jQuery

  1. core functionality
  2. selection and traversal
  3. manipulation & css
  4. events
  5. effects
  6. AJAX
  7. UI
  8. Extensibility

Window.OnLoad vs. Document.Ready

- window.onload – fires after all images have been loaded on the page (could take a while)
- document.ready – fires when the DOM has been loaded.

Code Overview & Samples

We just dove into some great stuff. Joe Marini promised slides and code samples at the end of the bootcamp, so I will post it after they become available.

Breaking News (sort of)
jQuery Mobile is coming! What jQuery did for cross-browser compatibility, jQuery Mobile is going to do for mobile browsers/devices.  I don’t like to throw around the term “game changer,” but I think this deserves it.

LiveBlog from Microsoft Mix 11 – Cloud Bootcamp

64,000 ft. View of the Microsoft cloud a.k.a Azure

  • Development Platform agnostic – in addition to .Net, it can run Java, PHP, etc – basically, anything platform that you can install on a windows box.
  • Machine Abstraction – your application may run on 1 machine or 1,000.  The beauty of the cloud – it’s abstracted, so it’s taken care of and you need not worry during development.
  • The cloud virtual machine consists of 3 levels
    • IIS (in web roles)
    • Your app code + role runtime
    • Windows Azure OS

Requirements for Azure development

  • .Net 4.0/3.5 SP1
  • Visual Studio 2010/2008
  • MVC 2.0/3.0 (optional)
  • Powershell
  • IIS7

[Short Demo]
Azure comes with an emulator – you can see and manage instances of your VMs to get an idea of how they will run when you publish to the cloud.

SQL Azure

Why do we need a special version of SQL Server for the cloud? Database connections are stateful (opposite of stateless).  That means that once it makes a connection, it needs to persist it. Since the data connection for a single given session can come from random servers in the cloud, you need a special way to handle that in the cloud.  SQL Azure takes care of that for you.

SQL Azure Reporting Services are in beta

Azure Storage Overview

Virtual Machine Role

So, what happens when you have a third-party component that is not compatible with Windows Azure? One of your options is utilizing the Virtual Machine Role. Essentially, you are creating your own VM and upload the VHD file to Azure.  With this option, you

  • are solely responsible for it
  • have to have it running on Windows 2008 R2 Enterprise (license $$)
  • acknowledge that it’s in beta form.
  • should really consider if it’s worth the hassle.

Data Market
In the cloud with your app,  you have data providers; some paid, some free.  If your app uses data like zip codes, census information, or other data, it may be available from vendors in the data marketplace.

Azure Security

Microsoft handles DDoS and other attacks for you within the Azure platform.


Second Portion – Demos

Check out the speaker’s (Vishwas Lele) blog for a full demo of the Cloud Portal here – http://vlele.wordpress.com/2011/04/11/windows-azure-boot-camp-at-mix/

Conclusion

Stay tuned for the slides I’ll post after the event.