Email Availability Control using Microsoft AJAX and Json WCF
Hi Guys,
If you are a web developer, I am sure you would have encountered a scenario where you have to check the email/username availability. So I thought of making a control which will call a WCF service through Microsoft AJAX and let the user know whether the email/username is already taken or not. Hope you like it.
Solution
1) Create a Solution like following,
- One is a web site
- Other is a Class Library
2) Open AjaxEnabledControls -> EmailTextBox.cs and paste the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace AjaxEnabled
{
public class EmailTextBox : TextBox,IScriptControl
{
private ScriptManager sMgr;
public string ServiceUrl;
protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
ScriptControlDescriptor descriptor =
new ScriptControlDescriptor("AjaxEnabled.EmailTextBox", this.ClientID);
descriptor.AddProperty("serviceUrl", this.ServiceUrl);
return new ScriptDescriptor[] { descriptor };
}
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference reference = new ScriptReference();
reference.Assembly = "AjaxEnabled";
reference.Name = "AjaxEnabled.EmailTextBox.js";
return new ScriptReference[] { reference };
}
protected override void OnPreRender(EventArgs e)
{
if (!this.DesignMode)
{
//test for the existence of a ScriptManager
sMgr = ScriptManager.GetCurrent(Page);
if (sMgr == null)
throw new HttpException(
"A ScriptManager control must exist on the page.");
sMgr.RegisterScriptControl(this);
}
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
if (!this.DesignMode)
sMgr.RegisterScriptDescriptors(this);
base.Render(writer);
writer.WriteLine(string.Format(@"<br /><div><input type=""hidden"" id=""{0}""/>
<div id=""{1}"" style=""float:left""></div><span class=""emailTextboxSpan"" id=""{2}""></span></div><br />",
this.ClientID + "_Hidden",
this.ClientID + "_Image",
this.ClientID + "_Status"));
}
IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
{
return GetScriptReferences();
}
IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
{
return GetScriptDescriptors();
}
}
}
If you are a web developer, I am sure you would have encountered a scenario where you have to check the email/username availability. So I thought of making a control which will call a WCF service through Microsoft AJAX and let the user know whether the email/username is already taken or not. Hope you like it.
Solution
1) Create a Solution like following,
- One is a web site
- Other is a Class Library
2) Open AjaxEnabledControls -> EmailTextBox.cs and paste the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace AjaxEnabled
{
public class EmailTextBox : TextBox,IScriptControl
{
private ScriptManager sMgr;
public string ServiceUrl;
protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
ScriptControlDescriptor descriptor =
new ScriptControlDescriptor("AjaxEnabled.EmailTextBox", this.ClientID);
descriptor.AddProperty("serviceUrl", this.ServiceUrl);
return new ScriptDescriptor[] { descriptor };
}
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference reference = new ScriptReference();
reference.Assembly = "AjaxEnabled";
reference.Name = "AjaxEnabled.EmailTextBox.js";
return new ScriptReference[] { reference };
}
protected override void OnPreRender(EventArgs e)
{
if (!this.DesignMode)
{
//test for the existence of a ScriptManager
sMgr = ScriptManager.GetCurrent(Page);
if (sMgr == null)
throw new HttpException(
"A ScriptManager control must exist on the page.");
sMgr.RegisterScriptControl(this);
}
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
if (!this.DesignMode)
sMgr.RegisterScriptDescriptors(this);
base.Render(writer);
writer.WriteLine(string.Format(@"<br /><div><input type=""hidden"" id=""{0}""/>
<div id=""{1}"" style=""float:left""></div><span class=""emailTextboxSpan"" id=""{2}""></span></div><br />",
this.ClientID + "_Hidden",
this.ClientID + "_Image",
this.ClientID + "_Status"));
}
IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
{
return GetScriptReferences();
}
IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
{
return GetScriptDescriptors();
}
}
}
3) Open AjaxEnabledControls -> EmailTextBox.js and paste the following code
/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("AjaxEnabled");
//create constructor
AjaxEnabled.EmailTextBox = function (element) {
AjaxEnabled.EmailTextBox.initializeBase(this, [element]);
this._serviceUrl = null;
this._spanControlId = '';
this._imageControlId = '';
this._hiddenControlId = '';
this._isEmailAvailable = true;
}
//define class
AjaxEnabled.EmailTextBox.prototype = {
//initialize the UI control
initialize: function () {
AjaxEnabled.EmailTextBox.callBaseMethod(this, 'initialize');
this._onKeyupHandler = Function.createDelegate(this, this._onKeyup);
this._onTextChangeHandler = Function.createDelegate(this, this._onTextChange);
$addHandlers(this.get_element(), { 'keyup': this._onKeyup, 'change': this._onTextChange }, this);
},
dispose: function () {
$clearHandlers(this.get_element());
AjaxEnabled.EmailTextBox.callBaseMethod(this, 'dispose');
},
//define keystroke event
_onKeyup: function (e) {
this.validateEmail(e);
},
_onTextChange: function (e) {
this.validateEmail(e);
},
validateEmail: function (e) {
//get email text
var emailValid = true;
var x = this.get_element().value;
var email = x;
var atpos = x.indexOf("@");
var dotpos = x.lastIndexOf(".");
if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= x.length) {
emailValid = false;
}
this._spanControlId = this.get_element().id + '_Status';
this._imageControlId = this.get_element().id + '_Image';
this._hiddenControlId = this.get_element().id + '_Hidden';
var spanEmail = $get(this._spanControlId);
var imageElement = $get(this._imageControlId);
if (emailValid) {
this.returnEmailAvailable(email);
}
else {
this.get_element().className = '';
imageElement.className = '';
spanEmail.innerHTML = '';
this._isEmailAvailable = false;
}
},
//define properties
get_serviceUrl: function () {
return this._serviceUrl;
},
set_serviceUrl: function (value) {
this._serviceUrl = value;
},
get_isEmailAvailable: function () {
return this._isEmailAvailable;
},
OnWebRequestCompleted: function onWebRequestCompleted(executor, eventArgs) {
if (executor.get_responseAvailable()) {
var userContext = executor.get_webRequest().get_userContext();
userContext.DisplayWebRequestBody(executor);
}
else {
if (executor.get_timedOut())
alert("Timed Out");
else
if (executor.get_aborted())
alert("Aborted");
}
},
DisplayWebRequestBody: function displayWebRequestBody(executor) {
var userContext = executor.get_webRequest().get_userContext();
var displayElement = $get(userContext._spanControlId);
displayElement.innerHTML =
"Email Address is ";
var isAvailable = executor.get_responseData() == "true" ? true : false
var content = (isAvailable) ? "Available" : "Taken";
if (document.all)
displayElement.innerText += content;
else
// Firefox
displayElement.textContent += content;
userContext.get_element().className = content + "CssClass";
userContext._isEmailAvailable = isAvailable;
var imageElement = $get(userContext._imageControlId);
var hiddenElement = $get(userContext._hiddenControlId);
imageElement.className = content + "ImageCssClass";
hiddenElement.value = isAvailable.toString();
},
returnEmailAvailable: function (email) {
// Instantiate the WebRequest object.
var wRequest = new Sys.Net.WebRequest();
// Set the request Url.
wRequest.set_url(this._serviceUrl + email);
// Set the request verb.
wRequest.set_httpVerb("GET");
// Set user's context
wRequest.set_userContext(this);
// Set the web request completed event handler,
// for processing return data.
wRequest.add_completed(this.OnWebRequestCompleted);
// Execute the request.
wRequest.invoke();
}
}
//register class as a Sys.Control
AjaxEnabled.EmailTextBox.registerClass('AjaxEnabled.EmailTextBox',
Sys.UI.Control);
//notify loaded
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
4) Open AjaxEnabled WebSite -> App_Code -> IEmailService.cs and paste the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IEmailService" in both code and config file together.
[ServiceContract]
public interface IEmailService
{
[OperationContract]
[WebGet(UriTemplate = "/CheckEmail?email={email}",
ResponseFormat = WebMessageFormat.Json)]
bool CheckEmail(string email);
}
5) Open AjaxEnabled WebSite -> App_Code -> EmailService.cs and paste the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "EmailService" in code, svc and config file together.
public class EmailService : IEmailService
{
public bool CheckEmail(string email)
{
if (email.Trim().ToLower() == "shahim@dummy.com")
return false;
else
return true;
}
}
6) Open AjaxEnabled WebSite -> Styles -> Site.css and paste the following styles
.weak
{
border: medium solid #008000;
}
.medium
{
border: thin solid #FFFF00;
}
.strong
{
border: medium solid #FF0000;
}
.emailTextboxSpan
{
font-style : oblique;
}
.TakenCssClass
{
border : 1px solid red;
}
.AvailableCssClass
{
border : 1px solid green;
}
.TakenImageCssClass
{
background-image : url('../Images/Taken.png');
background-repeat : no-repeat;
padding-top : 2px;
width:24px;
height:24px;
}
.AvailableImageCssClass
{
background-image : url('../Images/Available.png');
background-repeat : no-repeat;
padding-top : 2px;
width:24px;
height:24px;
}
7) Finally add the following mark up in AjaxEnabled WebSite -> Default.aspx
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="AjaxEnabled" Namespace="AjaxEnabled"
TagPrefix="ajaxEnabled" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<script type="text/javascript">
function ClientValidate(source, arguments) {
var available = document.getElementById("MainContent_emailTextBox1_Hidden").value;
if (available != '')
arguments.IsValid = (available == "true") ? true : false;
else
arguments.IsValid = true;
}
</script>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
Email Validator TextBox using Microsoft AJAX
<br />
<br />
<ajaxEnabled:EmailTextBox ID="emailTextBox1" serviceUrl="./EmailService.svc/CheckEmail?email="
runat="server" width="200" ></ajaxEnabled:EmailTextBox>
<br />
<br />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" ValidationGroup="vgSubmit"/>
<br />
<br />
<asp:CustomValidator
ID="cvEmail" runat="server" ErrorMessage="Email Address is already Taken. Please change to Proceed!"
ClientValidationFunction="ClientValidate" ValidationGroup="vgSubmit"></asp:CustomValidator>
</asp:Content>
Comments
Post a Comment