Pranay Rana: JAVA SCRIPT / JQUERY
Showing posts with label JAVA SCRIPT / JQUERY. Show all posts
Showing posts with label JAVA SCRIPT / JQUERY. Show all posts

Saturday, March 16, 2013

Store data locally with HTML5 Web Storage

Now new version of HTML5 having number of new API one of the is Storage API, which allow you to store data of use locally. Here in following post I am going to describe Storage API.

Cookies vs. Storage
In previous version of HTML allows to store data locally with the help of Cookies but the
  •  issue with the cookies is its not allow to big object and which can be easily done. Storage allows 5M (most browsers) or 10M (IE) of memory at disposal. 
  • Another problem is cookies get sent to server with each HTTP request which in term increases traffic.
Storage
Now lets start using the store in application
if(typeof(Storage)!=="undefined")
{
  alert("storage is supported and you can store data in it"); 
}
else
{
 alert("Get new version of browser or use browser which support storage");
}
So here in above as you can see, first line of code check weather browser supports/have Storage object. It's good to check because most of the older browser is not supporting and as its new feature its mostly supported in new browsers.

After doing check for Storage support decide either you want to store data for given session only or want to store data which available even after session is over and when user come back.
So there are two type of object which is explained below
  • sessionStorage is used to store within the browser tab or window session. so it allows to store data in a single web page session.
  • localStorage is used to kept even between browser sessions. so it allows to access data after the browser is closed and reopened again, and also instantly between tabs and windows.
Note : Storage data created by one browser is not avaible in other browser. for example created in IE is not available in FireFox.

Following is the way you can use the localStorage and sessionStorage in your application.
//sessionStorage 
//set and get object 
sessionStorage.setItem('myKey', 'myValue');
var myVar = sessionStorage.getItem('myKey');
//another way to set and get 
sessionStorage.myKey = 'myValue';
var myVar = sessionStorage.myKey;

//remove item
sessionStorage.removeItem('myKey');

//clear storage 
sessionStorage.clear();
//localStorage 
//set and get object 
localStorage.setItem('myKey', 'myValue');
var myVar = localStorage.getItem('myKey');
//another way to set and get 
localStorage.myKey = 'myValue';
var myVar = localStorage.myKey;

//remove item
localStorage.removeItem('myKey');

//clear storage 
localStorage.clear();
as in the above code both of the object support same set of methods to store and retrieve data.
  • setItem - allows to set value. 
  • getItem - allows to get value.
  • removeItem - allows to remove object from storage. Note: if it used like removeItem(), it removes all stored object , so be careful when removing -to remove specific object use removeItem("myKey"). 
  • clear - clear storage i.e. clear all stored data.
and as you can see storage store data in key value pair.

Conclusion
Web Storage simplify the storing of object in client and also have advantage over cookies, but its always good to not store sensitive information in the client side storage as storage is not provide that much security.

Thanks for reading and do post comment if you like it or something is missing or wrong.

Friday, March 30, 2012

Cascading with jQuery AutoComplete

Source Code


In this post I am going to show how to achieve cascading functionality with the help of jQuery AutoComplete UI control rather than we are doing with the help of comobo-box controls till date.

By the following screen shot I am going to explain what I am going to achieve in this post and in later on post I am going to explain the part of the code did by me.

Screen 1: Loading Suggestion
When user start typing in country textbox  loader image shows that its loading suggestion for the character typed in textbox.

Screen 2: Display Suggestion
List of suggestion displayed to the end user , which is in turn fetch from the server.

Screen 3: Display State aftter country selection
Select State textbox get visible once user select country name from the suggestion list.

Screen 4: Display City after State selection
Select city textbox get visible once user select state name from the suggestion list.

Screen 5: Display Search button after selecting city
Search button get visible once user done with the selection of city name from the suggested cities.

Screen 6: Displaying Search data
Search Data get displayed in the gridview control once user click on search button.

Screen 7: "No Data Found" Error Message
Error message get displayed when user types in the textbox and suggestion is not available to display.

Screen 8: "Enter valid Data" Error Message

Alert Message of enter data get displayed when search button is press and one of the textbox value is not present.

Screen 9: "Enter valid Data" Error Message
Alert Message of enter data get displayed when search button is press and one of the textbox having value for which suggestion is not present.

As you can see in the screen shot when I type auto-complete functionality show me the suggestion and once I select suggestion , selected value get placed in the textbox and another row get visible which does the same functionality.

Now in the below post I am going to discuss about cascading thing with one textbox only but you can see whole by downloading the full source code of this post.

Aspx page i.e html markup
First start with the Aspx page, what the changes I did for the autocomplete textbox which is going to cascade other autocomplete textbox
<tr id="trCountry">
  <td>
   <label id="lblCountry" runat="server" text="Select Country" width="150px">   
   </label>
  </td>
  <td>
    <div style="float: left;">
TextBox id="txtCountry"
attached class="autosuggest", which tells that when you start typing in its going to display list of suggestion which fetched from the database using ajax and autocomplete plug-in.
<textbox class="autosuggest" font-size="10px" id="txtCountry" runat="server" 
                  width="250px"></textbox>
<span id="spCountry" style="display:none;color:Red;">No Data Found</span>
Span id="spCountry"
It get display when there is no suggestion avaialbe for the character typed in textbox.
<div style="display: none;">
As you see above div having style display=none that means the button and textbox both remains hidden when the page get display on browser.
Button id "btnCountry"
on click event get fire when of of the suggestion get selected. So this button fire up the server side event from javascript and make visible the next level textbox. How it fires the event
<button font-size="10px" id="btnCountry" onclick="btnCountry_Click" 
                runat="server" width="250px"></button>
TextBox id="txtCountryID"
this textbox stores the value of the country id which is going to be selected from the suggestion list.
<textbox id="txtCountryID" runat="server"></textbox>
       </div>
    </div>
  </td>
</tr>
this layout is same for the State and City next level selection textboxes that you can see in full source code.

jQuery/Javascript
Following is jQuery method that going be utilize for the showing the suggestion , which is provided by autocomplete plug-in.

autocomplete - method
method provided by the pug-in which is in turn get attach with the textbox control which than show the suggestion when user types in. In the above code its attached with the Country textbox, which is same for the State and city textbox that you can see in full code.
var pagePath = window.location.pathname;
         $(function() {

         $("#" + "<%=txtCountry.ClientID %>").autocomplete(
             {
Attribute of autocomplete
source - is from which suggestion will come up, as I am fetching data from the server side page/function I used jQuery ajax function to get the list from server.
Sucess - function attached with this attribute of the ajax function get the data for suggestion list as you can see if the data length is equal to 0 than it display span element which shows that data is not present.
source: function(request, response) {

                     $.ajax({
                     url: pagePath + "/GetCountry",
                         data: "{ 'id': '" + request.term + "'}",
                         dataType: "json",
                         type: "POST",
                         contentType: "application/json; charset=utf-8",
                         dataFilter: function(data) { return data; },
                         success: function(data) {
                             if (data.d.length == 0) 
                                 $("#spCountry").show();
                             else
                                 $("#spCountry").hide();
                             response($.map(data.d, function(item) {
                                 {
                                     value = item.Name + " : " + item.ID;
                                     return value;
                                 }
                             }))
                         },
                         error: function(XMLHttpRequest, callStatus, errorThrown) {
                             alert(callStatus);
                         }
                     });
                 },
minLength - no of char typed by use in textbox before the suggestion come up i.e after this many character typed by user than the source get query for suggestion. over here is having value 1 means its start showing suggestion once you start writing in it.
minLength: 1,
select - function associated with this attribute get fire when the use select the item from suggestion list. This is most useful function that do postback and do execute code on serverside by calling serverside button click function , button click function enable State row. As well as this break the string and assign text value to country textbox and id to countryid textbox which is hidden one and which value utilize by the state texbox to display suggestion.
select: function(event, ui) {
                     var str = ui.item.label.split(":");
                     $("#" + "<%=txtCountry.ClientID %>").val(str[0]);
                     $("#" + "<%=txtCountryID.ClientID %>").val(str[1]); 
                     $("#" + "<%=btnCountry.ClientID %>").click();
                 }
             });
         });

Validate function
The function get fire when user click on search button to search people resides in which city once done with selection of country,satate and city.
function Validate() {
      var retVal = true;
      if ($("#spCountry").is(":visible")||
            $("#spSatate").is(":visible") ||
            $("#spCity").is(":visible"))
          retVal = false;
      if($("#" + "").val()=="" ||
         $("#" + "").val()=="" ||
         $("#" + "").val()=="")
          retVal = false;
         if(!retVal) 
      alert("Enter Valid Data"); 
      return retVal;
  }
