Repeater shows wrong column content - c#

I have a repeater to show an order confirmation. It is bound to a table generated with Entity Framework code first. The table contains the right information and the repeater shows all the information right except for the part where I show the totals which I paste below.
I believe that this part also works okay but quantity does not. For example if I add 5 products it will only show one, but if I put a break point and I run the code in debug mode I see that the value inserted in the Quantity table is 5 not 1, so the Quantity value on the table is inserted correctly, but the repeater reports 1.
Here is the code:
<asp:Repeater ID="rptConfirmOrder" runat="server">
<ItemTemplate>
<fieldset class = "OrderConfirmationFieldset"><legend class ="OrderDataLegend">Order Summary</legend>
<td align="left" width="60%" runat="server" id="Td25">
<asp:Label ID="lblQuantity" runat="server" Text="Quantity: " CssClass = "lblOrderConfirmation">
</asp:Label> <%# Eval("Quantity") %>
<br />
</td>
<td align="left" width="60%" runat="server" id="Td26">
<asp:Label ID="lblProductName" runat="server" Text="Product Name: " CssClass = "lblOrderConfirmation">
</asp:Label><%# Eval("ProductName" ,"{0:c}" ) %>
<br />
</td>
<td align="left" width="60%" runat="server" id="Td27">
<asp:Label ID="lblProductPrice" runat="server" Text="Product price: " CssClass = "lblOrderConfirmation">
</asp:Label> <%# Eval("ProductPrice" ,"{0:c}" ) %>
<br />
</td>
<td align="left" width="60%" runat="server" id="Td28">
<asp:Label ID="lblSubtotal" runat="server" Text="Subtotal: " CssClass = "lblOrderConfirmation">
</asp:Label> <%# Eval("Subtotal" ,"{0:c}" ) %>
<br />
</td>
<td align="left" width="60%" runat="server" id="Td29">
<asp:Label ID="lblTotal" runat="server" Text="Total: " CssClass = "lblOrderConfirmation">
</asp:Label> <%# Eval("Total" ,"{0:c}" ) %>
<br />
</td>
</ItemTemplate>
</asp:Repeater>
Can Anyone help?
Thank you in advance!

Your repeater markup doesn't look right.
have it as follows:
<asp:Repeater ID="rptConfirmOrder" runat="server" OnItemDataBound="rptConfirmOrder_ItemDataBound">
<ItemTemplate>
// stuff
</ItemTemplate>
</asp:Repeater>
And if you have it that way, and this was a paste error, then forget the value in the database/entity etc.
You can verify accurately, what value is being bound by tapping into the row data bound event as follows..
protected void rptConfirmOrder_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var dataItem = e.Item.DataItem as YOUR_ENTITY_TYPE;
Debug.Assert(5 == dataItem.Quantity);
}
}

I think you may need to add the < itemtemplate > tags in after the opening repeater and close it off before the closing repeater tag.

Related

Change repeater border colour through code

I have a repeater which is visible only by managers where they can accept/reject leave requests made by the users.
The following code while binding my repeater, retrieves if there are any employees on leave working in the same department and on the same date as the one requested by the user.
protected void RptLeaveRequests_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
otherEmpsLeave = new LeaveLogic().CheckEmployeeLeaveOnDateInSameDep(date, currEmp);
if (otherEmpsLeave != "")
{
//change border of repeater row to another colour and display otherEmpsLeave when manager hovers on repeater row
}
}
How can I change repeater row border colour (ex add a red border to make it stand out) and display otherEmpsLeave on hover?
ASP Repeater Code:
<h3>LEAVE REQUESTS</h3>
<asp:Label ID="LblNoRequests" Visible="false" Font-Size="14px" runat="server"></asp:Label>
<asp:HiddenField ID="dataGroups" runat="server" />
<asp:Repeater ID="RptLeaveRequests" runat="server"
onitemdatabound="RptLeaveRequests_ItemDataBound">
<ItemTemplate>
<table id="tableItem" runat="server">
<tr>
<td style="width:400px;">
<asp:Label ID="lblEmployeeId" runat="server" Text='<%#Eval("EmployeeId") %>' Visible="false" />
<asp:HiddenField ID="HdnEmployeeId" runat="server" Value='<%#Eval("EmployeeId") %>' />
<asp:Literal Text="" runat="server" ID="LiteralUser" ></asp:Literal>
</td>
</tr>
<tr>
<td style="width: 100px;">
<asp:HiddenField ID="HdnRequestId" runat="server" Value='<%#Eval("id") %>' />
<asp:Label ID="lblDate" runat="server" Text='<%#Eval("Date", "{0:dd/MM/yyyy}") %>'></asp:Label>
</td>
<td style="width: 80px;">
<asp:Label ID="lblHours" runat="server" Text='<%#Eval("Hours") %>'></asp:Label>
</td>
<td style="width: 50px; font-size:10px;">
<asp:Label ID="lblPeriod" runat="server" Text='<%#Eval("AMorPM") %>'></asp:Label>
</td>
<td style="width: 850px; font-size:10px;">
<asp:Label ID="lblNote" runat="server" Text='<%#Eval("Note") %>'></asp:Label>
</td>
<td style="width: 50px;">
<asp:RadioButtonList ID="rbtVerified" runat="server" Visible='<%#!(Boolean)Eval("ReadOnly") %>' >
<asp:ListItem Value="1">Accept</asp:ListItem>
<asp:ListItem Value="2">Reject</asp:ListItem>
</asp:RadioButtonList>
</td>
<td>
<asp:TextBox ID="txtNotes" runat="server" ></asp:TextBox>
</td>
</tr>
</table>
<div style="border-style: dotted; border-color:Black; width:100%; border-width:1px; border-color:#999999"></div>
</ItemTemplate>
</asp:Repeater>
From the MSDN example, something like
void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e) {
// This event is raised for the header, the footer, separators, and items.
// Execute the following logic for Items and Alternating Items.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
if (((Evaluation)e.Item.DataItem).Rating == "Good") {
((Label)e.Item.FindControl("RatingLabel")).Text= "<b>***Good***</b>";
}
}
}
instead of setting .Text set whatever property(s) you need, such as Background or Tooltip

How to databind to a Gridview where column values should appear in sub rows within a main row?

Please can anyone suggest a way to databind a database table to a gridview but in a specific layout where column values should appear in sub rows within a main row, like wise all rows from the database table should list down inside that Gridview.I know the normal way of databinding to a gridview Where it display row data(From Database Table) as columns, but what I want is like below
Gridview is not suitable for this type of format.
If you are okay with repeater, you can do something like this:
And here's a link to MSDN: Repeater Class.
UPDATE: If you want to post each answer selection, you can use option button and group them. You can use questionid as a part of group name and in the code get the question id. Your markup may look like below:
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table border="1">
<tr>
<th colspan="2"></th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container.DataItem, "QuestionId") %> </td>
<td>
<table>
<tr>
<td colspan="4"><%# DataBinder.Eval(Container.DataItem, "Question") %> </td>
</tr>
<tr>
<td>
<asp:RadioButton ID="RadioButton1" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer1") %>'
OnCheckedChanged="RadioButton1_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
<td><asp:RadioButton ID="RadioButton2" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer2") %>'
OnCheckedChanged="RadioButton2_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
<td><asp:RadioButton ID="RadioButton3" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer3") %>'
OnCheckedChanged="RadioButton3_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
<td><asp:RadioButton ID="RadioButton4" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer4") %>'
OnCheckedChanged="RadioButton4_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
</tr>
</table>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
And in the code:
protected void RadioButton1_CheckedChanged(object sender, EventArgs e)
{
string grpId = ((RadioButton)sender).GroupName;
int questionId = 0;
int.TryParse(grpId.Split('_')[1].ToString(), out questionId);
//Use questionId
}

Group Repeater for each Distinct User

I have the following repeater item:
<asp:Repeater ID="RptLeaveRequests" runat="server"
onitemdatabound="RptLeaveRequests_ItemDataBound">
<ItemTemplate>
<table id="tableItem" runat="server">
<tr>
<td style="width: 100px;">
<asp:Label ID="lblDate" runat="server" Text='<%#Eval("Date", "{0:dd/M/yyyy}") %>'></asp:Label>
</td>
<td style="width: 100px;">
<asp:Label ID="lblHours" runat="server" Text='<%#Eval("Hours") %>'></asp:Label>
</td>
<td style="width: 200px;">
<asp:Label ID="lblPeriod" runat="server" Text='<%#Eval("AMorPM") %>'></asp:Label>
</td>
<td style="width: 200px; font-size:10px;">
<asp:Label ID="lblNote" runat="server" Text='<%#Eval("Note") %>'></asp:Label>
</td>
<td style="50px">
<asp:RadioButtonList ID="rbtVerified" runat="server" >
<asp:ListItem Value="1">Accept</asp:ListItem>
<asp:ListItem Value="2">Reject</asp:ListItem>
</asp:RadioButtonList>
</td>
<td>
<asp:TextBox ID="txtNotes" runat="server" ></asp:TextBox>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
on page load I am binding the Repeater
else if(Convert.ToInt32(Session["UserLevel"]) != 0 && Convert.ToInt32(Session["UserLevel"]) < 151)
{
RptLeaveRequests.DataSource = newLeaveLogic().GetManagerUnverifiedLeaveRequests(Convert.ToInt32(Context.User.Identity.Name));
RptLeaveRequests.DataBind();
hasRequests = true;
}
Now how can group the Repeater item for each distinct user returned by the GetManagerUnferifiedLeaveRequests which returns a DataTable in the method below:
protected void RptLeaveRequests_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (hasRequests)
{
//grouping
}
}
I see two possible solutions:
1) Use nested repeaters:
<asp:Repeater ID="RptGroups" runat="server" onitemdatabound="RptGroups_ItemDataBound">
<ItemTemplate>
<asp:Repeater ID="RptLeaveRequests" runat="server" onitemdatabound="RptLeaveRequests_ItemDataBound">
<ItemTemplate>
...
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
2) Use single repeater for groups and render each group using for example DataList or other control for list of items.
In this case you bind list of groups to datasource here:
RptLeaveRequests.DataSource = itemsGroups;
RptLeaveRequests.DataBind();
And bind list of group items here:
protected void RptLeaveRequests_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
//bind here list of group items
}
I would prefer the second version.

