Switch Div Class in Repeater based on Checkbox.Checked Using C# - c#

I have a repeater that will present a set of titles and checkboxes (some checked some not). Each is wrapped in a div with a background colour. All I want to do is change the background colour for the checkboxes that are already checked so they are easily identified on the page.
Here's the repeater:
<asp:Repeater ID="rptCartridges" runat="server" OnItemDataBound="rp_ItemDataBound">
<ItemTemplate>
<div class="cartridgebox">
<span class="cartridgeboxl"><%#Eval("cartName") %></span>
<span class="cartridgeboxr">
<asp:CheckBox ID="chkCart" name="chkbox" Checked = '<%#Convert.ToBoolean(DataBinder.Eval(Container.DataItem, "cartChecked"))%>' runat="server" />
<asp:HiddenField ID="hfCartID" runat="server" Value='<%#DataBinder.Eval(Container.DataItem, "cartID")%>' />
</span>
</div>
</ItemTemplate>
</asp:Repeater>
All I really want to do is change the class cartridgebox to cartridgeboxchecked if the checkbox is returned as checked.
I have tried manipulating rp_ItemDataBound. Where it goes wrong is the actual changing of the class inline. I've tried using if statements, add runat="server" to the div and populating a variable and then using Response.Write inside the class statement. But nothing seems to work.
What seems the neatest way would be to use rp_ItemDataBound like so:
protected void rp_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
string chkboxClass = "cartridgebox";
CheckBox chk = (CheckBox)e.Item.FindControl("chkCart");
HiddenField hfCartID = (HiddenField)e.Item.FindControl("hfCartID");
// Adding the hide.Value Attribute to the chk.Text field.
chk.Attributes.Add("Text", hfCartID.Value);
if (chk.Checked == true)
{
chkboxClass = "cartridgeboxchecked";
}
else
{
chkboxClass = "cartridgebox";
}
}
But I lack the understanding to pass the variable chkboxClass to the div's class dynamically. Of course I am probably looking at this completely wrong so any guidance would be appreciated.

Use following markup for div in ItemTemplate : <div class='<%# ((bool)Eval("cartChecked"))? "cartridgeboxchecked" : "cartridgeboxl" %>' >
If you need to change div's class on checkbox change immediatelly, consider to add onclick client-side event handler to checkbox in ItemDataBound Repeater's event handler

Related

Repeater pulling as Null is code behind?

I have a repeater for Frequently asked questions on a Website that I'm trying to get separated into categories depending on which treeid it is related to.
When I reference the repeater (rp_FAQ) in the code behind to check if it is null so I can pass the category id to the stored procedure it keeps returning null when I need the item to exist when check that it's null.
I can't seem to find the route of the problem so as second set of eyes would be really grateful.
Thanks.
I have this repeater:
<asp:Repeater ID="rp_FAQ" DataSourceID="DS_GetFAQs" runat="server" OnItemDataBound="rp_FAQCategories_ItemDataBound">
<HeaderTemplate>
<div class="container-full fares_container">
<div class="row">
</HeaderTemplate>
<ItemTemplate>
<dt>Q: <%# Eval("Question") %></dt>
<dd>A: <%# Eval("Answer") %></dd>
</ItemTemplate>
<FooterTemplate>
</dl>
</div>
</div>
</FooterTemplate>
</asp:Repeater>
Here is my code behind:
protected void rp_FAQCategories_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rp_FAQRep = e.Item.FindControl("rp_FAQ") as Repeater;
if (rp_FAQRep != null)
{
if (TreeData.CurrentDefault.IsRelation(Convert.ToInt32(Resources.Pages.FAQ)))
{
DS_GetFAQs.SelectParameters["CategoryID"].DefaultValue = "1";
}
rp_FAQRep.DataSource = DS_GetFAQs;
rp_FAQRep.DataBind();
}
}
The FindControl method is only needed if you are trying to get a reference to a control which is inside the control which raised the event (in this case ItemDataBound). So you can either reference the control directly if it's not nested inside another control or use sender. For example:
var rp_FAQRep = rp_FAQ; //A bit pointless but demonstrates the point
or
var rp_FAQRep = (Repeater)sender;
The problem is that you are trying to find the rp_FAQ control in a control inside rp_FAQ itself.
Since e.Item is the RepeatItem under rp_FAQ, you can just cast e.Item.Parent, or sender if you will.
e.Item is the RepeaterItem within the Repeater - it does not contain the Repeater itself. Just cast the sender of the event:
var rp_FAQRep = (Repeater)sender;

Finding Div present inside the data list on runtime

