Conditionally show image in a repeater if the database is not null - asp.net

I have a repeater that includes as image. However, there is an image that may not be in all of the Promotions in this repeater
<div class="promo">
<h2><%# ((Promotion)Container.DataItem).Title %></h2>
<p><img src="/Uploads/<%# ((Promotion)Container.DataItem).Image %>" alt="" class="promoImg" /><%# ((Promotion)Container.DataItem).Description %></p>
<p><em><%# ((Promotion)Container.DataItem).Restrictions %></em></p>
</div>
Can someone show me how to make the only show up if that entry does not have a null field?

I prefer do something in server side, so, my sugestion is:
Add a event handler to your repeater
<asp:Repeater ID="myRpt" runat="server" onitemdatabound="myRpt_ItemDataBound" >
<ItemTemplate>
<div class="promo">
<h2>
<%# ((Promotion)Container.DataItem).Title %></h2>
<p>
<asp:Image ID="imgTest" CssClass="promoImg" ImageUrl="" runat="server" />
<%# ((Promotion)Container.DataItem).Description %></p>
<p>
<em>
<%# ((Promotion)Container.DataItem).Restrictions %>
</em>
</p>
</div>
</ItemTemplate>
</asp:Repeater>
i will "bind" the image source in code behind, you could do it for other controls too.
So, the code behind is:
protected void myRpt_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Image imgTest = (Image)e.Item.FindControl("imgTest");
Promotion pActual = (Promotion)e.Item.DataItem;
bool needToShowImage = !String.IsNullOrEmpty(pActual.Image)
if (needToShowImage)
{
imgTest.ImageUrl = "Uploads/" + pActual.Image;
}
else
{
imgTest.Visible = false;
}
}
}
It will do the trick. If it dont work, please, let me know.

This should do the trick:
For C#.Net:
<div class="promo">
<h2><%# ((Promotion)Container.DataItem).Title %></h2>
<p><img runat="server" visible='<%# Information.IsDBNull(((Promotion)Container.DataItem).Image) %>' src=""/Uploads/<%# ((Promotion)Container.DataItem).Image.ToString %>" alt="no image found" class="promoImg" /><%# ((Promotion)Container.DataItem).Description %></p>
<p><em><%# ((Promotion)Container.DataItem).Restrictions %></em></p>
</div>

I've added some jquery to check each image on the page to make sure there is a image associated with that promotion:
$(document).ready(function () {
$('.promoImg').each(function (index) {
if ($(this).attr('src') == "/Uploads/") {
$(this).hide();
}
});
});
I'm still interested in a server side solution

I think you can use panel to do this.
<div class="promo">
<h2><%# ((Promotion)Container.DataItem).Title %></h2>
<asp:Panel ID="pnlImage" runat="server">
<p><img src="/Uploads/<%# ((Promotion)Container.DataItem).Image %>" alt="" class="promoImg" /><%# ((Promotion)Container.DataItem).Description %></p>
</asp:Panel>
<p><em><%# ((Promotion)Container.DataItem).Restrictions %></em></p>
In ItemDataBound event, do this
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
if (((Promotion)e.Item.DataItem).Image == null) {
((Panel)e.Item.FindControl("pnlImage")).Visible = false;
}
when panel is invisible, it will not be rendered.

why not use the
<% if()%>
to judge either there is a image source? if not ,then didn't response.so we can save more

Related

ASP.Net repeater control - using conditional statements

I am trying to use an if statement inside of a repeater control and receiving an InvalidOperationException on the if.
What I'm trying to do is run a block of code inside the repeater only if the current item has a UserType that is set to Admin.
<asp:Repeater ID="rptSingleValueHeaders" runat="server">
<ItemTemplate>
<% if (Eval("UserType").ToString() == "Admin") { %>
<div>
do stuff here
</div>
<% } else { %>
<div>
do other stuff
</div>
<% } %>
</ItemTemplate>
</asp:Repeater>
My datasource is defined on the aspx.cs and contains a property named UserType which is of type string. Let me know if I need to provide any more details. Thank you.
You could use server side visibility:
<ItemTemplate>
<div runat="server" visible='<%# (Eval("UserType").ToString() == "Admin") %>'>
I show this HTML
</div>
<div runat="server" visible='<%# (Eval("UserType").ToString() != "Admin") %>'>
I show this other HTML
</div>
</ItemTemplate>

