Topics discussed: jQuery, jQuery Ajax, ASP.NET partial page
rendering, Javascript
Scenario: This blog explains a case typical of a social web app,
where the user can select a list of intended recipients of a publication (e.g.:
a blog post, a text message, an email, or some other kind of notification.)
This would be a case when the user does not want to share information with the
whole community, but rather with only a subset of select users (e.g.: friends,
colleagues, followers, group members, etc.)
The page that contains the data-entry form enables the user to
select his/her target audience by making behind-the-scenes jQuery Ajax calls to
the server and refreshing only a portion of the page’s UI.
Let’s examine the code in different layers of the application:
The Client Code:
It consists of jQuery Ajax calls to a server side ASP.NET code, and
Javascript helper methods:
<head>
…
1.
$("a#hlSavedList").click(function () {
2. var userId =
$get('<%=hfUserId.ClientID%>').value;3. var sUrl = "GetRecipientsByAjax.aspx?userId=" + userId;
4. $.get(sUrl, function (result) {
5. $('#divRecipientList').html(result);
});
});
…
</head>
The above jQuery code executes (line 1 above) when a hyperlink with
ID= hlSavedList is clicked. The html of this hyperlink is shown below:
<a href="#links" ID="hlSavedList" name="hlSavedList">Get my list</a>
In order to retrieve the user’s list, we need to reference user’s UserId stored in a hidden field that is
placed on the ASP.NET page:
<asp:HiddenField ID="hfUserId" runat="server" /> And jQuery accesses the value of this HiddenField with this line of code (line 2 above):
var userId = $get('<%=hfUserId.ClientID%>').value;
The HiddenField can be assigned the UserId value after the user logs in (in page’s server-side code), and it would look something similar to this:
MembershipUser mu = Membership.GetUser();
Guid guidUserID = new Guid(mu.ProviderUserKey.ToString());
this.hfUserId.Value = guidUserID.ToString();
Alternatively, the UserId can be read from a Session object if it has stored the value earlier:
if (Session[“UserId”] != null)
{
this.hfUserId.Value = Session[“UserId”].ToString();
}
Next, we can call our target ASP.NET page to do the work and return the HTML markup that will populate only a portion (a <div> element) of the page (lines 3, 4, and 5):
var sUrl = "GetRecipientsByAjax.aspx?userId="
+ userId;
$.get(sUrl, function (result) {
$('#divRecipientList').html(result);});
protected void Page_Load(object
sender, EventArgs e)
{if (Request.QueryString["userId"] != null)
{
GetAudienceByUser(Request.QueryString["userId"].ToString());
}
else
{
Response.Write("<table><tr><td>Error: No query string value in url.</td></tr></table>");
Response.End();
}
}
This method binds the
data to the DataList control and then calls the helper method GetHtml() which retrieves
the controls HTML, places it in the page’s Response and ends the processing on
the server by calling Response.End();
{
try
{
//Get the data from the data source:
this.dataListAudience.DataSource =
DataAccessLayer.GetAudienceByUser(userId);
this.dataListAudience.DataBind();
if (this.dataListAudience.Items.Count > 0)
{Response.Cache.SetCacheability(HttpCacheability.NoCache);
string sRet = GetHtml(this.dataListAudience);
Response.Write(sRet);
}
else
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write(@"<table width=""460""><tr><td
style=""text-align:center;color:red;height:30px;"">
No contacts in your Saved List.
</td></tr></table>");
}
}
catch (SqlException sqlEx)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write("Database Error: " + sqlEx.Message);
}
catch (Exception ex)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write("Generic Error: " + ex.Message);
}
finally
{
Response.End();
}
}
{
StringBuilder sbHtml = new StringBuilder();
HtmlTextWriter oWriter = new HtmlTextWriter(new StringWriter(sbHtml));
try
{
//Get the control’s HTML
oCtrl.RenderControl(oWriter);
}
finally
{
oWriter.Close();
}
return sbHtml.ToString();
}
The DataList control in the .aspx page:
<asp:DataList ID="dataListAudience"
runat="server" RepeatColumns="2" RepeatDirection="Vertical"
DataKeyField="User_Id" EnableViewState="true"
Width="500">
<HeaderTemplate>
<table width="460" cellpadding="0" cellspacing="0" border="0">
<tr><td style="height:6px;"></td></tr>
<tr><td align="center"><strong>Audience List</strong></td></tr>
<tr><td style="height:10px;"></td></tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<table width="215" cellpadding="0" cellspacing="0" border="0">
<tr>
<td width="215" align="right" valign="bottom">
<%# Eval("Email") %>
<input type="checkbox" name="audience"
value='<%# Eval("AudienceUser_Id") %>'
title='<%# Eval("Email") %>' />
</td>
</tr>
</table>
</ItemTemplate>
<FooterTemplate>
<table width="460" cellpadding="0" cellspacing="0" border="0">
<tr style="height:20px;"><td></td></tr>
</table>
</FooterTemplate>
</asp:DataList>
<table id="dataListAudience"
cellspacing="0" border="0"
style="width:500px;border-collapse:collapse;">
<tr>
<td colspan="2"><tr>
<table width="460" cellpadding="0" cellspacing="0" border="0">
<tr><td style="height:6px;"></td></tr>
<tr><td align="center"><strong>Audience List</strong></td></tr>
<tr><td style="height:10px;"></td></tr>
</table>
</td>
</tr>
<tr>
<td>
<table width="215" cellpadding="0" cellspacing="0" border="0">
<tr>
<td width="215" align="right" valign="bottom">
user0@adventureworks.com
<input type="checkbox" checked="checked" name="Audience"
value='44813d2c-b9ac-4a8a-aab1-4a25bba1a466'
title=' user0@adventureworks.com ' />
</td>
</tr>
</table>
</td>
<td>
<table width="215" cellpadding="0" cellspacing="0" border="0">
<tr>
<td width="215" align="right" valign="bottom">
user1@adventureworks.com
<input type="checkbox" checked="checked" name="Audience"
value='f8213e5b-53d9-4102-9bfa-9363f5ec82b0'
title='user1@adventureworks.com' />
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2">
<table width="460" cellpadding="0" cellspacing="0" border="0">
<tr style="height:20px;"><td></td></tr>
</table>
</td>
</tr>
</table>
The returned HTML shown in Fiddler2 (the source):
The design view:



No comments:
Post a Comment