the code checks for is any of the span element associated with the textbox control is visible which display error message "No Data Found" and also check that is any on textbox contrains blank value. If its all proper it return true value otherwise return false.

CodeBehind Files - aspx.cs file
In cs file I designed class for the testing purpose the name of the class is Common which is going to be utilize by GetCountry, GetState and GetCity methods
public class Common
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int ParentID { get; set; }
}
ID - is the unique value to detect each element uniquely.
Name - is value string value for each element.
ParentID - is value to detect element is child of which element.

People class is used to bind data with the gridview control once user press the search button.
public class People
{
    public string Name { get; set; }
    public string Email { get; set; }
    public int CityID { get; set; }
}
Name- name of the person
Email - email Address
CityID - is the id of city which user belongs.

As I explained before when user start typing in the textbox suggestion list come from the serverside method, following is the one of the method you find other in full code. GetCountry method get called when start typing in Country textbox.
[WebMethod]
    public static List GetCountry(string id)
    {
        try
        {
            List<common> country = new List<common> 
            {
                new Common(){ ID=1 ,Name = "India",ParentID=0 },
                new Common(){ ID=2 ,Name = "USA",ParentID=0 },
                new Common(){ ID=3 ,Name = "Ireland",ParentID=0 },
                new Common(){ ID=4 ,Name = "Australia",ParentID=0 }
            };
As I am going to call the method from server side its having attribute WebMethod. In the above code I initialize the collection of country and country is parent element all element have the parentid 0.
Method has parameter called id which is contains the value of the textbox which is typed in textbox. ajax calling function in source pass the id as json parameter to method that you can see in above method of jQuery/javascript.

List lstcountry =
                        (from c in country
                         where c.Name.StartsWith(id)
                         select c).ToList();
            return lstcountry;
 
        }
        catch (Exception ex)
        {
            return null;
        }
    }
Above code as you can see apply linq query on the collection and locate the match element which starts by the character typed in textbox.

Conclusion
So the above post demonstrate that its easy to achieve the cascading with the help of the auto suggest functionality provided by jQuery autosuggest plug-in.

Note : 
Find download code at the start of article and if you have any problem in downloading source code and if you have any query regarding this please mail me at : pranayamr@gmail.com or post comment at below.

Thursday, February 16, 2012

Attach Javascript with AutoGenerated Buttons of GridView control

This small post about how you can attach javascript confirm box with the the autogenerated delete button of the Gridview of Asp.net. This might be the old trick but this is helpful to the beginner developer.

Consider following Aspx Grid Code
<asp:GridView ID="GridView1" runat="server" AutoGenerateDeleteButton="true"
   AutoGenerateColumns="false" AutoGenerateEditButton="True" 
   onrowcancelingedit="GridView1_RowCancelingEdit" 
   onrowdeleting="GridView1_RowEditing" onrowupdating="GridView1_RowUpdating"
   onrowdatabound="GridView1_RowDataBound"
   <Columns>
    <asp:BoundField DataField="EMPID" HeaderText="EmployeeID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
    <asp:BoundField DataField="LastName" HeaderText="LastName" />
    <asp:BoundField DataField="Address" HeaderText="Address" />
   </Columns>>
</asp:GridView>
 
Now as you can see in the above code AutoGenerateDeleteButton="true" is true that means in grid You can see one delete button to remove record from the grid. But the requirement is I have to ask user weather he wants to delete record or not.

So to achieve this I made use of the RowDataBound and the javascript function confirm which ask user weather to delete record or not if user press yes than page get postback and it remove record from the grid and mark it as delete in my database.

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
  {
     if (e.Row.RowState == DataControlRowState.Normal || e.Row.RowState ==
                                            DataControlRowState.Alternate)
     {
            ((LinkButton)e.Row.Cells[0].Controls[2]).Attributes["onclick"] = 
                  "if(!confirm('Are you sure to delete this row?'))return   false;";
     }
   }
}
Now as you can see in above code I am searching for the deletelinkbutton and attaching OnClick event of javascript with the control no 2 of the cell 0. Because autogenerated button are always place in cell 0 of the grid and here as you can see in code edit button is also auto generate which get place 1 in cell 0 of grid so autogenerated delete button get placed 2 in the cell 0.

Sunday, December 4, 2011

Month and Year Picker UserControl

I am going to discuss about the pop-Up calender control created by me for selecting Month and Year. By this post you will get to know how to easily you can create pop-Up window using jQuery as well as little about how to use it as Asp.Net user control. Well that's not it you can also utilize this thing in you web project develop in any other language.

Below is the picture of the control


Now following is step by step Explanation of control created and how to use that control in your application.

Step 1 : Control Design i.e ASCX file
To create user control you need to left click on the solution and click on Add New Item >> than in screen select WebUserControl as below

After you click on Add button one ASCX file is get created , than you can add the following line of code to get display as show in the fist image above
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DateBox.ascx.cs" Inherits="DateBox" %>

lblText : - Label to hold the text to display with the text box.
txtDate : - TextBox to hold the text get selected by user from the pop-Up calender window shown in the second image above.
btnDate : - Button control, when get clicked it display the pop-Up calender window.

Step 2 : Control Code-Behind i.e .CS file
Once you done with the control design you can paste the following code in the codebehind i.e. .cs file
public partial class DateBox : System.Web.UI.UserControl
{
    public string LabelText
    {
        get
        {
            return lblText.Text;
        }
        set
        {
            lblText.Text = value;
        }
    }

    public string TextData
    {
        get
        {
            return txtDate.Text;
        }
        set
        {
            txtDate.Text = value;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            if (lblText.Text == string.Empty)
                labelContainer.Visible = false;

            this.btnDate.Attributes.Add("OnClick", "return buttonClick(this,'"+ txtDate.ClientID +"');");
        }
    }
}
Property
LabelText : - Used to get/set the text for the label control.
TextData : - Used to get/set the text of the textbox conrol which is going to display selected date.

Method 
Page_Load : - method get executed when page load check, if the label control don't have text make the container div set to visible off. Adding client script on button control and passing button control itself and textbox control client id which going to use by the jQuery/javascript to display selected date.