I need to find the div which belongs my current clicked Link button from the code behind file in c#. Then i need to apply the class for that div. So far i tried to access by html table cell. But i cant able to access my div. So please any valuable suggestion to find the div?
<asp:DataList ID="DataList1" runat="server" OnItemCommand="DataList1_ItemCommand" style="width:100%">
<ItemTemplate>
<div runat="server" id="DivContent" style="padding-top: 25px; height: 65px;" align="center"
onmouseover="this.className='MsgClick'" onmouseout="this.className=''" >
<asp:LinkButton ID="LinkButton2" runat="server" Text='<%# Eval("UserName") %>' CommandName="show"
class="InnerMenuFont"></asp:LinkButton>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("AdminId") %>' Visible="False"></asp:Label>
<br />
</div>
<hr style="width: 80%" />
</ItemTemplate>
</asp:DataList>
In the above code i need to access the current div in the id "DivContent"
.MsgClick
{
background-image: url('Images/AdminHighlight.png');
background-repeat: no-repeat;
vertical-align: top;
margin-right: -38px;
padding-right: 30px;
}
above code is my class file.
use below code
Control objDiv = e.Item.FindControl("DivContent");
hope it will help you
Might be wrong, but I don't believe it's possible to access a div from code behind if the div is part of a data bound control (DataList, GridView, etc), even if you have runat="server" set.
You can however swap the div for asp:Panel - which renders as a div when the page is served up to the browser. e.g.
<asp:Panel ID="DivContent" runat="server">
div content... LinkButton, Label etc...
</asp:Panel>
When the LinkButton is clicked, you can find the asp:Panel in your code behind using the item index of the DataList to which the LinkButton belongs:
LinkButton OnClick event:
protected void LinkButton2_Click(object sender, EventArgs e)
{
// Get the Link Button which has been clicked.
LinkButton btn = (LinkButton)sender;
// Get the DataListItem in the DataList which contains the LinkButton which was clicked.
DataListItem listItem = (DataListItem)btn.NamingContainer;
// Get the ItemIndex of the DataListItem.
int itemIndex = listItem.ItemIndex;
// Find the asp:Panel in the DataListItem of the DataList (e.g. DataList1).
Panel currentPanel = (Panel)DataList1.Items[itemIndex].FindControl("DivContent");
}
You should then hopefully be able to change style settings form code behind.
You could possibly use the CssClass property to change what you need:
...
Panel currentPanel = (Panel)DataList1.Items[itemIndex].FindControl("DivContent");
currentPanel.CssClass = "NewClassName";
Just did this myself good sir. There is a much simpler solution!
From your c# code behind, a div would be refereed to as type HtmlGenericControl.
You will need to add a onitemdatabound="DataList1_ItemDataBound" to your DataList control markup.
Inside your itemdatabound event you can modify the div.
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
// Find the div control as htmlgenericcontrol type, if found apply style
System.Web.UI.HtmlControls.HtmlGenericControl div = (System.Web.UI.HtmlControls.HtmlGenericControl)e.Item.FindControl("DivContent");
if(div != null)
div.Style.Add("border-color", "Red");
}

radiobutton inside repeater always returns false

I have a repeater with radiobuttons in it.
<script type="text/javascript">
$(document).ready(function ()
{
$("#test input:radio").attr("name", "yourGroupName");
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="test">
<asp:Repeater runat="server" ID="rep" onitemdatabound="rep_ItemDataBound"
onitemcommand="rep_ItemCommand">
<ItemTemplate>
<asp:RadioButton ID="n" runat="server" Text='<%# Eval("name") %>' AccessKey='<%# Eval("id")%>' />
</ItemTemplate>
</asp:Repeater>
</div>
I am using the javascript at the top to fix the radiobutton bug in .net.
i bind a list to the repeater at page load, with a if (!Page.IsPostback) around it.
edit:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
rep.DataSource = z.Table.ToList();
rep.DataBind();
}
}
then i have a button, that when clicked should do something with the radio button that's been selected, this is the problem now:
foreach (RepeaterItem i in rep.Items)
{
RadioButton erb = i.FindControl("n") as RadioButton;
if (erb.Checked)
{
//do stuff
}
}
no matter which radiobutton i select, when i click the button and i debug the entire loop, every checkbox == false. i'm doing more stuff with the code but i've simplified it, because this is the biggest problem.
i have seen countless of topics about this issue and i have looked through them all but i still can't seem to get this to work.
Please try adding OnCheckedChanged="RadioButton1_OnCheckedChanged" AutoPostBack="true" on you radio button this will trigger post back on click of the button and you will be able to find the Checked one
I think this is all down to the sequence of events in ASP.NET .
Try putting your DataBind code in the Page_Init procedure, that way the state of the radiobuttons will be set by the time it reaches the Page_Load procedure.

