Sunday, April 13, 2008

How to have more, then one forms in page and be able to submit it to server without page refresh using ASP.NET AJAX

Someone asked me in Meet an Expert lunch in TechEd about having more, then one server forms in one page, using ASP.NET AJAX. The answer was simple – make only one visible at one time. Other words, hide all and show only one relevant

<script runat=server language="C#">
private void Page_Load(object sender, System.EventArgs e)
{
Form1.Visible = !Form1.Visible;
Form2.Visible = !Form2.Visible;
}

<form id="Form1" runat="server" >…
<form id="Form2" runat="server" visible="false">…



That’s all. However, what to do if you need to show them all? Let’s try to understand. First of all, let’s make them client based




<form id="form1" >…

<form id="form2" >…




Then we should handle onsubmit method and neutralize it, before the page will be reloaded (we do not want reloads – AJAX rulez!)




<form id="form1" onsubmit="onSubmit(this); return false;">…

<form id="form1" onsubmit="onSubmit(this); return false;">…




So, the final code will looks as following (there are some of such forms):




<form id="form1" onsubmit="onSubmit(this); return false;">

    <div>


    <h2>Client Form 1</h2>


    <input type="text" id="val" />


    <input type="submit" value="Submit 1" />


    </div>


    </form>




Then, let’s have one server side form, that will handle our requests




<form runat="server">

<asp:Label ID="Result" runat="server"/>




And now, let’s submit our results there. Yes, we can access server side controls from client side JavaScript




<script type="text/javascript">

       function onSubmit(sender)


       {


            var what = sender["val"].value;


            if(what == "")


                what = "nothing";


            $get("Result").innerHTML=sender.id+" tells you "+what;



       }




Well, but as you, probably understand, there is no real submit was performed. We need client-server-client roundtrip in order to do it. What to do? The answer is PageMethods.



Let’s add simple page method, that formats the string and added time tag




<script runat="server">

            [System.Web.Services.WebMethod]


            public static string UpdatePanel(string senderID, string what)


            {


                return string.Format("{0} tells you {1} at {2} with server roundtrip", senderID, what, DateTime.Now);


            }


       </script>




One we have such. All we have to do is to enable page methods by using ScriptManager




<form runat="server">

    <h2>Result</h2>


        <asp:ScriptManager runat="server" EnablePageMethods="true" />


        <asp:Label ID="Result" runat="server"/>


    </form>




And then, call it from javascript




function onServerSubmit(sender)

       {


            var what = sender["val"].value;


            if(what == "")


                what = "nothing";


            PageMethods.UpdatePanel(sender.id,what,onServerSubmitCompleted);



       }

function onServerSubmitCompleted(value)


       {


         $get("Result").innerHTML=value;


       }




We done. BTW, if we’ll try to pass HTML object into server, we’ll get "Cannot serialize object with cyclic reference within child properties" exception – this is not bug, this is warlock for bad HTML programmers. If you want to be able to pass whole form (HTML object) into server you’ll probably have to either use LosFormatter, or any other custom HTML serializer to do it.  Want to know more about it? Maybe another time.



Have a nice week and be good people.



Source code for this article

No comments: