Tuesday, June 10, 2008

AJAX+ASP.NET = Win: Screw the Iframe idea ... at least for now...

Last post I talked about using an Iframe to delete a relation between two objects. Well I changed my mind and decided to go the Javascript only route with a XMLHttpRequest object. Basically this is AJAX or something very close to it and worked amazingly well. I was concerned that I would not be able to leverage ASP.NET like so many people leverage Java to use pages to return something other than a page, but I figured out a way around that (which I show at the very bottom.)

This is obviously an Intro to Ajax type situation. This is not a big class but a simple method to do an XMLHttpRequest. You could write a larger overarching Ajax framework, but this example shows the basics behind it.
The script I used is this:

This is the script to make the actual sender, it takes into account the different browsers we might have to accomodate.


XMLHTTP VAR Code:

var xmlhttp


if


(!xmlhttp && typeof XMLHttpRequest!='undefined')


{


   try


   {


     
xmlhttp = new XMLHttpRequest();


   }


   catch (e)


   {


      xmlhttp=false;


   }


}


if (!xmlhttp && window.createRequest)


{


   try


   {


      
xmlhttp = window.createRequest();


   }


   catch (e)


   {


      xmlhttp=false;


   } 

}


This section does a call to the ASPX Remove page passing it the parent and child id's. If the return is false, this means we did not have an error, otherwise we did and we use our favorite Javascript Debugger Firebug to figure out what the problem is. Luckily I have tried this code and it fits my needs and works perfectly. (I do know that run is probably the dumbest function name ever, but I didnt even expect this to work :). I guess I should change it!)



Example Code:



function run(i , j, element)


{


  
//This grabs the element name we passed which when we remove we are hiding


  
element = element + "";




  
//The URL of the aspx page that is going to accept this request and


  
// delete the relation in the database



  
url="./remove.aspx?pid="+i+"&cid="+j



  

//The meat! We use the xmlhttp from the code that creates it way above 

   //We are using the "GET" method, sending it the URL, and true means asynchronous response.


  
// this is not sending the request just creating the object, we send further down.



  
xmlhttp.open("GET",url,true);



  

// Now we defie an function to handle when the status of the XMLHttp object changes.



  
xmlhttp.onreadystatechange=function()


   {


       // ReadyState = 4 means all done


      
if (xmlhttp.readyState==4)


       { 

         
//Read the response text, In my case I am only returning


         
// false when the backend was unable to process the move


         
// so we should probably have an else to show failure but I didnt do that yet:)


         
if(xmlhttp.responseText == "false") 

          { 

            
document.getElementById(element).style["visibility"] = "hidden"; 

          }


       }


   }


  
//I tell the backend that this is a form 

   xmlhttp.setRequestHeader('Accept','message/x-formresult')




   // I send the request


  
xmlhttp.send(null)

return false

}



Now if you are anything like I was when I started off down this path you might be wondering, well wtf does remove.aspx do??? I will show you that too but if you only cared about the java you are done :).





This is the only function in Remove.aspx and all it does is send back the exceptions/"" or the word false if it was executed successfully.

The Response.End is particularly important so that you only send what you write to the Response, otherwise it will send whatever design etc that is included in the actual page and that would just be crippling yourself because you would have to sift through all that crap on the Javascript side.

So this is sort of a way to give yourself utility function calls with no UI problems. Technically this might be mixing UI and Business logic but the sheer power it provides is just too powerful to pass up.


ASPX CODE:


protected void Page_Load(object sender, EventArgs e)


{


  
int parentid;


  
int childid;


  
cret ret = new cret();


  

if (Request.QueryString["pid"] != null && Request.QueryString["cid"] != null && Int32.TryParse(Request.QueryString["pid"], out parentid) && Int32.TryParse(Request.QueryString["cid"], out childid))
{
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
ret = DBData.removeParentalLink(parentid, childid);

Response.Write(ret.err);
Response.End();

}
}


If there are any questions or comments feel free.

No comments: