How to access the input control’s data at Server side during Client Callback : A useful trick

Client callback is one way to update the webpage without performing the full page postback. It maintains the Client state while updating the Webpage. During Client callback the webpage runs through modifies version of Page Life Cycle.

The LifeCycle of a page in Client Call Back is  as

Page Lifecycle iin Callback

If you want to learn  more about Client Callback, click here.

But the main drawback of  Client Callback, The input data is not posted from Client to Server. Also,  It does not maintain the view state during partial postback as you can see the Page life cycle of Client callbak it is not saved or SaveViewState event is not fired.

Lets see it with an example.

I have created a simple form to collect some information of an person data. And it has a submit button, which initiates a Callback. As

 <table>
 <tr><td><asp:Label id="lblFName" runat="server" Text="First Name" /> </td>
 <td><asp:TextBox ID="tbFName" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblMName" runat="server" Text="Middile Name" /> </td>
 <td><asp:TextBox ID="tbMName" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblLName" runat="server" Text="Last Name" /></td><td><asp:TextBox ID="tbLName" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblAge" runat="server" Text="Age" /></td><td><asp:TextBox ID="tbAge" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblMailId" runat="server" Text="Email" /></td><td><asp:TextBox ID="tbEMail" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblSex" runat="server" Text="Sex" /></td><td><asp:TextBox ID="tbSex" runat="server"></asp:TextBox></td></tr><tr>
 <td colspan="2"><input id="btnCallBack" type="button" value="Submit" onclick="InitiateCallBack();"/></td></tr>
</table>

Server side code is as

public partial class Callback : System.Web.UI.Page,ICallbackEventHandler
{
    string result;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsCallback)
            return;
        //Creating a reference of Client side Method, that is called after callback on server
        String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg",
            "ReceiveServerData", "");

        //Putting the reference in the method that will initiate Callback
        String callbackScript = "function CallServer(arg, context) {" +
            cbReference + "; }";

        //Registering the method
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
            "CallServer", callbackScript, true);
    }
    public void RaiseCallbackEvent(String eventArgument)
    {
        string firstName = tbFName.Text;
        //Read other data as well

    }
    public string GetCallbackResult()
    {
        return result;
    }
}

And the client side method is

function InitiateCallBack() {
     //Intiate the callback
     CallServer("",'');
}

// Called after the server side processing is done
function ReceiveServerData(arg, context) {
    //arg: hold the result
    //Updating the UI
    document.getElementById('divCallbacl').innerHTML = arg;
}

After filling this form, I submitted it. Now if you try to access the entered using control’s property, you would not get it.

Let’s dig it more and check the form collection, whether the data is passed from Client to server or not

So as you can see that the data is not passed in form collection

But let’s put the following lines of code in java-script, just before initiating the call for Callback as

 function InitiateCallBack() {
	__theFormPostCollection.length = 0;
        __theFormPostData = "";
        WebForm_InitCallback();

        //Intiate the callback
        CallServer("",'');
}

Now let’s run the code and submit the form as earlier.

Now let’s check the form collection.

What a surprise, we got all the input data in form collection. That’s nice.

Now access the data using control’s property.

and you got it.

Now let’s try to see, what does the extra lines of code does

//This Clear the earlier the old data in form collection.
__theFormPostCollection.length = 0;
//It sets the forms data to empty
__theFormPostData = "";
//This method builds the body of the POST request when the page loads. The body of the page is a string 
//(that is __theFormPostData) filled with the contents 
of the view state and all of the input fields in the form.
WebForm_InitCallback();

But I would suggest to use these line at caution. Use only when you need to collect the update from Page during Callback. If you don’t need to get some data or it is in readonly page, don’t use it it introduce extra overhead to your page and costs at performance point of view.

Hope you  all have enjoyed the post.

Advertisement

Page.ClientScript.RegisterStartupScript is not working : A Solution

This is going to be a very short post but will be useful many developers.

You have registered some JavaScript block from server side. But it’s not working. Actually it’s not getting rendered on Client side when you see the PageSource. But the same code works in different projects/applications/pages. Say you have code like this

           Page.ClientScript.RegisterStartupScript(this.GetType(), "ShowStatus", "javascript:alert('Record is not updated');", true);
 

It is registering one one startup script that will be fired when the page will be loaded.
Say you have used at several time and it was working but now it is failing.  Similarly Page.ClientScript provide many other methods that will also not work.

One of the main reasons is, We start using Ajax on our pages. Ajax requires a ScriptManager to handle all the ajax related (Partial postback) tasks. Ajax requires lots of JavaScript code that is managed by the ScriptManager. And it must be noted on a single page only one instance of ScriptManager is allowed.

