I have listview in asp.net web form . I want to select rows and update selected after button click.
For this i want to use Checkbox/CheckboxList . But i don't understand how to send information about row or from column in selected row to Checkbox/CheckboxList item .
How can i select rows, and update them , using Checkbox/CheckboxList ?
I use Asp.net Linq Entity Framework.
My code
<asp:Button ID="ButtonTest" runat ="server" OnClick="ButtonTest_Click" />
<asp:ListView ID="ListView2" ItemType="DocCat.Models.ReqInf" SelectMethod="GetReqF" OnItemDataBound="ListView2_ItemDataBound"
DataKeyNames="requestN" EnableViewState="true" runat="server" UpdateMethod="ListView2_UpdateItem" DeleteMethod="ListView2_DeleteItem" InsertMethod="ListView2_InsertItem">
<LayoutTemplate>
<div class="outerContainer" style="overflow: scroll">
<table id="docTable">
<thead>
<tr>
<th>
Выбрать
</th>
<th>First</th>
<th>Request</th>
<th>Third</th>
<th>Four</th>
</tr>
</thead>
<tbody runat="server" id="itemPlaceholder"></tbody>
</table>
</div>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td> <asp:CheckBoxList runat="server" ID="CheckNew" ><asp:ListItem>Выбрать</asp:ListItem></asp:CheckBoxList></td>
<td>
</td>
<td><%# Item.BirthDate.Date%></td>
<td><%# Item.F1 %></td>
<td><%# Item.F2 %></td>
<td><%# Item.F3 %></td>
</tr>
</ItemTemplate>
</asp:ListView>
Selected rows don't display in Checkboxlist items and in string selectedItems :
CheckBoxList cblRoles = ListView2.Items[0].FindControl("CheckNew") as CheckBoxList;
string selectedItems = "";
for (int i = 0; i < cblRoles.Items.Count; i++)
{
if (cblRoles.Items[i].Selected)
{
selectedItems = selectedItems + cblRoles.Items[i].Value + ",";
}
}
I recently used this kind of UI. First I created Table UI, I created populate Table method in my code behind.I used ADO.net for Data Access.
Note: Create stored procs for getting the data and updating the data after button click.
Step1: Write Populate Table method in that create object for checkbox but I used radio Button.
using (mTableRow = new HtmlTableRow()){
{
#region Radio Button
using (HtmlTableCell lTableCell = new HtmlTableCell())
{
RadioButton mradioButton = new RadioButton();
mradioButton.ID = "Radio" + listInfo.ID;
mradioButton.GroupName = "rowSelector1";
mradioButton.AutoPostBack = true;
mradioButton.Checked = false;
mradioButton.CheckedChanged += new EventHandler(AvailableRadioButton_CheckedChanged);
lTableCell.Attributes["class"] = "RadioButton";
lTableCell.Controls.Add(mradioButton);
mTableRow.Cells.Add(lTableCell);
#endregion
// add all the remaining columns
// add table row to the table.
Step2: Create a method for event click of Checkbox.
My problem was to find checkbox, i just missed this :
foreach (ListViewDataItem item in this.ListView2.Items)
{
if (item.ItemType == ListViewItemType.DataItem)
{
and all is working .
My button_click method:
List<int> ls = new List<int>();
{
foreach (ListViewDataItem item in this.ListView2.Items)
{
if (item.ItemType == ListViewItemType.DataItem)
{
CheckBox chkRow = item.FindControl("CheckBox") as CheckBox;
if (chkRow.Checked)
{
int request = int.Parse((item.FindControl("FirstFind") as Label).Text.Trim());
ls.Add(request);
}
}
}
repository.Approved(ls, newstat);
Update Method
public void Approved(List<int> list,int stat )
{
var friends = context.Requery.Where(f => list.Contains(f.parametr)).ToList();
friends.ForEach(a =>
{
a.par1 = 0;
a.par2 = stat;
});
context.SaveChanges();
}
Related
In Visual Studio, I have a Repeater. This functions fine. It has checkboxes and labels. If someone checks the checkboxes in the Repeater, I want my button to be clicked and update my database based on what is and isn't checked.
My code currently selects ALL fields and updates ALL of them in the database (all rows get set to visible = 0). I want ONLY the CHECKED boxes to get Visible = 0. I need a WHERE statement that somehow sees only the checked fields, but I am at a loss of how to do this.
Here is my Repeater:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<table>
<tr>
<td>
<asp:CheckBoxList ID="CheckBoxList1" runat="server">
<asp:ListItem></asp:ListItem></asp:CheckBoxList>
</td>
<td> <asp:Label ID="lblTest" runat="server" Text='<%# Eval("MyColumn") %>'></asp:Label>
</td>
</table>
</ItemTemplate>
</asp:Repeater>
Here is my button:
protected void ButtonSubmit_Click(object sender, EventArgs e)
{
using (SqlConnection sqlConn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["Events2"].ConnectionString))
{
sqlConn2.Open();
using (SqlCommand sqlCmd2 = new SqlCommand())
{
sqlCmd2.Connection = sqlConn2;
sqlCmd2.CommandType = System.Data.CommandType.Text;
foreach (RepeaterItem aItem in Repeater1.Items)
{
CheckBoxList CheckBoxList1 = (CheckBoxList)aItem.FindControl("CheckBoxList1");
foreach (ListItem listItem in CheckBoxList1.Items)
{
if (listItem.Selected == true)
{
sqlCmd2.CommandText = string.Format("UPDATE FormField SET Visible = 0");
sqlCmd2.ExecuteNonQuery();
}
else
{
//do something else
}
}
} sqlConn2.Close();
}
}
}
Your problem is in your SQL. UPDATE without a WHERE will apply to all rows in a table. I'm guessing at your table and data structure, but your solution might look more like this:
CheckBoxList CheckBoxList1 = (CheckBoxList)aItem.FindControl("CheckBoxList1");
foreach (ListItem listItem in CheckBoxList1.Items)
{
if (listItem.Selected)
{
sqlCmd2.CommandText = string.Format("UPDATE FormField SET Visible = 0 WHERE MyField = '{0}';", listItem.Value);
sqlCmd2.ExecuteNonQuery();
}
else
{
//do something else
}
}
I use this code to put the selected gridview row to Label or textbox and they are working properly, However when I choose to display the data in a dropdownlist which loads data from sqldatasource, it produces this error:
'ddlRPGroup' has a SelectedValue which is invalid because it does not exist in the list of items.
protected void grdTenant_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = grdTenant.SelectedRow;
lblRPCode.Text = row.Cells[1].Text;
lblRP.Text = row.Cells[2].Text;
lblType.Text = row.Cells[3].Text;
lblBusiness.Text = row.Cells[4].Text;
ddlRPGroup.SelectedValue = row.Cells[5].Text;
}
Markup
<table border="0" class="tblEditTenant" cellpadding="3">
<tr>
<td colspan ="4" style="font-weight: 700; font-size: medium;"><asp:Label ID="lblRP" runat="server" Text="Retail Partner"></asp:Label>-
<asp:Label ID="lblRPCode" runat="server" Text="RP Code"></asp:Label> </td>
</tr>
<tr>
<tr>
<td>Type:</td>
<td colspan ="3"><asp:Label ID="lblType" runat="server" Text="Type"></asp:Label></td>
</tr>
<tr>
<td>Business:</td>
<td colspan ="3"><asp:Label ID="lblBusiness" runat="server" Text="Business"></asp:Label></td>
</tr>
<tr>
<td>RP Group:</td>
<td colspan ="3">
<asp:DropDownList ID="ddlRPGroup" runat="server" DataSourceID="SqlDataSource3" DataTextField="name" DataValueField="code"></asp:DropDownList> <asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</td>
</tr>
</table>
What the error tells you, that the value you want to select in your DropdownList does not yet exist in the list.
If this value already should be in the ddl, then you need to edit the DataSource of your ddl to insert the correct values.
If you want to insert the selected value into the dropdownlist first and then select it, do it like this:
protected void grdTenant_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = grdTenant.SelectedRow;
lblRPCode.Text = row.Cells[1].Text;
lblRP.Text = row.Cells[2].Text;
lblType.Text = row.Cells[3].Text;
lblBusiness.Text = row.Cells[4].Text;
//new ListItem with Text and Value of cells[5] gets inserted into ddl
ddlRPGroup.Items.Insert(0, new ListItem(row.Cells[5].Text,row.Cells[5].Text));
ddlRPGroup.SelectedValue = row.Cells[5].Text;
}
If this value should already be in the list, the you need to edit your datasource to return to proper values.
Found out the answer already, and what is causing the error.
Just replace this line
ddlRPGroup.SelectedValue = row.Cells[5].Text;
with this:
ddlRPGroup.SelectedItem.Text = row.Cells[5].Text;
It should be selectItem.Text because selectedValue points the code of the item and not the item itself
I have a simple repeater that gets the 'groups' of 'widgets' The home page lists all of the groups:
<ItemTemplate>
<tr>
<td width="60" class="center"><%# DataBinder.Eval(Container.DataItem, "Number") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "Name") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "Description") %></td>
</tr>
</ItemTemplate>
Code Behind
private void LoadForm()
{
using (MarketingWebContentEntities context = new MarketingWebContentEntities())
{
rptGroup.DataSource = (from groups in context.URLGroup
select groups).ToList();
rptGroup.DataBind();
}
}
I would like within the repeater to show number of 'widgets' within each 'group'. I know I'd need to run a query on the 'widgets' table to see how many items are in that list. I'm just unsure how to add that within the repeater mark-up.
As mentioned in the comment, you could use the ItemDataBound event for this.
This example is in VB - been a while since I wrote C#, though will give you an idea. I haven't checked it for syntax either, it's more an example to get you up and running.
In your <ItemTemplate> add yourself, say, a ASP:Label. In this case, it's called myLabel
So in your code behind, create a private method that will handle the ItemDataBound event.
Protected Sub myRepeater_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles myRepeater.ItemDataBound
If (e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim uG As URLGroup = CType(e.Item.DataItem, URLGroup)
'' you now have the group for that one item
'' you should now be able to get additional information needed.
'' you can also get the myLabel from this item
dim lbl as Label = CType(e.Item.FindControl("myLabel", Label)
'' and set its text to whatever you need
lbl.Text = MyCounter
End If
End Sub
Hopefully this will get you on your way.
Here is a link to the MSDN documentation for it too.
I used the OnItemDataBount event
<asp:Repeater runat="server" ID="rptGroup" OnItemDataBound="rptDestinationCount_ItemDataBound">
<HeaderTemplate>
<table id="tblUrlGroup" class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th style="width:20px;">Count</th>
<th style="width:35px;">Add</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><i class="icon-wrench" rel="tooltip" title="Edit Group Name"></i> <%# DataBinder.Eval(Container.DataItem, "Name") %></td>
<td class="center"><asp:HiddenField runat="server" ID="hidURLGroupRowID" Value='<%# DataBinder.Eval(Container.DataItem, "URLGroupRowID") %>' /><asp:Label runat="server" ID="lblCount"></asp:Label></td>
<td class="center">
<i class="icon-plus" rel="tooltip" title="Manage Destination URLs"></i>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
On the function I made sure I was only looking through the repeater Item and Item Template. The hidden field is set with the ID with the datasource. This allowed me to run a query and set the lblCount.Text to the destination count.
Code Behind
protected void rptDestinationCount_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
using (MarketingWebContentEntities context = new MarketingWebContentEntities())
{
Label lblCount = (Label)e.Item.FindControl("lblCount");
HiddenField hidURLGroupRowID = (HiddenField)e.Item.FindControl("hidURLGroupRowID");
int groupRowID = Convert.ToInt32(hidURLGroupRowID.Value);
var destination = (from dest in context.URLDestination
where dest.URLGroup.URLGroupRowID == groupRowID
select dest).ToList();
lblCount.Text = destination.Count.ToString();
}
}
}
The following is the design.
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<tr>
<td><asp:Label ID="dlLbl" runat="server"></asp:Label></td>
<td><asp:Label ID="dlLink" runat="server"></asp:Label></td>
</tr>
</table>
And the following is the backend codes.
foreach (SPListItem objInnovationListItem in objInnovationList.Items)
{
if (Convert.ToString(objInnovationListItem["Innovation Approval Status"])== status)
{
countStatus++;
//Displays name of the document and download link
dlLbl.Text = objInnovationListItem["Project Title"].ToString();
dlLink.Text = "<a href='/RIDepartment/Innovation%20Submission/" + objInnovationListItem.File.Name + "'>Download</a><br>";
}
}
Hence, my question is, what can I do to allow the tables to dynamically accommodate the document and dl link when there's more than 1 in the loop?
Appreciate some code samples.
With your code style (manual creating html without web-controls) i recommend you to look on ASP.NET MVC side. But i can answer to your question:
First - you need to use asp:Repeater like this:
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<asp:Repeater ID="repLinks" runat="server"
onitemdatabound="repLinks_ItemDataBound">
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblProject" runat="server" Text="Label"></asp:Label>
</td>
<td>
<asp:HyperLink ID="hlLink" runat="server">HyperLink</asp:HyperLink>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
second: you need to initialize your collection, that you want to display. For example: you want to display a collection of objInnovationListItem class:
public class objInnovationListItem
{
public string Name { get; set; }
public string Title { get; set; }
public override string ToString()
{
return Title;
}
}
you need do next:
// list - it's source List<objInnovationListItem>
var bindList = list.Where(p => objInnovationListItem["Innovation Approval Status"] == status); // filter your collection - replace you foreach and if statement
repLinks.DataSource = bindList; // set to repeater your displayed collection
repLinks.DataBind(); // bind your collection
and last - you need to indicate in your Repeater ItemTemplate how to display your objInnovationListItem instance - subscribe to event of your Repeater ItemDataBound:
protected void repLinks_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var item = e.Item.DataItem as objInnovationListItem;
((Label) e.Item.FindControl("lblProject")).Text = item.Name;
((HyperLink) e.Item.FindControl("hlLink")).NavigateUrl = string.Format("/downloaduri?id={0}", item.Title);
}
Result will look like that:
I would use a repeater... Something like this (code might not be exact):
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<asp:Repeater id="rptItems" runat="server">
<ItemTemplate>
<tr>
<td><asp:Label ID="dlLbl" runat="server"></asp:Label></td>
<td>Download<br></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
and then in the ItemDataBound event of the repeater, do something like this:
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
((Label)e.Item.FindControl("dlLbl")).Text= ((SPListItem)e.Item.DataItem)["Project Title"].ToString();
}
Why don't you skip the server side controls, and just write the actual html?
Include this div in your aspx file:
<div runat="server" id="divTable"></div>
And put this in your Page_Load():
StringBuilder sb = new StringBuilder();
sb.Append("<table><tr><td>Project Title</td><td>Download Link</td></tr>");
for (int i = 0; i < 10; i++)
{
sb.AppendFormat("<tr><td>{0}</td><td><a href='{1}'>{1}</a></td></tr>", "Title", "Link");
}
sb.Append("</table>");
divTable.InnerHtml = sb.ToString();
You'll of course need to replace "Title" and "Link" with the appropriate values.
Your other options is to actually create new labels and links, but ASP.net is notoriously difficult to work with when you create your server side controls dynamically.
I have a document management system which creates a report showing people who own which document. There are times where people have 0 documents and in that case I would like the repeater table for that person to not be visible. I have looked around for a while and have not had much luck, maybe its because I am new or maybe its because I havent found my answer.
I have repeaters nested inside repeaters but if the first repeater is not visible the rest should follow.
aspx file
<h3> <%# DataBinder.Eval(Container.DataItem, "FullNm") %></h3>
<table ID="CollectorTable" runat="server" class="report-totals">
<tr>
<th>Total Collected:</th>
<td><asp:Literal ID="CollectorTotalCollected" runat="server" /></td>
<td class="report-totals-spacer"></td>
<th>Total Contacted:</th>
<td><asp:Literal ID="CollectorTotalContacted" runat="server" /></td>
<td class="report-totals-spacer"></td>
<th></th>
<td></td>
</tr>
</table>
// etc....
Code Behind
// ...pull totals
Control CollectorRepeater = new Control();
CollectorRepeater = (Control)e.Item.FindControl("CollectorRepeater");
CollectorRepeater.Visible = false;
Repeater collectorData = (Repeater)item.FindControl("CollectedTableRepeater");
collectorData.DataSource = collectedDocuments;
collectorData.DataBind();
Repeater contactedData = (Repeater)item.FindControl("ContactedTableRepeater");
contactedData.DataSource = contactedDocuments;
contactedData.DataBind();
So all you need to do is check if your data is empty - either before you bind it, or on a repeater's OnDataBinding event, and hide the repeaters if appropriate.
Repeater collectorData = (Repeater)item.FindControl("CollectedTableRepeater1");
Repeater contactedData = (Repeater)item.FindControl("ContactedTableRepeater2");
if( collectedDocuments.Tables[0].Rows.Count > 0 ){
//if there is data(more than 0 rows), bind it
collectorData.DataSource = collectedDocuments;
collectorData.DataBind();
contactedData.DataSource = contactedDocuments;
contactedData.DataBind();
} else {
collectorData.Visible = False;
//optional display "No data found" message
contactedData.Visible = False;
}
In the code behind, in the Repeater's ItemCreated event you can do a check for the document count, and only bind the table within the repeater item it if the count for the data is more than 0.
You can do exactly like "rlb.usa" said or just replace the else part with:
else {
collectorData.DataSource = null;
collectorData.DataBind();
contactedData.DataSource = null;
contactedData.DataBind();
}