How to show a message inside a Repeater control if it has no data inside it?

I am developing an intranet web application. I am working now on the User Profile which shows four tables about the employee personal information, training courses, company short quizzes and his submitted ideas and suggestions.
What I want now is if the employee has no suggestions, the message such as ( You don't have any suggestions) inside the table instead of showing a table with its header without telling the user that he has no suggestions. So how to do that?
My ASP.NET code:
<asp:Repeater ID="Repeater4" runat="server" DataSourceID="SqlDataSource4">
<HeaderTemplate>
<div>
<table border="1">
<thead>
<tr>
<td colspan="3">
<center> <strong>Safety Suggestions</strong> </center>
</td>
</tr>
<tr>
<td>
<center> <strong>Suggestion Title</strong> </center>
</td>
<td>
<center> <strong>Description</strong> </center>
</td>
</tr>
</thead>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<p>
<%# Eval("Title") %>
</p>
</td>
<td>
<p>
<%# Eval("Description") %>
</p>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</div>
</FooterTemplate>
</asp:Repeater>
<asp:SqlDataSource ID="SqlDataSource4" runat="server"
ConnectionString="<%$ ConnectionStrings:testConnectionString %>" SelectCommand="SELECT dbo.SafetySuggestionsLog.Title, dbo.SafetySuggestionsLog.Description, dbo.SafetySuggestionsLog.Username
FROM dbo.SafetySuggestionsLog INNER JOIN
dbo.employee ON dbo.SafetySuggestionsLog.Username = dbo.employee.Username
WHERE (dbo.employee.Username = #Username)">
<SelectParameters>
<asp:Parameter Name="Username" />
</SelectParameters>
</asp:SqlDataSource>
You can use a footer template to manage massage, like this
step 1...
<FooterTemplate>
<%-- Label used for showing Error Message --%>
<asp:Label ID="lblErrorMsg" runat="server" Text="Sorry, no item is there to show." Visible="false">
</asp:Label>
</FooterTemplate>
step 2...
handle visibility of lable in Repeater_ItemDataBound event like
protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rptDemo = sender as Repeater; // Get the Repeater control object.
// If the Repeater contains no data.
if (repeaterTopItems != null && repeaterTopItems.Items.Count < 1)
{
if (e.Item.ItemType == ListItemType.Footer)
{
// Show the Error Label (if no data is present).
Label lblErrorMsg = e.Item.FindControl("lblErrorMsg") as Label;
if (lblErrorMsg != null)
{
lblErrorMsg.Visible = true;
}
}
}
}
1. You can check for repeater items count in row databound event
2. Place a label somewhere in your repeater(footer etc.)
3. If count < 1 (find your label on footer row)
4. Populate label with "No data to display"

How to enhance the Drill Down feature in the GridView?

I am a new ASP.NET developer and I am trying to develop a GridView with Drill-Down Feature. I am following the steps in the following post in the CodeProject but I failed and I don't know how to fix it.
In my case, I have two tables:
Course Table: CourseID, CourseName, GroupID
Group Table: GroupID GroupName
(The first attribute in each table is the primary key)
I want to show the second table in the GridView and when the user clicks on the search icon image, the information in the first table will be displayed. So HOW TO DO THAT?
My ASP.NET:
<div align="center">
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataKeyNames="CourseID" DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField HeaderText="Item Details">
<ItemTemplate>
<table>
<tr>
<td>
<img src="images/system-search-md.png" alt="click here to see details"
onclick='ToggleDisplay(<%# Eval("GroupID") %>);' style="cursor:pointer; height:15px; width:15px" />
</td>
<td<>
<p><%# Eval("CourseID") %></p>
</td>
<td>
<%# Eval("CourseName") %>
</td>
<td>
<%# Eval("CourseName") %>
</td>
</tr>
<tr>
<td colspan="4">
<div id'coldiv<%# Eval("GroupID") %>' style="display:none;">
<asp:Literal runnat="server" ID="ltrl" Text='<%# Eval("GroupName") %>'></asp:Literal>
</div>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<script language="JavaScript">
function ToggleDisplay(id) {
var elem = document.getElementById('coldiv' + id);
if (elem) {
if (elem.style.display != 'block') {
elem.style.display = 'block';
elem.style.visibility = 'visible';
}
else {
elem.style.display = 'none';
elem.style.visibility = 'hidden';
}
}
}
</script>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:testConnectionString %>"
SelectCommand="SELECT dbo.groups.*, dbo.courses.*
FROM dbo.courses INNER JOIN
dbo.groups ON dbo.courses.GroupID = dbo.groups.ID"></asp:SqlDataSource>
</div>
Your approach seems reasonable. I'd make sure your ToggleDisplay function is working correctly, and you also need to fix your markup errors:
<td<> = <td>
<div id'coldiv<%# Eval("GroupID") %>' = <div id='coldiv<%# Eval("GroupID") %>'
<asp:Literal runnat="server" = <asp:Literal runat="server"

Categories