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();
}
Related
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();
}
I am adding a textbox like this dynamically in my aspx file:
Here is my code:
foreach (DataRow info in myDataTable.Rows)
{
//draw html table and add controls
<input type="text" name="myTxt" id="myTxt" runat="server" />
<tr><td><%=Convert.ToString(info[0][1]) %></td></tr>
//more code here
}
How can I assign particular cell value to textbox?
I tried using <%=Eval(info[0][1])%> but it is not working as expected
Some guidance with this would be appreciated.
Thanks in advance.
Updated Q:
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<%
var rowId = 0;
foreach (System.Data.DataRow info in MyTable.Rows)
{
%> <tr>
<td> //want to draw a textbox which show value of column
<td><%=Convert.ToString(info[0]) %></td>
<td><%=Convert.ToString(info[3]) %></td>
}
%>
</tbody>
</table>
If you want to access the rows value and assign it:
myTxt.Value = info["column"].ToString();
or by column index:
myTxt.Value = info[index].ToString();
As you mentioned, that there is some constraint and you have to do this in aspx only. Keeping that in mind, you can use following code. And make a note here multiple inputs will have id = myTxt , you need to handle this. Else good approach is to follow Repeater and use databinding.
<table>
<%
int counter = 0;
foreach (System.Data.DataRow info in myDataTable.Rows)
{
string txtid = "myTxt" + counter.ToString();
%>
<tr>
<td>
<input type="text" name='myTxt<%=txtid %>' id='myTxt<%=txtid %>' value="<%=Convert.ToString(info[0]) %>" /></td>
<td><%=Convert.ToString(info[0]) %></td>
</tr>
<%
counter = counter + 1;
}%>
</table>
To retrieve changed textbox value on PostBack, use this Request.Form["myTxtmyTxt0"], Request.Form["myTxtmyTxt1"] etc..
You are doing it in wrong way. You need to instantiate TextBox control class and then attach it's properties and values. Finally add the newly created control to your webform's control collection like below. This may not guarantee any particular position where the control will be added. To guarantee the specific position you need to use a place holder control and then add your textbox control to that place holder.
foreach (DataRow info in myDataTable.Rows)
{
TextBox tbx = new TextBox();
tbx.Name = "some_name";
tbx.Text = info[idx].Tostring();
this.webform1.Controls.Add(tbx);
}
Example of using Place Holder Control
Add a place holder control to your ASPX design
<asp:PlaceHolder id="PlaceHolder1" runat="server"/>
Then in your code behind .cs file add the newly created TextBox control to place holder control collection
PlaceHolder1.Controls.Add(tbx);
(OR)
If you already have declared a textbox named myTxt in your design then you can just attached the value saying
foreach (DataRow info in myDataTable.Rows)
{
this.myTxt.Text = info[0] as string;
}
I have a textbox control and a button control inside a listview, I want to hide those controls when required from code behind, I have tried using something like this
ListViewName.FindControl("TextBoxComment").Visible = false;
and
((TextBox)ListViewName.FindControl("TextBoxComment")).Visible = false
but when I run the code it gives NullReference Exception
Please help.
<ItemTemplate>
<table>
<tr>
<td>
<asp:TextBox ID="TextBoxComment" runat="server" >
</asp:TextBox>
</td>
<td>
<asp:Button ID="ButtonSubmit" runat="server"
CommandName="Comment"
CommandArgument='<%# Eval("FlowPostID") %>'/>
</td>
</tr>
</table>
</ItemTemplate>
You need to do this on the ListView's ItemDataBound Event Handle.
var item = (ListViewItem)e.DataItem;
var txtBox = (txtBox)item.FindControl("TextBoxComment");
if(txtBox != null)
{
txtBox.Visible = false;
}
And so forth...
You need to check for the null values
var textbox=ListViewName.FindControl("TextBoxComment");
if(textbox!=null)
ListViewName.FindControl("TextBoxComment").Visible = false;
I did this, it worked
TextBox Box = new TextBox()
Button Butt = new Button();
Box = (TextBox)e.Item.FindControl("TextBoxComment")
Butt = (Button)e.Item.FindControl("ButtonSubmit")
Box.Visible = false;
That worked perfectly fine :) Thank you all for your effort :)
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'm getting the following error, ever since I moved my DataTable to a different function.
Both DataSource and DataSourceID are defined on 'TestView'. Remove one definition.
By all means if you have tips on style / standards, I welcome that as well, I am very new to aspx coding. Any idea what could be causing this? It wasn't happening before when it wasn't its own function. Is it a local variable problem?
Here's the code for the code that binds and is highlighted in the error:
testDAO tda = new testDAO();
DataTable testTable = new DataTable("TestView");
testTable = tda.GetTestTable();
TestView.DataSource = testTable;
TestView.DataBind();
Here's the code for the GetTestTable():
public DataTable GetTestTable()
{
DataTable testTable = new DataTable("TestView");
testTable.Columns.Add("testdata", typeof(String));
testTable.Columns.Add("user", typeof(String));
testTable.Columns.Add("date", typeof(String));
DataRow arow = testTable.NewRow();
arow["testdata"] = "test data";
arow["user"] = "System";
arow["date"] = "";
testTable.Rows.Add(arow);
return testTable;
}
List view in aspx file:
<asp:ListView ID="TestView" runat="server">
<ItemTemplate>
<tr id="row" runat="server" class='<%# Container.DataItemIndex % 2 == 0 ? "row" : "altrow" %>'>
<td align="left">
<%# Eval("testdata") %>
</td>
<td align="center">
<%# Eval("user") %>
</td>
<td align="center">
<%# Eval("date") %>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table class="system">
<tr>
<th>
Test Data
</th>
<th>
User
</th>
<th>
Date
</th>
</tr>
<tr id="itemPlaceholder" runat="server" />
</table>
</LayoutTemplate>
</asp:ListView>
I think its due to some Naming conflicts Try renaming Either your DataTable name or ListView ID to somthing else like TestListView. Also you have an extra line for creating a New DataTable thats a redundency as you are assigning the table returned from method GetTestTable
Edit
If you are still having some problems then some where else you might be assigning a data source by setting DataSourceID to some data source provides, then do somthing like this:
TestView.DataSourceID = null;
testDAO tda = new testDAO();
DataTable testTable = tda.GetTestTable();
TestView.DataSource = testTable;
TestView.DataBind();
setting DataSourceID to null will definitely solve the problem..
id rewrite it to this
testDAO tda = new testDAO();
TestView.DataSource = tda.GetTestTable();
TestView.DataBind();
and that should do it - theres no need to create a DataTable and then assign a datatable to it from the tda.GetTestTable()