Please consider these operations -
Bind a list of files in a DataList.
Once the user clicks delete LinkButton, delete the file, in
ItemCommandEvent.
Since rebinding whole data is inefficient, I am simply hiding
deleted row.
Following code displays files in a DataList. There is a delete button beside each row.
<asp:DataList ID="DataList1" OnItemCommand="DataList1_ItemCommand" runat="server">
<ItemTemplate>
<tr>
<asp:Label Text='<%# Eval("ContainingFolder") as string + "\\" + Eval("FileName") as string %>'
Visible="false" ID="lblFullPath" runat="server" />
<td><%# Eval("FileName") %></td>
<td><%# Eval("ContainingFolder") %></td>
<td><%# Eval("FileSize") %></td>
<td><%# Eval("Modified") %></td>
<td>
<asp:LinkButton Text="Delete" ID="linkDelete" runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:DataList>
In ItemCommand Event Handler this code deletes the selected file from this list.
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return;
var selectedItem = e.Item.FindControl("lblFullPath") as Label;
e.Item.Visible = false; //doesn't work
File.Delete(selectedItem.Text);
}
However e.Item.Visible = false does not hides the row.
As a workaround found here, How to hide an item in datalist
I have wrapped contents inside a placeholder control.
<ItemTemplate>
<asp:PlaceHolder ID="ph1" runat="server">
<%--wrapped content--%>
</asp:PlaceHolder>
</ItemTemplate>
And hiding the placeholder control -
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return;
var selectedItem = e.Item.FindControl("lblFullPath") as Label;
//e.Item.Visible = false;
e.Item.FindControl("ph1").Visible = false;
File.Delete(selectedItem.Text);
}
Generally in asp.net hiding parent control hides all of its child controls.
But I am not able to understand,
Why hiding the parent control e.Item doesn't hide its containing
elements, in case of DataList ? Can you please advise.
Thank you for your help.
EDIT: Updating more info about generating list of files to display in DataList.
Generating fileList at runtime on button click, this list is not
persistent, currently.
protected void btnFindDuplicates_Click(object sender, EventArgs e)
{
DataList1.DataSource = FindDuplicates();
DataList1.DataBind();
}
In the event handler of delete Click, delete operation has been
completed successfully.
So, just to remove deleted item from the page, It would not be wise
to regenerate the dataSource and bind this. Hiding seems more logical to me.
I created this sample using JQuery and PageMethods:
Result
ASPX
<script>
$(function () {
var $list = $("table[id*=myDataListID]");
var $buttons = $("input:submit[id*=remove]", $list);
$buttons.click(function (e) {
e.preventDefault();
if (!confirm("Are you sure?")) {
return false;
}
var $self = $(this);
var $jobID = $self.closest("tr").children().find("span[id*=jobID]");
$buttons.prop("disabled", true);
$.ajax({
url: "<%: this.ResolveClientUrl("~/Topics/JQuery/Ajax/RemoveRowUsingJQueryAfterCallingService.aspx/Remove") %>",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: "{id: " + $jobID.text() + "}",
async: true,
cache: false,
success: function () {
$buttons.prop("disabled", false);
$self.closest("tr").remove();
},
error: function (XHResponse, errorMessage, errorCode) {
$buttons.prop("disabled", false);
alert(errorMessage);
}
});
});
});
</script>
<asp:DataList runat="server" DataKeyField="job_id" DataSourceID="lds" ID="myDataListID">
<HeaderTemplate>
<tr>
<th>
</th>
<th>
ID
</th>
<th>
Name
</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Button Text="Remove" runat="server" ID="remove" />
</td>
<td>
<asp:Label Text='<%# Eval("job_id") %>' runat="server" ID="jobID" />
</td>
<td>
<asp:Label ID="jobDesc" Text='<%# Eval("job_desc") %>' runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:DataList>
Code behind
[WebMethod]
public static void Remove(Int16 id)
{
// simulate deleting the file
Thread.Sleep(3000);
}
I just uploaded the full working example to my GitHub site
Related
I have created an HTML table with a repeater. In this table, I added a button column. It is an HTML button because ASP buttons not working inside of the tag. Therefore, I added an ASP hidden field inside of this HTML button to get selected row ID. I tried several ways to get the ID from the hidden field. I want to get selected row ID when the button click.
I have tried followings
I have tried this code but shows error in SendValueToSender(id); line. SendValueToSender is shown in red line using suggestions It generated method. But when I run the code and click the button shows error.
button_edit_ServerClick
protected void button_edit_ServerClick(object sender, EventArgs e)
{
try
{
var btn = (HtmlButton)sender;
var child = btn.FindControl("hidden");
string id = Convert.ToString(((HiddenField)child).Value);
SendValueToSender(id);
Response.Write("id" + id);
}
catch (Exception exception)
{
Response.Write(exception);
}
}
Generated method for SendValueToSender
private void SendValueToSender(string id)
{
throw new NotImplementedException();
}
Error-After add SendValueToSender method
System.NotImplementedException: The method or operation is not implemented. at EasyTravel.Manage.ManageNode.SendValueToSender(String id) in C:\Users\kularathna\source\repos\EasyTravel\EasyTravel\Manage\ManageNode.aspx.cs:line 241 at EasyTravel.Manage.ManageNode.button_edit_ServerClick(Object sender, EventArgs e) in C:\Users\kularathna\source\repos\EasyTravel\EasyTravel\Manage\ManageNode.aspx.cs:line 229
229 - SendValueToSender(id);
241 - throw new NotImplementedException();
PageLoad Method
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Create Database Connection
SqlConnection con = new SqlConnection("Data Source= LAPTOP-J70EHC58 ; Initial Catalog= Bus_Management_System ; Integrated Security = True ; Connect Timeout = 30 ; ");
con.Open();
//Retrieve node details
string sqlst = "SELECT * FROM Node ";
SqlDataAdapter sqlData = new SqlDataAdapter(sqlst, con);
DataTable dt = new DataTable();
sqlData.Fill(dt);
rptrNode.DataSource = dt;
rptrNode.DataBind();
}
}
ManageNode.aspx
<table id="datatable-buttons" class="table table-striped table-bordered">
<thead>
<tr>
<th>Node_ID</th>
<th>Node_Name</th>
<th>Starting_Node</th>
<th>Ending_Node</th>
<th>Distance_Between_Nodes</th>
<th>Ticket_Price</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<asp:Repeater ID="rptrNode" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblNodeID" runat="server" Text='<%# Eval("Node_ID") %>'></asp:Label></td>
<td>
<asp:Label ID="lblNodeName" runat="server" Text='<%# Eval("Node_Name") %>'></asp:Label></td>
<td>
<asp:Label ID="lblStartingNode" runat="server" Text='<%# Eval("Starting_Node") %>'></asp:Label></td>
<td>
<asp:Label ID="lblEndingNode" runat="server" Text='<%# Eval("Ending_Node") %>'></asp:Label></td>
<td>
<asp:Label ID="lblDistance" runat="server" Text='<%# Eval("Distance_Between_Nodes") %>'></asp:Label></td>
<td>
<asp:Label ID="lblTicketPrice" runat="server" Text='<%# Eval("Ticket_Price") %>'></asp:Label></td>
<td>
<button runat="server" clientidmode="Static" class="btn btn-success" id="button_edit" onserverclick="button_edit_ServerClick">
<asp:HiddenField runat="server" ID="hidden" Value='<%#Eval("Node_ID") %>' />
Edit
</button>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
Button Column(It is in above ManageNode.aspx)
<td>
<button runat="server" clientidmode="Static" class="btn btn-success" id="button_edit" onserverclick="button_edit_ServerClick">
<asp:HiddenField runat="server" ID="hidden" Value='<%#Eval("Node_ID") %>' />
Edit
</button>
</td>
In Design part, Load Jquery Js and Page Js.
<td>
<button runat="server" clientidmode="Static" class="btn btn-success"
id="button_edit" onclick="func('<%#Eval("Node_ID") %>')">
Edit
</button>
</td>
In Page Js:
$(document).ready(function(){
//button Click Function.
function func(Id){
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../ManageNode.aspx/SendValueToSender",
data: "{ID: '" + Id + "'}",
dataType: "json",
success: function (data) {
var tdata = jQuery.parseJSON(data.d);
},
error: function (result) {
alert('Data not found.');
}
});
}
});
In Server side.
[WebMethod]
public static void SendValueToSender(string ID)
{
//do your stuff.
}
I am receiving an error when I try to execute code in a style attribute as followed
<asp:LinkButton ID="lnkActivate" style='<%#Convert.ToBoolean(Eval("Activate")) ? "text-decoration:none;display:none;" : "text-decoration:none;display:block;"%>' runat ="server" CommandArgument='<%# Eval("ID") %>' OnClientClick ='return confirm("You want to send email to user to activate his account?");' CommandName ="activate" Text="Send Email" ></asp:LinkButton>
The error being thrown back is:
Error: Unexpected '<' in tag 'asp:LinkButton'.
I'm sorry if this question does not meet the community standards.
The code is also in C#
Edit:
Here is some more markup
<asp:Repeater ID="rpHostUsersList" runat="server" >
<ItemTemplate>
<tr class="odd gradeC" >
<td><%#DataBinder.Eval(Container.DataItem, "AccountID")%></td>
<td><%#DataBinder.Eval(Container.DataItem, "EmailAddress")%></td>
<td><%#DataBinder.Eval(Container.DataItem, "FirstName")%>, <%#DataBinder.Eval(Container.DataItem, "LastName")%></td>
<td><%#DataBinder.Eval(Container.DataItem, "Phone")%></td>
<td><%#DataBinder.Eval(Container.DataItem, "Address1")%></td>
<td><%#DataBinder.Eval(Container.DataItem, "City")%></td>
<td><%#DataBinder.Eval(Container.DataItem, "State")%></td>
<td><%#DataBinder.Eval(Container.DataItem, "Zip1")%></td>
<td>
<%#Convert.ToBoolean(Eval("Active")) ? "Yes" : "No"%>
</td>
<td> <%#Convert.ToBoolean(Eval("Activate")) ? "Yes" : "No"%>
<asp:LinkButton ID="lnkActivate" style='<%#Convert.ToBoolean(Eval("Activate")) ? "text-decoration:none;display:none;" : "text-decoration:none;display:block;"%>' runat ="server" CommandArgument='<%# Eval("ID") %>' OnClientClick ='return confirm("You want to send email to user to activate his account?");' CommandName ="activate" Text="Send Email" ></asp:LinkButton>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
EDIT
Ok, your problem is related to Style Property of your LinkButton, which is read only
public CssStyleCollection Style { get; }
But you can use the CssClass property
public virtual string CssClass { get; set; }
So you can do something like this:
Define you style tag outside your control:
<style>
.myclassBlock{
text-decoration:none;
display: block
.myclassNone{
text-decoration:none;
display:none;
}
</style>
But if you apply your conditional logic inside your Linkbutton markup:
<asp:LinkButton ID="lnkActivate" CssClass='<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>' runat ="server" CommandArgument='<%# Eval("ID") %>' OnClientClick ='return confirm("You want to send email to user to activate his account?");' CommandName ="activate" Text="Send Email" ></asp:LinkButton>
In your output you will see this:
<a onclick="return confirm("You want to send email to user to activate his account?");" id="lnkActivate" class="<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>" href="javascript:__doPostBack('lnkActivate','')">Send Email</a>
Because '<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>', is not scriptlet, and will be output as plain text.
So you have to do something like this:
I have semplified your LinkButton:
<form>
<asp:Repeater ID="rpHostUsersList" runat="server" OnItemDataBound="rpHostUsersList_OnItemDataBound">
<HeaderTemplate>
<table border="1">
<tr>
<td><b>Activate</b></td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%#Convert.ToBoolean(Eval("Activate")) ? "Yes" : "No"%> <asp:LinkButton ID="lnkActivate" runat="server" Text="Send Email"></asp:LinkButton></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</form>
In code behind I have create a Datatable on the fly just to have some fake data to bind:
protected void Page_Load(object sender, EventArgs e)
{
Activate = true;
var ds = new DataSet();
var dt = new DataTable();
dt.Columns.Add("Activate");
dt.Rows.Add(new object[] { true });
dt.Rows.Add(new object[] { false });
dt.Rows.Add(new object[] { true });
ds.Tables.Add(dt);
rpHostUsersList.DataSource = ds;
rpHostUsersList.DataBind();
}
So this is what you have to do to achieve your task:
protected void rpHostUsersList_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var currentData = ((System.Data.DataRowView)e.Item.DataItem)["Activate"];
var b = Convert.ToBoolean(currentData);
var btn = (LinkButton)e.Item.FindControl("lnkActivate");
btn.CssClass = b ? "myclassBlock" : "myclassNone";
}
}
OUTPUT
No matter what combination I try, the button (ibtnDeleteDiaryEntry) simply will not raise an event although it does seem to do postback as it should. ViewState is turned on by default, read elsewhere that it is sometimes problematic. Also, I've used the Repeater's OnItemCommand property as required. Any kind of help is appreciated.
EDIT: It seems that the problem is somehow connected to the jQuery UI's Accordion Widget. The repeater is located within a div that is used to initialize the accordion. If I remove the div tags surrounding the repeater, the OnItemCommand event gets called. Very weird.
Markup:
<asp:Repeater ID="repAccordion" OnItemCommand="repAccordion_OnItemCommand" runat="server">
<ItemTemplate>
<h3> <%# "Date: " + Eval("date", "{0:d}") %>
<span class="deleteButtonContainer">
<asp:ImageButton ID="ibtnDeleteDiaryEntry" CommandArgument='<%# Eval("diary_entry_id") %>' CommandName="Delete" AlternateText="ibtnDeleteDiaryEntry" ImageUrl="images/remove_item.png" runat="server" />
</span>
</h3>
<div>
<table>
<tr>
<td>
<asp:Label ID="lblText" runat="server" ForeColor="#AA0114" Text="Text:"></asp:Label>
</td>
</tr>
<tr>
<td>
<%# Eval("text") %>
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
_db = new PersonalOrganizerDBEntities();
_diary_entryService = new Diary_EntryService();
_userService = new UserService();
if (!IsPostBack)
{
LoadItems();
}
}
public void LoadItems()
{
long currentUserId = (long) Session["userId"];
User currentUser = _userService.GetById(currentUserId);
Diary_Entry[] diaryEntriesArray =
_diary_entryService.GetAll().Where(current => current.diary_id == currentUser.user_id).ToArray();
if (diaryEntriesArray.Length == 0)
{
noItems.Text = "You currently have no diary entries.";
noItems.Visible = true;
}
else
{
noItems.Visible = false;
}
repAccordion.DataSource = diaryEntriesArray;
repAccordion.DataBind();
}
protected void repAccordion_OnItemCommand(object sender, RepeaterCommandEventArgs e)
{
Response.Write("test");
}
If it doesn't work I would recommend removing OnItemCommand from repeater and adding OnClick event for ImageButton instead. In OnClick event in code behind you can cast 'sender' to ImageButton and read CommandArgument value to get diary_entry_id.
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();
}
}
}
I used repeater in asp.net. My problem is don't know how to hide a fields in repeater. There is a regular price and now price if regular price is equal to zero it will hide the fields and if not it will show the value of the regular price. i hope you can help on this.
here my code in asp:
<a href="<%=Utility.GetSiteRoot() %>/BookInfo.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>">
<img width="150px" src='<%# Eval("lb_picturepath")%>'>
</td>
<td valign="top">
<asp:Label ID="lb_titleLabel" runat="server" CssClass="center-head" Text='<%# Eval("lb_title") %>' />
<p><asp:Label ID="lb_descriptionLabel" runat="server" Text='<%# Eval("lb_description") %>' /></p>
<div class="price"><%# "Price: " + decimal.Round((decimal)Eval("lb_sellingprice"),2)%></div>
</td>
</tr>
<tr>
<td></td>
<td>
<a class="addtocart" href="<%=Utility.GetSiteRoot() %>/AddToCart.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>" >Add To Cart</a>
<a href="<%=Utility.GetSiteRoot() %>/BookInfo.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>" class="readmore">
View Details
</a></td>
thanks!
You would need to handle the OnItemDataBound event, and then change the visibility of the control. An example of this is shown below:
ASPX Page
<asp:Repeater ID="MyRepeater" OnItemDataBound="MyRepeater_OnItemDataBound" runat="server">
<ItemTemplate>
<asp:Label ID="RegularPriceLabel" runat="server" />
<br/>
<asp:Label ID="BuyNowPriceLabel" runat="server" />
</ItemTemplate>
</asp:Repeater>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
MyRepeater.DataSource = GetDataSource();
MyRepeater.DataBind();
}
}
protected void MyRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// This will be your data object
MyEntity o = (MyEntity) e.Item.DataItem;
// Get the labels
Label RegularPriceLabel = (Label) e.Item.FindControl("RegularPriceLabel");
Label BuyNowPriceLabel = (Label) e.Item.FindControl("BuyNowPriceLabel");
// Only show regular price if it is set
RegularPriceLabel.Visible = (o.RegularPrice > 0);
// Populate labels
RegularPriceLabel.Text = o.RegularPrice.ToString();
BuyNowPriceLabel.Text = o.BuyNowPrice.ToString();
}
}
I would take a look at the ItemDataBound event of the Repeater. It will fire for every item in the repeater and allow you to do any code-behind (like hiding labels) more easily.
Edit: For your specific example, since you are formatting the price as well, it may be easier to just call a custom method to to render the price, like so:
ASPX:
<%#RenderPrice((decimal)Eval("lb_sellingprice"))%>
Method:
protected string RenderPrice(decimal price) {
if (price > 0) {
return "Price: $" + decimal.Round(price);
} else {
return string.Empty;
}
}
It's quick-and-dirty but it works.