We currently have an application which we have a repeater
<asp:Repeater ID="rptOfficials" runat="server">
<ItemTemplate>
<tr>
<td>
<p class="officials">
<%#Eval("OffPosition") %> <%#Eval("FullName") %>
</p>
<p class="officials">
<%#Eval("Phone") %>
</p>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
The Phone field is not always supplied, when not there a blank paragraph tag is generated, we're thinking of changing
<p class="officials">
<%#Eval("Phone") %>
</p>
to either:
<p class="officials">
<asp:label id="lblPhone" runat="server"/>
</p>
or:
<p class="officials">
<%#GetPhone("OffId") %>
</p>
and then have either the label return the phone number with the paragraph tags wrapped around it, or have the function return it. Is there a better way to get around this?
It depends how your Binding model is composed but I suggest adding the logic in your property (Phone) on your page your (view)model (yes you can and should use ViewModels in web forms as well).
That way you keep logic outside the view.
public string Phone {
get {
return this.phone ?? string.Empty;
}
}
That way your logic stays nicely inside your view model and your view just takes care of binding it.
If you don't want to generate the -tag, you can add a boolean property to your model.
public bool DisplayPhone{
get {
return this.Phone == string.Empty;
}
}
You then need to bind it to the visible property as Halcyon mentioned. (note you need a runat="server" for this)
<p runat="server" class="officials" visible='<% #Eval("DisplayPhone") %>'>
<% #Eval("Phone") %>
</p>
I would not recommend using "display: none" since it will keep the space of the p tag. Instead, make the p tag a server tag and set its visibility to false.
<p runat="server" class="officials" visible='<% !string.IsNullOrEmpty(#Eval("Phone")) %>'>
<% #Eval("Phone") %>
</p>
Instead of using
<p class="officials">
<%#GetPhone("OffId") %>
</p>
I prefer generate <p class="officials">foo</p> inside GetPhone(), then you can return nothing when Phone is empty.
You can add small logic like the following -
<%# string.IsNullOrWhiteSpace(Eval("Phone").ToString()) ?
"" : ("<p class=\"officials\">" + Eval("Phone") + "</p>")%>
However, if you want to add more logic, I would like to suggest to use Repeater.ItemDataBound Event
try with this
<p class="officials" <%#string.IsNullOrEmpty(Eval("Phone").ToString())? "style='display:none;':''" %> >
<%#Eval("Phone") %>
</p>
Related
All, Generally .If we want to output a variable in a page which defined in the code-behind class file of page . We could set the variable with public or protect visibility. and in the front page we can use it like below.
<%=VariableName%>.
But I don't know why can't use it in the ListView. Please help to review my code.
In the front page
<div id="divIssuedListContainer" class="myIssuedList">
<asp:ListView id="listShower" runat="server">
<LayoutTemplate>
<div id="divIssuedListHeadTitle">
<div id="divIssuedListTitleIco">
<img alt="" src="ico/IssuedCap.png" />
</div>
<div id="divIssuedListTitleName">
<span>ISSUED</span><span>TRADE NAMES</span><span>/LICENSES</span>
</div>
<div id="divIssuedListItemNumber">
<span>
<%=iListNumber%></span>
</div>
</div>
<div style="clear:both"></div>
<div id="divIssuedListBody">
<ul>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</ul>
</div>
</LayoutTemplate>
<ItemTemplate>
<li>
<table>
<tr>
<td>
<img alt="" src="" />
</td>
<td>
<div>
<span>
<%# Eval("altID") %>
-
<%# Eval("englishTradeName") %></span></div>
<div>
<span>Expired Date:<%# Eval("expDate") %></span>
</div>
</td>
</tr>
</table>
</li>
</ItemTemplate>
</asp:ListView>
In the code-behind of page
public partial class _Default : System.Web.UI.Page
{
protected int iListNumber = 0;
protected void Page_Load(object sender, EventArgs e)
{
List<SimpleCapModel> DataSourceList = TestDataHelper.GetMyIssuedList();
listShower.DataSource = DataSourceList;
iListNumber = DataSourceList.Count();
listShower.DataBind();
}
}
I got an error page said :
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
Source Error:
Line 19: listShower.DataSource = DataSourceList;
Line 20: iListNumber = DataSourceList.Count();
Line 21: listShower.DataBind();//this line cause error.
Line 22: }
Line 23: }
And If I use the expression <%#iListNumber%>. The error is gone, but I got a empty value instead of the number of the list. please review below rendered result html :
<div id="divIssuedListItemNumber">
<span> </span>
</div>
I didn't know whether I missed something ? If I did .Please help to let me know it.thanks.
You need to use <%#iListNumber %> because you are using data-binding the ListView, otherwise you'll get the exception (see: http://support.microsoft.com/kb/976112 for more on inline expressions).
Try using <%#iListNumber.ToString %> and see if that makes a difference.
UPDATE:
The problem appears to be that your inline-expression is in the LayoutTemplate, where data-binding [apparently] won't work without either handling the OnLayoutCreated event, or extending the ListView.
See either of the following for examples of how to extend the ListView:
http://www.codeproject.com/Articles/42962/Databind-Expression-in-ListView-LayoutTemplate
http://forums.asp.net/p/1201992/3319344.aspx#3319344
Given the error you're receiving, it basically means this: you can't just randomly throw .NET tags in databound controls.
The solution is to, instead, throw that random text in a .NET control, like this: <asp:Literal Runat="server" Text="<%# iListNumber %>" />
When you put a .NET codeblock in code, it dynamically has to build a control placeholder for it. It's a little tricky. But if you wrap all your custom tags up in a control, then just that one property gets databound and the databound block remains "clean" if that makes sense.
I have some tabular data, when the label has some specific value I need to make it show off.
Trying to do by styling the TD.
My C# sets the value for Label1.text
Can you think of any other way for doing so? It's throwing ambiguity error.
<% if (Label1.Text == "1") { %>
<td style="background:#ffedad; border:#e3a345; color:#cd5c0a"><asp:Label ID="Label1" runat="server" /></td>
<% } else {%>
<td><asp:Label ID="Label1" runat="server" /></td>
<% } %>
EDIT
Did something else (and cleaner).
Worked on some code behind variables along with some new td.alt on my css file to get the value of the label. If it's 1, then I set a
classLabel variable to alt and then I just set the class inside the td
<td class="<%classLabel%>"><asp:Label ID="Label1" runat="server" /></td>
Still, I'm getting and error on this last line in my aspx page, any ideas where the error is?
You can try this with a single line :
<td <%=Label1.Text != "1"?"":"style='background:#ffedad; border:#e3a345; color:#cd5c0a'"%>><asp:Label ID="Label1" runat="server" /></td>
Setting the style code behind and with a css class would be cleaner IMHO
Hope this will help
You can call the code behind method which will return the formatted HTML string that can be directly rendered by the browser. In that code behind method you can do almost anything: access any type of database or any business logic.
Possible return div element encapsulating the content (without style).
You can return divs with different ids or classes by having if-else logic inside the code-behind method. Then you can write different CSS styles to apply to different divs.
<% if (Label1.Text == "1") { %>
<td style="background:#ffedad; border:#e3a345; color:#cd5c0a">
<%# generateOutput() %></td>
<% } else {%>
<td> <%# generateOutput() %> </td>
<% } %>
Instead of having if-else in asp.net markup, you can simply have
<%# generateOutput() %>
and return the whole content from code behind and write styles in CSS files.
If the content to be displayed is less or less complicated this second approach will work, otherwise you may prefer first approach.
However if you are accessing the data directly from database you can you ASP.NET data controls like GridView, style them in templates and also filter the data using querystring or form values.
I'm trying to upload a default thumbnail image if user hasn't uploaded any thumbnail for their news article. Can you please help?
I tried at first, but it didn't work:
<%#Eval("Thumbnail")!=null ? Eval("Thumbnail"):"~/Images/test.jpg"%>" alt="<%#Eval("Title") %>"
I'm have the following code in a repeater:
<asp:Repeater ID="rptRotator" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<div class="widgetContent">
<img class="thumbNail" src="<%#Eval("Thumbnail") %>" alt="<%#Eval("Title") %>" />
<h4 style="width: 155px;">
<a href="/news/<%#Eval("PublicationDate","{0:yyyy/MM/dd}")%>/<%#Eval("UrlName") %>">
<%#Eval("Title") %></a></h4>
<div class="clear">
</div>
<span class="newsDate">
<%# Eval("PublicationDate", "{0:dd MMMM yyyy}")%></span>
<div class="widgetTextSummary">
<p>
<%#Eval("Summary").ToString().Substring(0,60)%>...</p>
</div>
</div>
</li>
</ItemTemplate>
<FooterTemplate>
</ul></FooterTemplate>
</asp:Repeater>
A simple way to do this is to create a public method that you can use to determine if the data item is null or not and set it accordingly. This way you wouldn't have to put all your code inline. You would then have something like this in vb .net in your code behind:
Public Function ProcessDataItem(myDataItemValue As Object) As String
If myDataItemValue Is Nothing Then Return "~/Images/test.jpg"
Return myDataItemValue.ToString()
End Function
And then call it in the repeater:
<%# ProcessDataItem(Eval("Title")) %>" alt="<%#Eval("Title") %>"
Also, I recommend using Container.DataItem instead of Eval as it creates less overhead. So in the end it would be something like this:
<%# ProcessDataItem(Container.DataItem("Title")) %>" alt="<%#Container.DataItem("Title") %>"
How about give your property Thumbail a default value?
Then when the Thumbnail hasn't been set to a non-null value the default image will be displayed, otherwise the users thumbnail will be shown.
One of the following should work:
<%# Eval("Thumbnail") ?? "/images/default.png" %>
<%# Eval("Thumbnail") == DBNull.Value ? "/images/default.png" : Eval("Thumbnail") %>
<asp:Image ID="imgProd" runat="server" src="<%#Eval('Thumbnail')"
onerror="this.onload = null; this.src='ImageurlORAnyImageHere.jpg';"/>
I am trying to execute the following code in a .aspx page:
<asp:Repeater ID="rptComentarios" runat="server">
<ItemTemplate>
<% if (Convert.ToInt32(Eval("int_tipo")) == 1)
{ %>
<div class="resp">
<div class="top">
</div>
<div class="cont-resp">
<h3>
<%# Eval("txt_nome") %></h3>
<p>
<%# Eval("txt_comentario") %></p>
</div>
</div>
<% }
else
{%>
<div class="usuario">
<div class="top">
</div>
<div class="cont-usuario">
<h3>
<%# Eval("txt_nome") %></h3>
<p>
<%# Eval("txt_comentario") %></p>
</div>
</div>
<% } %>
</ItemTemplate>
</asp:Repeater>
It throws a runtime exception in the first line:
<% if (Convert.ToInt32(Eval("int_tipo")) == 1)
System.InvalidOperationException: Databinding methods such as Eval(), XPath() and Bind() can only be used in the context of a databound control.
What's wrong? Any ideas?
I had a similar problem and the following code worked for me:
<asp:Repeater ID="rptComentarios" runat="server">
<ItemTemplate>
<asp:PlaceHolder ID="placeholderBlaBlaBla" runat="server" Visible='<%# Convert.ToInt32(Eval("int_tipo")) == 1 %>'>
Your optional HTML
</asp:placeholder>
Other HTML
</ItemTemplate>
</asp:Repeater>
Some more comments:
Please note that single quotes are used to define the value Visible attribute of asp:placeholder. I tried double quotes too and they didn't work.
Anytime you want to get some optionally displayed HTML you should use a control to show/hide it. asp:placeholder works fine for that purpose. Don't ever do <% if(..) { %> - this is evil.
<%# ... %> is used to calculate or display expressions inside a repeater. These expressions can be displayed as HTML or passed as attributes of server side controls. You can't use if inside it.
I think there needs to be a # sign for the enclosure <%# ..Eval...%>
Or try the full Eval version
<%# if (Convert.ToInt32(DataBinder.Eval(Container.DataItem, "int_tipo"))
== 1) { %>
i have a repeater than creates a table:
<itemtemplate>
<tr id="theTableRow" runat="server">
<td>
<asp:LinkButton runat="server"
OnClientClick="todo"
Text="Do Something" />
</td>
</tr>
</itemtemplate>
Note: the OnClientClick="todo" line.
In the final rendered code, i want the todo to contain a call to a javascript function, passing:
the ID of the generated table row, and
the Eval of a property of the currently bound object
And now for some pseudo-code:
Pseudocode 1:
OnClientClick="DoSomething(theTableRow, CromulentGuid); return false;"
Pseudocode 2
OnClientClick="javascript:DoSomething(theTableRow, CromulentGuid); return false;"
Pseudocode 3
OnClientClick="javascript:DoSomething(theTableRow, <%# Eval("CromulentGuid") %>); return false;"
Pseudocode 4
OnClientClick="javascript:DoSomething(<%= theTableRow %>, <%# Eval("CromulentGuid") %>); return false;"
Pseudocode 5
OnClientClick='javascript:DoSomething(<%= Eval(theTableRow) %>, <%# Eval("CromulentGuid") %>); return false;'
Whatever the ASP.NET code used, i want the rendered HTML to be:
<tr id="ctl00__itemRepeater_ctl01_theTableRow">
<td>
<a
onclick="DoSomething('ctl00__itemRepeater_ctl01_theTableRow', '19a149db-5675-4eee-835d-3d78372ca6f9'); return false;"
href="javascript:__doPostBack('ctl00$itemRepeater$ctl01$ctl04','')">
Do Something
</a>
</td>
</tr>
i would also be okay with:
<tr id="ctl00__itemRepeater_ctl01_theTableRow">
<td>
<a
onclick='DoSomething("ctl00__itemRepeater_ctl01_theTableRow", "19a149db-5675-4eee-835d-3d78372ca6f9"); return false;'
href="javascript:__doPostBack('ctl00$itemRepeater$ctl01$ctl04','')">
Do Something
</a>
</td>
</tr>
Note: i'm okay with the 2nd form since i know it is functionally identical, and ASP.NET code cannot generate the former, even if the latter is less readable.
Related questions:
ASP.NET: How to access repeater generated elements from javascript?
The better solution is to put the presentation logic in the business layer:
Presentation:
<asp:LinkButton runat="server"
OnClientClick="<%# GetItemClientClick((MySomething)Container.DataItem) %>"
Text="Do stuff" />
Business Logic
protected string GetItemClientClick(MySomething item)
{
...
String szOnClientClick =
"return DeleteItem(this, "+
Toolkit.QuotedStr(item.NodeGUID.ToString()) + ", "+
Toolkit.QuotedStr(GetItemText(item))+");";
return szOnClientClick;
}
Much cleaner. Much more readable. Much more maintainable.
You can use the OnItemDataBound event to alter each element in your code. Since you're particular about the HTML I might also recommend using hybrid controls rather than asp controls. For example:
<itemtemplate>
<tr id="theTableRow" runat="server">
<td>
<a runat="server"
onclick="todo(this.parent.parent, '<%# Eval("Property") %>');return false;" >
Do Something
</a>
</td>
</tr>
</itemtemplate>
This probably isn't 100% perfect, as I just typed it directly in the reply window and I always screw up the Eval() syntax on my first go, but it should help some.
Why not put the JS on the table row?
<tr onClick="DoSomething(this, '<%# Eval("GUIDColumn") %>')"; ><td>
<%# Eval("ColumnText") %>
</td></tr>
This gets you a reference to the table row, and the data that you're needing. It does break downlevel support, so browsers under IE6 won't really work as expected, but that's pretty much par for the course these days.
Two other possibilities are to utilize the Datagrid/Gridview object and the OnItemDatabound aspects or to build the table in code utilizing the ASP.NET TABLE control, and iterating through your datasource manually.