ASP.NET AJAX Advance Tips & Tricks (2) Create Rating Control dynamically
Preface:
Rating control of AJAX Control Toolkit are already widely used, However, many of my friends recently complained that if they create Rating control in code-behind dynamically, then, the Rating status will be lost after a PostBack(not into ViewState). This article describes two ways to solve the problem.
To reproduce the problem:
If we use the following code to create Rating control dynamically, then after the Button click, Rating selected value will be lost:

<%@ Register Assembly=”AjaxControlToolkit” Namespace=”AjaxControlToolkit” TagPrefix=”cc1″ %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=“server”>
protected void Page_Load(object sender, EventArgs e)
{
AjaxControlToolkit.Rating rt = new Rating();
Page.Form.Controls.Add(rt);
rt.ID = “LikeRating”;
rt.MaxRating = 5;
rt.CurrentRating = 2;
rt.StarCssClass = “ratingStar”;
rt.WaitingStarCssClass = “savedRatingStar”;
rt.FilledStarCssClass = “filledRatingStar”;
rt.EmptyStarCssClass = “emptyRatingStar”;
}
</script>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head runat=“server”>
<title></title>
<style type=“text/css”>
/* Rating */.ratingStar
{
font-size: 0pt;
width: 13px;
height: 12px;
margin: 0px;
padding: 0px;
cursor: pointer;
display: block;
background-repeat: no-repeat;
}
.filledRatingStar
{
background-image: url(Images/FilledStar.png);
}
.emptyRatingStar
{
background-image: url(Images/EmptyStar.png);
}
.savedRatingStar
{
background-image: url(Images/SavedStar.png);
}
</style>
</head>
<body>
<form id=“form1″ runat=“server”>
<cc1:ToolkitScriptManager ID=“ToolkitScriptManager1″ runat=“server”>
</cc1:ToolkitScriptManager>
<div>
</div>
<asp:Button ID=“Button1″ runat=“server” Text=“Button” />
</form>
<p>
</p>
</body>
</html>
Reason
The problem is because we cannot create the Rating control in the Page_Load, just as we create other server-side controls (for example, TextBox, and so on) in code-behind. the Rating control must be created in Page_Init if we need ViewState to save its status across the PostBack.
Solution 1:
We can create the Rating control in Page_Init:
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”><script runat=“server”>void Page_Init(object sender, EventArgs e)
{
AjaxControlToolkit.Rating rt = new Rating();
Page.Form.Controls.Add(rt);
rt.ID = “LikeRating”;
rt.MaxRating = 5;
rt.CurrentRating = 2;
rt.StarCssClass = “ratingStar”;
rt.WaitingStarCssClass = “savedRatingStar”;
rt.FilledStarCssClass = “filledRatingStar”;
rt.EmptyStarCssClass = “emptyRatingStar”;
}
</script><html xmlns=“http://www.w3.org/1999/xhtml”>
<head runat=“server”>
<title></title>
<style type=“text/css”>
/* Rating */.ratingStar
{
font-size: 0pt;
width: 13px;
height: 12px;
margin: 0px;
padding: 0px;
cursor: pointer;
display: block;
background-repeat: no-repeat;
}
.filledRatingStar
{
background-image: url(Images/FilledStar.png);
}
.emptyRatingStar
{
background-image: url(Images/EmptyStar.png);
}
.savedRatingStar
{
background-image: url(Images/SavedStar.png);
}
</style>
</head>
<body>
<form id=“form1″ runat=“server”>
<cc1:ToolkitScriptManager ID=“ToolkitScriptManager1″ runat=“server”>
</cc1:ToolkitScriptManager>
<div>
</div>
<asp:Button ID=“Button1″ runat=“server” Text=“Button” />
</form>
<p>
</p>
</body>
</html>
Solution 2:
we can use Hidden Field to save the state of Rating control:
Note: We need to set up the Rating control’s BehaviorID, in order to call the Rating’s js interface in JavaScript
<%@ Register Assembly=”AjaxControlToolkit” Namespace=”AjaxControlToolkit” TagPrefix=”cc1″ %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”><script runat=“server”>void Page_Load(object sender, EventArgs e)
{
AjaxControlToolkit.Rating rt = new Rating();
Panel1.Controls.Add(rt);
rt.ID = “LikeRating”;
rt.MaxRating = 5;
rt.CurrentRating = 2;
rt.StarCssClass = “ratingStar”;
rt.WaitingStarCssClass = “savedRatingStar”;
rt.FilledStarCssClass = “filledRatingStar”;
rt.EmptyStarCssClass = “emptyRatingStar”;
rt.BehaviorID = “hichange”;
rt.CurrentRating = Convert.ToInt32(this.Hidden1.Value);
}
</script><html xmlns=“http://www.w3.org/1999/xhtml”>
<head runat=“server”>
<title></title>
<style type=“text/css”>
/* Rating */.ratingStar
{
font-size: 0pt;
width: 13px;
height: 12px;
margin: 0px;
padding: 0px;
cursor: pointer;
display: block;
background-repeat: no-repeat;
}
.filledRatingStar
{
background-image: url(Images/FilledStar.png);
}
.emptyRatingStar
{
background-image: url(Images/EmptyStar.png);
}
.savedRatingStar
{
background-image: url(Images/SavedStar.png);
}
</style>
<script type=“text/javascript”>function save_rate() {
var state = $find(“hichange”).get_Rating();
$get(“Hidden1″).value = state;
alert(state);
}
</script>
</head>
<body>
<form id=“form1″ runat=“server”>
<cc1:ToolkitScriptManager ID=“ToolkitScriptManager1″ runat=“server”>
</cc1:ToolkitScriptManager>
<asp:Panel ID=“Panel1″ runat=“server” onclick=“save_rate();”>
</asp:Panel>
<asp:Button ID=“Button1″ runat=“server” Text=“Button” />
<input id=“Hidden1″ runat=“server” type=“hidden” value=“1″ />
<p>
</p>
</form>
</body>
</html>
