I have a repeater control and a check box on each row. On the checkbox click event I wanted to obtain the data items for this row. I have tried the following but the data items within Repeater Item is always empty.
protected void CheckChanged(object sender, EventArgs e)
{
string county = string.Empty;
string country = string.Empty;
string postcode = string.Empty;
string posttown = string.Empty;
var item = ((CheckBox) sender).Parent as RepeaterItem;
if (item != null)
{
if (item.ItemType == ListItemType.Item)
{
System.Data.DataRowView drv = (System.Data.DataRowView)(item.DataItem);
county = drv.Row["county"].ToString();
country = drv.Row["country"].ToString();
postcode = drv.Row["postcode"].ToString();
posttown = drv.Row["posttown"].ToString();
}
}
}
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table border="1" width="100%" >
<tr>
<th>Select</th>
<th>Country</th>
<th>County</th>
<th>CSS Database Code</th>
<th>Postcode</th>
<th>Town</th>
</tr>
</HeaderTemplate>
<Itemtemplate>
<tr>
<td><asp:CheckBox ID="selectAddress" runat="server" OnCheckedChanged="CheckChanged" AutoPostBack="true"/></td>
<td><%# Eval("county")%>
<td><%# Eval("country")%></td>
<td><%# Eval("cssDatabaseCode")%></td>
<td><%# Eval("postcode")%><br /></td>
<td><%# Eval("postTown")%><br /></td>
</tr>
</Itemtemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
try this:
If CheckBox is Inside Repeater Then
var chk = (CheckBox)sender;
var item = (RepeaterItem)chk.NamingContainer;
if (item.ItemType == ListItemType.Item)
{
//find your items here
}
Here You can get the RepeaterItem by casting the CheckBox's NamingContainer. Then you can use FindControl to get the reference to your other Controls Inside Repeater
Related
Goal: Update row(s) in SQL table when Checkbox inside ListView is clicked.
I would like to update the following columns from sql:
IsApproved
ApprovalType
I am able to find the checkbox in the row that is clicked from the Listview on the page. However, that is as far as I got. Current code below, as well as what I've tried and the subsequent errors.
Code:
aspx:
<asp:ListView ID="lstUsers" runat="server" ItemType="Program.Data.Table" DataKeyNames="ID" SelectMethod="lstUsers_GetData"
OnItemCommand="lstUsers_ItemCommand" DeleteMethod="lstUsers_DeleteItem" OnSorting="lstUsers_Sorting"
OnItemDataBound="lstUsers_ItemDataBound"
ItemPlaceholderID="litPlaceHolder" >
<LayoutTemplate>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>UserName</th>
<th>Approve User</th>
<td><%# Item.LastName %></td>
<td><%# Item.FirstName %></td>
<td><%# Item.UserName %></td>
<td> <asp:CheckBox ID="cbApproved" runat="server" AutoPostBack="true" OnCheckedChanged="Approve_Click" /> </td>
c#:
protected void Approve_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in lstUsers.Items)
{
if ((item.FindControl("cbApproved") as CheckBox).Checked == true)
{
System.Diagnostics.Debug.WriteLine("it was checked!");
I've tried:
item.ColumnName -- but get error ListView does not contain a
definition for ''
item.DataItem -- the output displays what looks
like an object as a whole
(System.Web.UI.WebControls.ListViewDataItem)
item.DataItem.ColumnName
-- but get error Object does not contain a definition for ''
Do the column values im looking to update in SQL have to be displayed on the ASPX page?
I looked through:
https://msdn.microsoft.com/en-us/library/bb398790.aspx#ModifyingDataUsingTheListViewControl
Asp.Net CheckBoxList to update a SqlDataSource
Why not simply cast the sender to a CheckBox?
protected void Approve_Click(object sender, EventArgs e)
{
if ((sender as CheckBox).Checked == true)
{
System.Diagnostics.Debug.WriteLine("it was checked!");
}
}
You must bind data to the ListView inside an IsPostBack check for it to work.
UPDATE
What you want can be done easily with DataKeyNames. Add it to the ListView as a property.
<asp:ListView ID="ListView1" runat="server" DataKeyNames="IDColumn">
Then when the checkbox is changed read the correct key
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
ListView1.DataSource = Common.fillBooks();
ListView1.DataBind();
}
}
protected void Approve_Click(object sender, EventArgs e)
{
//cast the sender back to the checkbox
CheckBox cb = sender as CheckBox;
if (cb.Checked)
{
//get the parent of the parent (itemtemplate > listiew)
ListView lv = cb.Parent.Parent as ListView;
//get the dataitem from the namingcontainer
ListViewDataItem item = cb.NamingContainer as ListViewDataItem;
//get the correct datakey with the index of the dataitem
int ID = Convert.ToInt32(lv.DataKeys[item.DataItemIndex].Values[0]);
//update database here with the ID
}
}
ListView
<asp:ListView ID="ListView1" runat="server" DataKeyNames="id" ItemType="Namespace.Class">
<ItemTemplate>
<div class="table-responsive">
<table class="table">
<tr>
<td>
<asp:CheckBox ID="cbApproved" runat="server" AutoPostBack="true" OnCheckedChanged="Approve_Click" />
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:ListView>
This is what is currently working for me. Too long to add in comment or clutter original post:
ASPX:
<ItemTemplate>
<tr>
<td><asp:Label ID="UserNameLabel" runat="server" Text='<%#Eval("UserName") %>' /></td>
<td> <asp:CheckBox ID="Approved" runat="server" AutoPostBack="true" OnCheckedChanged="Approve_Click" /> </td>
</tr>
</ItemTemplate>
Changed the ItemTemplate to use asp Label controls so I could reference them in the code behind:
protected void Approve_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in listUsers.Items)
{
if ((item.FindControl("Approved") as CheckBox).Checked == true)
{
Label myLabel = (Label)item.FindControl("UserNameLabel");
try
{
IQueryable<SUR> user = null;
user = db.SURs.Where(m => !m.IsApproved && m.UserName == myLabel.Text);
if(user != null)
{
db.sp_SUA(user.FirstOrDefault().ID, SessionMgr.CurrentUserID.ToString(), "Manual");
db.SaveChanges();
}
Response.Redirect(Request.RawUrl);
}
catch(Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
}
}
}
Once getting the control that had the username, I check if the DB has a row with the same value
If so, use a stored procedure to update the DB
EDIT:
After refactoring, I was wondering if it would be more efficient to get rid of the foreach loop, and instead use the OnItemCommand property of ListView and set the OnCheckedChanged for the Checkbox to point to the ItemCommand method? My thinking is since I am not looping through each item, would having the array index be better in terms of Big O?
Code would be:
protected void listSTUFF_ItemCommand(object sender, ListViewCommandEventArgs e)
if (int.TryParse(list.DataKeys[e.Item.DisplayIndex].Value.ToString(), out id)) {
var myQuery = db.Table.Where(a=>a.ID == id).FirstOrDefault();
db.StoredProcedure(myQuery.ID)
db.SaveChanges();
I have a Datatable that has a checkbox and a value, What I want is that when I click a button it would get all the checked boxes and their corresponding value and Add them to a blank Datatable. I not planning to save the data moved from 1 list to another, as there will be another functionality to confirm if I want to save the changes(not being asked in this question).
This is my html code:
<asp:ListView runat="server" ID="uoListViewAirportSaved" EmptyDataText="No Data Found">
<LayoutTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="500px">
<tr>
<th runat="server"> </th>
<th runat="server">Airport</th>
</tr>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td class="leftAligned">
<asp:CheckBox ID="uoCheckBoxSelect" runat="server" />
</td>
<td class="leftAligned">
<asp:HiddenField ID="uoHiddenFieldAirport" runat="server" Value='<%# Eval("ColAirportCodeVarchar") %>' />
<asp:Label ID="uoLabelAirport" runat="server" Text='<%# Eval("colAirportFullName")%>' />
</td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="500px">
<tr>
<td>Airport</td>
</tr>
<tr>
<td colspan="3" class="leftAligned">No Record</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:ListView>
And the code when I click the add button:
private void AddAirport() {
CheckBox uoCheckBoxSelect;
HiddenField uoHiddenFieldAirport;
Label uoLabelAirport;
DataTable dt = new DataTable();
DataTable dt2 = new DataTable();
DataTable dt3 = new DataTable();
string serviceProvider = GlobalCode.Field2String(Request.QueryString["pid"]);
///datatable with all list of airports
dt = VendorMaintenanceBLL.GetServiceProviderAirportbyBrand(serviceProvider);
///datatable with provider's current airports
dt2 = VendorMaintenanceBLL.GetServiceProviderAirportbyVendor(serviceProvider);
foreach(ListViewItem item in uoListViewAirport.Items)
{
uoCheckBoxSelect = (CheckBox)item.FindControl("uoCheckBoxSelect");
if (uoCheckBoxSelect.Checked == true)
{
uoHiddenFieldAirport = (HiddenField)item.FindControl("uoHiddenFieldAirport");
uoLabelAirport = (Label)item.FindControl("uoLabelAirport");
/// my new list should contain the values from the checked values of the checkboxes
???
}
}
}
My Datatable contains the AirportID and the AirportStringName columns.
I found a code that I'm trying to replicate, logic-wise. However it is designed for a list:
List<AirportDTO> listToBeAdded = new List<AirportDTO>();
List<AirportDTO> listAdded = new List<AirportDTO>();
listToBeAdded = GetAirportNotInUser(false, false);
listAdded = GetAirportInUser(false);
foreach (ListViewItem item in uoListViewAirport.Items)
{
uoCheckBoxSelect = (CheckBox)item.FindControl("uoCheckBoxSelect");
if (uoCheckBoxSelect.Checked == true)
{
uoHiddenFieldAirport = (HiddenField)item.FindControl("uoHiddenFieldAirport");
uoLabelAirport = (Label)item.FindControl("uoLabelAirport");
var listToAdd = (from a in listToBeAdded
where a.AirportIDString == GlobalCode.Field2String(uoHiddenFieldAirport.Value)
select new
{
AirportID = a.AirportIDString,
AirportName = a.AirportNameString,
}).ToList();
}
}
I do not know how I would get the necessary data from the datatable as it is different from a list. Is there a way for me to do the same thing with DataTables the way lists were tackled.
Since I really need to fix the problem yesterday, I decided to do the following.
What I did was just basic for loop, then inside compare each row and then just use Datatable.ImportRow and DataTable.RemoveAt. I also added a temporary Datatable for the changed lists.
foreach(ListViewItem item in uoListViewAirport.Items)
{
uoCheckBoxSelect = (CheckBox)item.FindControl("uoCheckBoxSelect");
if (uoCheckBoxSelect.Checked == true)
{
uoHiddenFieldAirport = (HiddenField)item.FindControl("uoHiddenFieldAirport");
uoLabelAirport = (Label)item.FindControl("uoLabelAirport");
string HiddenFieldAirport = GlobalCode.Field2String(uoHiddenFieldAirport.Value);
for (var f = 0; f < dt.Rows.Count; f++ )
{
if (dt.Rows[f]["colAirportIDInt"].ToString() == HiddenFieldAirport)
{
dt3.ImportRow(dt.Rows[f]);
dt.Rows.RemoveAt(f);
}
}
}
}
The code is dirty, plus I had to sort it as well, but since I really needed it, I can make do with this.
How do I hide a particular column in Asp Repeater ? I want to hide POwner in this case !
<ItemTemplate>
<tr>
<td>
<%#Eval("Priority") %>
</td>
<td>
<%#Eval("ProjectName") %>
</td>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("POwner") %>'></asp:Label>
</tr>
</ItemTemplate>
Adding this in code behind gives an error :s
public void Repeater1_ItemDatabound(Object Sender, RepeaterItemEventArgs e)
{
Repeater a =(Repeater)e.Item.FindControl("Label1");
a.Visible = false;
}
Label1 is a Label control and not Repeater, that's why you're getting an error
You also need to add an if condition so you only get the Label1 for items and not for header or footer.
Try with this
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
Label label = (Label)e.Item.FindControl("Label1");
label.Visible = false;
}
You should cast Label1 to a Label not to a repeater try this :
Label a =(Label)e.Item.FindControl("Label1");
a.Visible = false;
i suppose it's impossible. but i can be mistaken
maybe you can try to use following inside your item template:
<tr>
<td runat="server" visible='<%# expression %'>
......
</td>
<td>
....
</tr>
or use ListView control instead Repeater
I have a DropDownList inside in ListView..
I wanted to get a data when command clicked.
this is my code..
protected void ListView2_ItemCommand(object sender, ListViewCommandEventArgs e){
string shipmethod = ((DropDownList)e.Item.FindControl("ShippingComapnyDDL")).SelectedValue;
}
but it always return null value..
I've googling about 3 hours, and try many function..
but still cant solve this bug..
please help me guys,
UPDATE
here's my aspx page
<asp:DropDownList ID="ShippingComapnyDDL" runat="server" SelectedValue='<%# Eval("ShippingCompany") %>'>
<asp:ListItem Text="" Value=""></asp:ListItem>
<asp:ListItem Text="FedEx" Value="FedEx"></asp:ListItem>
<asp:ListItem Text="UPS" Value="UPS"></asp:ListItem>
<asp:ListItem Text="Other" Value="Other"></asp:ListItem>
</asp:DropDownList>
DO you have headers set?try
if(e.Item.ItemIndex!=-1)
{
string shipmethod = ((DropDownList)e.Item.FindControl("ShippingComapnyDDL")).SelectedValue;
}
if not working then try
string shipmethod = (e.Item.FindControl("ShippingComapnyDDL") as DropDownList).SelectedValue;
Please try
<%#DataBinder.Eval(Container.DataItem,"ShippingCompany")%>
instead of
<%#Eval("ShippingCompany")%>
For more details:
http://aspadvice.com/blogs/joteke/archive/2008/08/24/Is-_2200_Databinding-methods-such-as-Eval_280029002C00_-XPath_280029002C00_-and-Bind_28002900_-can-only-be-used-in-the-context-of-a-databound-control_2E002200_-causing-you-grief_3F00_.aspx
try this:
DropDownList ddl = (DropDownList)e.Item.FindControl("ShippingComapnyDDL");
if (ddl != null)
{
//code here
}
<asp:ListView ID="lvwCoreConfigureData" runat="server" DataKeyNames="Course_Config_Id" OnItemCommand="lvwCore_Config_ItemCommand" OnItemDataBound="lvwCore_Config_ItemDataBound">
<LayoutTemplate>
<table class="table mobile-stacked mb-0">
<thead>
<tr role="row">
<th style="width: 240px">
<asp:Label runat="server" Text="<%$Lang:Resource.Core_Config_Course %>"></asp:Label>
</th>
</tr>
</thead>
<tbody>
<tr runat="server" id="itemPlaceholder" />
</tbody>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr role="row">
<td data-th="Name">
<asp:DropDownList ID="ConfigCourseName" runat="server" AutoPostBack="true" CssClass="form-control" OnSelectedIndexChanged="ConfigCourseName_SelectedIndexChanged"></asp:DropDownList>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
2 . This methos will be provide data binding to dropdown while edit mode
protected void lvwCore_Config_ItemDataBound(Object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item; // load one row item
var CourseId = ((Edulearn.Model.CoreProgramme.CoreProgrammeConfigrationDM)dataItem.DataItem).CourseId; //
DropDownList ConfigCourseName = (e.Item.FindControl("ConfigCourseName") as DropDownList);
ConfigCourseName.DataSource = CoreProgrammeRepository.GetCoreProgrammeCourseList(TimeZoneId, new { Name = "TEST" }); // Get the data to dropdown (all data)
ConfigCourseName.DataTextField = "Name"; // assign here which one need to display
ConfigCourseName.DataValueField = "CourseId"; // assign here which one is the value for database save
ConfigCourseName.DataBind(); // bind the data
ConfigCourseName.SelectedValue = CourseId.ToString(); // Here selected values from database will be added
ConfigCourseName.Items.Insert(0, new ListItem("Please select")); // Default value only for display
}
}
<asp:Repeater ID="rptList" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td width="15%">
<b>Subject</b>
</td>
<td width="60%">
<%#Eval("Title")%>
</td>
</tr>
I do databind to a repeater, and bind the title value.
string MysqlStatement = "SELECT Title, RespondBy FROM tbl_message WHERE MsgID = #Value1";
using (DataServer server = new DataServer())
{
.. }
rptList.DataSource = ds;
rptList.DataBind();
How can I get the value of title in server side, when a button in clicked in the same page.
I would put the title in a server control, like a label, and then you can do something like this:
<asp:Repeater ID="rptList" runat="server">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%#Eval("Title")%>' />
</ItemTemplate>
</asp:Repeater>
And then in the code behind:
int itemIndex = 0;
Label lbl = rptList.Items[itemIndex].FindControl("Label1") as Label;
if (lbl != null)
{
string labelValue = lbl.Text;
}
I would set the value of title to the text of a label that you could call FindControl() on.