How can i do an if statement inside a repeater - c#

<asp:Repeater> is driving me mad..
I need to do
<ItemTemplate>
<% if (Container.DataItem("property") == "test") {%>
I show this HTML
<% } else { %>
I show this other HTML
<% } %>
</ItemTemplate>
But I can't for the life of me find any way to make that happen. Ternary isnt any good, because the amount of HTML is quite large, setting labels via a DataBind event is not very good either, as I'd have to have large blocks of HTML in the code-behind.
Surely there's a way to do this....

You could use server side visibility:
<ItemTemplate>
<div runat="server" visible='<% (Container.DataItem("property") == "test") %>'>
I show this HTML
</div>
<div runat="server" visible='<% (Container.DataItem("property") != "test") %>'>
I show this other HTML
</div>
</ItemTemplate>

You could try creating a kind of ViewModel class, do the decision on your code-behind, and then be happy with your repeater, simply displaying the data that it is being given.
This is a way to separate logic from UI. You can then have a dumb-UI that simply displays data, without having to decide on what/how to show.

You could do this with user controls:
<ItemTemplate>
<uc:Content1 runat='server' id='content1' visible='<%# Container.DataItem("property") == "test" %>'/>
<uc:Content2 runat='server' id='content2' visible='<%# Container.DataItem("property") != "test" %>'/>
</ItemTemplate>

Looks like I got this mixed up with the actual databinding
You can do it like so:
<asp:Repeater runat="server">
<ItemTemplate>
<% if (((Product)Container.DataItem).Enabled) { %>
buy it now!
<% } else {%>
come back later!
<% } %>
</ItemTemplate>
</asp:Repeater>

I had a similar problem and stumbled across this page. Thanks for the great answers, Gavin and Keltex got me on the right track but I had a bit of a tricky time getting this to work on my page. Ultimately I was able to get it to work with this boolean, so I wanted to share for posterity:
Show Checkbox if false
<asp:CheckBox ID="chk_FollowUp" Visible='<%# (DataBinder.Eval(Container.DataItem, "FollowUp").ToString() == "False") %>' runat="server" />
Show Flag img if true
<asp:Image ID="img_FollowUp" AlternateText="Flagged" ImageUrl="Images/flag.gif" runat="server"
Visible='<%# DataBinder.Eval(Container.DataItem, "FollowUp") %>' Height="30" Width="30" />

