From a listview control, when checkboxes are checked and a button is clicked from outside the listview, I need to be able to delete the items that have been checked. Here's the listview:
EDIT
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack) return;
var notes = (from n in db.Notes
select n).OrderBy(n => n.FiscalYear).ThenBy(n => n.Period);
notesListView.DataSource = notes;
notesListView.DataBind();
}
<asp:ListView ID="notesListView" ItemPlaceholderID="itemPlaceholder" runat="server">
<LayoutTemplate>
<div>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
<asp:CheckBox ID="checkNote" runat="server" />
<div><%# Eval("Period") %></div>
<div><%# Eval("FiscalYear") %></div>
<div><%# Eval("Account") %></div>
<div class="wrap"><%# Eval("Description") %></div>
</ItemTemplate>
<EmptyDataTemplate>
<div>No notes have been submitted.</div>
</EmptyDataTemplate>
</asp:ListView>
<br />
<asp:Button ID="deleteNotes" CssClass="deleteButton" Text="Delete Notes" runat="server" OnClick="deleteNotes_Click" />
Here's the code behind:
protected void deleteNotes_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in notesListView.Items)
{
// I know this is wrong, just not sure what to do
if (notesListView.SelectedIndex >= 0)
{
CheckBox ck = (CheckBox)item.FindControl("checkNote");
if (ck.Checked)
{
var index = item.DataItemIndex; // the item row selected by the checkbox
// db is the datacontext
db.Notes.DeleteOnSubmit(index);
db.SubmitChanges();
}
}
else
{
errorMessage.Text = "* Error: Nothing was deleted.";
}
}
}
You need to find the object before deleting it. To do so, I would add a hiddenfield to store NoteID like this:
<asp:HiddenField ID="hdnId" Value='<%#Eval("Id")%>' runat="server" />
<asp:CheckBox ID="checkNote" runat="server" />
... ... ...
And in my code I am finding the note by ID and deleting that note (You may use any other unique field instead of ID). My code may look like this:
... ... ...
int id = 0;
var hdnId = item.FindControl("hdnId") as HiddenField;
CheckBox ck = (CheckBox)item.FindControl("checkNote");
//I would check null for ck
if (ck != null && ck.Checked && hdnId != null && int.TryParse(hdnId.Value, out id)
{
// db is the datacontext
Note note = db.Notes.Single( c => c.Id== id );
db.Notes.DeleteOnSubmit(note );
db.SubmitChanges();
}
Related
I have a repeater using for getting an image nad a radio button on the bottom. I want to achieve a combination of this radio button (repeater speaking) with the property of autoexcluyent feature. How can I achieve it?
As far as I got ...
<asp:Repeater runat="server" ID="repeater1">
<ItemTemplate>
<div class="col-xs-12 col-sm-4 col-md-3">
<asp:Image ID="img" runat="server" ImageUrl="<%#GetRutaImagen(Eval("id").ToString())%>" />
<span>
<asp:RadioButton runat="server" ID="rb1" Text='<%#Eval("description").ToString()%>' GroupName="nameGroup"/>
</span>
</div>
</ItemTemplate>
</asp:Repeater>
With this code I am getting a one radio button per each image but no one autoexcuyent even I am using GroupName property
USING NET FRAMEWORK 4.6.2.
I don't know if easy way to manage this situation however you can manage by below code. It will be good to wrap your contents into update panel so you can prevent page refresh on checkbox changed.
Additionally, IsChecked property being used to initialize checked on page load. You can remove if not required.
.ASPX
<asp:Repeater runat="server" ID="repeater1">
<ItemTemplate>
<div class="col-xs-12 col-sm-4 col-md-3">
<span>
<asp:RadioButton runat="server" ID="rb1" Checked='<%# Eval("IsChecked") %>' AutoPostBack="true" OnCheckedChanged="rb1_CheckedChanged" Text='<%#Eval("description").ToString()%>' />
</span>
</div>
</ItemTemplate>
</asp:Repeater>
.CS
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<test1> lst = new List<test1>();
lst.Add(new test1() { Id = 1, description = "R1", IsChecked = false });
lst.Add(new test1() { Id = 3, description = "R2", IsChecked = true });
lst.Add(new test1() { Id = 2, description = "R3", IsChecked = false });
lst.Add(new test1() { Id = 4, description = "R4", IsChecked = false });
repeater1.DataSource = lst;
repeater1.DataBind();
}
}
protected void rb1_CheckedChanged(object sender, EventArgs e)
{
foreach (RepeaterItem item in repeater1.Items)
{
(item.FindControl("rb1") as RadioButton).Checked = false;
}
(sender as RadioButton).Checked = true;
}
After researching between SOF and a few forums I implemented a quite right solution using JS. I am handling another problem related with OnCheckedChanged´s event on RadioButton...
But the initial issue is fixed.
Forum Solution
I am posting the solution that works for me, using as base as a help coming from a forum, hoping it helps others as well with this bug.
REPEATER.
<asp:Repeater runat="server" ID="repeater1" OnItemDataBound="repeater1_ItemDataBound">
<ItemTemplate>
<div class="col-xs-12 col-sm-4 col-md-3">
<asp:Image ID="img" runat="server" ImageUrl="<%#GetRutaImagen(Eval("id").ToString())%>" />
<span>
<asp:RadioButton runat="server" ID="rb1" Text='<%#Eval("description").ToString()%>' GroupName="nameGroup" OnCheckedChanged="rb1_CheckedChanged"/>
</span>
</div>
</ItemTemplate>
</asp:Repeater>
JS
<script>
function SetUniqueRadioButton(nameregex, current) {
for (i = 0; i < document.forms[0].elements.length; i++) {
elm = document.forms[0].elements[i]
if (elm.type == 'radio') {
elm.checked = false;
}
}
current.checked = true;
}
</script>
BACKEND
protected void repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
try
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
RadioButton rbLogoSeleccionado = (RadioButton)e.Item.FindControl("rb1");
string script = "SetUniqueRadioButton('repeater1.*nameGroup',this)";
rbLogoSeleccionado.Attributes.Add("onclick", script);
}
}
catch (Exception ex)
{
PIPEvo.Log.Log.RegistrarError(ex);
throw;
}
}
Here is my part of Shop.aspx code:
<% foreach(var item in items){ %>
...
<asp:Button id="btnBuy" runat="server" class="btn" Text="Buy" OnClick ="btnBuy_Click" CommandArgument='<%#Eval("item.id") %>' />
<% } %>
I've got a loop where I create few buttons to my shopping items, and I need them to have id of my item
protected void btnBuy_Click(object sender, EventArgs e)
{
int itemId = Convert.ToInt32(btnBuy.CommandArgument);
}
On click i need to have id of the item/button clicked, to save them later in my database.
Problem -
When i click on button btnbuy.CommandArgument is "".
It's wrong: you wrote c#in asp style. You have to use a Repeater and then you can manage ItemCommand for every button click.
Aspx
<asp:Repeater ID="myRepeater" runat="server" OnItemCommand="myRepeater_ItemCommand">
<ItemTemplate>
<asp:Label id="myLbl" runat="server" Text='<%# ((Item)(Container.DataItem)).ProductName %>'/>
<asp:Button id="btnBuy" runat="server" CssClass="btn" Text="Buy" CommandName="Click" CommandArgument='<%# ((Item)(Container.DataItem)).ProductId %>' />
</ItemTemplate>
</asp:Repeater>
c# (eg. OnLoad)
List<Item> myCollection = ...; // get list of items
myRepeater.DataSource = myCollection;
myRepeater.DataBind();
...
protected void myRepeater_ItemCommand(Object sender, RepeaterCommandEventArgs e)
{
if(e.CommandName == "Click")
{
int idRecord = Convert.ToInt32(e.CommandArgument);
// do something using idRecord or
// get sender properties: ((Button)e.CommandSource).Text
}
}
I am using listview in Update panel. When i try to delete its deleting record from datatable but listview not updating. Bellow my button code inside in listview:
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:ListView ID="lvSelectedVoucher" OnItemCommand="lvSelectedVoucher_OnItemCommand" OnLayoutCreated="lvSelectedVoucher_LayoutCreated" runat="server">
<LayoutTemplate>
<ItemTemplate>
<tr class="odd">
<td class="text-left" colspan="2">
<div id="mvRemoveSelectedId1" class="mv-action" title="Remove item" onclick="removeVoucher">
<asp:ImageButton class="ui-icon ui-icon-close" ID="imgDelete" OnClientClick="return confirm('Are you sure you want to delete this Voucher?')"
runat="server" CommandArgument='<%# Container.DataItemIndex +1%>' CommandName="Delete" />
</div>
<asp:Literal ID="ltlMerchant" Text='<%# Eval("MerchantName") %>' runat="server" ></asp:Literal>
</td>
My server side code bellow:
protected void lvSelectedVoucher_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
int index = Convert.ToInt32(e.CommandArgument);
int listcount = lvSelectedVoucher.Items.Count;
if (listcount - 1 == index)
{
DataTable curTable = (DataTable)ViewState["SelectedVoucher"];
curTable.Rows[index].Delete();
ViewState.Add("SelectedVoucher", curTable);
lvSelectedVoucher.DataSource = null;
lvSelectedVoucher.DataSource = curTable;
lvSelectedVoucher.DataBind();
UpdatePanel1.Update();
}
}
}
How can I refresh my listview after delete one record ? Thanks in advance.
Something seems logically incorrect here.
Are you always deleting the last Item of ListView ? you are comparing the Index of item to be deleted with the last item actually in the two lines :
int listcount = lvSelectedVoucher.Items.Count;
if (listcount - 1 == index)
Everything else seems fine, So, did you tried deleting the Last Item of List view and see if it refreshes ?
I have using my inside ItemDeleting event & ListView refreshing properly
protected void lvSelectedVoucher_ItemDeleting(object sender, ListViewDeleteEventArgs e)
{
if (e.CommandName == "Delete")
{
int index = Convert.ToInt32(e.CommandArgument);
int listcount = lvSelectedVoucher.Items.Count;
if (listcount == index+1)
{
DataTable curTable = (DataTable)ViewState["SelectedVoucher"];
curTable.Rows[index].Delete();
ViewState.Add("SelectedVoucher", curTable);
lvSelectedVoucher.DataSource = null;
lvSelectedVoucher.DataSource = curTable;
lvSelectedVoucher.DataBind();
UpdatePanel1.Update();
}
}
I am trying to find the formview inside my listview on the page load. However, my result is always null. I called the DataBind method first but still nothing.
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
String list = itemdropdownlist.SelectedValue;
switch (list)
{
case "Section Item":
SectionListView.DataBind();
//SectionListView.Enabled = false;
var temp = (FormView)SectionListView.FindControl("SectionFormView");
temp.Enabled = true;
renderView(SectionListView, "hidden"); // hide listview on page load
break;
}
}
ASP.net code
<InsertItemTemplate>
<tr style="">
<td>
<div style="font-size: .8em;">
<asp:FormView ID="SectionFormView" runat="server" DataKeyNames="SectionItemID" DataSourceID="SectionDataSource">
<ItemTemplate>
<asp:Button ID="InsertButton" runat="server" Text="Insert" OnClick="SectionItemButton_Click" Font-Size="1.2em" />
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Clear" Font-Size="1.2em" />
<asp:Label ID="SectionItemLabel" runat="server" Text="SectionItem" Font-Bold="true" Font-Size="1.2em" />
<asp:TextBox ID="SectionItemTextBox" runat="server" />
<asp:Label ID="SectionItemSubLabel" runat="server" Text="SectionItem Label" Font-Bold="true" Font-Size="1.2em" />
<asp:TextBox ID="SectionItemLabelTextBox" runat="server" />
</ItemTemplate>
</asp:FormView>
</div>
</td>
</tr>
</InsertItemTemplate>
<ItemTemplate>
You got that error, because the listview was not binded yet, so i think the best way would be to do all this on the ItemDataBound event. You would find the FormView like:
if (e.Item.ItemType == ListViewItemType.DataItem)
{
FormView SFormView= (FormView)e.Item.FindControl("SectionFormView");
if (SFormView!= null)
{
//code here
}
}
You could use this code to find about anything. I used it before to find Literals that I created in code behind. Use this code to find your FormView
private readonly List<FormView> _foundControls = new List<FormView>();
public IEnumerable<FormView> FoundControls
{
get { return _foundControls; }
}
public void FindChildControlsRecursive(Control control)
{
foreach (Control childControl in control.Controls)
{
if (childControl.GetType() == typeof(FormView))
{
_foundControls.Add((FormView)childControl);
}
else
{
FindChildControlsRecursive(childControl);
}
}
}
FindChildControlsRecursive(<Insert relevent Code Here: Whatever element you want to search inside of like your listView, find that using FindControl>);
FormView[] strControl = new FormView[200];
strControl = FoundControls.ToArray();
foreach (FormView i in strControl)
{
if (i.ID.Equals("< insert controlId of your FormView>"))
{
// do something when you find it
}
}
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.