Step 3 : Code to create popUp Calender i.e. .JS file
After you done with Stpe 2, Add new javascript file to your solution and paste the following code in it
jQuery(document).ready(function ($) {

    var divContainer = $("");

    var divButtonHolder = $("
"); var buttonOk = $("
"); var buttonCancel = $("
"); var divSelectHolder = $("
Select Month and Year : 
"); var ddlmonth = $("    "); var ddlyear = $(""); var i = 0; var month = 1; for (i = 1985; i <= 2020; i++) { ddlyear.append(''); } i = 0; for (i = 1; i <= 12; i++) { if (i < 10) { month = "0" + month; } ddlmonth.append(''); month++; } divSelectHolder.append(ddlmonth); divSelectHolder.append(ddlyear); divContainer.append(divSelectHolder); divButtonHolder.append(buttonOk); divButtonHolder.append(buttonCancel); divContainer.append(divButtonHolder); $('body').append(divContainer); }); var txtDate; function buttonDoneClick() { var month = $("#ddlmonth").val(); var year = $("#ddlyear").val(); $(txtDate).val(month + year); Close_Popup() } function buttonClick(obj,id) { txtDate = ('#' + id); var position = $(obj).position(); $('#window').css({ top: position.top, left: position.left }).fadeIn('fast'); return false; } function Close_Popup() { $('#window').fadeOut('fast'); }
Variables
divContainer : - Main container which contains all controls of pop-Up.
divButtonHolder : - Hold button controls of the window i.e Done and Cancel.
buttonOk : - Hold reference of button control called Done.
buttonCancel : - Hold reference of button control called Cancel.
divSelectHolder : - Hold Select control i.e Month and Year combo.
ddlmonth : - Hold reference of select control called Month.
ddlmonth : - Hold reference of select control called Month.
ddlyear : - Hold reference of select control called Year.

jQuery method
.append : - allows to append control to the control selected by filter.
.ready : - method contains the code for initialize the variable, add the option to select control and attach all created control to body of the page.
.position : - method to get the location of the control which selected by selector.

Method
buttonDoneClick : - Get the selected value of the Month and Year combo box and display text in the textbox attached with the calender control.
buttonClick : - Display calender popUp window , the method make use of position method of jquery to get the location of button and assign it to popUp window.
Close_Popup : - To close the popUp window called when the Cancel button of the popUp window clicked.

Step 4 : popUp window Style sheet i.e .Css file
Add following style shit to Css file which you can able to add from the solution.
#window {
margin: 0 auto;
border: 1px solid #000000;
background: #ffffff;
position: absolute;
left: 25%;
width:250px;
height:50px;
padding:5px;
}
Style is get attached with the the div which is having id called window i.e the popUp window.

Step 5 : How to use control in your project ASPX file
<%@ Register  Src="~/DateBox.ascx" TagPrefix="UC" TagName="DateBox"   %>



So to use control in your application you just need to register the user control, need to include jquery, created js and css file. And you can make use of Lable property to display text with control.

Summary
So its quite easy to create popUp control and use it as User Control in your application. But if you are working on other than .net than just you need to use .Js and .Css file and need to create control on your page.

Friday, July 8, 2011

Jquery Ajax Calling functions

Download Code

Recently I am working on Website with the asp.net and jQuery. While working with jquery library I found that there are 5 diffrent function that used to make ajax call to page and to fetch data. I am going to discuss about that five function one by one.

Following is list of that five function availale in jquery libaray to make ajax call.
  1. Load
  2. getJson
  3. GET
  4. POST
  5. Ajax
Load
Method allow to make ajax call to the page and allows to send using both Get and Post methods.
var loadUrl = "TestPage.htm";
$(document).ready(function () {
   $("#load_basic").click(function () {
     $("#result").html(ajax_load).load(loadUrl, function (response, status, xhr) {
                    if (status == "error") {
                        var msg = "Sorry but there was an error: ";
                        $("#dvError").html(msg + xhr.status + " " + xhr.statusText);
                    }
                }
                );
                return false;
});
As you can see in above code you can easily make call to any page by passing it Url. The call back function provide more control and allows to handle the error if any by making use of the Status value.
One of the important thing about the load method is its allow to load part of page rather than whole page. So get only part of the page call remains same but the url is
var loadUrl = "TestPage.htm #dvContainer";   
So by the passing above url to load method it just load content of the div having id=dvContainer. Check the demo code for detail.



Firebug shows the repose get return by when we call the page by Load method.

Important Feature
  • Allow make call with both Get and Post request
  • Allow to load part of the page.
getJson
Method allow get json data by making ajax call to page. This method allows only to pass the parameter by get method posting parameter is not allowed. One more thing this method treat the respose as Json.
var jsonUrl = "Json.htm";
            $("#btnJson").click(function () {
                $("#dvJson").html(ajax_load);

                $.getJSON(jsonUrl, function (json) {
                    var result = json.name;
                    $("#dvJson").html(result);
                }
                );
                return false;
            });
Above code make use of getJSON function and displays json data fetch from the page.
Following is json data return by the Json.htm file.
{
"name": "Hemang Vyas",
"age" : "32",
"sex": "Male"
}

Following image displays the json Data return as respose.


Important Feature
  • Only send data using get method, post is not allowed.
  • Treat the response data as Json only

get
Allow to make ajax request with the get method. It handles the response of many formats including xml, html, text, script, json, and jonsp.
var getUrl = "GETAndPostRequest.aspx";
            $("#btnGet").click(function () {
                $("#dvGet").html(ajax_load);

                $.get(getUrl, { Name: "Pranay" }, function (result) {
                    $("#dvGet").html(result);
                }
                );
                return false;
            });
As in code I am passing Name parameter to the page using get request.
On server side you can get the value of the Name parameter in request object querycollection.
if (Request.QueryString["Name"]!=null)
{
    txtName.Text = Request.QueryString["Name"].ToString();
} 

The firebug shows the parameter passe by me as Get request  and  value of the parameter is pranay



Important Feature
  • Can handle any type of the response data.
  • Send data using get method only.

post
Allow to make ajax request with the post method. It handles the response of many formats including xml, html, text, script, json, and jonsp. post does same as get but just send data using post method.
var postUrl = "GETAndPostRequest.aspx";
            $("#btnPost").click(function () {
                $("#dvPost").html(ajax_load);

                $.post(postUrl, { Name: "Hanika" }, function (result) {
                    $("#dvPost").html(result);
                }
                );
                return false;
            });
As in code I am passing Name parameter to the page using post request.
On server side you can get the value of the Name parameter in request object formcollection.
if (Request.Form["Name"] != null)
{
    txtName.Text = Request.Form["Name"].ToString();
}

The firebug shows the parameter passe by me as Get request  and  value of the parameter is Hanika



Important Feature
  • Can handle any type of the response data.
  • Send data using post method only.

ajax
Allow to make the ajax call. This method provide more control than all other methods we seen. you can figure out the difference by checking the list of parameter.
var ajaxUrl = "Json.htm";
            $("#btnAjax").click(function () {
                $("#dvAjax").html(ajax_load);


                $.ajax({
                    type: "GET", //GET or POST or PUT or DELETE verb
                    url: ajaxUrl, // Location of the service
                    data: "", //Data sent to server
                    contentType: "", // content type sent to server
                    dataType: "json", //Expected data format from server
                    processdata: true, //True or False
                    success: function (json) {//On Successfull service call
                        var result = json.name;
                        $("#dvAjax").html(result);
                    },
                    error: ServiceFailed// When Service call fails
                });


                return false;
            });
In above code you can see the all the parameter and comment related to each parameter describe the purpose of each one.

Fire bug shows the called page return json data and Ajax function treat the respose as Json because in code datatype = json


Important Feature
  • Provide more control on the data sending and on response data.
  • Allow to handle error occur during call.
  • Allow to handle data if the call to ajax page is successfull.

Summary
So each method of jQuery ajax is different and can use for the difference purpose.

Thursday, June 23, 2011

Calling Cross Domain WCF service using Jquery/Javascript

This post is about to call the cross domain WCF service from you page i.e Calling WCF service hosted on one domain and calling the service form jquery/javascript of page which is hosted on some other domain.
But before we start its better to get understand about the format of the data get exchange from one server to other server.

JSONP
Ajax allows to get data in the background without interfering with the display. Ajax call done by using XMLHttpRequest object, which is allow the client side javascript code to make HTTP connections.

But Ajax call does not allow to get data from cross-domain because of restrictions imposed by the browser. Security error get issued when requesting data from a other domain. one way to avoid security errors is to control remote server where data resides and every request goes to the same domain, that rise question what's the fun if data come form own server only? What to do if data require to get form the other server?

There is one way to come out form this limitation is to insert a dynamic script element in the Web page, one whose source is pointing to the service URL in the other domain and gets the data in the script itself. When the script loads, it executes. It works because the same-origin policy doesn't prevent dynamic script insertions and treats the scripts as if they were loaded from the domain that provided the Web page. But if this script tries to load a document from yet another domain, it will fail. Fortunately, you can improve this technique by adding JavaScript Object Notation (JSON) to the mix.

JSONP or "JSON with padding" is a complement to the base JSON data format, a pattern of usage that allows a page to request data from a server in a different domain. As a solution to this problem, JSONP is an alternative to a more recent method called Cross-Origin Resource Sharing.

Under the same origin policy, a web page served from server1.example.com cannot normally connect to or communicate with a server other than server1.example.com. An exception is the HTML <script> element. Taking advantage of the open policy for <script> elements, some pages use them to retrieve Javascript code that operates on dynamically-generated JSON-formatted data from other origins. This usage pattern is known as JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. They are evaluated by the JavaScript interpreter, not parsed by a JSON parser.

Calling Cross Domain WCF service
Now in following discuss I am going to show you how easily you can call the WCF service hosted on the other domain from the page hosted on the other domain.

Following is list of article you should look first before moving further

Create, Host(Self Hosting, IIS hosting) and Consume WCF servcie
Steps to Call WCF Service using jQuery

To start first create new solution and Add new Project which is WCF service and follow below steps

Step 1
In new release of .net 4.0 the WCF developer team added support for JSONP. There is a new property added which enable to call WCF service from other domain by setting its true.
CrossDomainScriptAccessEnabled - Gets or sets a value that determines if cross domain script access is enabled.

Change your WCF servcie config file as below


  
    
    
  
  
    
  
  
    
    
      
        
      
    
  

As you can see in above config code I have set crossdomainscriptaccessenabled to true and aspnetcompatibilityenabled is to true so that the WCF service works as a normal ASMX service and supports all existing ASP.NET features.
Step 2

SVC file of the service should be like as below

<%@ ServiceHost Language="C#" Debug="true" 
Service="WcfService1.Service1" 
CodeBehind="Service1.svc.cs"
Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"  %> 
Don't forget to add Factory attribute because it cause error if you remove it. Following are the reason to add Factory attribute
1. Service host factory is the mechanism by which we can create the instances of service host dynamically as the request comes in.
2. This is useful when we need to implement the event handlers for opening and closing the service.
3. WCF provides ServiceFactory class for this purpose.
Step 3

CS file for the WCF file is

using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace WcfService1
{
    
    [DataContract]
    public class Customer
    {
        [DataMember]
        public string Name;

        [DataMember]
        public string Address;
    }


    [ServiceContract(Namespace = "JsonpAjaxService")]
    [AspNetCompatibilityRequirements(RequirementsMode =   AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1
    {
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        public Customer GetCustomer()
        {
            return new Customer() { Name = "Pranay", Address = "1 Ahmedabad" };
        }
    }

}
As you can see in the above code I have created Service class which is service contract which servs data and Customer class is DataContract which get served as respose.
In the service class GetCustomer method service data in Json format.

Once the WCF service created to move further Add new project >> Asp.Net service. So that both the WCF service and website runs on tow different like both hosted on different domain.

There is two solution to call the Cross Domain WCF service.

Solution 1 : Call WCF service by using JQuery
Jquery already have support to handle the jsonp. Jquery library provided function ajax and getJson which can allow to call the WCF service which send jsonp data in response.

CallService - Generic function is used to call the WCF servcie, which get called by other javascript function to get and display data

var Type;
        var Url;
        var Data;
        var ContentType;
        var DataType;
        var ProcessData;
        var method;
        //Generic function to call WCF  Service
        function CallService() {
            $.ajax({
                type: Type, //GET or POST or PUT or DELETE verb
                url: Url, // Location of the service
                data: Data, //Data sent to server
                contentType: ContentType, // content type sent to server
                dataType: DataType, //Expected data format from server
                processdata: ProcessData, //True or False
                success: function (msg) {//On Successfull service call
                    ServiceSucceeded(msg);
                },
                error: ServiceFailed// When Service call fails
            });
        }
ServiceFailed - is get called when call to service fail.

function ServiceFailed(xhr) {
            alert(xhr.responseText);
            if (xhr.responseText) {
                var err = xhr.responseText;
                if (err)
                    error(err);
                else
                    error({ Message: "Unknown server error." })
            }
            return;
        }
ServiceSucceeded - is get called when the service successfully return response. As you can see in the function I am checking DataType is jsonp which is just to demonstrate that service is returning jsonp data.

function ServiceSucceeded(result) {
            if (DataType == "jsonp") {
                
                    resultObject = result.GetEmployeeResult;
                    var string = result.Name + " \n " + result.Address ;
                    alert(string); 
            }
        }
GetEmployee - is function that get called to request data from WCF service hosted on other domain. As you can see in code DataType value is get set to jsonp.

function GetEmployee() {
            var uesrid = "1";
            Type = "GET";
            Url = "http://localhost:52136/Service1.svc/GetCustomer"; 
            DataType = "jsonp"; ProcessData = false;
            method = "GetCustomer";
            CallService();
        }

        $(document).ready(
         function () {
            
             GetEmployee();
         }
);
Solution 2 : Call WCF Service by Javascript

To call the service using javascript make use of ScriptManager


        
            
        
    
in above code I set the servicereferance to the WCF service hosted on other domain.
makeCall - is function that get called to request data from WCF service hosted on other domain.

function makeCall() {
                      var proxy = new JsonpAjaxService.Service1();
                     proxy.set_enableJsonp(true);
                     proxy.GetCustomer(onSuccess, onFail, null);
                 }
onSuccess - is called when the result from the service call is received and display data.

function onSuccess(result) {
                     alert( result.Name + " " +result.Address);
                 }
onFail - is called if the service call fails

function onFail(){
                     alert("Error");
                 }
Summary
So after the addition to the special property by the WCF team its quite easy to call cross domain WCF service.
References
JSONP - WIKI
Cross-domain communications with JSONP


Wednesday, March 2, 2011

Create REST service with WCF and Consume using jQuery

Code
What is REST ?
Rest=Representational state transfer which is an architecture design to represent the resources. Rest provide the uniform interface through additional constraints around how to identify resources, how to manipulate resources through representations, and how to include metadata that make messages self-describing.
Rest is not tied with any platform and technology but WEB is only platform which satisfy the all constrain. So any thing you build using Rest constrain, you do it on Web using HTTP.

Following are the HTTP methods which are use full when creating Rest Services.


HTTP Mehtods
  • GET - Requests a specific representation of a resource
  • PUT - Create or update a ersoure with the supplied representation
  • DELETE - Deletes the specified resource
  • POST - Submits data to be processed by the identified resource
  • HEAD - Similar to GET but only retrieves headers and not the body
  • OPTIONS - Returns the methods supported by the identified resource
In this article I am going discuss how to design and consume REST web service using WCF framework of .net service. As Example I am going to create  REST service which create, update and select Employee. Now start following the steps given below.

Designing of the URI
To designing Rest services you need to design URI, so for that you need to list out the resources that going to be exposed by the service.  As I am going to design Employee Create,updae and select service, so resource is
  • Employee
Now to be more specific towards the operation
  • List of Employees
  • A Employee by Id
  • Create Employee
  • Update Employee
  • Delete Employee
For example service is hosted on on local IIS server  and URL to locate it is
        http://localhost/restservices/MyRestServices.svc
In below discussion I am going to design the URL presentation for each operation
  • List  Employees 
         URL is to get list of all employee
               http://localhost/restservices/MyRestServices.svc/Employees
         But there are no. of Employee in system and to apply filter on Employees
              http://localhost/restservices/MyRestServices.svc/Employees?type = {type}
         Note : In above url get list of employee of the type specified {type} of url.
         To Get single Emplyee by using uniqid of Employee.
              http://localhost/restservices/MyRestServices.svc/Employees/{EmployeesID}
         Note : In above URL {EmployeesID} is get replaced by ID of Employee.
         Extension to above scenario, If want to get employee by using id with the type
              http://localhost/restservices/MyRestServices.svc/Employees/{EmployeesID}?type = {type}
  • Create Employee
          URL is to create employee is
             http://localhost/restservices/MyRestServices.svc/Employees/{employeeid}
         Note : In above URL {EmployeesID} is get replaced by ID of Employee.
  • Update Employee
          URL to update employee is
             http://localhost/restservices/MyRestServices.svc/Employees/{employeeid}
         Note : In above URL {EmployeesID} is get replaced by ID of Employee.
  • Delete Employee
         URL to delete employee is
             http://localhost/restservices/MyRestServices.svc/Employees/{EmployeeID}
        Note : In above URL {EmployeesID} is get replaced by ID of Employee.

As you can see here the URL for Create, Update and Delete are same but it makes actual difference when you combile this URL with specific HTTP methods.

Now Combine the url(s) with the HTTP methods

List Employees
  • GET - http://localhost/restservices/MyRestServices.svc/Employees
Create/Update  Employee
  • PUT - http://localhost/restservices/MyRestServices.svc/Employees/{employeeid}
Note : Both Create/Update employee use the same url but when you create employee employeeid =0 and when you update employee empoloyeeid=anynumeircvalue or GUID. This URL can be differ in you implementation this just example.

Delete Employee
  • DELETE - http://localhost/restservices/MyRestServices.svc/Employees/{EmployeeID}


Designing WCF with REST
Article link to get understanding about WCF service Create, Host(Self Hosting, IIS hosting) and Consume WCF servcie

To design Rest WCF service first start to design Class to represent Employee
[DataContract]
    public class Employee
    {
        [DataMember]
        public string Employeename { get; set; }
        [DataMember]
        public string Designation { get; set; }
        [DataMember]
        public string Address { get; set; }
        [DataMember]
        public string Email { get; set; }
    }
as you see Employee class DataContaract attribute so that is going to serve data to client i.e going to work as data exchanger.

Now start with Creation of WCF service which going to serve data to the client i.e going to work as REST full service.
You need to decorate each method in your Servercie interface with the WebInvoke attribute in addition to OperationContract, which allows user to bind method with UrlTemplate and HTTP method. Lets look the each method of interface one by one
public interface IService1
{
Get Methods
Following methods serve data which is requested using GET method of HTTP.
  • GetEmployees
Allow to get all employees. "tag" allow user to filter data because some times system contains more no. of employee which increase traffice and slow down respose, so by specifing tag=manager or tag=senior you will get specific set of employee.
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json,UriTemplate = "?tag={tag}")]
  [OperationContract]
  Employees GetEmployees(string tag);
  • GetEmployee
Allow to get the employee with specific id. "Employee_id" of the uritemplate get replace with the employeeid.
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "Employees/{Employee_id}")]
  [OperationContract]
  Employee GetEmployee(string Employee_id);
Create and Update Method
Following method allow to insert new data and update existed using HTTP method PUT.
  • PutEmployeeAccount
This method allow to insert new employee into system and to update existed employee. "Employee_Id" of the uritemplate get replaced by employee id if update is there and 0 if new employee require to create.
[WebInvoke(Method = "PUT", ResponseFormat = WebMessageFormat.Json, UriTemplate = "Employees/{Employee_Id}")]
  [OperationContract]
   string PutEmployeeAccount(Employee Employeeobj,string Employeename );    

Delete Mehtod
Method allow to remove data using HTTP method DELETE.
  • DeleteEmployeeAccount
Method allow to delete employee from system. "Employee_Id" of the uritemplate get replace by the employee id.
[WebInvoke(Method = "DELETE", UriTemplate = "Employees/{Employee_Id}")]
  [OperationContract]
  void DeleteEmployeeAccount(string Employeename);
}
WebInvoke
  • The WebInvokeAttribute determines what HTTP method that a service operation responds to I.e Http post, get or delete.
  • Indicates a service operation is logically an invoke operation and that it can be called by the REST programming model.
UriTemplate
  • An URI template is a URI-like String that contained variables marked of in braces ({, }), which provides a consistent way for building and parsing URIs based on patterns.
  • UriTemplates are composed of a path and a query. A path consists of a series of segments delimited by a slash (/). Each segment can have a literal value, a variable value (written within curly braces [{ }] .query part is optional. If present, it specifies same way as querystring name/value pairs. Elements of the query expression can be presented as (?x=2) or variable pairs (?x={val}).
  • One of the reason to add this class in .net is to support the REST architectural style used by developers today.


Consume WCF RESTfull service
Before you start following reading below its better to know that how to configure and consume WCF service using jQuery : Steps to Call WCF Service using jQuery

Below is jQuery code to consume web service.
var Type;
var Url;
var Data;
var ContentType;
var DataType;
var ProcessData;
var method;
//Generic function to call WCF  Service
function CallService() {
   $.ajax({
      type: Type, //GET or POST or PUT or DELETE verb
      url: Url, // Location of the service
      data: Data, //Data sent to server
      contentType: ContentType, // content type sent to server
      dataType: DataType, //Expected data format from server
      processdata: ProcessData, //True or False
      success: function(msg) {//On Successfull service call
       ServiceSucceeded(msg);
      },
   error: ServiceFailed// When Service call fails
  });
 }

function ServiceFailed(result) {
   alert('Service call failed: ' + result.status + '' + result.statusText);
   Type = null; 
   Url = null; 
   Data = null; 
   ContentType = null; 
   DataType = null; 
   ProcessData = null;
}
Code above declare and initializes variables which are defined above to make a call to the service. CallService function sent request to service by setting data in $.ajax
GetEmployee
function GetEmployee() {
   var uesrid = "1";
   Type = "POST";
   Url = "Service1.svc/Employees/1";
   ContentType = "application/json; charset=utf-8";
   DataType = "json"; ProcessData = false;
   method = "GetEmployee";
   CallService();
}
GetEmployee method used to get employee with specific id. URL to make call to service is
Service1.svc/Employees/1
in this 1 is employeeid that which is example in turn this function call the RESTfull service function which is having URLTemplate Employees/{Employee_Id} and method type is POST.
CreateEmployee
function CreateEmployee() {
   Type = "PUT";
   Url = "Service1.svc/Employees/0";

    var msg2 = { "Employeename": "Denny", "Designation": "engg.", "Address": "vadodara", "Email": "pr@ab.com" };

   Data = JSON.stringify(msg2);
   ContentType = "application/json; charset=utf-8";
   DataType = "json";
   ProcessData = true;
   method = "CreateEmployee";
   CallService();
}
this method used to create employee. URL to make call to service is
Service1.svc/Employees/Denny
in this 0 is employeeID (0 because I am creating new employee) that which is example in turn this function call the RESTfull service function which is having url template Employees/{Employee_Id} and method type is POST.
In the createemployee method I am creating Employee object with the property require which is going to be consume by service to create employee.

The following code checks the result.GetUserResult statement, so your result object gets the property your service method name + Result. Otherwise, it will give an error like object not found in Javascript.
function ServiceSucceeded(result) {
   if (DataType == "json") {
     if(method == "CreateEmployee")
     {
        alert(result);
     }
     else
     {
        resultObject = result.GetEmployeeResult;
        var string = result.Employeename + " \n " + result.Designation + " \n " +          result.Address + " \n " + result.Email;
        alert(string);
     }
             
   }         
}

function ServiceFailed(xhr) {
   alert(xhr.responseText);
   if (xhr.responseText) {
      var err = xhr.responseText;
      if (err)
          error(err);
      else
          error({ Message: "Unknown server error." })
   }
      return;
 }

$(document).ready(
         function() {
             CreateEmployee();
         }
);
So in this article I am just showed example of CreateEmployee and GetEmployee because this is enough to understand how to consume the method of WCF RESTfull service. Now can create other methods by downloading code and to understand it better way.

Summary
Its quite easy to Create RESTfull service using .net WCF framework. But it must require to understand how you represent your resource i.e design URL template to represent your resource on WEB.

Wednesday, December 1, 2010

Steps to Call WCF Service using jQuery

Download Code

This article illustrates how to call Windows Communication Foundation (WCF) services from your jQuery client code, and points out where special care is needed. Before you start reading and following this article, first read this blog entry which describes how to create a WCF service: Create, Host(Self Hosting, IIS hosting) and Consume WCF servcie

Step 1

Once you are done with creating the WCF service, you need to specify the attributes on the server type class for ASP.NET  Compatibility mode, so that the WCF service works as a normal ASMX service and supports all existing ASP.NET features. By setting compatibility mode, the WCF service will have to be hosted on IIS and communicate with its client application using HTTP.

Read more about this in detail here: WCF Web HTTP Programming Object Model

Following line of code set ASP.NET Compatibility mode
[AspNetCompatibilityRequirements(RequirementsMode =
            AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
    //  .....your code
}

Service.Cs
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }


    public string[] GetUser(string Id)
    { return new User().GetUser(Convert.ToInt32(Id)); }
}

public class User
{

    Dictionary<int, string> users = null;
    public User()
    {
        users = new Dictionary<int, string>();
        users.Add(1, "pranay");
        users.Add(2, "Krunal");
        users.Add(3, "Aditya");
        users.Add(4, "Samir");
    }

    public string[] GetUser(int Id)
    {
        var user = from u in users
                   where u.Key == Id
                   select u.Value;

        return user.ToArray<string>();
    }

}

Step 2

Next you need to specify attributes at operation level in the service contract file for each method or operation. To do this, decorate the method with WebInvoke, which marks a service operation as one that responds to HTTP requests other than GET. Accordingly, your operational level code in the contract file will be as follows:

[OperationContract]
    [OperationContract]
    [WebInvoke(Method = "POST", 
BodyStyle = WebMessageBodyStyle.Wrapped, 
ResponseFormat = WebMessageFormat.Json)]
    string[] GetUser(string Id);

As you can see in the code, sub-attributes having values to support calling via jQuery are marked with Method=post, so data gets posted to the service via a POST method.

ResponseFormat = WebMessaeFormat Json indicate data return as json format.

IService.cs
[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebInvoke(Method = "GET",
     ResponseFormat = WebMessageFormat.Json)]
    string GetData(int value);

    [OperationContract]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
    string[] GetUser(string Id);
}

Step 3

You need to change the default configuration created by Visual Studio in Web.Config file for WCF services, so that it works with the HTTP protocol request send by jQuery client code.

<system.serviceModel>
  <behaviors>
   <serviceBehaviors>
    <behavior name="ServiceBehavior">
     <serviceMetadata httpGetEnabled="true"/>
     <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
   </serviceBehaviors>
   <endpointBehaviors>
    <behavior name="EndpBehavior">
     <webHttp/>
    </behavior>
   </endpointBehaviors>
  </behaviors>
  <services>
   <service behaviorConfiguration="ServiceBehavior" name="Service">
    <endpoint address="" binding="webHttpBinding" contract="IService" behaviorConfiguration="EndpBehavior"/>
   </service>
  </services>
</system.serviceModel>


As you can see in above config file, the EndPoint setting is changed, and EndPointBehaviors added to support WEBHTTP requests.

Note :
Endpoint settings done in the config works in conjunction with the WebInvoke attribute of the operation and the compatibility attribute set in ServiceType to support HTTP requests sent by jQuery.

Step 4

To consume web service using jQuery i.e to make call to WCF service you either use jQuery.ajax() or jQuery.getJSON(). For this I am using jQuery.ajax() method

To set the request, first define a variable. This will be helpful when you are calling multiple methods and creating a different js file to call the WCF service.

<script type="text/javascript">
         var Type;
         var Url;
         var Data;
         var ContentType;
         var DataType;
         var ProcessData;

The following function initializes variables which are defined above to make a call to the service.

function WCFJSON() {
             var userid = "1";
             Type = "POST";
             Url = "Service.svc/GetUser";
             Data = '{"Id": "' + userid + '"}';
             ContentType = "application/json; charset=utf-8";
             DataType = "json"; varProcessData = true; 
             CallService();
         }

CallService function sent request to service by setting data in $.ajax

         //function to call WCF  Service       
         function CallService() {
             $.ajax({
                 type: Type, //GET or POST or PUT or DELETE verb
                 url: Url, // Location of the service
                 data: Data, //Data sent to server
                 contentType: ContentType, // content type sent to server
                 dataType: DataType, //Expected data format from server
                 processdata: ProcessData, //True or False
                 success: function(msg) {//On Successfull service call
                     ServiceSucceeded(msg);
                 },
                 error: ServiceFailed// When Service call fails
             });
         }

         function ServiceFailed(result) {
             alert('Service call failed: ' + result.status + '' + result.statusText);
             Type = null; varUrl = null; Data = null; ContentType = null; DataType = null; ProcessData = null;
         }

Note:
The following code checks the result.GetUserResult statement, so your result object gets the property your service method name + Result. Otherwise, it will give an error like object not found in Javascript.

         function ServiceSucceeded(result) {

             if (DataType == "json") {

                 resultObject = result.GetUserResult;
               
                 for (i = 0; i < resultObject.length; i++) {
                     alert(resultObject[i]);
                 }
            
             }
        
         }

         function ServiceFailed(xhr) {
             alert(xhr.responseText);
             if (xhr.responseText) {
                 var err = xhr.responseText;
                 if (err)
                     error(err);
                 else
                     error({ Message: "Unknown server error." })
             }
             return;
         }

 $(document).ready(
         function() {
         WCFJSON();
         }
         );
</script>

Summary

It is easy to call a WCF service from your client code you; just need to set your WCF service to serve requests through the HTTP protocol and set your client to consume it via the HTTP protocol.

Saturday, November 13, 2010

jQuery Plugin- How and when to use it

What is jQuery plugin ?

jQuery plugin is like extension to the jquery existing function. If you are c# developer plugin likes the extension function to add more functionality existing types or to dlls. Extending jQuery with plugins and methods is very powerful and can save you and your peers a lot of development time by abstracting your most clever functions into plugins.

Steps to make jquery plug

You can start writing your jQuery plugin as you can see below.

Step 1:

Always wrap your plugin in
(
     function( $ )
     { 
          // plugin goes here 
     }
) ( jQuery );
By passing jQuery to a function that defines the parameter as $, $ is guaranteed to reference jQuery within the body of the function.

Step 2:

Create function assign name to function as below
(
     function( $ )
     {
          $.fn.pluginName = function ()
          {
               // there's no need to do $(this) because
               // "this" is already a jquery object
          }; 
     }
) ( jQuery );

Use of jquery plugin

After the end of my last article related to validating fields based on datatype which is more relay on Javascript/jQuery function. I found to much lengthy and repeated code for textbox and for the textarea validation. Something as below

Example:
$("input[isRequired=true]").each(
     function(n)
     {
          $('#' +this.id).addClass('mandatory');

          if(this.value==='')
          {
               $('#' +this.id).removeClass('normal');
               $('#' +this.id).addClass('mandatory');
          }
          else
          {
               $('#' +this.id).removeClass('mandatory');
               $('#' +this.id).addClass('normal');
          }
     }
);

$("textarea[isRequired=true]").each(
     function(n)
     {
          $('#' +this.id).addClass('mandatory');
          if(this.value==='')
          {
               $('#' +this.id).removeClass('normal');
               $('#' +this.id).addClass('mandatory');
          }
          else
          {
               $('#' +this.id).removeClass('mandatory');
               $('#' +this.id).addClass('normal');
          }
}
);
But after use of the jquery this code gets reduce as shown below

$("input[isRequired=true]").ApplyCSSClass();
$("textarea[isRequired=true]").ApplyCSSClass();

(function ($) {

     $.fn.ApplyCSSClass = function () {
               this.each(
                    function () {

                         $('#' + this.id).addClass('mandatory');
                         if (this.value === '') {
                              $('#' + this.id).removeClass('normal');
                              $('#' + this.id).addClass('mandatory');
                         }
                         else {
                              $('#' + this.id).removeClass('mandatory');
                              $('#' + this.id).addClass('normal');
                         }
     });
    };
}
)(jQuery);

So as you can see in above code bunch of line code et related by jQuery plugin which can be applied to the input and textarea field and can be used for other type of fields.

Summary

jQuery plugins allows you to make the most out of the library and abstract your most clever and useful functions out into reusable code that can save you time and make your development even more efficient.

Friday, April 9, 2010

Enhanced Textbox Control


Introduction

In application development, there is always the need for validating input controls. To validate input controls, ASP.NET has a set of validation controls. To apply validation on input controls, you require to attach a validation control with the input control.
Here, I will discuss about an extended control which doesn't require attaching a validation control, but just needs specifying the input type.

Implementation

Custom control implementation

As this is a generic control which can be used by any developer in any ASP.NET application, it inherit the ASP.NET TextBox control to support a basic textbox control and to add extra features for validation; it's basically a custom control, i.e., a custom textbox control.

Properties of the control

All properties use the viewstate to persist values. Another thing to note here is the property appends the ID of the control so that if two textbox controls are dropped on the same page, they do not conflict with each other's property values.

ValidationType
This property allows applying a validation type on the textbox control.
The following validation types are supported by the textbox control:

  • None – allows to enter any type of data.
  • Integer – allows to enter only integer. E.g., 123.
  • Numeric – allows to enter only integer and decimal point values. E.g., 123.12 or 123.
  • Alpha – allows to enter alphabets. E.g., A-Z or a- z.
  • AlphaNumeric – allows to enter alpha and numeric data. E.g., A-Z or a-z or 0-9.
  • Custom – allows to enter data based on patterns specified by the user.
  • Required – allows to enter any kind of data but you are required to enter data in the field.
  • RequiredAndInteger – allows to enter integer and must enter data.
  • RequiredAndNumeric – allows to enter numeric and must enter data.
  • RequiredAndAlpha – allows entering alphabets and must enter data.
  • RequiredAndAlphaNumeric – allows to enter alphanumerics and must enter data.
  • RequiredCustom – allow to enter data based on pattern and must enter data.

AssociatedLabelText
This property allows to set the label that should be displayed with an error message when invalidate data is entered.
public string AssociatedLableText
{
     get
     {
          if (ViewState["LableText" + this.ID.ToString()] == null)
               return "Textbox";
          return (string)(ViewState["LableText" + this.ID.ToString()].ToString());
     }
     set
     {
          ViewState["LableText" + this.ID.ToString()] = value;
     }
}
CustomPattern
This property allows to set a custom Regular Expression to validate the entered data. This property is used when the user wants to validate complex data like email.
public string CustomPattern
{
     get
     {
          if (ViewState["CustomPattern" + this.ID.ToString()] == null)
               return string.Empty;
          return (string)(ViewState["CustomPattern" + this.ID.ToString()].ToString());
     }
     set
     {
          ViewState["CustomPattern" + this.ID.ToString()] = value;
     }
}
ReadOnly
This property causes the textbox control to be displayed as a label control so that its does not allow editing data.
public string ReadOnly
{
     get
     {
          if (ViewState["ReadOnly" + this.ID.ToString()] == null)
               return string.Empty;
          return (string)(ViewState["ReadOnly" + this.ID.ToString()].ToString());
     }
     set
     {
          ViewState["ReadOnly" + this.ID.ToString()] = value;
     }
}
LabelCSSClass
This property allows to set the CSS class when the textbox has the ReadOnly property set to true.
public string LabelCSSClass
{
     get
     {
          if (ViewState["LabelCSSClass" + this.ID.ToString()] == null)
               return string.Empty;
          return (string)(ViewState["LabelCSSClass" + this.ID.ToString()].ToString());
     }
     set
     {
          ViewState["LabelCSSClass" + this.ID.ToString()] = value;
     }
}
ShowWaterMark
This property allows to set the watermark in textbox when property set to true.
public bool ShowWaterMark
{
     get
     {
          if (ViewState["ShowWaterMark" + this.ID.ToString()] == null)
               return false;
          return Convert.ToBoolean(ViewState["ShowWaterMark" +this.ID.ToString()].ToString());
     }
     set
     {
          ViewState["ShowWaterMark" + this.ID.ToString()] = value;
     }
}

WaterMarkText
This property allows to set watermark in textbox when ShowWaterMark propety is set to true.
public string WaterMarkText
{
     get
     {
          if (ViewState["WaterMarkText" + this.ID.ToString()] == null)
               return string.Empty;
          return (string)(ViewState["WaterMarkText" +this.ID.ToString()].ToString());
     }
     set
     {
          ViewState["WaterMarkText" + this.ID.ToString()] = value;
     }
}
GroupId
This property is used by the validation function to know with which group it is associated. E.g., if groupId = ‘A’ for the textbox, then the validation event is fired by the button control having groupId = ‘A’ and the textbox control is validated. In this case, it is not going to be validated by the control having groupId = ‘B’.

Note: this property is used by the JavaScript only and it's added to the control directly; it works the same as the group property in .NET, but the difference is this is used by the JavaScript function.

Overridden methods
The Render method of the control cause rendering of the control on the client with the HtmlTextWriter object. By using this method, changing the rendering of the textbox control is possible.

Render
protected override void Render(HtmlTextWriter writer)
{
If the ReadOnly property of the control is true, than only span is going to be rendered in place of the textbox control so it is not displayed as an editable control.
     if (this.ReadOnly)
     {
          writer.Write(@"<span class=""{0}"">{1}</span>",
          this.LabelCSSClass, this.Text);
     }
If the ReadOnly property of the control is false, than it calls the ApplyValidation method which adds JavaScript and validates the data entered by the client in the textbox control.
     else if (!this.ReadOnly)
     {
          string strError= ApplyValidation(writer);
          base.Render(writer);
          if (((int)this.DataType) > 4)
          {
               writer.Write(strError);
          }
     }
ApplyValidation
private string ApplyValidation(HtmlTextWriter writer)
{
The following line of code defines errorMsg and the script which is going to be bound with the textbox control.
     string errorMsg = string.Empty;
     string script = string.Empty;
As you see below, if DataType has a value more than 5, it adds the required attribute with the value true, which is used by JavaScript to check whether the value is present or not. It also binds the keyup JavaScript method with the onBlur and onKeyUp events. A span tag is also rendered to display an error message when there is no data present in the textbox control.
     if (((int)this.DataType) > 5)
     {
          this.Attributes.Add("isRequired", "true");
          this.Attributes.Add("onKeyUp", "keyup('" + this.ClientID + "')");
          this.Attributes.Add("onBlur", "keyup('" + this.ClientID + "')");
          errorMsg = string.Format(@"<span id='spError{2}' style='display:" +@"none;' >{0} {1}</span>",
                         "Enter value in ", this.AssociatedLableText,this.ClientID);
     }
The below line of code adds the ShowWaterMark attribute to the textbox rendered at the client, which is used by the JavaScript function.
     this.Attributes.Add("ShowWaterMark", this.ShowWaterMark.ToString());
If the ShowWaterMark value is set to true, than it adds the LabelValue attribute to the textbox control which is displayed as the watermark in the textbox:
     if(this.ShowWaterMark)
          this.Attributes.Add("LabelValue", this.WaterMarkText);
If DataType is less than 6, it means it is not required to attach the showWaterMarkText method to the onblur event.
     if (((int)this.DataType) < 6)
          this.Attributes.Add("onBlur", "showWaterMarkText('" + this.ClientID + "')");
If the DataType is Integer, requiredAndInteger, numeric, or requireAndNumeric, it binds the IntegerAndDecimal method withonKeyPress so that it is only allowed to enter integer or decimal data in the textbox control.
     if (this.DataType == ValidationType.integer||
          this.DataType == ValidationType.requiredAndInteger)
     {
          script="IntegerAndDecimal(event,this,'false')";
     }
     if (this.DataType == ValidationType.numeric ||
      this.DataType == ValidationType.requiredAndNumeric)
     {
          script = "IntegerAndDecimal(event,this,'true')";
     }
An important thing to note here is the third argument passed to the JavaScript function: when the value passed to the argument is true, it means it allows to enter decimal data, and if it is false, it allows to enter integer data without a decimal point.

If the DataType is alpha, requiredAndalpha, alphaNumeric, or requireAndAlphaNumeric, it binds the AlphaNumericOnly method withonKeyPress so that it allows to enter integer or decimal data only in the textbox control.
     if (this.DataType == ValidationType.alpha ||
          this.DataType == ValidationType.requiredAndAlpha)
     {
          script = "return AlphaNumericOnly(event,'true')";
     }
     if (this.DataType == ValidationType.alphaNuemric ||
          this.DataType == ValidationType.requiredAndAlphaNumeric)
     {
          script = "return AlphaNumericOnly(event,'false')";
     }
An important thing to note here is the second argument passed to the JavaScript function: when the value passed to the argument is true, it allows to enter alpha characters only, and when it is false, it allows to enter alphanumeric characters.

If the DataType is custom or requiredCustom, it binds the checkReg function with the onBlue event. It also adds a span tag with the text box to display an error message when the data entered doesn't match with the Regular Expression assigned to the CustomPattern property. It adds thepattern attribute with the textbox to validate the data.
     if (this.DataType == ValidationType.custom ||
          this.DataType == ValidationType.requiredCustom)
     {
          errorMsg = errorMsg +string.Format(@"<span id='spCuError{2}' style='display:none;' >{0} {1}     </span>", "Invalid data in ", this.AssociatedLableText, this.ClientID);
          this.Attributes.Add("pattern", this.CustomPattern);
          if (this.DataType == ValidationType.custom)
               this.Attributes.Add("onBlur", "checkReg(this,'" + this.CustomPattern + "');");
          else
               this.Attributes.Add("onBlur", "keyup('" + this.ClientID +"'); checkReg(this,'" + this.CustomPattern + "');");
     }
If the TextMode of the textbox control is set to MultiLine, it binds the CountText method with the onKeyPress event, so that it doesn't allow to enter characters more than a maximum length.
     if (this.TextMode == TextBoxMode.MultiLine)
     {
          if (this.MaxLength <= 0)
          this.MaxLength = 200;
          script = "return CountText(this,'" + this.MaxLength + "')";
     }
As CountText is bound to onKeryPress, it overrides other scripts bind on the control with the keypress event.
The following line of code binds the script with the onKeyPress event.
     this.Attributes.Add("onKeypress", script);

This code returns the errorMsg associated with the textbox:

     return errorMsg;
}
JavaScript functions

IntegerAndDecimal
This method allows to enter only integer and decimal data in the textbox control. If the isDecimal value is true, then it allows to enter decimal point values; otherwise, it allows to enter integer values only.
function IntegerAndDecimal(e,obj,isDecimal)
{
     if ([e.keyCode||e.which]==8) //this is to allow backspace
          return true;
     if ([e.keyCode||e.which]==46) //this is to allow decimal point
     {
          if(isDecimal=='true')
          {
               var val = obj.value;
               if(val.indexOf(".") > -1)
               {
                    e.returnValue = false;
                    return false;
               }
               return true;
          }
          else
          {
               e.returnValue = false;
               return false;
          }
     }
     if ([e.keyCode||e.which] < 48 || [e.keyCode||e.which] > 57)
          e.preventDefault? e.preventDefault() : e.returnValue = false;
}
AlphaNumericOnly
This function allows to enter only alphabets or alphanumeric values in the textbox control. It checks if isAlphaonly is true, then allows to enter only alphabets;otherwise, allows to enter alphanumeric values in the textbox control.
function AlphaNumericOnly(e,isAlphaonly)
{
     // copyright 1999 Idocs, Inc. http://www.idocs.com
     var key = [e.keyCode||e.which];
     var keychar = String.fromCharCode([e.keyCode||e.which]);
     keychar = keychar.toLowerCase();
     if(isAlphaonly=='true')
          checkString="abcdefghijklmnopqrstuvwxyz";
     else
          checkString="abcdefghijklmnopqrstuvwxyz0123456789";

     if ((key==null) || (key==0) || (key==8) ||   (key==9) || (key==13) || (key==27) )
          return true;
     else if (((checkString).indexOf(keychar) > -1))
          return true;
     else
          return false;
}

keyup
This function shows and hides the error message associated with the textbox control when the textbox Required property is set to true. It also calls the showWaterMarkText method if the ShowWaterMark text attribute value is set to true.
function keyup(cid)
{
     var showWaterMark = $('#' + cid).attr("ShowWaterMark");
     if (showWaterMark === "True")
          test = watermark + $('#' + cid).attr("LabelValue");
     else
          test = '';
     if ($('#' + cid).val() === '' || $('#' + cid).val() === test) {
          document.getElementById('spError' + cid).style.display = 'block';
          $('#' + cid).removeClass('normal');
          $('#' + cid).addClass('mandatory');
     }
     else {
          document.getElementById('spError' + cid).style.display = 'none';
          $('#' + cid).removeClass('mandatory');
          $('#' + cid).addClass('normal');
     }
     if (showWaterMark === "True")
          showWaterMarkText(cid);
}

CountText
This function does not allow entering more characters than maxlimit. Note: it's used only for multiline textboxes.
function CountText(field, maxlimit)
{
     if (field.value.length < maxlimit) // if too long...trim it!
     {
          return true;
     }
     else
          return false;
}
checkReg
This function is to display the error message when data entered is not valid according to the custom pattern specified in the CustomPatternproperty.
function checkReg(obj,pattern)
{
     if(obj.value!=='' && pattern!=='')
     {
          var pattern1= new RegExp(pattern);
          if(obj.value.match(pattern1))
          {
               document.getElementById('spCuError'+obj.id).style.display='none';
               return true;
          }
          else
          {
               document.getElementById('spCuError'+obj.id).style.display='block';
               return false;
          }
     }
}

callOnload
This function sets the style of the textbox to the mandatory CSS class when the Required property is set to true and no data can be entered by the user. It also calls the showWaterMark function to show the watermark text in the textbox.
function callOnload()
{
     $("input[isRequired=true]").each(
          function(n)
          {
               $('#' +this.id).addClass('mandatory');
               if(this.value==='')
               {
                    $('#' +this.id).removeClass('normal');
                    $('#' +this.id).addClass('mandatory');
               }
               else
               {
                    $('#' +this.id).removeClass('mandatory');
                    $('#' +this.id).addClass('normal');
               }
          });

     $("textarea[isRequired=true]").each(
          function(n)
          {
               $('#' +this.id).addClass('mandatory');
               if(this.value==='')
               {
                    $('#' +this.id).removeClass('normal');
                    $('#' +this.id).addClass('mandatory');
               }
               else
               {
                    $('#' +this.id).removeClass('mandatory');
                    $('#' +this.id).addClass('normal');
               }
          });

          showWaterMark(); // call function to add watermark to textbox
}
showWaterMark
This function get called by callOnLoad method this function show watermarktext in textbox control when the ShowWaterMark attribute value is set to true.
     var watermark = "";
function showWaterMark() {
     $("input[ShowWaterMark=True]").each(
     function(n) {
          showWaterMarkText(this.id);
          $('#' + this.id).focus(function() {
               test = watermark + $('#' + this.id).attr("LabelValue");
               if (this.value == test) {
                    this.value = "";
               }
     });
  });

     $("textarea[ShowWaterMark=True]").each(
          function(n) {
               showWaterMarkText(this.id);
               $('#' + this.id).focus(function() {
                    test = watermark + $('#' + this.id).attr("LabelValue");
                    if (this.value == test) {
                         this.value = "";
          }
     });
   });
}

showWaterMarkText
This function is called on onBlur event or form keyUp event. Function show watermarktext if the there is no value in textbox or value is equal to watermarktext, Otherwise it remove the watermark CSS values.
function showWaterMarkText(id)
{
     test = watermark + $('#' + id).attr("LabelValue");
     if ($('#' + id).val() === ''|| $('#' + id).val() == test)
     {
          $('#' + id).val(watermark + $('#' + id).attr("LabelValue"));
          $('#' + id).css("color", "#999");
          $('#' + id).css("font-style", "italic");

          if(document.getElementById('spError' + id) !== null)
               document.getElementById('spError' + id).style.display = 'none';
     }
     else
     {
          $('#' + id).css("color", "#000");
          $('#' + id).css("font-style", "");
     }
}
validateFormInputs
The function attached with the button click which submits data to the server, but before that, it validates all the textbox controls having thegroupid which is passed in as a function parameter.
function validateFormInputs(gropId)
{
     var isAllValid = true;
     var searchConditon = "";
     if (gropId !== "" && gropId !== undefined)
     {
          searchConditon = searchConditon +"input[isRequired=true][GroupId=" + gropId + "]";
     }
     else
     {
          searchConditon = searchConditon + "input[isRequired=true]";
     }
     $(searchConditon).each(
          function(n)
          {
               test = watermark + $('#' + this.id).attr("LabelValue");
               if (this.value === '' || this.value == test)
                    isAllValid = false;
               document.getElementById('spError' +this.id).style.display = 'block';
          }
          else {
               if (this.pattern !== '' && this.pattern !== undefined) {
                    if (!checkReg(this, this.pattern)) {
                         isAllValid = false;
                    }
               }
               if (document.getElementById('spError' + this.id) != null)
                    document.getElementById('spError' +this.id).style.display = 'none';
        }
   });

     searchConditon = "";
     if (gropId !== "" && gropId !== undefined)
     {
          searchConditon = searchConditon +"textarea[isRequired=true][GroupId=" + gropId + "]";
     }
     else
     {
          searchConditon = searchConditon + "textarea[isRequired=true]";
     }
     $(searchConditon).each(
          function(n) {
               test = watermark + $('#' + this.id).attr("LabelValue");
               if (this.value === ''|| this.value == test)
                    isAllValid = false;
               document.getElementById('spError' +this.id).style.display = 'block';
     }
     else {
          if (document.getElementById('spError' + this.id) != null)
               document.getElementById('spError' +this.id).style.display = 'none';
          }
     });
     return isAllValid;
}
Note: You need to pass the group ID only when you have to validate the controls related to the given group, i.e., if there are two or more groups of the control validated by different buttons.