Placing ListView DataItem Property into UserControl Template

Sort of new to .NET and trying to understand how best to accomplish this task: I have a listview with a datasource containing a list of string values. The last property is some text that I'd like to place in the Text template; normally when not used inside a listview I can place markup and text inside the template successfully, so I'd like to keep this structure. But what would be a way of placing that string inside there? I've tried Databinder.Eval but as expected it says that the template doesn't contain the property I'm referring to from Container.DataItem (which becomes the template).
<asp:ListView runat="server"
ID="ListView1"
OnItemDataBound="ListView1_ItemDataBound">
<LayoutTemplate>
<div class="navigation">
<asp:PlaceHolder runat="server" id="itemPlaceholder" />
</div>
</LayoutTemplate>
<ItemTemplate>
<my:Control id="VideoLink1" runat="server">
<Text>
--- PLACE CONTENT HERE --
</Text>
</my:Control>
</ItemTemplate>
</asp:ListView>
Anyone have an idea how to accomplish this? Would be greatly appreciated.
Use ItemDatabound event of the ListView. In that find your control and then assign the desired properties.
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
YourControl VideoLink1= e.Item.FindControl("VideoLink1") as YourControl ;
if(VideoLink1!= null)
{
YourClass obj = ((YourClass)(((System.Web.UI.WebControls.ListViewDataItem)(e.Item)).DataItem));
VideoLink1.TextProperty = obj .TextProperty ;
}
}
}

Gridview event not firing

I have a requirement where i have to update a textbox if any of the value in my grid view changes.. I have a gridview with 2 rows ..
one a template field with label and another template field with a textbox...
my Grid view looks like
name value
a (empty textbox)
b (empty textbox)
c (empty textbox)
now when the user enters a value in teh text box it should automatically update another textbox which is linked to this.
Here my questions is when someone enters a value in the textbox an event should be fired!
(I am getting the names a,b,c, from database). i dont want to have an edit link or update link because all the values to be entered are mandatory!
i tried Grid_SelectedIndexChanged1 but this not firing.. is there something i am missing or i need to change so that the evant is fired and i can update the other textbox??
I am new to ASP.NET so please help!
Thanks in advance!
If the updates are supposed to be triggered when the text changes, you should use the OnTextChanged event of the TextBox, and set AutoPostBack to true.
EDIT
To avoid duplicating efforts here, using the above approach you can find the row index using the technique that Pankaj Garg outlined in his answer:
int rowIndex = ((GridViewRow)((TextBox)sender).NamingContainer).RowIndex;
The biggest caveat to this approach is that it's not forgiving of changes in the markup. If you were to wrap the TextBox in another control that implements INamingContainer, the example above would break. For example:
<asp:TemplateField>
<asp:Panel ID="Panel1" runat="server"> <!-- becomes the naming container -->
<asp:TextBox ID="TextBox1" runat="server" onchange='valueChanged(<%# Container.ItemIndex %>);' />
</asp:Panel>
</asp:TemplateField>
That being said, you would want to notate your markup accordingly so other developers know to be careful when making changes.
EDIT
As an alternative, you could also trigger the postback in JavaScript using the onchange event of the TextBox:
<script type="text/javascript">
valueChanged = function(rowIndex){
__doPostBack("<%= GridView1.ClientID %>", rowIndex);
}
</script>
<asp:GridView ID="GridView1" runat="server" DataKeyNames="ID" ...>
<Columns>
<asp:TemplateField>
<asp:TextBox ID="TextBox1" runat="server" onchange='valueChanged(<%# Container.ItemIndex %>);' />
</asp:TemplateField>
</Columns>
</asp:GridView>
In the code-behind, override the RaisePostBackEvent method, and put your update logic there:
protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
base.RaisePostBackEvent(source, eventArgument);
if (source == GridView1)
{
int rowIndex = int.Parse(eventArgument);
TextBox txt = GridView1.Rows[rowIndex].FindControl("TextBox1") as TextBox;
if (txt != null)
{
var id = (int)GridView1.DataKeys[rowIndex]["ID"];
var text = txt.Text.Trim();
//update the database
}
}
}
You can check the Current Row Index like below...
((GridViewRow)((TextBox)sender).NamingContainer).RowIndex
Create a handler for OnTextChanged event and set the AutoPostBack Property True.
protected void TextBox_TextChanged(object sender, EventArgs e)
{
int CurrentGridIndex = ((GridViewRow)((TextBox)sender).NamingContainer).RowIndex
}

Categories