I have a repeater on my webforms page, with a list bounded to it. while binding the list, I also attach a data-id attribute to the tr. The problem is I need to use that id in a web service call from jQuery, I am testing whether I can get the id by logging the data-id attribute value when I click on a button from the repeater item, but from the looks of things, it only logs the Item and not the Alternating item.
Button one, three and five gets log every time I click them but when I click on button two and button four, nothing gets logged in the console. See code below.
Repeater Template
<asp:Repeater runat="server" ID="rptList" OnItemDataBound="rptList_OnItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr runat="server" id="trList">
<td runat="server" id="tdList"></td>
<td runat="server" id="tdBtnRemove">
<asp:Button runat="server" ID="btnRemove" CssClass="btnRemove" Text="Remove" OnClientClick="return false;"/></td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr runat="server" id="trList">
<td runat="server" id="tdList"></td>
<td runat="server" id="tdBtnRemove">
<asp:Button runat="server" ID="btnRemove" Text="Remove" OnClientClick="return false;"/></td>
</tr>
</AlternatingItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
List item
List<string> listObj = new List<string>(){"one", "two", "three", "four", "five"};
protected void rptList_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
string listItem = (string) e.Item.DataItem;
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
HtmlTableRow trList = (HtmlTableRow)e.Item.FindControl("trList");
trList.Attributes.Add("data-id", listItem);
HtmlTableCell tdList = (HtmlTableCell)e.Item.FindControl("tdList");
tdList.InnerHtml = listItem;
}
}
jQuery button click method:
$(".btnRemove").click(function () {
var dataAttributVal = $(this).closest("tr");
var datA = dataAttributVal.data('id');
console.log(datA);
});
Console result:
As stated in the comments, your AlternatingItemTemplate misses the CssClass="btnRemove" attribute.
For this reason your $(".btnRemove").click(... binding does not target the buttons in your AlternatingItemTemplate
Related
I have a button in a ListView that when its click it opens a modal with information relevant to the button that was clicked. I was able to get the index of the current listview item but I need to get the text from a label in both the previous item and next item. Heres what I have:
protected void List_ItemCommand(object sender, ListViewCommandEventArgs e)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
//Gets index of Listview
int DispalyIndex = e.Item.DisplayIndex;
int ItemIndex = e.Item.DataItemIndex;
Button index = (Button)dataItem.FindControl("TitleButton");
Label Name = (Label)dataItem.FindControl("LabelName");
}
I tried decrementing the index but no luck, anyone have an idea or a better solution? Thanks.
UPDATE
Heres my listviews, I use the first Listview to get the title and then the second to pull Jobs under the title. I bind both with a query using data bind
<asp:ListView ID="List" runat="server" OnItemCommand="List_ItemCommand" OnItemDataBound="List_ItemDataBound">
<LayoutTemplate>
<table>
<tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<span class="label label-primary"><%# Eval("LabelName")%></span> <br />
<asp:ListView ID="JobList" runat="server" ItemPlaceholderID="JobPlaceHolder" OnItemDataBound="JobList_ItemDataBound">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="JobPlaceHolder" />
</LayoutTemplate>
<ItemTemplate>
<br />
<asp:Button runat="server" ID="TitleButton" Text='<%# Eval("Job Title") %>' Font-Size="XX-Small" Font-Bold="true" CssClass="btn-xs btn-default" ClientIDMode="Static" OnClick="TitleButton_Click" />
</ItemTemplate>
<EmptyDataTemplate>
<br />
<b> <asp:Label runat="server" Text="There is no job for this Family and Level!" /></b>
</EmptyDataTemplate>
Try this
//null check before performing an operation, dataItem might be the first element in the page
//If so, prevItem will be null
var prevItem = List.Items[itemIndex - 1].FindControl("LabelName") as Label;
//null check before performing an operation, dataItem might be the last element in the page
//If so, nextItem will be null
var lastItem = List.Items[itemIndex + 1].FindControl("LabelName") as Label;
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'd like to have the user click the select button of, lets say, the 250th row of a 400 row gridview. When they click that, then another gridview that's 3x12 appears below that row, then the 150 other rows appear below that. Is this at all possible? I guess I could create a whole other div that'll have three gridviews that output depending on being <= and > the index of the selected row.
It starts as:
Gridview rows 1-400
Then after row 350 is selected is it:
Gridview rows 1-350
Gridview of row 350 info
Gridview rows 351-400.
It's definitely possible, but I would use a ListView or DataList as your parent container instead, because with a GridView, you'll have to put the child list in a column, which will look ugly. This should put you on the right path:
<asp:ListView ID="lstOuterList" runat="server" DataKeyNames="ID, OtherColumn">
<LayoutTemplate>
<table width="100%">
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton ID="LinkButton1" runat="server" Text="Expand" OnCommand="LinkButton1_Command" CommandArgument='<%#Container.DisplayItemIndex%>'></asp:LinkButton></td>
<td><%#Eval("Value")%></td>
<td><%#Eval("OtherValue")%></td>
<td><%#Eval("OtherOtherValue")%></td>
</tr>
<asp:PlaceHolder ID="plcInnerList" runat="server">
<asp:ListView ID="lstInnerList" runat="server" Width="100%">
<LayoutTemplate>
<tr>
<td colspan="4">
<div style="padding:20px;background-color:#fffeee;">
<table width="100%">
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
</table>
</div>
</td>
</tr>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#Eval("Value")%></td>
<td><%#Eval("OtherValue")%></td>
<td><%#Eval("OtherOtherValue")%></td>
</tr>
</ItemTemplate>
</asp:ListView>
</asp:PlaceHolder>
</ItemTemplate>
</asp:ListView>
And when the user clicks the LinkButton/Button in DataList1, do something like this:
protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
//pass index of item in command argument
var itemIndex = Convert.ToInt32(e.CommandArgument);
//find the pnlChildView control
var innerPlaceHolder = lstOuterList.Items[itemIndex].FindControl("plcInnerList") as PlaceHolder;
if (innerPlaceHolder != null)
{
innerPlaceHolder.Visible = !innerPlaceHolder.Visible;
if (innerPlaceholder.Visible)
{
var innerList = innerPlaceHolder.FindControl("lstInnerList") as ListView;
if (innerList != null)
{
//the id to retrieve data for the inner list
int keyValue = (int)lstOuterList.DataKeys[itemIndex]["ID"];
//bind the list using DataList1 data key value
innerList.DataSource = new DataTable("DataSource"); //your datasource
innerList.DataBind();
}
}
}
}
one way is:
on the rowcommand of the main grid:
create c# code for the grid will be inside GridView grd = new GridView();
bind this instance like any other grid
add on the controls from the main grid current line, should be something like
e.Cells[0].Controls.Add(grd);
I don't have VS here right now but I guess you could get the idea, I use this approach all the time
I have a form with containing a datalist which is bound to a datasource which contains a list of items and a true/false flag. If true, the myCheck checkbox is checked:
<form id="myForm" runat="server">
<asp:Button ID="save" runat="server" Text="Save" OnClick="save_Click" />
<br />
<asp:DataList runat="server" id="myList" onitemdatabound="myList_ItemDataBound">
<HeaderTemplate>
<th>Item Name</th>
<th id="thCheck" runat="server">Check?</th>
</HeaderTemplate>
<ItemTemplate>
<td id="tdName" runat="server"><%# Eval("Name") %></td>
<td runat="server"><asp:CheckBox id="myCheck" runat="server" Checked="false" /></td>
</ItemTemplate>
</asp:DataList>
On clicking save, I want to see which items have been checked. I am using the following to iterate through the items in the datalist:
protected void save_Click(Object sender, EventArgs e)
{
String Name;
Boolean omit;
foreach (DataListItem item in myList.Items)
{
CheckBox omitCheck = (CheckBox)item.FindControl("myCheck");
if (omitCheck != null)
{
if (omitCheck.Checked == true) // This line is my problem!!
{
// do stuff
}
break;
}
}
FindControl appears to work ok and returns a checkbox, however the value is always false, even if I have checked some of the boxes. If I set the value of the checkboxes to True in the aspx page, omitCheck.Checked is always true. ViewState is not disabled.
I'm new to this so sure there is an obvious answer.
what does the myList_ItemDataBound function look like? I suspect it needs a !IsPostback to not override entered values on the postback
I am building a website whereby people, before checking out of the shopping cart (and transferring to the payment iframe) can select which items from the shopping cart list to delete. The results from the shopping card are listed in a Repeater control. There is a Button in the Repeater which deletes a record from the database (used LINQ to SQL to do that.)
The problem is that the ItemCommand event doesn't fire when i click the button. I tried response.write(test) and it still would not work.
It is as if the repeater cannot interact with the commands. It does render the results though.
<asp:Repeater ID="RepeaterKoshnichka"
runat="server" OnItemCommand="RepeaterKoshnichka_ItemCommand"
DataSourceID="LinqDataSource1">
<ItemTemplate>
<tr>
<td background="images/message-bar.gif">
<div class="message_head" style="float:left"><cite>Производ: <asp:Label ID="lblProizvod" CssClass="red_tx" Text='<%# Eval("Proizvod") %>' runat="server"></asp:Label> / Тип на Претплата: <asp:Label ID="lblPretplata" runat="server" Text='<%# Eval("Tip") %>' CssClass="red_tx"></asp:Label></cite></div>
<div class="message_head" style="float:right"><cite>Цена: <asp:Label ID="lblCena" CssClass="red_tx" Text='<%# Eval("Cena") %>' runat="server"></asp:Label>
<asp:Button ID="Button2" CssClass="main_tx" CommandName="Delete" CommandArgument='<%# Eval("NDetID") %>' runat="server" Text="Отстрани" /></cite>
</div>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
protected void RepeaterKoshnichka_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
if (Request.Form[e.CommandArgument.ToString()] != null)
{
if (Page.User.Identity.IsAuthenticated)
{
var nar = new DataClasses1DataContext();
Guid detnar = new Guid(e.CommandArgument.ToString());
var query = from c in nar.Naracka_Dets
where c.NDetID == detnar
select c;
foreach (var c in query)
{
nar.Naracka_Dets.DeleteOnSubmit(c);
}
nar.SubmitChanges();
lblSuma.Text = ((Button)e.CommandSource).ToString();
}
}
}
}
Likely an <asp:GridView> would be a better server control for what you're working on.
As an aside, consider making a small change to your code. To help make it more readable, combine your 3 conditions into one if:
if (e.CommandName == "Delete" &&
Request.Form[e.CommandArgument.ToString()] != null &&
Page.User.Identity.IsAuthenticated)
{
//delete things.
}
If you are not tied to using a Repeater you should switch to DataGrid and use a ButtonColumn for this feature - it will make life easier for you handling Item events.