Advantages

  • SQL injection attack - Because the control only allows to enter data specified in a property, it does not allow entering unwanted characters which creates problems when doing database DML operations. Read more about SQL injection attacks here: http://en.wikipedia.org/wiki/SQL_injection.
  • Rendering cost decrease - It also decreases the cost of rendering. Because you attach the validation control itself on the page and also emit JavaScript if theEnableClient property is set to true.
  • Multiple type of validation in one textbox control - By setting the ValidationType property, we can apply more than one validation method, e.g., required + alpha, required + numeric etc.
  • Watermark - If showWaterMark = true, it allows to show a watermark in the textbox control, which can be used to show help text or a text value to enter in the textbox.
  • ReadOnly - Using this property, we can show the textbox as a label when the form is in read-only mode, i.e., in non-editable form just for viewing purposes.

How to use
Following is an implementation of the textbox control on a page. To get more information about this, download the code and check it out.
<form id="form1" runat="server">
     <table>
          <tr>
               <td>
                    <!--To Allow only ahlpha numeric char.Data must required to enter by user before submit. -->
                    <cc:MyTextBox runat="server" id="MyTextBox2" GroupId="A"
                              AssociatedLableText="FirstName" DataType="requiredAndAlphaNumeric" >
                    </cc:MyTextBox>
               </td>
               <td>
                  <!--To Allow only ahlpha char. Data must required toenter by user before submit. -->
                    <cc:MyTextBox runat="server" id="MyTextBox1" GroupId="A"
                              AssociatedLableText="LastName" DataType="requiredAndAlpha" >
                    </cc:MyTextBox>
               </td>
               <td>
                      <!--Data must required to enter by user before submit. -->
                    <cc:MyTextBox runat="server" id="MyTextBox3" GroupId="B"
                         AssociatedLableText="Remark" TextMode="MultiLine"
                         DataType="required" ></cc:MyTextBox>
               </td>
               <td>
                    <!--Data must match with pattern specified .Data must required to enter by user before submit.-->
                    <cc:MyTextBox runat="server" id="MyTextBox4" GroupId="A"
                         AssociatedLableText="Email" DataType="requiredCustom"
                         CustomPattern="([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+
                         \.([a-zA-Z])+([a-zA-Z])+" >
                    </cc:MyTextBox>
               </td>
               <td>
                    <cc:MyTextBox runat="server" id="MyTextBox5" AssociatedLableText="Test"
                              ShowWaterMark="true" WaterMarkText="TestBox" ></cc:MyTextBox>
               </td>
     </tr>
</table>
<!-- Validate only textboxes which is having gorupid=A when button is clicked-->

<cc:MyButton runat="server" ID="mybutton" OnOnCustomCommand="mybutton_OnCustomCommand" CausesValidation="true" OnClientClick="return validateFormInputs('A');" CommandArgument="" Text="test" />
</form>

Conclusion
This textbox control implementation provides a basic implementation of a custom control with the use of jQuery and JavaScript.