|Delphi Clinic||C++Builder Gate||Training & Consultancy||Delphi Notes Weblog||Dr.Bob's Webshop|
AJAX with ASP.NET and ECO
Now that I've been using my ECO-driven weblog for a year, the number of posts is growing and growing. Even within some categories, there are more posts than can easily be seen in a single view. So I decided to add a filter. But not a "normal" ASP.NET TextBox with a Button to execute the filter, but a somewhat more sophisticated filter using AJAX techniques so all we have to do is type the first few characters of the search expression, wait half a second, and then have the filter execute behind the scenese and produce the result for us (without having to click on a Button).
First of all, using AJAX we can make an asynchronous request to our ASP.NET application, passing the current content of the tbSearch TextBox and ddlSearch DropDownList, receiving as response only a portion of the actual Blogs page. As a result, the effect is not a complete page refresh, but only a refresh of the portion of the page which needs to be changed. For my weblog, that’s the DataGrid.
Instead of updating the ASP.NET DataGrid control, I’m using a placeholder <p> tag, embedding the ASP.NET DataGrid. So in the Blogs.aspx, I’ve added a <p> and </p> tag around the <ASP:DataGrid> tag, with the <p> tag including an id and the runat=”server” attribute so we can access its contents in code:
<p id="dgAJAX" runat="server"> <ASP:DataGrid id="dgPosts" runat="server" allowsorting="True" ... </ASP:DataGrid> </p>When we assign a value to the dgAJAX.innerHTML, the ASP:DataGrid will be hidden from view by the <p> tag internals (which will be the HTML from the DataGrid rendering itself), until we click on one of the categories in the dgCategories DataGrid on the left, which will reload and redisplay the dsPosts again.
Next, we should extend add a lbAjax Label and a TextBox control called AJAX in the Blogs page, where the TextBox has a special attribute onkeydown as follows:
We must now write the ASP.NET code to handle the incoming request. This will be done in the Page_Load event of the Blogs.aspx page. Here, we can see if the Request.Params contains an item with the name “Filter”. If so, then we are inside an AJAX request, and should perform some special processing before ending the response with the HTML needed only for the DataGrid control.
Filter := Request.Params['Filter']; if Assigned(Filter) then begin ... end;Once we know that we’re inside an AJAX request, we must apply the RowFilter on the OCL Expression, using the Filter value that was passed along.
Filter := Request.Params['Filter']; if Assigned(Filter) then begin if (Filter <> '') and not User.Identity.IsAuthenticated then ehPosts.Expression := ehPosts.Expression + '->select(p|p.Title.sqlLikeCaseInsensitive(''%' + Filter + '%''))'; HtmlWriter := HtmlTextWriter.Create(Response.Output); dgPosts.RenderControl(HtmlWriter); HtmlWriter.Flush; Response.&End endNote that we have to end the response to avoid the entire page from rendering, instead of only the dgPosts DataGrid.
Unfortunately, typing a character in the TextBox to start the AJAX filter gives a nasty error about the fact that an ASP.NET DataGrid control can only be rendered in the context of a form (i.e. within a <form> tag). The DataGrid doesn’t know that its resulting HTML will be placed inside a <form> tag, in the innerHTML of our <p> tag, so it gives this error.
We can ignore the error, and allow the DataGrid to render itself by overriding the VerifyRenderingInServerForm method from the ASP.NET Web Form. In the implementation of this method, we should do nothing, allowing all controls to be rendered without the verification (we know what we’re doing, right?).
procedure TWebForm1.VerifyRenderingInServerForm(control: Control); begin //inherited; end;ASP.NET 2.0 Error: RegisterForEventValidation
The AJAX filter now works fine. As long as we don't select a category of posts first, otherwise the filter will be applied on the full set of posts, and not just the posts within the selected category. To be able to use the category specific posts, we need to pass some more information to the call to the Blogs.aspx page: the Id of the RootHandle which is passed in the Request.Params['RootId'].
In the end, the application results in the Blogs page where we can enter text inside the search box, and after half a second the DataGrid with the courseware items will automatically be updated, based on the value in the search field .
Finally, note that even after applying the AJAX filter, the DataGrid can still be sorted and paged. The result is indeed a happy combination of ASP.NET and AJAX using Delphi 2006.