First You Have to Defind a Count variable in your Page.cs file
<%if (Count == 0)
{
%>
<div style="background-color:#cfe9ed" class="wid_100 left special_text"><%# Eval("CompanyName") %></div>
<%}
else if (Count == TotalCount - 1)
{
%>
<div style="background-color:#f2f1aa" class="wid_100 left special_text"><%# Eval("CompanyName") %></div>
<%}
else
{
%>
<div class="wid_100 left special_text"><%# Eval("CompanyName") %></div><% } %>
<%Count++; %>

Related

Access a control in Codebehind that's in a Template

In my ASP.NET WebForms application using Scafolding I have many pages where I need to restrict certain links based on user's role.
For instance, in my Site.Master in my <LoggedTemplate> along with other <li>, I have a <li> for Admin page also. By default, that is not visible, but if the user is logged as an Admin, then I want it to make visible. Which I am not able to do. Here's the code for it :
<LoggedInTemplate>
<ul class="nav navbar-nav">
<li><a runat="server" id="adminLink" visible="false" href="~/Admin/Admin_Page">Admin</a></li>
<li><a runat="server" href="~/Inquiries/Default.aspx">Inquiry</a></li>
In my Codebehind, in Page_Load I am not able to access adminLink only.
Simialrly, in one of the Default page of a Model, the list has links to View, Insert & Delete. If the user is admin, then only I want to show Insert & Delete links. Here's the code for it :
<td>
<asp:HyperLink runat="server" NavigateUrl='<%# FriendlyUrl.Href("~/Channels/Details", Item.ChannelId) %>' Text="View" /> |
<asp:HyperLink runat="server" ID="editLink" NavigateUrl='<%# FriendlyUrl.Href("~/Channels/Edit", Item.ChannelId) %>' Text="Edit" /> |
<asp:HyperLink runat="server" NavigateUrl='<%# FriendlyUrl.Href("~/Channels/Delete", Item.ChannelId) %>' Text="Delete" />
</td>
</tr>
</ItemTemplate>
I tried adding
<% if (CommonUtilities.IsUserAdmin) { %>
hyperlinks for Insert & delete & finally
<% } %>
but this was giving error. I added ID to editLink, but again cannot access it in Page_Load method.
I am sure, their must be some method to work out with this which I am not able to find yet.
How to deal with this problem ?? Please help me, I have several pages & links to hide & show based on admin role.
Any help is highly appreciated.
Thanks
I think you are looking for FindControl. For example:
Label adminLabel = LoggedInTemplate.FindControl("adminLink") as Label;
adminLabel.visible = true;
Works for me in a few templates, dont know about LoggedInTemplate tho, but can't see why not.
edit: didn't realize ur using <a>. Not sure why you mix asp hyperlink and html but anyway, logic is still the same.
Thanks WEDEBE for pointing out to mix <a> and .
That point gave me a way out. In my design, I change <a> to <asp:HyperLink> & removed code from Codebehind. In design only I tried checking hte role of user & then adding full <li>. Like this :
<LoggedInTemplate>
<ul class="nav navbar-nav">
<% if (VincitoreCRMApplication.CommonUtilities.IsCurrentUserAdmin)
{ %>
<li> <asp:HyperLink runat="server" id="adminLink" NavigateUrl="~/Admin/Admin_Page.aspx">Admin</asp:HyperLink> </li>
<% } %>
<li><a runat="server" href="~/Inquiries/Default.aspx">Inquiry</a></li>
With the other 2 HyperLink's also I did the same way :
<% if (VincitoreCRMApplication.CommonUtilities.IsCurrentUserAdmin)
{ %>
<asp:HyperLink runat="server" ID="editLink" NavigateUrl='<%# FriendlyUrl.Href("~/Channels/Edit", Item.ChannelId) %>' Text="Edit" /> |
<asp:HyperLink runat="server" NavigateUrl='<%# FriendlyUrl.Href("~/Channels/Delete", Item.ChannelId) %>' Text="Delete" />
<% } %>
And this worked. But I realized one thing, when If I add
<% if (VincitoreCRMApplication.CommonUtilities.IsCurrentUserAdmin) { %>
like this, in a single line, it's not working. But on adding the curly braces in new line, it works. I know this sounds very strange, I also can't make out why it happens so. But it is fact, that what I have faced & learned.
I know this is quiet simple thing, but just in case my code helps anyone, have shared here.
Thanks

Eval in a Databinding Control

I know this question has been answered a few times but it just hasn't been the way I've need it.
Basically I have this code:
<Engine:WidgetSQLDataSource ID="DS_Hotel" runat="server" SelectCommand="site.GetHotelList" />
<asp:Repeater ID="rp_GuestHotelInfo" runat="server" DataSourceID="DS_Hotel">
<ItemTemplate>
<% if (Convert.ToInt32(Eval("TreeID")) == PrimaryNavigation1.ParentID) { %>
<img width="226" height="68" src="<%# Eval("Logo") %>" alt="<%# Eval("HotelName") %>" />
<% } %>
</ItemTemplate>
</asp:Repeater>
What I am trying to do is change the logo based on the currents pages parent id.
However I'm getting an error saying that:
Databinding methods such as Eval(), XPath(), and Bind() can only be
used in the context of a databound control.
Any ideas how I can tackle this issue?
Thanks,
T.J.
Repeater, in webform at least, does not support the "if" statement, instead you can use the "ternary" operator, for example: string src = (a==b) ? "equal":"diferent";
So your code may be replaced by this:
<ItemTemplate>
<a href="#" class="logo">
<img width="226" height="68"
src='<%# (Convert.ToInt32(Eval("TreeID")) == PrimaryNavigation1.ParentID) ? Eval("Logo") : "" %>'
alt="<%# Eval("HotelName") %>"
/>
</a>
</ItemTemplate>

Hilighting the current page in an asp.net 3.5 master page

In my project the master page contains a repeater that's used as a menu with an Xml file as the data source for the repeater.
<asp:Repeater ID="Admin_menus" runat="server">
<HeaderTemplate><div id="navmenu"><ul></HeaderTemplate>
<FooterTemplate>|</ul></div></FooterTemplate>
<ItemTemplate>
|<li>
<a href="<%# DataBinder.Eval(Container.DataItem, "url")%>"
class="link6" id="<%# DataBinder.Eval(Container.DataItem, "id")%>">
<strong>
<%# DataBinder.Eval(Container.DataItem, "title")%>
</strong>
</a>
</li>
</ItemTemplate>
</asp:Repeater>
urls in the xml file is as
<menuitems>
<item id="1" url="Employee.aspx" title="Employee" description="Employee" />
<item id="2" url="Location.aspx" title="Location" description="Location" />
</menuitems>
Here I want to change the CSS style of the current page in the menu.
One solution you can opt for is to handle the ItemCreated event of the <asp:Repeater> control. To do this you need to add an event handler:
In the .master markup:
<asp:Repeater ID="Admin_menus" runat="server" OnItemCreated="Admin_menus_ItemCreated">
<HeaderTemplate>
<div id="navmenu">
<ul>
</HeaderTemplate>
<FooterTemplate>
|</ul></div></FooterTemplate>
<ItemTemplate>
|<li runat="server" id="hyperlink"><a href="<%# DataBinder.Eval(Container.DataItem, "url")%>" class="link6" id="<%# DataBinder.Eval(Container.DataItem, "id")%>">
<strong>
<%# DataBinder.Eval(Container.DataItem, "title")%></strong> </a></li>
</ItemTemplate>
</asp:Repeater>
In the .master.cs codebehind:
protected void Admin_menus_ItemCreated(object sender, RepeaterItemEventArgs e)
{
// Ensure that the ItemCreated is not null, the first one (header?) gets
// returned null
if (e.Item.DataItem != null)
{
// Extract the "url" attribute from the Xml that's being used for
// databinding for this particular row, via casting it down to
// IXPathNavigable as the concrete type of e.Item.DataItem isn't available
// to us.
var currentUrl = ((IXPathNavigable)e.Item.DataItem).CreateNavigator().GetAttribute("url", "");
if (Request.Url.PathAndQuery.Contains(currentUrl))
{
// This just adds a background color of "red" to the selected
// menu item. What you actually do is entirely up to you
var hyperlink = (HtmlGenericControl) e.Item.FindControl("hyperlink");
hyperlink.Style.Add(HtmlTextWriterStyle.BackgroundColor, "red");
}
}
}
Note that I've added a runat="server" as well as an id="hyperlink" to the <li> tag in your ItemTemplate so that the code in the ItemCreated handler can find it easily to style it.
Perhaps one solution is to check the current page in your inline Eval code and add the "currentpage" class to the anchor
For simplicity I'm using Eval() instead of DataBinder.Eval()
<asp:Repeater ID="Admin_menus" runat="server">
<HeaderTemplate>
<div id="navmenu"><ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<a href='<%# Eval("url") %>' class='link6<%# Request.RawUrl.EndsWith(Eval("url").ToString()) ? " currentpage" : "" %>' id='<%# Eval("id")%>'><strong><%# Eval("title")%></strong></a>
</li>
</ItemTemplate>
<FooterTemplate>
</ul></div>
</FooterTemplate>
</asp:Repeater>
Instead of binding directly from your xml data to repeater, try to get the repeater databing event, and compare with the current page url and the each binding item to determine if the current item should be hi-lighted

How to have an ASP checkbox for each entry in a list?

I want to do something like this in my asp code:
<%
foreach Record record in listOfRecords
{
%>
<asp:checkbox runat="server" id="employeeIdNumber" />
<p>Employee's Name: <%= record.name %> </p>
<p>Employee's Phone Number: <%= record.phoneNumber %></p>
<%
}
%>
The problem is that the checkbox id is a string literal. How can I give a unique id to each employee's checkbox?
Wrap this in a repeater. Then bind your listOfRecords to the repeater.
<asp:Repeater runat="server">
<ItemTemplate>
<asp:checkbox runat="server" id="employeeIdNumber" />
<p>Employee's Name: <%# Eval("name") %> </p>
<p>Employee's Phone Number: <%# Eval("phoneNumber") %></p>
</ItemTemplate>
</asp:Repeater>
Then to get it out, you run through the RepeaterItems collection and look for the checkboxes by RepeaterItem.FindControl("employeeIdNumber") to determine if they are checked.
I think you should use Repeater instead.
<asp:Repeater ID="rptEmployees" runat="server">
<ItemTemplate>
<asp:CheckBox ID="employeeIDNumber" runat="server" />
</ItemTemplate>
</asp:Repeater>
This Control will render unique ID for each checkbox for you.
CheckboxList is an option too.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.checkboxlist.aspx
This also has an example on how to check the checked state - just iterate through and check the Selected property.

adding logic to datagrid item template

how would you go about adding logic to a datagrid item template? In my datagrid, i want to add a logic to it. that is, if the result for the data equals to "Yes", an "asp:label" control will be displayed; otherwise a "asp:imagebutton" control will be shown
<ItemTemplate1>
<% if DataBinder.Eval(Container.DataItem, "boflag").equals("Yes") then%>
<asp:Label id="Label1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem,"boflag")%>'></asp:Label>
<% Else %>
<asp:imagebutton id="imgBtnUpdate" runat="server" NAME="Imagebutton3"
ImageUrl="no.gif"></asp:imagebutton>
<% end if %>
</ItemTemplate>
However, "<% if DataBinder.Eval(Container.DataItem,
"boflag").equals("Yes") then%> " this is not valid.
So, how can i get the data to compare the value.
Thank you
You should implement the items Data Bound Event in the code behind. Then show/hide/populate the controls there.
One other option you can do is to use a ternary operator to evaluate the boflag field and output accordingly. For example:
<%# DataBinder.Eval(Container.DataItem, "boflag").equals("Yes") ? DataBinder.Eval(Container.DataItem,"boflag") : "<input type=\"image\" src=\"\" />" %>
I'm not sure that you could add server controls through this method, but you could certainly add conditional HTML.

Categories

Resources