So whenever we have an instance of  ScriptManager on our page, we need to register the Script using ScriptManager. So you need to change the code like this

            ScriptManager.RegisterStartupScript(this, this.GetType(), "ShowStatus", "javascript:alert('Record is not updated');", true);

       

Now this code make the script start working. Similarly , we also need to change other Page.ClientScript methods to appropriate ScriptManager method.

Cheers,

Brij

Validating partial page with ASP.NET Validators using JavaScript

Validation plays a key role whenever we take a inputs from the user. For this, ASP.NET provides us few validator controls that are used a lot in web applications.
Now a days, in our application, we used to have several section in our web pages.
And also, we populate some data based on the user’s input.
So several times, it requires  to validate the page partially not the entire page,
while earlier we used to have single submit button and their we need to validate the page.

AJAX also played a key role, for partial post back, initiate a call to server etc, which requires to validate a part of the page.

So in these scenarios our earlier approach of validation would not work.
In this kind of scenario, I will discuss few things that will be very helpful.

First, I would suggest, to divide your page in some logical section, those you might need to validate at certain points. And assign a different group name to the validators on those section.

1) If you are initiating an ajax call or initiating a callback from java-script, and you want to validate certain section/part of the page.

So before initiating the ajax call, you need to validate the user inputs. This can be easily with the following method.

You need to call Page_ClientValidate() method, this method has two flavors,
– Page_ClientValidate() it fires all the validators on the page and returns false, if it fails
– Page_ClientValidate(‘groupname’), this method fires all the validators having the passed groupname and returns false if any validator fails.
This is quite useful, while validating partial section/part of the page. So your java script code may look like this

function SaveAddress()
{
	if(Page_ClientValidate('groupname') == false)
		return false;
	else
	{
		//Save Address
	}
}

2) Several time, it happens, that based on some requirement, we used to hide some section of input form or hide some input control, but whenever page/section is going to be submitted, the hidden validators also gets fired. So to overcome this problem, you may need to disable the validators. So to disable any validator from javascript as

document.getElementById('ValidatorClientId').enabled=false;

So these validator wont be fired till you gain enable it. You can enable it as

document.getElementById('ValidatorClientId').enabled=true;

Hope you all will like this post and will found it to be useful.

Why MaxLength property of a textbox with multiline mode doesn’t work? A Solution

Many developers set the MaxLength property of a Textbox and it works fine until the Textbox is not in multiline mode, which is by default behavior of a Textbox.

So what is the basic diffference between a textbox in single line and multiline mode!!!

Let’s see, how it gets rendered as html. Lets have a look

Textbox with SingleLine mode

Textbox with SingleLine mode

Now Textbox with MultiLine mode

Textbox with MultiLine mode

Textbox with MultiLine mode

As you can see, When a Textbox is in SingleLine mode, it gets rendered as a input type text  and when it is in MultiLine mode, it gets rendered as a textarea. As we know MaxLength property works only for input type.

So what is the solution. We need to have a custom solution for this.

Let’s try some solution,

One thing we can do, we can attach a function on onkeypress event to the textbox, which first check the length of input string and if exceed with limit it just returns else allow to enter any input. In the below example I have used the maximum length as 10.

<asp:TextBox ID="tb" runat="server" TextMode="MultiLine" onkeypress="return CheckLength();"></asp:TextBox>

//And the javascript code is
function CheckLength() {
            var textbox = document.getElementById("<%=tb.ClientID%>").value;
            if (textbox.trim().length >= 10) {
                return false;
            }
            else {
                return true;
            }
        }

This works fine until, a user doesn’t paste a text  which is greater than the max length that is given( here 10).  So there is no simple way to stop this. To overcome this problem, one should use one of the asp.net validators.

One can go for the custom validator, and provide a javascript function, which checks the length of the text and if exceeds the maxlength then show an error. Let’s see the code below

<asp:TextBox ID="tb" runat="server" TextMode="MultiLine" ></asp:TextBox>
//Validator
        <asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Please enter maximum 10 charachters." ControlToValidate="tb"
         SetFocusOnError="true" ClientValidationFunction="CheckMaxLength" ></asp:CustomValidator>

//Client Validator function
function CheckMaxLength(sender, args) {
            if (args.Value.trim().length >= 10) {
                args.IsValid = false;
            }
        }

But there is another smart way is there, to acheive this. We can also use Regular expression validator for this, which will check the count of the entered character and will throw an error if it exceeds. Here we would not require to write a javascript function. We need to have a regular expression that will work. Let’s see the code

<asp:TextBox ID="tb" runat="server" TextMode="MultiLine" ></asp:TextBox>