ASP.NET - child control in a Repeater doesn't get initialized in time

I'm facing the following problem: I have an asp repeater who has a control as ItemTemplate. In codebehind, I assign a DataSource to the repeater:
...
this.ProductList = searchResult.Entry.ToList();
EntriesList.DataSource = this.ProductList;
...
void EntriesList_ItemDataBound(object sender, ListViewItemEventArgs e)
{
var productBlock = (ProductBlock)e.Item.FindControl("productBlock"); //Here I obtain the child, then assign the values from the datasource
productBlock.ProductEntry = (Entry)e.Item.DataItem;
}
This is the aspx code of the childcontrol:
<%# Control Language="C#" CodeBehind="ProductBlock.ascx.cs" Inherits="EPiServer.Commerce.Sample.Templates.Sample.Units.CategoryDisplay.SharedModules.ProductBlock" %>
<%# Import Namespace="EPiServer.Commerce.Sample" %>
<%# Import Namespace="EPiServer.Commerce.Catalog.ContentTypes" %>
<%# Import Namespace="EPiServer.Core.Html" %>
<%# Import Namespace="EPiServer.Commerce.Catalog.ContentTypes" %>
<%# Import Namespace="Mediachase.Commerce.Catalog.Objects" %>
<%# Import Namespace="Mediachase.Commerce.Website.Helpers" %>
<%# Register Src="StarButton.ascx" TagName="StarButton" TagPrefix="catalog" %>
<%# Register Src="CommonButtons.ascx" TagName="CommonButtons" TagPrefix="catalog" %>
<li class="span3">
<div class="thumbnail thumbnail-product">
<catalog:StarButton runat="server" ID="StarButton" />
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%# ResolveUrl(StoreHelper.GetEntryUrl(ProductEntry)) %>'>
<span class="product-img-holder">
<asp:Image runat="server" ID="Image1" AlternateText="" />
</span>
</asp:HyperLink>
<div class="product-dsc">
<asp:HyperLink ID="HyperLink3" runat="server" NavigateUrl='<%# ResolveUrl(StoreHelper.GetEntryUrl(ProductEntry)) %>' CssClass="product-name">
<span><asp:Literal ID="HeadingLiteral" runat="server" /></span>
</asp:HyperLink>
<div class="tp-additional">
<ul class="unstyled">
<li><strong>Marca:</strong>
<asp:Literal ID="BrandLiteral" runat="server" />
</li>
<li>
<strong>Principio Activo:</strong>
<asp:Literal ID="ActiveIngredientLiteral" runat="server" />
</li>
<li>
<strong>Patología:</strong>
<asp:Literal ID="PathologyLiteral" runat="server" />
</li>
<%--<li><strong>In Stock:</strong> <asp:Literal ID="InStock" runat="server"></asp:Literal></li>--%>
<li><strong>Código Nacional:</strong>
<span title="<%# ProductEntry.ID %>"><%# ProductEntry.ID %></span></li>
<%--<li><strong>Model:</strong>
<%# WebStringHelper.EncodeForWebString(GetModelNumber((EntryContentBase) Container.DataItem)) %></li>
<li><strong>List Price:</strong> <asp:Literal ID="ListPrice" runat="server" /></li>
<li><strong>Discount Pricing</strong> <asp:Literal ID="DiscountPricing" runat="server" /></li>
<li><strong>You Save:</strong> <asp:Literal ID="DiscountAmount" runat="server" /></li>--%>
</ul>
<asp:PlaceHolder runat="server" Visible="False" ID="PromotionsHolder">
<%--<strong>Promotions:</strong><br />
<asp:Literal ID="Promotions" runat="server" />--%>
</asp:PlaceHolder>
</div>
<div class="C_Product-ItemSelector">
<div class="btn-group">
<a class="btn btn-info" href="<%# ResolveUrl(StoreHelper.GetEntryUrl(ProductEntry)) %>"><i class="icon-shopping-cart icon-white"></i> Ver detalles</a>
<a class="btn btn-info dropdown-toggle" data-toggle="dropdown" href="#"><span class="caret"></span></a>
<catalog:CommonButtons runat="server" ID="CommonButtons" />
</div>
</div>
</div>
</div>
</li>
The code behind of this control just sets the values that should be given to the ProductEntry public property. In the debug, immediately after executing the EntriesList.DataSource = this.ProductList; line, the application raises a NullArgumentException, telling me that ProductEntry property from the child control is null.
However, if in the code behind of the child control of the repeater I do the following:
protected void Page_Init(object sender, EventArgs e)
{
ProductEntry = new Entry();
}
Everything works as ProductEntry will not be null anymore.
This solution is rather ugly to me and I don't know why it happens and what is the best way to set a value for a child control inside a repeater. Can anyone enlighten me?
Thank you
You said Repeater control. If so, EntriesList_ItemDataBound's EventArgs should be RepeaterItemEventArgs
Another problem is you need to filter ItemType inside ItemDataBound, because Header, Footer and others also fire ItemDataBound event.
protected void EntriesList_ItemDataBound(
Object Sender, RepeaterItemEventArgs e) {
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem) {
var productBlock = (ProductBlock)e.Item.FindControl("productBlock");
productBlock.ProductEntry = (Entry)e.Item.DataItem;
}
}
Win your approach didn't work, child objects were still being created before and inited before I could assign them their values.
Hopefully, I've found the solution. Using the OnItemCreated event instead of the OnItemDatabound event solved my problem, as it was called when the child item was created, but before the Page_Init event of the child was called.
Thank you

