HomeASP.NET Delving Deeper into Constructing ASP.NET A...
Delving Deeper into Constructing ASP.NET AJAX-based Applications
In the previous article we started our examination of three patterns for constructing ASP.NET AJAX-based applications. We were just starting to "ajaxify" JSSK. In this article we continue our exploration of these three patterns.
Contributed by Xianzhong Zhu Rating: / 13 July 18, 2007
Using the UpdatePanel Server Control to Update Partially
The UpdatePanel server control holds the functions of updating asynchronously and locally posting back, which is pretty suitable for reconstructing a legacy ASP.NET 2.0 application. For more about it please refer to the online tutorials. Here, let's delve into some related parts for rebuilding JSSK using UpdatePanel.
1. Reconstructing the Navigator Tree
The navigator tree, as one of the most frequently-accessed controls, serves as the control center to dispatch each function of JSSK. There are two distinct cases to be considered here: one, there is no need to ajaxify the leaf nodes. Here each of the leaf nodes is associated with another page (such as Login.aspx, PostResume.aspx, etc. ) through a hyperlink; thus, when users click one of the them a whole page post back will be triggered. Since we don't plan to reconstruct the whole architecture of the web site, we choose not to ajaxify the leaf nodes.
As to the second point, the non-leaf nodes, such as Main Options, Job Seekers, Employers, and so forth, however, need to be rebuilt using the UpdatePanel control since each of them is only in relation to the ASP.NET TreeView control while clicking them will still result in a meaningless post back, which obviously provides a poor user experience.
The solution is simple -- enclose the navigator tree with UpdatePanel. Just open the user control NavigationTree.ascx and put this idea into action, as follows:
Note that the navigator tree is completely "static." Therefore, there is no need to update it when the rest of the UpdatePanel controls in the web site are to be refreshed. And thus, we set the Mode property of this UpdatePanel herein to Conditional -- only this tree itself triggers a post back that can be updated, which drastically decreases the unnecessary network traffic and improves the user experience.
2. Ajaxifying page postresume.aspx
Job seekers can modify their resumes on the postresume.aspx page and save the modification into the server-side database by clicking the "Save" button below. The initial page looks like Figure 2.
Figure 2-the pre-modified snapshot for page postresume.aspx.
Here, when the job seeker clicks the "Save" button a whole page post back will be triggered. However, the factually changed parts are merely the one line of prompt message just below the two buttons, which tremendously wastes the network bandwidth and leads to unavoidable flickering.
Now, with the analysis above, we can enclose this ASP.NET Label control that is used to show the prompt message with an UpdatePanel control and set its trigger to the "Save" button above so as to gain a much smoother asynchronous post back. The following is the related modified code snippet:
Here, the two objects, namely the "Save" button and the "lblMsg" label, are bound together. When the "Save" button is clicked the contents within the < ContentTemplate > block will be updated. Now you can register with the web site using the "alok" name (the job seeker role) to appreciate the ajaxified locally updating experience.
Author's Note: First, there are two more places that have also been ajaxified (using the above UpdatePanel policy). One is the GridView control at the bottom of the jobsearch.aspx page; the other is the DetailsView control at the middle of the EducationLevelsManager.aspx page. However, for brevity, we do not delve into them here. Readers can refer to the downloaded source code for more detail. Second, there are virtually more secrets with the MS AJAX server-side UpdatePanel control. Thus, to achieve a satisfying effect in reconstructing any legacy ASP.NET 2.0 web application, it is highly recommended that you find out everything about UpdatePanel.
The UpdateProgress server control can be used in conjunction with the UpdatePanel control so that when the UpdatePanel asynchronously updates its related contents, users can be shown a friendly prompt for current progress. Altogether, wherever the UpdatePanel is used there should be an associated UpdateProgress to give users a clear message.
Apparently, with so many UpdatePanel controls used, we'd better put the UpdateProgress inside the MasterPage.master master page so that users are given a consistent experience all over the web site. Now, open the MasterPage.master and modify the HTML code by adding the following just after the ScriptManager control definition:
Note here we mimic the Gmail design with a red label filled with "Loading..." plus a progress.gif animation on its left at the top right corner of the page. This means, in theory, that whenever any UpdatePanel in JSSK starts to update there will be an animation with a red label filled with "Loading..." at the top right corner to give the user a clue about the current updating state. However, UpdateProgress has a property named DisplayAfter whose default value is 500 milliseconds, which means the UpdateProgress contents will appear after the asynchronous update progress has been lasting for 500 milliseconds. Here, I deliberately set the value of the DisplayAfter property to 5 milliseconds to gain a much clearer effect.
Sometimes, keeping something always floating and visible at some special position of the page will achieve a better advertising effect (despite causing some impoliteness to customers). What is appropriate to make always visible in JSSK is the statistics info at the top right corner. The idea is that, however users scroll the page, the information remains stuck in that "fixed" visible place.
Well, by using the Extender control-AlwaysVisibleControl, the above requirement can be easily met.
First of all, we should notice that the statistic info in JSSK is implemented by a UserControl named Statistics.ascx. Opening the control, we will find that all the contents are encapsulated by a HTML <table> label. Since any object to be extended by the Extender control must be some ASP.NET server-side control, the first thing for us to do is to convert the original HTML <table> label into a server control. With a little modification, we can see the related part of code, as follows.
Note here we merely need to keep the statistic info always visible to the administrator, and thus we will put the AlwaysVisibleControl control inside the LoginView control in JSSK. Since ASP.NET LoginView strays from the point, we won't dwell much on it.
Next, we need to add the declaration for the AlwaysVisibleControl control within the <ContentTemplate> block:
Note that the above TargetControlID property points to the <table> server control that has been converted just now. That's all; you can press F5 and test it.
In real scenarios and as a general rule, for some important operations, such as deleting some record or when users wish to give up filling some web form, the system should pop up an unambiguous message to prompt users to say Yes or No; otherwise some mishandling would lead to fatal error. With the ConfirmButton Extender Control provided by the MS Control Toolkit, when a user is about to submit some data which will trigger a post back we can easily pop up a confirmable JavaScript dialog to let the user further affirm; and, only after the user clicks the "OK" button can the post back take place, or else the submission would be canceled.
Now let's research into two places in JSSK appropriate to enhance by using the ConfirmButton extender control.
1. Canceling the Modification with Personal Resume
The original page looks like the above Figure 2. Though with two buttons, "Save" and "Cancel," on the page, clicking the "Cancel" button would not trigger some further affirmation prompts. Therefore, once users do something wrong, they can not take back what they just did.
Now, let's ameliorate this with the ConfirmButton control. First, locate the source inside file jobseekerpostresume.aspx (here we only allow for the "Cancel" button):
<ajaxToolkit:ConfirmButtonExtender ID="cbe" runat="server" ConfirmText="Leave this page without saving your changes?" TargetControlID="btnCancel" />
Easily, we bind the ConfirmButtonExtender control to the "Cancel" button via the TargetControlID property. That's okay. Now, press F5 to start JSSK, and use the "alok" username (the job seeker) to register into JSSK, and when you click the "Cancel" button in the above page you will see an ordinary affirmation dialog box to let you further affirm the current cancel operation. That's much safer and friendlier.
2. Deleting a Post
Now let's discuss the second case suitable for modification with ConfirmButtonExtender.
As one of the functions to manipulate the posts, the employers are able to delete some post. This is accomplished through the AddEditPosting.aspx page, whose runtime snapshot is shown in Figure 3.
Figure 3-the pre-modified snapshot for page AddEditPosting.aspx.
As illustrated from the above figure, there are three buttons lining up with a little horizontal padding between each of them. And what's more, there is no related affirm hint appearing when the employers click the "Delete" button. This kind of design will also easily result in problems for users. Here, we'd better take out our ConfirmButton extender control to reconstruct this.
Here, there's a little trouble in modifying ASP.NET DetailsView since we can not separate one button from another in coding mode to get the reference to the "Delete" button. So, we have to use some tips to convert the <asp:CommandField> into a <asp:TemplateField>. For this, switch to the design view of the AddEditPosting.aspx page, select DetailsView1 on it, and then left-click the suspension points on the right of the "Fields" item on the Properties window. In the subsequent dialog box "Fields" click the "Command Field" item (the last item in the ListBox on the lower left corner), and then click the "Convert this field into a TemplateField" hyperlink on the lower right corner on the dialog box. In this way, we can make a successful conversion.
The subsequent operation is quite similar -- locate the "Delete" button and add the follow line after it:
<ajaxToolkit:ConfirmButtonExtender ID="cbe" runat="server" TargetControlID="LinkButton3" ConfirmText="Are you sure you want to delete this post?" />
Here, we still use the TargetControlID property of ConfirmButtonExtender to succeed in binding the ConfirmButtonExtender control to the "Delete" button.
Please check back next week for the conclusion to this article.