//Regular Expression validator
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="tb" ErrorMessage="Please enter maximum 10 charachters."
 SetFocusOnError="true" ValidationExpression="^[a-zA-Z.]{0,10}$"></asp:RegularExpressionValidator>

Here we don’t require to write a javascript function. I have used a regular expression ^[a-zA-Z.]{0,10}$, which allows all the characters with length 0 to 10.

Hope you all must have enjoyed.

Thanks,

Brij

 

Javascript Dictionary

Might be some of you already know about Dictionaries in JavaScript. But recently I, worked on JavaScript dictionary. And that was really interesting and helpful for me. So I wanted to share my findings to you all. Please share your feedback for my posting.

JavaScript provides us a way to make a Dictionary object and use it as a C# dictionary. Although we would not be having all the properties that is supported by C# dictionary, but we will be able to use it as a normal dictionary i.e. in key value format.

Let’s see one simple example:

I have stored list of all week days as keys and assigned some numbers to these as values. Let’s see the code.

function CreateDayDictionary() {
var days = new Array();
days['Sunday'] = 1;
days['Monday'] = 2;
days['Tuesday'] = 3;
days['Wednesday'] = 4;
days['Thursday'] = 5;
days['Friday'] = 6;
days['Saterday'] = 7;
}

Now to fetch the values at any point of time, we can fetch as per the code given below. Here I have made a function to alert some data. It can be as

 function ShowDays() {
        alert(days['Sunday']);
        alert(days['Thursday']);
        alert(days['Saterday']);
    }

It will show three alerts, first 1 then 5 and lastly 7.

So we can store some global data in our page. And this data we can access, at different events, we require.

Similarly we can store objects in the dictionary in same way. Let’s see the code

 function CreateDictionarywithObject() {
        var objDictionary = new Array();
        // Creating a dictionary which is holding five objects
        for (var i = 0; i < 5; i++) {

            var obj= new myClass();
            obj.member1 = 'member1data' + i;
            obj.member2 = 'member2data' + i;
            obj.member3 = 'member3data' + i;

            objDictionary['Obj' + i] = obj;
        }
        //Fetching third Object
        var fetchedObj = objDictionary['Obj3'];
        alert(fetchedObj.member1);
        alert(fetchedObj.member2);
        alert(fetchedObj.member3);

    }

Now, one more thing if you want to pass the data from server to client as a JSON data, you can serialize a C# dictionary at server side, and again when you will desterilize at client side you will be getting the dictionary as we discussed above. Let’s see the magic.

Here I have made one class Employee as

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Salary { get; set; }
    public int Age { get; set; }
}

Now, on the page load, I created a dictionary with some data, like below

List<Employee> employees= new List<Employee>()
        {
            new Employee{ Id=1000, Name="Brij", Age=27, Salary=800000},
            new Employee {Id=1001, Name = "Rahul", Age=28,Salary=500000},
            new Employee {Id=1002, Name = "Anoop", Age= 29 ,Salary = 60000}
        };
Dictionary<string, Employee> employeeData = employees.ToDictionary(em => em.Id.ToString(), emp => emp);

Now serialize the data using JavaScriptSerializer and assigned it in a hidden variable

JavaScriptSerializer ser = new JavaScriptSerializer();

hfData.Value = ser.Serialize(employeeData);

Now I have a textbox and a button to show employee details. My aspx code looks like this

<body>
    <form id="form1" runat="server">
    <div>
        <span>Id: </span> &nbsp;<input id="idName" type="text" /><br  />
        <input id="Button2" type="button" value="Displaydetail" onclick="show();"/>
        <asp:HiddenField ID="hfData" runat="server" />
    </div>
    </form>
</body>

Here I will be entering the Id of the employee, and on clicking the button “Show details”, I am displaying the data as JavaScript alerts. So let’s see the JavaScript code

function parseEmployeeData() {
        //for parsing the data
        employees = JSON.parse(document.getElementById("<%= hfData.ClientID%>").value);

    }

    function show() {
        parseEmployeeData();
        var key = document.getElementById('idName').value;
        var emp = employees[key];
        if (typeof (emp) != 'undefined') {
        // If key is found then dispaly the details
            alert(emp.Name);
            alert(emp.Age);
            alert(emp.Salary);
        }
        else {
        // key not found
            alert('No data found');
        }
    }

As you can see, first I am parsing the data using JSON, and then finding the value in the dictionary using some key and displaying the details as a JavaScript alert.
This sample is just for an example, to show how we can use JavaScript dictionary in our daily life.

Here, I have used namespace System.Web.Script.Serialization for serializing the data at C#. Also, I have included JSON JavaScript file in my application to parse the data at Client Side.

Happy Client Scripting

Thanks,

Brij