Saving a comment from inside an updatepanel in a repeater

(Asp.net 4)
I have a blog where i use a repeater to show all the blog-articles and the comments to each blog. I'm trying to change how the users can post comments to the blog. I want to put the comments under each blog in an UpdatePanel, and when they write a comment and click on a save-button, i want to refresh the comments, so their new comment will show. But I'm having difficulties achieving this.
I've added the UpdatePanel in the ItemTemplate of the Repeater, and added the Textboxes and Button for saving the comment. Each UpdatePanel is placed in a with the id of the blog. But I don't know how to create the code for saving the comment for the correct blog-id, and then to refresh that UpdatePanel.
Code:
<asp:Repeater ID="RepeaterBlog" runat="server">
<ItemTemplate>
<article>
<% if (repeaterCounter == 0)
{
Response.Write("<header class=\"firstArticleInBlog\">");
}
else
{
Response.Write("<header class=\"normalArticle\">");
}
%>
<h2><%# Eval("article_header") %> <span class="date">
<time datetime="<%# GetPubDate(Eval("article_date")) %>"><%# FormatDate(Eval("article_date")) %></time></span></h2></header>
<p><%# Eval("article_content") %><p><br />
<div class="comments">
<div class="showhidecomments">
<!--<a class="iframe-comments" data-fancybox-type="iframe" href='WriteComments.aspx?BlogId=<%# DataBinder.Eval(Container, "DataItem.id") %>'>Skriv kommentar</a> | -->
Vis/Skriv kommentarer (<%# CountComments (DataBinder.Eval(Container, "DataItem.id")) %>) | <a href="javascript:void(0);" title="i<%# Eval("id") %>" >Skjul kommentarer</a>
</div>
<section>
<article>
<div id="i<%# Eval("id") %>" style="display: none;">
<asp:UpdatePanel ID="upPanel" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmdSaveComment" EventName="Click" />
</Triggers>
<ContentTemplate>
<%# GetComments (DataBinder.Eval(Container, "DataItem.id")) %>
<asp:TextBox ID="txtName" runat="server" />
<asp:TextBox ID="txtComment" runat="server" TextMode="MultiLine" />
<asp:Button ID="cmdSaveComment" runat="server" OnClick="cmdSaveComment_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</article>
</section>
</div>
<% repeaterCounter++; %>
</article>
</ItemTemplate>
</asp:Repeater>
And in the code-behind:
protected void cmdSaveComment_Click(object sender, EventArgs e)
{
//simplified code:
string name = txtName.Text;
string comment = txtComment.Text;
int blogId = (int)(Eval("DataItem.id"));
dataHandler.NewComment(name, comment, blogId);
}
Am i at least close to something here, or am i completely on the wrong track?
You need to use the ItemCommand property for the repeater and the CommandName property for your button.
First declare the event name for the repeater and the button's command name in your aspx. Note the CommandName replaces the OnClick for your button. Also you give the button a command argument, this being the ID for the article record that the comment is for.
<asp:Repeater ID="RepeaterBlog" runat="server" OnItemCommand="RepeaterBlog_ItemCommand">
<asp:Button ID="cmdSaveComment" runat="server" CommandName="SaveComment" CommandArgument='<%# Eval("id")%>' />
Now add this in the code behind
void RepeaterBlog_ItemCommand(Object Sender, RepeaterCommandEventArgs e) {
if(e.CommandName == "SaveComment") {
string name = ((TextBox)e.Item.FindControl("txtName")).Text;
string comment = ((TextBox)e.Item.FindControl("txtComment")).Text;
dataHandler.NewComment(name, comment, e.CommandArgument);
}
}
That should get you started

asp.net HyperLink dynamic creation of NavigateUrl path

I have this in my asp.net page:
<% foreach (Product item in ProductList())
{
%>
<div id="i<%:item.CODE %>" class="item" dir="rtl">
<label class="code"><%:item.CODE %></label>
<asp:HyperLink runat="server" ID="DetailsLink" Text="Details"
NavigateUrl="~/Details.aspx?ProductCode=<%:item.CODE %>" font-size="18px"></asp:HyperLink>
</div>
<% } %>
Although the first <%:item.CODE%> works and I can see the item's code written,
in the NavigateUrl string it does not work.
I get a link to "http://localhost:34546/Details.aspx?ProductCode=<%:item.CODE %>"
How can I concat the item's code to the link?
Try this
<% foreach (String str in new string[] { "Apple", "Mango", "Orange" })
{
%>
<div id="i<%: str %>" class="item" dir="rtl">
<label class="code">
<%: str %></label>
<a href='<%: "Details.aspx?ProductCode=" + str %>'>DetailsLink</a>
</div>
<% } %>
instead of
<asp:HyperLink runat="server"
ID="DetailsLink"
Text="Details"
NavigateUrl="~/Details.aspx?ProductCode=<%:item.CODE %>"
font-size="18px"/>
You should use repeater control & handle its ItemDataBound event.
That will make you code cleaner & easy to debug.
in your .aspx.cs file:
protected void rpt_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Product item = e.Item.DataItem as Product ;
HyperLink DetailsLink = e.Item.FindControl("DetailsLink") as HyperLink;
DetailsLink.NavigateUrl= "~/Details.aspx?ProductCode=" + item.CODE;
}
}
protected void Page_Load(object sender, EventArgs e)
{
rpt.DataSource = ProductList();
rpt.DataBind();
}
in your .aspx file:
<asp:Repeater ID="rpt" runat="server"> <ItemTemplate>
<asp:HyperLink runat="server" ID="DetailsLink" Text="Details"
font-size="18px"></asp:HyperLink>
</ItemTemplate>
</asp:Repeater>

