January 2009 - Posts
Today, while creating some javascript popup I had a condition in which I place onclick function on body tag. I had an other button which also implement onclick. So the code looks like as follows
1: <body onclick="disappearPopup()">
2: <a href="#" onclick="ShowPopup()">Show me</a>
3: </body>
So, what happen is whenever link is click the body clicked even called automatically. Practically speaking, we need to cancel the body onclick even each time we click the link click.
And for that I write the following code on click of the link
1: if (window.event) {
2: window.event.cancelBubble = true;
3: }
4: else {
5: e.stopPropagation();
6: }
And it works ……..
Yesterday, one my my friend ask me a query about sending some 500+ emails using an asp.net page. Sending bulk email using asp.net is obviously an issue. I mean, You cannot keep the page on the post back state for the five minutes. Your page will get expired and even if you increase the Request Timeout period it is still not a good approach.
So for that, There are couple of approaches like
1. You can have a table in which you store all the emails and create a Windows Service or Schedule Task to read tables of send emails accordingly.
2. Open a thread on the server side using delegate and return the page to the browser and show the progress using Asynchronous operation.
As We were operating on shared hosting first approach doesn't seem fruitful for us. So, we decided to go with the second approach and for that we use delegates. Let me show you step by step.
1: Public Delegate Sub LongTimeTask_Delegate()
2: Private fileName as String
Here I have declared a delegate and a global variable called filename which I will use for getting the status of the process.
Now on the click event of my button which start the process. I have write the following code
1: Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
2: Dim rnd As Double = New Random().Next()
3: fileName = Session.SessionID & "_" & rnd & ".txt"
4: Dim d As LongTimeTask_Delegate
5: d = New LongTimeTask_Delegate(AddressOf LongTimeTask)
6:
7: Dim R As IAsyncResult
8:
9: R = d.BeginInvoke(New AsyncCallback(AddressOf TaskCompleted),nothing)
10: Dim strScript As String = "<script language='javascript'> setInterval('GetResult(""" + fileName + """)',2000); </script>" 11:
12: Button1.Enabled= False
13: Response.Write(strScript) 'TODO : Can take write on literal
14: End Sub
On line no 3, I am setting filename variable to the session id and a random number
On line no 4, Declare and Initialize Delegate and passed a function that will be executed by Delegate
On line no 7 and on, We invoke the delegate and store the result in IAsyncResult and also specify the function that will execute once the delegate is complete.
On line no 10, we are writing a script on the page which is there to show us the status of process timely.
Now, lets come LongTimeTask function, in which we have the whole stuff.
1: Public Sub LongTimeTask()
2: Dim totCount As Integer = 500
3: For a As Integer = 1 to totCount
4: Try
5: If Not File.Exists(fileName)
6: File.Create(fileName)
7: End If
8: using sw As StreamWriter = New StreamWriter(Server.MapPath(fileName))
9: sw.WriteLine("Processing " + a.ToString() + " of " + totCount.ToString() + " emails") 10: End Using
11: Catch
12:
13: End Try
14: System.Threading.Thread.Sleep(2000)
15: Next
16: End Sub
Notice that, system will be in the loop for 500 times and each time before start processing it will update the status which will display to the browser. The Try/Catch block is updating the status where as notice the line no 14 in which I pause the thread. You can add your email sending or other long process stuff here but for me it is enough to sleep the thread for twenty seconds.
Let me show you what happen when the task gets finished.
1: Public Sub TaskCompleted(ByVal R As IAsyncResult)
2: Try
3: using sw As StreamWriter = New StreamWriter(Server.MapPath(fileName))
4: sw.WriteLine("Process has been completed successfully <a href='default.aspx'>Click here </a> to go back") 'You might shoot an email or some thing else here 5: End Using
6: If File.Exists(fileName)
7: File.Delete(fileName)
8: End If
9: Catch
10:
11: End Try
12: End Sub
This time, we have updated the status with some other text and a hyper link. You can also have any kind of alert here. This is just the part of the code behind stuff. ASPX file contain the actual Asynchronous logic here is the HTML
1: <form id="form1" runat="server">
2: <div>
3:
4: <asp:Button ID="Button1" runat="server" Text="Start IAsync" />
5: <div id="resultDiv"></div>
6: </div>
7: </form>
The resultDiv is responsible of showing the status. Now to get the status following Javscript will do the complete magic
1: <script language="javascript">
2: var request = false;
3: try { 4: request = new XMLHttpRequest();
5: } catch (trymicrosoft) { 6: try { 7: request = new ActiveXObject("Msxml2.XMLHTTP"); 8: } catch (othermicrosoft) { 9: try { 10: request = new ActiveXObject("Microsoft.XMLHTTP"); 11: } catch (failed) { 12: request = false;
13: }
14: }
15: }
16:
17: function GetResult(filename) { 18: var rnd = Math.random() * 1000000;
19: var url = filename + '?rnd=' + rnd;
20: request.open("GET", url, true); 21: request.onreadystatechange = GetResultComplete;
22: request.send(null);
23: }
24: function GetResultComplete() { 25: if (request.readyState == 4) { 26:
27: if (request.status == 200) { 28: var divComm = document.getElementById('resultDiv'); 29: if (divComm) { 30: divComm.innerHTML = request.responseText;
31: }
32: }
33: }
34: }
35: </script>
There it is ... we are all done. Following is the snapshot of the working long waited task in asp.net
You can find the complete code for Visual Studio 2008 below ... cheers
Some days back I got a query from one of my fellow, regarding a very normal situation I mean that’s the day to day task that we as a developers are doing. Here is the scenario
Scenario:
Consider you have a data grid view which show a list of products from northwind database and you want a link button which will edit the same grid view entry but in a separate page and on separate form with the help of the primary key which you may want to send to another page using query string or else.
So the task is to get the primary key of the row on which the link button is pressed.
Solution:
Well, we can achieve this task from variety of methods. Let me just give you a quick list of how we can do this.
1. Have Hidden Field in Link button column
2. Pass PK in command argument
3. Using Data key names.
Ok, for basics I have created two pages one if default.aspx which holds the grid and the other is editform.aspx which will get the primary key sent by Default.aspx
On editForm.aspx add the following code on page load.
1: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
2: If Not Request.QueryString(”Id”) Is Nothing Then ‘check if there is nothing in query string
3: Response.Write(”Product Id Is : ” + Request.QueryString(”Id”).ToString()) ‘print the id
4: End If
5: End Sub
Now for the for the different approaches let’s read below
Approach 1 (Hidden field)
Write the following grid view on default.aspx
1: <asp:GridView ID=”GridView1″ runat=”server” AutoGenerateColumns=”False” DataSourceID=”SqlDataSource1″>
2: <Columns>
3: <asp:BoundField DataField=”ProductName” HeaderText=”ProductName” />
4: <asp:BoundField DataField=”QuantityPerUnit” HeaderText=”QuantityPerUnit” />
5: <asp:BoundField DataField=”UnitPrice” HeaderText=”UnitPrice” />
6: <asp:TemplateField>
7: <ItemTemplate>
8: <asp:HiddenField ID=”hfKey” runat=”server” Value=’<%#Eval(”ProductID”) %>‘ />
9: <asp:LinkButton ID=”Edit” CommandName=”edt” runat=”server”>Edit</asp:LinkButton>
10: </ItemTemplate>
11: </asp:TemplateField>
12: </Columns>
13: </asp:GridView>
Notice that, we have taken a hidden field just in the same column we have the link button and have it default value of out primary key field. Now on RowCommandEvent of the grid view write the following code
1: Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
2: If e.CommandName.ToLower() = “edt” Then
3: Dim lb As LinkButton = CType(e.CommandSource, LinkButton) ‘getting clicked link button
4: Dim strKey As String = CType(lb.Parent.FindControl(”hfKey”), HiddenField).Value ‘getting PK Value
5: Response.Redirect(”EditForm.aspx?id=” + strKey) ‘redirecting
6: End If
7: nd Sub
I guess code does not need any explanation, so let’s move on to the next approach.
Approach 2
We have a minor change the in Template Field of the Gridview we write in Default.aspx. replace that with the following code.
1: <asp:TemplateField>
2: <ItemTemplate>
3: <asp:LinkButton ID=”Edit” CommandName=”edt” CommandArgument=’<%#Eval(”ProductId”) %>‘ runat=”server”>Edit</asp:LinkButton>
4: </ItemTemplate>
5: </asp:TemplateField>
So, we have remove the hidden field we have added in the last approacha and simply add the command argument to the link button, now to catch the command argument and send it to edit form write the following code onRowCommand Event
1: Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
2: If e.CommandName.ToLower() = “edt” Then
3: Dim strKey As String = e.CommandArgument ’Getting Pk Value from argument
4: Response.Redirect(”EditForm.aspx?id=” + strKey) ‘redirecting
5: End If
6: End Sub
Approach 3:
Ok, for this you need to add DataKeyNames Property to main GridViewMarkup. In other word, it is an attribute of grid view which can accept multiple values using “,” but in our case we are using one. So when we add this attribute our grid markup will look like as follows
1: <asp:GridView ID=”GridView1″ runat=”server” AutoGenerateColumns=”False” DataKeyNames=”ProductID” DataSourceID =”SqlDataSource1″>
2: <Columns>
3: <asp:BoundField DataField=”ProductName” HeaderText=”ProductName” />
4: <asp:BoundField DataField=”QuantityPerUnit” HeaderText=”QuantityPerUnit” />
5: <asp:BoundField DataField=”UnitPrice” HeaderText=”UnitPrice” />
6: <asp:TemplateField>
7: <ItemTemplate>
8: <asp:LinkButton ID=”Edit” CommandName=”edt” runat=”server”>Edit</asp:LinkButton>
9: </ItemTemplate>
10: </asp:TemplateField>
11: </Columns>
12: </asp:GridView>
Notice that we have remove command argument from link button, now add the following code on the RowCommand Function.
1: Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
2: if e.CommandName.ToLower() = “edt” Then
3: Dim lb As LinkButton = CType(e.CommandSource, LinkButton)
4: Dim gvRow As GridViewRow = lb.BindingContainer ‘Getting current row to get index
5: Dim strKey As String = GridView1.DataKeys(gvRow.RowIndex)(0).ToString()
6: Response.Redirect(”EditForm.aspx?id=” + strKey) ‘redirecting
7: End If
8: End Sub
In the above code we are getting the current row from which the link button is clicked because we need the index of the row to get the data key name value.
So, now you have plenty of choices to select which approach you like to go with
.
Screen Cast : http://tinyurl.com/5fuj8e
This morning when I was taking backup of the database located on one of our dedicated server. I hunt the following error.
System.Data.SqlClient.SqlError: Failed to pause catalog for backup. Backup was aborted.
In short, you are no more able to take backups. So I googled about this error but trust me, there is no much information regarding this stuff. So, to get rid of it, you quickly need to do the following steps.
1. Jump to the services console. (Control Panel-> Administrative Tools -> Services)
2. Locate the SQL Server FullText Search and verify is it running.
3. If it is not running then start it …. but hold on read the next point
4. If it is running then verify what account which it is using under Log On tab. (it should be Local System Account)
5. Save the settings and make sure to restart the service and you are done.
This weekend, I was in Morgan Technologies as they were facing some installation problem in SQL Server 2005 enterprise edition. So they called me up with relation to the community work. So the error was
Errors occurred during the installation:
Beta components detected.
It looks that there is some beta software running on the server but after looking at the Program Files and Add Remove Program It seems that there is nothing installed before. No Visual Studio Installation (as that is server) , no Beta stuff. There was .net framework 2.0 installed but to get rid of this error I did uninstall that too.
But the error doesnot seems to go. still the beta components deteced comes on screen each time I try to install SQL Server.
So, Finally I found Microsoft MSI Cleanup Utility which did my job perfectly. on a clean machine where there is nothing Installed I found two microsoft beta installations, No idea where it came from but this tool remove that and afterward SQL Server installed like a butter with no issue.
To download the tool : http://support.microsoft.com/kb/290301
I thought I am CLR Integration Guru in Sql Server but this morning I came to know that there are lots of things left to grab. While I was moving the local database on the new live server I run some CLR Procedure which Says these procedures required CLR Integration enabled. So to get that done.
I went on SQL Server Surface Area Configuration -> Surface Area configuration for features -> Enable CLR Integration. till here, every thing seems fine I encounter no error.
After that when I re-execute the same query I get a new error:
“Invalid connection (Common language
runtime (CLR) execution is not supported under lightweight pooling.
Disable one of two options: “clr enabled or “lightweight pooling”.
I really have no idea what the light weight pooling is but the need of the time is to disable it. After googling for a bit I get this link. but still no use as the query written in this page is not working infact it is giving error.
1: sp_configure ’show advanced options’, 1;
2: GO
3: sp_configure ‘lightweightpooling’, 0;
4: GO
5: RECONFIGURE;
6: GO
Error:
The configuration option ‘lightweightpooling’ does not exist, or it may be an advanced option.
To find what is going wrong, I quried on sys.configurations because this table contain database configuration.
1: select * from sys.configurations where name like ‘%light%’
Finally, after running the above query I came to know that there is a space in ‘lightweightpooling’. It means it is ‘lightweight pooling. Now when I diagnose the problem I execute the following query which make my sql server CLR Integrated.
1: USE master
2: GO
3: EXEC sp_configure ’show advanced options’, 1
4: GO
5: RECONFIGURE WITH OVERRIDE
6: GO
7: EXEC sp_configure ‘lightweight pooling’, 0
8: GO
9: EXEC sp_configure ‘clr enabled’, 1
10: go
11: RECONFIGURE WITH OVERRIDE
12: GO
13: EXEC sp_configure ’show advanced options’, 0
14: GO
After executing the query, we might need to restart the SQL Services to make it work.
This is like a very common issue, specially for those who are working on public site which is live and they have to release the builds every week or month and if the new build contain JS files then your change will not reflect on the client browser until someone there presses ctrl + F5.
So, after googling this issue. I came to know it is possible to prevent the browser from accessing the cache copy by writing the script tag as below
1: <script type="text/javascript" src="../Includes/main.js?random=556"></script>
It is good, when I have a single or some number of pages to change. Unfortunately, That is not the case I have hundreds of pages and that will be hassle to make those changes again and again for every build. So, I try to make this thing happen using Response Filter.
Create Response Filter:
So, to write the Response Filter we need to create a class and which is extended from Stream (System.IO.Stream) and I named it BuildTokenFilter.
1: Imports Microsoft.VisualBasic
2: Imports System.IO
3: Imports System.Text.RegularExpressions
4: Imports System.Configuration
5:
6:
7: Public Class BuildTokenFilter
8: Inherits Stream
9: Private _responseStream As Stream
10: Public Sub New(ByVal responseStream As Stream)
11: _responseStream = responseStream
12: End Sub
13: Public Overrides ReadOnly Property CanRead() As Boolean
14: Get
15: Return _responseStream.CanRead
16: End Get
17: End Property
18: Public Overrides ReadOnly Property CanSeek() As Boolean
19: Get
20: Return _responseStream.CanSeek
21: End Get
22: End Property
23:
24: Public Overrides ReadOnly Property CanWrite() As Boolean
25: Get
26: Return _responseStream.CanWrite
27: End Get
28: End Property
29:
30: Public Overrides Sub Flush()
31: _responseStream.Flush()
32: End Sub
33:
34: Public Overrides ReadOnly Property Length() As Long
35: Get
36: Return _responseStream.Length
37: End Get
38: End Property
39:
40: Public Overrides Property Position() As Long
41: Get
42: Return _responseStream.Position
43: End Get
44: Set(ByVal value As Long)
45: _responseStream.Position = value
46: End Set
47: End Property
48:
49: Public Overrides Function Read(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) As Integer
50: Return _responseStream.Read(buffer, offset, count)
51: End Function
52: Public Overrides Function Seek(ByVal offset As Long, ByVal origin As System.IO.SeekOrigin) As Long
53: _responseStream.Seek(offset, origin)
54: End Function
55:
56: Public Overrides Sub SetLength(ByVal value As Long)
57: _responseStream.SetLength(value)
58: End Sub
59: Public Overrides Sub Write(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer)
60: Dim strRegex As String = "src=(?<Link>.*js)"
61: Dim BuildTokenString As String = "?token=" & IIf(ConfigurationManager.AppSettings("BuildToken") = Nothing, "1.0", ConfigurationManager.AppSettings("BuildToken"))
62: Dim objRegex As New Regex(strRegex)
63: Dim html As String = System.Text.Encoding.UTF8.GetString(buffer)
64: Dim extCharCount As Integer = 0
65:
66: Dim objCol As MatchCollection = objRegex.Matches(html)
67: For Each m As Match In objCol
68: extCharCount += BuildTokenString.Length
69: Dim newJSValue As String = m.Value & BuildTokenString
70: html = html.Replace(m.Value, newJSValue)
71: Next
72: buffer = System.Text.Encoding.UTF8.GetBytes(html)
73: _responseStream.Write(buffer, offset, count + extCharCount)
74: End Sub
75: End Class
"Write" is the function which is doing the whole stuff. It is really simple to understand. Let me go linewise.
60. Create a string variable and assign and regular expression which will search all the js files tags in html
61. Create a string which will append to the JS file. Checking the App key in web.config So that the token can be extended in future.
62. Create a Regex Object
63. Get the html from Buffer
64. Create an integer variable which will keep track of the characters that are added to the html variable.
66. Save the matches in a collection
67. Get each mach object from Match Collection
68. Add the character count which will added to the html variable
69. Create a variable and assign value of match and concatenated with build token
70. Replace the old value with the new with build token in html variable
72. Encode the html variable back to the buffer
73. Write the buffer to the stream by adding count with build token character count.
Now lets create a HttpModule which will responsible of attaching this response filter with every request.
Create HttpModule:
Now to write HttpModule, I will create a class which will Implements IHttpModule (interface) and I name it "BuildToken"/
1: Imports Microsoft.VisualBasic
2: Imports System.Web
3: Public Class BuildToken
4: Implements IHttpModule
5: Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
6:
7: End Sub
8: Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
9: AddHandler context.BeginRequest, AddressOf Application_BeginRequest
10: End Sub
11: Private Sub Application_BeginRequest(ByVal source As Object, ByVal e As EventArgs)
12: Dim context As HttpApplication = CType(source, HttpApplication)
13: If context.Request.RawUrl.Contains(".aspx") = True Then
14: context.Response.Filter = New BuildTokenFilter(context.Response.Filter)
15: End If
16: End Sub
17: End Class
In this case the magical function is Application_BeginRequest which can easily be understand but the question might arises why I have put the If condition on line number 13. Well, I don't want my module to attach response filter against all the files. Keep in mind, HttpModule is always called no matter what content type are you requesting. when somebody write http://www.sitename.net/images/border2.jpg it will still process through HttpModule and that is what I don't want.
Configuration Setting:
We are almost done, just a web.config entry is left which we keep for the modification of token string.
1: <appSettings>
2: <add key="BuildToken" value="7.0"/>
3: </appSettings>
Test the filter:
Now to check the the response filter create a page that is called default.aspx and paste the following markup
1: <html xmlns="http://www.w3.org/1999/xhtml" >
2: <head runat="server">
3: <title>Untitled Page</title>
4: <script type="text/javascript" src="../Script/samain.js"></script> 1:
2: <script type="text/javascript" src="../ControlsScripts/preloadshare.js">
1: </script>
2: <script type="text/javascript" src="../Script/mainview.js">
</script>
5: </head>
6: <body>
7: <form id="form1" runat="server">
8: <div>
9: <p>
10: Right click and view source you will find JS files with query string</p>
11: </div>
12: </form>
13: </body>
14: </html>
Now Run the application and view source the page you will notice some thing like give below.
Each time, when you made some changes in JS file just change Build Token entry in the web.config file and your visitors will get the updated copy of JS. You can also download the project files given below.
Well, I with my designer Atiq was trying to set the a div which is working fine in IE7 but when it comes to Firefox, it was asking us to give the margin-top:10px. when we put that, the div comes down in IE7. So, in this situation we need to specify two different styles for these two browsers.
I don't want to use that, which can also be done using the following HTML.
1: <!--[if IE 7]><link rel="stylesheet" type="text/css" href="IE7styles.css" /><![endif]-->
But I don't want to create two css files for this work. Somehow, I want to mage it in the name same CSS. So what I did is so I use Child Selector Command and Star HTML Hack.
Child Selector Command is not understandable by IE, hence whenever it gets something like this .... IE Ignores the style. So I decided to specify Firefox stuff here. it looks like as follows
1: html>body #ContainerCodeQuestionAnser
2: {
3: position:absolute; z-index:50;background-color:#FFFFFF;width:auto;
4: height:20px;margin-left:10px;overflow:hidden;top:10px; /*top is for firefox*/
5: }
In contrast, Star HTML Hack is not understandable by any other browser except IE. So IE Stuff Goes here.
1: * #ContainerCodeQuestionAnser
2: {
3: position:absolute; z-index:50;background-color:#FFFFFF;width:auto;
4: height:20px;margin-left:10px;overflow:hidden;
5: }
That's it ... the design looks really good.......
Often, we have condition when we have multiple forms on a page which have multiple submit buttons as well. Whenever, you press enter on any text box it will call the command button which is at top most sequence of command buttons.
So, to overcome this problem here is the little code. Take your each set of fields and button in a panel and specify the default Button Property. In the example below I have a form which have two buttons one is command button and another is an image button and I am setting the second button of the sequence to get called each time enter key press on the panel. (rather then the top most)
1: <asp:Panel ID="pnl1" runat="server" DefaultButton="ImageButton1">
2: <asp:TextBox ID="TextBox1" runat="server">
3: </asp:TextBox>
4: <asp:Button ID="Button1" runat="server" Text="Submit" />
5: <asp:ImageButton ID="ImageButton1" runat="server" />
6: </asp:Panel>
In this post, I will explain you how to have an ajax call on custom validator control and check for the username in the database. This task will include two pages one is the form page (default.aspx in our case) in which we have the custom validator and the other one is the page which we call through AJAX to give us the result (validateUser.aspx). You can also have a web service instead of that page but in my scenario , I am using ASPX page.
So, the form will look like as following.
1: <form id="form1" runat="server">
2: <div>
3: <asp:Panel ID="pnl1" runat="server" DefaultButton="Button1">
4: <asp:TextBox ID="TextBox1" runat="server">
5: </asp:TextBox>
6: <asp:Button ID="Button1" runat="server" Text="Submit" />
7: <asp:HiddenField ID="hfOutput" runat="server" />
8: </asp:Panel>
9: <asp:customvalidator ID="Customvalidator1" runat="server" errormessage="Enter Valid User" ControlToValidate="TextBox1" ClientValidationFunction="ValidMe"></asp:customvalidator>
10: </div>
11: </form>
Default.aspx (Form)
Notice, the hiddent field called hfOutput which we will use to store the output of the AJAX call.
Where as the page which we call through AJAX will look like as follows
1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="validateUser.aspx.cs" Inherits="LearnWebApp.validateUser" %>
validateUser.aspx
In short, we have deleted every thing from this page except page directive. Now if we call this page we will see the simple output without having any HTML tag. we did it because we want to get rid from all the html tags so that we can have a neat and clean output at the time we call this page from Javascript (AJAX). What we want this page to return us is either "True" or "False". If you look at the code behind file of this page you will have a good idea of what we actually upto. Here is the code for that.
1: protected void Page_Load(object sender, EventArgs e)
2: {
3: // We can also use a database call here ... right now we are compairing string.
4: if (Request.QueryString["username"] == "username")
5: {
6: Response.Write("true");
7: }
8: else
9: {
10: Response.Write("false");
11: }
12: }
validateUser.aspx.cs
As it is there on comments, here we are only comparing string. You can have a database call and return the result accordingly.
To call the validateUser.aspx from validMe function which we have defined in ClientValidationFunction property of custom validator, we need to write the following javascript on default.aspx
1: <script type="text/javascript">
2: var ajaxCalled = false;
3:
4: function ValidMe(source, args) {
5: callPage(args.Value)
6: while (document.getElementById("hfOutput").value != ""){
7: if (document.getElementById("hfOutput").value == "true") {
8: args.IsValid = true;
9: }
10: else {
11: args.IsValid = false;
12: }
13: document.getElementById("hfOutput").value = "";
14: return;
15: }
16: }
17:
18: function callPage(strName) {
19: var rnd = Math.random() * 1000000;
20:
21: if (window.XMLHttpRequest) { // Mozilla, Safari, IE7...
22: request = new XMLHttpRequest();
23: } else if (window.ActiveXObject) { // IE6 and older
24: request = new ActiveXObject("Microsoft.XMLHTTP");
25: }
26: var url = 'validateUser.aspx?username=' + strName + '&R=' + rnd;
27: request.open("GET", url, true);
28: request.onreadystatechange = SetPage;
29: request.send(null);
30:
31: }
32:
33:
34: function SetPage() {
35: if (request.readyState == 4) {
36: var objHf = document.getElementById("hfOutput");
37: if (request.status == 200) {
38: if (objHf) {
39: objHf.value = request.responseText;
40: }
41: }
42: }
43:
44: }
45: </script>
Let me describe what we have done here, I am calling CallPage function from ValidMe which will call from the asp.net validation mechanism. CallPage function is an AJAX call which will call validateUser.aspx and SetPage function will be called once the AJAX call is finish and we have output ready to use.
And on that SetPage function we are setting the Hidden field called hfOutput to get used by ValidMe function.
That's it ..... :) . You can also download the complete project give below.
More Posts
Next page »