I am using Bootstrap's Progress Bar inside a repeater to show score of different items. The aspx is like this:
<asp:Repeater ID="rptFinalScore" runat="server" OnItemDataBound="rptFinalScore_ItemDataBound">
<ItemTemplate>
<div class="row">
<div class="col-sm-2">
<asp:Label ID="rpt_Score" runat="server" Text='<%#Eval("TotalScore") %>'>></asp:Label>
</div>
<div class="col-sm-10">
<div class="progress">
<div id="rpt_proBar" class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" runat="server">
</div>
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
and the codebehind is:
protected void rptFinalScore_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
foreach (RepeaterItem item in rptFinalScore.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var Score = item.FindControl("rpt_Score") as Label;
var ProgBar = item.FindControl("rpt_proBar") as HtmlGenericControl;
string BuildingScore = ((Label)Score).Text;
ProgBar.Attributes.Add("style", string.Format("width:{0}%;", BuildingScore));
}
}
}
The problem I am facing is that if suppose there are 5 items in the repeater then it will correctly apply the style="width:x%" to first 4 items but not for the last item. The output is like this. Can someone please help me out with this.
Why are you looping in each ItemDataBound event handler call ? You have to set styles for the corresponding item that's stored in e argument. Last item's style is not set because repeater doesn't have that item in its Items collection when ItemDataBound event is fired.
You have to change your ItemDataBound handler to something like this:
protected void rptFinalScore_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var Score = e.Item.FindControl("rpt_Score") as Label;
var ProgBar = e.Item.FindControl("rpt_proBar") as HtmlGenericControl;
string BuildingScore = ((Label)Score).Text;
ProgBar.Attributes.Add("style", string.Format("width:{0}%;", BuildingScore));
}
}
Related
I have built a slideshow. Each of the slides has a div placed over the top of it. The div contains some text. What I want to do is if the h2 and p element have no text then hide the div that contains them. I have attempted to hide the div from the repeaters DataBound event but it is still showing the div over the slide.
Here's what I have so far:
aspx:
<asp:Repeater ID="rptSlides" runat="server" ClientIDMode="Static" OnItemDataBound="rptSlides_ItemDataBound">
<ItemTemplate>
<div runat="server" id="slideDiv" class="slide">
<img runat="server" src='<%# Eval("slideImgPath")%>' />
<div id="slideTextdiv" runat="server" class="slideText">
<h2 id="titlePlaceHolder" runat="server" class="slideTitle text-center text-capitalize h2 ">
<%# Eval("slideTitle") %>
</h2>
<p id="textPlaceHolder" runat="server" class="slideDes">
<%# Eval("slideDesc") %>
</p>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
Code behind:
protected void rptSlides_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
foreach (RepeaterItem item in rptSlides.Items)
{
HtmlGenericControl titleText = (HtmlGenericControl)item.FindControl("titlePlaceHolder");
HtmlGenericControl slidetextDesc = (HtmlGenericControl)item.FindControl("textPlaceHolder");
HtmlGenericControl slideDiv = (HtmlGenericControl)item.FindControl("slideTextdiv");
if (titleText.InnerText == "" && slidetextDesc.InnerText == "")
{
slideDiv.Style.Add("Display", "none");
}
}
}
Further info
I have also tried the following:
foreach (RepeaterItem item in rptSlides.Items)
{
HtmlGenericControl slideDiv = (HtmlGenericControl)FindControlRecursive(item, "slideTextdiv");
HtmlGenericControl titleText = (HtmlGenericControl)FindControlRecursive(item, "titlePlaceHolder");
HtmlGenericControl slidetextDesc = (HtmlGenericControl)FindControlRecursive(item, "textPlaceHolder");
if (string.IsNullOrWhiteSpace(titleText.InnerText) && string.IsNullOrWhiteSpace(slidetextDesc.InnerText))
{
slideDiv.Attributes["class"] = "emptySlideText";
}
}
I created a class in the css called emptySlideText, like so:
.emptySlideText {
display:none; }
Unfortunatley this has had no effect.
I have also tried changing the line
slideDiv.Style.Add("Display", "none");
to
slideDiv.Attributes.Add("style", "display:none");
But again it made no difference
First of all you don't need a foreach loop inside your rptSlides_ItemDataBound event as ItemDataBound event of a repeater control iterates for each item. Next Div is not a HtmlGenericControl control rather it is HtmlControl control. Once you have this you can hide the div using Visible property like this:-
protected void rptSlides_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
HtmlControl slideTextdiv = (HtmlControl)e.Item.FindControl("slideTextdiv");
HtmlGenericControl titlePlaceHolder = (HtmlGenericControl)e.Item.FindControl("titlePlaceHolder");
HtmlGenericControl textPlaceHolder = (HtmlGenericControl)e.Item.FindControl("textPlaceHolder");
if (titlePlaceHolder != null)
titlePlaceHolder.InnerText = Regex.Replace(titlePlaceHolder.InnerText, #"\r\n?|\n", "").Trim();
if (textPlaceHolder != null)
textPlaceHolder.InnerText = Regex.Replace(textPlaceHolder.InnerText, #"\r\n?|\n", "").Trim();
if (String.IsNullOrEmpty(titlePlaceHolder.InnerText) && String.IsNullOrEmpty(textPlaceHolder.InnerText))
{
slideTextdiv.Visible = false;
}
}
}
Please include using System.Text.RegularExpressions; to import Regex class.
This is how I will find out about my like a true or false, and I will do my Repeater.
If my like is false then the display content. but if it is true then the display content on the page.
Right now makes this error:
Databinding methods such as Eval(), XPath(), and Bind() can only be
used in the context of a databound control.
<asp:Repeater ID="RepeaterReport" runat="server">
<ItemTemplate>
<%--I have much more different content here.--%>
<% if (Convert.ToBoolean(Eval("like")) != true)
{ %>
<a href="../mentor/report.aspx?like=<%# Eval("IdBesked") %>" class="btn btn-success mr-xs mb-sm">
<i class="fa fa-thumbs-up"></i>Synes godt om
</a>
<% } %>
<%--I have much more different content here.--%>
</ItemTemplate>
</asp:Repeater>
Error are here:
<% if (Convert.ToBoolean(Eval("like")) == false) {%>
Select data:
var MentorBeskedReport = from mb in db.MentorBeskeds
where mb.Id == beskedId && mb.Til_BrugerId == Helper.ReturnBrugerId() && mb.godkendt == true && mb.opretdato < months
select new
{
IdBesked = mb.Id,
Navn = mb.brugere.fornavn + " " + mb.brugere.efternavn,
dag = mb.opretdato,
tekst = mb.tekst,
like = mb.like // Bit in database TRUE/FALSE
};
if (MentorBeskedReport != null)
{
//Report
RepeaterReport.DataSource = MentorBeskedReport.ToList().OrderByDescending(i => i.IdBesked);
RepeaterReport.DataBind();
}
The problem is that you're using the Eval method inside an if statement.
You should change your a tag to runat=server and give it an ID. Then, instead of doing the validation inside your .aspx file, you should add an ItemDataBound event and check it on .aspx.cs:
<asp:Repeater ID="RepeaterReport" ItemDataBound="RepeaterReport_ItemDataBound" runat="server">
<ItemTemplate>
<a id="myAnchor" runat="server" href="../mentor/report.aspx?like=<%# Eval("IdBesked") %>" class="btn btn-success mr-xs mb-sm">
<i class="fa fa-thumbs-up"></i>Synes godt om
</a>
</ItemTemplate>
</asp:Repeater>
public void RepeaterReport_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (Convert.ToBoolean(DataBinder.Eval(e.Item.DataItem, "like")) != true)
{
((HtmlControl)e.Item.FindControl("myAnchor")).Visible = false;
}
}
}
I have one Repeater
<asp:Repeater runat="server" ID="rptID" OnItemDataBound="repID_ItemDataBound">
<ItemTemplate>
<a href='example.com/somepage.aspx' id="myLink">
<%# Eval("MyVal")%>
</a>
</ItemTemplate>
</asp:Repeater>
In Code Behind I need to add one css class for this <a> tag when in repeater is one
Item
protected void repID_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
//how to set this class only then count of items is equal with 1
((HtmlGenericControl)e.Item.FindControl("myLink")).Attributes
.Add("class", "Count1");
}
}
This will give you the count of your datasource items:
if (((IEnumerable)rptID.DataSource).Cast<object>().Count() == 1)
{
((HtmlGenericControl)e.Item.FindControl("myLink")).Attributes
.Add("class", "Count1");
}
Counting the IEnumerable was borrowed from this thread: Calculating Count for IEnumerable (Non Generic)
I have three repeaters with a parent child relationship (so we have a parent repeater, and child repeater, and a child-child repeater) with the inner-most repeater not being triggered. here is my aspx page for the layout:
<asp:Repeater ID="rptMission" runat="server">
<HeaderTemplate>
<ul id="acc1" class="ui-accordion-container">
</HeaderTemplate>
<ItemTemplate>
<li>
<div class="ui-accordion-left"></div>
<a class="ui-accordion-link acc1"><%# Eval("Name") %><span class="ui-accordion-right"></span></a>
<div>
<ul class="ui-accordion-container" id="acc2">
<asp:Repeater ID="rptActivity" runat="server">
<ItemTemplate>
<li>
<div class="ui-accordion-left"></div>
<a class="ui-accordion-link acc2"><%# Eval("Name") %>
<span class="ui-accordion-right"></span></a>
<div>
<asp:Repeater ID="rptProject" runat="server">
<ItemTemplate>
<%# Eval("Name") %><br/>
</ItemTemplate>
</asp:Repeater>
</div>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</div>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
The top two repeaters work great but the 'rptProject' repeater doesn't get triggered. Here is my code behind:
protected void Page_Load(object sender, EventArgs e)
{
_presenter = new TierTypesPresenter(this);
rptMission.ItemDataBound += new RepeaterItemEventHandler(rptMission_ItemDataBound);
RaiseStartUp();
}
void rptMission_ItemDataBound(Object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Mission row = (Mission)item.DataItem;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var rptActivity = (Repeater)item.FindControl("rptActivity");
var activity = _presenter.GetActivitiesByMission(row.Id);
rptActivity.DataSource = activity;
rptActivity.DataBind();
}
}
void rptActivity_ItemDataBound(Object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Activity row = (Activity)item.DataItem;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var rptProject = (Repeater)item.FindControl("rptProject");
var project = _presenter.GetProjectsByActivities(row.Id);
rptProject.DataSource = project;
rptProject.DataBind();
}
}
public void SetMissions(IEnumerable<Mission> missionList)
{
rptMission.DataSource = missionList;
rptMission.DataBind();
}
If I could trigger the second ItemDataBound event 'rptActivity_ItemDataBound' I think it would work fine but it gets skipped over. Thanks for any insight!
I solved my problem by putting the third repeater binding into the second repeaters ItemBoundEvent. Here is the updated code for any interested:
void rptMission_ItemDataBound(Object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Mission row = (Mission)item.DataItem;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var rptActivity = (Repeater)item.FindControl("rptActivity");
var activity = _presenter.GetActivitiesByMission(row.Id);
var i = 0;
foreach (Activity data in activity)
{
RepeaterItem activityItem = rptActivity.Items[i];
var rptProject = (Repeater)activityItem.FindControl("rptProject");
var project = _presenter.GetProjectsByActivities(data.Id);
rptProject.DataSource = project;
rptProject.DataBind();
i++;
}
rptActivity.DataSource = activity;
rptActivity.DataBind();
}
}
I guess you are missing this line of code:
rptActivity .ItemDataBound += new RepeaterItemEventHandler(rptActivity_ItemDataBound);
It is easier to set the events in the asp file by the way...
I need to check every row of a datalist on a button click to check if the checkbox inside the each row is checked or not. I put my buttons inside the FooterTemplate of the DataList but I couldn't find a way yet. This is my ItemCommand method;
protected void DataList1_ItemCommand(object sender, DataListCommandEventArgs e) {
if (e.Item.ItemType == ListItemType.Footer) {
if (e.CommandName == "AddContinue") {
} else if (e.CommandName == "SkipContinue") {
}
}
}
here is my footer;
<FooterTemplate>
<div class="top-margin-25">
<div class="left-floathy">
<asp:Button runat="server" ID="btnPreviousStep" Text="<<< Previous Page"
class="blueButtonSmall boxShadow" onclick="btnPreviousStep_Click" />
</div>
<div class="right-floathy">
<asp:Button runat="server" ID="btnAddContinue" Text="Add & Contuniue >>>"
class="blueButtonSmall boxShadow" CommandName="AddContinue" /><br />
</div>
<div class="clarFix"></div>
<div class="right-floathy">
<asp:Button runat="server" ID="btnSkipContinue" Text="Skip & Continue >>>"
class="blueButtonSmall boxShadow" CommandName="SkipContinue" />
</div>
<div class="clarFix"></div>
</div>
</FooterTemplate>
Ok, apparently I was a little careless for not seeing DataList.Items thing. Answer is sitting here;
http://blog.ysatech.com/post/2011/06/03/ASPNET-Get-selected-checkbox-value-in-DataList.aspx
EDIT
For others who has the same problem, here is the code;
protected void DataList1_ItemCommand(object sender, DataListCommandEventArgs e) {
if (e.Item.ItemType == ListItemType.Footer) {
if (e.CommandName == "AddContinue") {
foreach (DataListItem item in DataList1.Items) {
CheckBox extraCheck
= item.FindControl("extraCheck") as CheckBox;
if (extraCheck != null) {
if (extraCheck.Checked) {
Response.Write(item.ItemIndex);
}
}
}
} else if (e.CommandName == "SkipContinue") {
}
}
}