How to pass client id of Item in repeater to javascript

I need to pass div client id to JavaScript of a repeater
I have 3 divs inside a repeater i have onmouseover event i want to grab client id of div element Is there any way i can pass exact client of div element
Can u guys help me out Thanks
If you would like to do it in markup, you can use
the following to get the ClientId:
<%# Container.FindControl("_RepeaterEL").ClientID %>
Something like this (if I understood you correctly):
Markup:
<asp:Repeater id="myRepeater" OnItemDataBound="myRepeater_ItemDataBound" runat="server">
<ItemTemplate>
<div id="myDiv" runat="server">......</div>
</ItemTemplate>
</asp:Repeater>
Code-behind:
protected void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
HtmlGenericControl myDiv = e.Item.FindControl("myDiv") as HtmlGenericControl;
// you can just pass "this" instead of "myDiv.ClientID" and get the ID from the DOM element
myDiv.Attributes.Add("onmouseover", "doStuff('" + myDiv.ClientID + "');");
}
}
<asp:Panel CssClass="modal hide fade" ID="myModal" runat="server">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Add to cart</h3>
</div>
<div class="modal-body">
<nav>
<iframe seamless src="/ToCart/<%# DataBinder.Eval(Container.DataItem, "code")%>"
style="border-style: none;"> </iframe>
</nav>
</div>
</asp:Panel>
<a data-toggle="modal" href="#<%#Container.FindControl("myModal").ClientID%>">
<div class="add-to-cart-one">+</div>
</a>
If the repeater renders to the browser, you can get the repeater element with:
var rep = $get("<%= rpt.ClientID %>");
Otherwise, wrap a
<DIV id="RepeaterEL"></div>
around the repeater, and access its children either through pure JavaScript (and the childNodes collection), or using JQuery like
$("#RepeaterEL").children("DIV").each(function(i) {
var id = $(this).attr("id"); //<- pointer to DIV });

Resources