I am using a DataGrid to display data retrieved from a database and I was wondering if it is possible to raise the grid's ItemCommand event using Javascript.
The snippet below shows roughly what I am trying to do within onclick handler for the DIV removeProductButton. I don't want to use asp:Button or asp:LinkButton as currently the look and feel of the DIV is controlled using CSS and the code should work regardless of the type HTML element used to create the click-able trigger to allow for future look and feel customisations.
<asp:datagrid id="itemGrid" runat="server" cellPadding="0" AutoGenerateColumns="False" GridLines="None">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<div class="items">
<div class="product_title"><%#Eval("ItemID")%>. <%#Eval("ItemDescription")%></div>
<div class="product_image">
<img id="productImage_<%#Eval("ItemID")%>" src="<%#Eval("ThumbnailURL")%>" />
</div>
<div class="buttons">
<div id="removeProductButton" class="buttonStandard" onclick="Do Something HERE...">Remove</div>
</div>
</div>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:datagrid>
I have tried using the following code in the grid's ItemCreated event but was not able to get it working
private void itemGrid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
dynamic itemData = e.Item.DataItem;
HtmlGenericControl removeProductButton = (HtmlGenericControl)e.Item.FindControl("removeProductButton");
removeProductButton.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(removeProductButton, ""));
}
}
Any help would be greatly appreciated.
Add a hidden button to the ItemTemplate with your desired CommandName:
<asp:Button
ID="removeProductButton_hidden"
runat="server"
style="display:none;"
CommandName="YourCommandName"
Text="" />
Make sure that your 'Remove' div has the runat="server" attribute:
<div ID="removeProductButton" runat="server" class="buttonStandard">Remove</div>
Get rid of the grid ItemCreated handler and create a grid ItemDataBound handler that looks like this:
public void grd_ItemDataBound(object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
HtmlGenericControl removeProductButton = (HtmlGenericControl)e.Item.FindControl("removeProductButton");
Button removeProductButtonHidden = (Button)e.Item.FindControl("removeProductButton_hidden");
removeProductButton.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(removeProductButtonHidden, ""));
}
}
So the entire grid definition would look like this:
<asp:DataGrid
runat="server"
ID="itemGrid"
OnItemCommand="itemGrid_ItemCommand"
OnItemDataBound="itemGrid_ItemDataBound">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Button
ID="removeProductButton_hidden"
runat="server"
style="display:none;"
CommandName="YourCommandName"
Text="" />
<div class="items">
<div class="buttons">
<div ID="removeProductButton" runat="server" class="buttonStandard">Remove</div>
</div>
</div>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Related
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="EntityDataSourceTeklifler">
<ItemTemplate>
<div class="panel panel-primary">
<div class="panel-body">
<strong>Teklif Kodu:</strong> <%#Eval("TeklifId") %><br />
<strong>Teklif Tarihi:</strong> <%#Eval("TeklifTarih") %><br />
<strong>Teklifi Hazırlayan:</strong> <%#Eval("Name") %> <%#Eval("Surname") %><br />
<strong>Firma Adı:</strong> <%#Eval("FirmaAdi") %><br />
<strong>Sipariş:</strong> <%#Eval("FUrunId") %><br />
<strong>Teklif Tutarı:</strong> <%#Eval("TeklifTutar") %><br />
</div>
</div>
</ItemTemplate>
</asp:Repeater>
As you can see I have a Repeater and it displays my data without a problem. I need to access TeklifIds in code-behind. I am going to make something like:
if(TeklifId == 1)
{
//do something
}
else if(TeklifId == 2)
{
//do something else
}
And to do this, I need to get all TeklifId while it is adding to the Repeater.
Ideally you should include the data withing some ASP.NET controls like Label, Textbox control within ItemTemplate tag because it is easy to work with them. But I am not sure why you are adding the normal html tags directly.
Anyways, to find the value you will have to find it within the ItemDataBound control of repeater control but for that you will have to make the strong tag a server control by adding runat="server" attrribute like this:-
<strong id="TeklifId" runat="server">Teklif Kodu:</strong> <%#Eval("TeklifId") %>
Then, add the ItemDataBound event in your repeatre control like this:-
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand"
Finally in the code behind you can find the value like this:-
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem ||
e.Item.ItemType == ListItemType.Item)
{
HtmlGenericControl TeklifId = e.Item.FindControl("TeklifId") as HtmlGenericControl;
string TeklifId = TeklifId.InnerText; //value here
}
}
Place TeklifId in a Label control so that you can use ID and FindControl to get the values like this:
<asp:Label ID="TeklifId" runat="server" Text='<%#Eval("TeklifId") %>'></asp:Label>
And then:
foreach (RepeaterItem item in Repeater1.Items)
{
var TeklifId = (Label)item.FindControl("TeklifId");
if (TeklifId == 1)
{
//do something
}
}
Repeater Code :
<td>
<span runat="server" id="lbBranchname" style="font-style:italic;"><%# Eval("branchname")%></span>
</td>
Code behind : rptBranch_ItemCommand
HtmlGenericControl lbBranchname = e.Item.FindControl("lbBranchname") as HtmlGenericControl;
BranchName = lbBranchname.InnerText;
I am creating a data list that will have multiple person records displayed inside a collapsible panel and iside each dataItem user can edit the record etc.
Following is my code
<%# Register TagName="CreateEditPerson" Src="~/ascx/create_edit_person.ascx" TagPrefix="WD" %>
<asp:DataList ID="dlPerson" runat="server" OnItemDataBound="dlPerson_OnItemDataBound">
<ItemTemplate>
<div class="personRow">
<div class="personRowHeader" id="divEditPerson">
<div class="lastNameColumn">
<asp:Label ID="lblLastName" runat="server"></asp:Label </div>
<div class="firstNameColumn">
<asp:Label ID="lblFirstName" runat="server"></asp:Label>
</div>
<div class="editColumn">
<asp:Image ID="imgExpandImage" runat="server" Class="divSearchLabel" meta:resourcekey="imgExpandImage" />
<asp:Label ID="lblEditPerson" runat="server" meta:resourcekey="lblEditPerson"></asp:Label>
</div>
<div style="clear: both">
</div>
</div>
<ajaxToolkit:CollapsiblePanelExtender ID="cpPerson" runat="server" meta:resourcekey="cpPerson"
Collapsed="true" TargetControlID="pnlpersonEdit" CollapseControlID="divEditPerson"
ExpandControlID="divEditPerson" TextLabelID="lblEditPerson" CollapsedSize="0"
ScrollContents="false" SuppressPostBack="True" ImageControlID="imgExpandImage">
</ajaxToolkit:CollapsiblePanelExtender>
<asp:Panel ID="pnlpersonEdit" runat="server">
<div class="product_technical_details">
<WD:CreateEditPerson ID="createEditPerson1" runat="server" />
</div>
</asp:Panel>
</div>
</ItemTemplate>
</asp:DataList>
My Problem is,
1. When I click on 1st dataitem panel, All the panels expands. Do i need the dynamic id of the TargetControlID ?
I solved it as follows:
on ItemDataBound event of the datalist, I just set dynamic ID of the collapsible panel, target panel and collaped/expand control; and set the "TargetControlID", "CollapseControlId" and "ExpandControlId"
I am giving the code snippet here:
protected void dlPerson_OnItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
//Find the controls in the Item Template
Panel pnlPersonEdit = e.Item.FindControlRecursive("pnlPersonEdit") as Panel;
CollapsiblePanelExtender cpPersonEdit =
e.Item.FindControlRecursive("cpPersonEdit") as CollapsiblePanelExtender;
//This panel was a div previously "divEditPerson" I have changed it to panel
Panel pnlEditPersonHead = e.Item.FindControlRecursive("pnlEditPersonHead") as Panel;
//Some object from db
PersonObject personObject = e.Item.DataItem as PersonObject;
//Set Id of the collapsed/expanded panel from unique key
pnlEditPersonHead.ID += personObject.CrmddressId.ToString();
//Set Id of the target panel from unique key
pnlPersonEdit.ID += personObject.CrmddressId.ToString();
//simillarly set Id of the collapsible panel extender
cpPersonEdit.ID += personObject.CrmddressId.ToString();
//Now set the TargetControlID, CollapseControlID and ExpandControlID
cpPersonEdit.TargetControlID = pnlPersonEdit.ID;
cpPersonEdit.CollapseControlID = pnlEditPersonHead.ID;
cpPersonEdit.ExpandControlID = pnlEditPersonHead.ID;
}
}
Binding data to checkbox list inside a repeater controls ItemDataBound event.
Here is Aspx code:
<asp:Repeater ID="rptrSelectedRcds" runat="server">
<ItemTemplate>
<div id="groupsDiv" runat="server">
<div class="hidden" id="divGroupSelector" runat="server">
<asp:CheckBoxList runat="server" ID="chkLstGroups"
RepeatDirection="Vertical">
</asp:CheckBoxList>
</div>
<asp:Button ID="btnConfirmGroups" runat="server" Text="Confirm" />
</div>
</ItemTemplate>
</asp:Repeater>
Code used inside ItemDataBound to bind data to repeater control:
protected void rptrSelectedRcds_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
Int32 iProviderID = Convert.ToInt32(((Label)e.Item.FindControl("lblIndividualID")).Text);
HtmlGenericControl selectGroupsDiv = (HtmlGenericControl)e.Item.FindControl("divGroupSelector");
if (divGroupSelector != null)
{
CheckBoxList chkLstGroups = (CheckBoxList)e.Item.FindControl("chkLstGroups");
chkLstGroups.DataSource = GetStateGroupsByProvider(stateValue, iProviderID);
//This code line gives different values for each record
chkLstGroups.DataTextField = "Name";
chkLstGroups.DataValueField = "pkID";
chkLstGroups.DataBind();
}
}
I can see in firebug the ids for chkLstGroups are different, but values bind to it are same.I want different values for each different checkbox id generated as from method - GetStateGroupsByProvider
Please help me out..!
Thanks.!
I have a repeater control as listed below. It has a textbox control. When a save button is clicked, I need to get the updated text from the textbox. I have the following code; but it gives me the old value when I take the textbox text.
How can we get the updated text?
Code Behind
protected void Save_Click(object sender, EventArgs e)
{
foreach (RepeaterItem item in repReports.Items )
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem )
{
string updatedEmail = ((TextBox)item.Controls[5]).Text;
string originalEmail = ((HiddenField)item.Controls[7]).Value;
}
}
}
Control Markup
<div class="repeaterTableBorder">
<asp:Repeater ID="repReports" runat="server">
<ItemTemplate>
<div id="repeaterIdentifier" class="repeaterIdentifier">
<div class="reportTitle">
<%# Eval("ReportName") + ":"%>
<asp:HiddenField ID="hdnLastChangeTime" runat="server" Value= '<%# ((DateTime)Eval("RecordSelectionTime")).ToString("MM/dd/yyyy hh:mm:ss.fff tt")%>' />
<asp:HiddenField ID="hdnReportID" runat="server" Value='<%# Eval("ReportTypeCode")%>' />
</div>
<div class="reportFrequency">
<%# " Frequency - Weekly" %>
</div>
</div>
<div class="reportContent">
<div class="repeaterLine">
<asp:TextBox ID="txtEmailRecipients" runat="server" class="textEdit"
Text='<%# Eval("ExistingRecipients") %>'
TextMode="MultiLine"></asp:TextBox>
<asp:HiddenField ID="hdnOriginalRecipients" runat="server" Value='<%# Eval("ExistingRecipients")%>' />
</div>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
I assume that you are binding the Repeater to it's DataSource also on postbacks. You should do that only if(!IsPostBack). Otherwise the values will be overwritten.
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
// databinding code here
}
}
For example in the backend I'm binding a datable to a repeater and in the front end I'm setting up my repeater as such:
<asp:Repeater ID="Repeater1" runat="server" onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<div class="user">
Name: <%# DataBinder.Eval(Container, "DataItem.Name")%>
Email: <%# DataBinder.Eval(Container, "DataItem.Email")%>
Active: <%# DataBinder.Eval(Container, "DataItem.Active")%>
Status: <%# DataBinder.Eval(Container, "DataItem.Status")%>
</div>
</ItemTemplate>
</asp:Repeater>
So the output for "name" and "email" are fine. However "Active" and "Status" print out an integer code that I would like to change to a more descriptive string based on a reference table I have.
I'm guessing I can do this on the "ItemDataBound" event of the repeater, but I'm stuck on what my next step should be, namely checking the two fields that I need to modify and change them.
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
//Do modifications here
}
}
You can either
Handle the formatting in the ItemDataBound event
Create public methods in your Page or WebUserControl class to handle the formatting.
Using option 1 will require you to declare a control such as a label to store the value for each field like so:
<asp:Repeater ID="Repeater1" runat="server" onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<div class="user">
<asp:Label ID="ActiveLabel" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Name")%>'></asp:Label>
</div>
</ItemTemplate>
</asp:Repeater>
Then in your ItemDataBound event you can find the control and set its value as required.
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Label activeLabel = (Label)e.Item.FindControl("ActiveLabel");
//Format label text as required
}
}
Using option 2 will require you to create a server side publicly accessible method which you can call like so:
<asp:Repeater ID="Repeater1" runat="server" onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<div class="user">
Active: <%# FormatActive((string)DataBinder.Eval(Container, "DataItem.Active")) %>
</div>
</ItemTemplate>
</asp:Repeater>
Then define a method like so:
public string FormatActive(string input)
{
//Format as required
//Return formatted string
}
I prefer creating format methods called in the markup rather than handling ItemDataBound.
<asp:Repeater ID="Repeater1" runat="server" onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<div class="user">
Name: <%# DataBinder.Eval(Container, "DataItem.Name")%>
Email: <%# DataBinder.Eval(Container, "DataItem.Email")%>
Active: <%# FormatActive((int)DataBinder.Eval(Container, "DataItem.Active"))%>
Status: <%# FormatStatus((int)DataBinder.Eval(Container, "DataItem.Status"))%>
</div>
</ItemTemplate>
</asp:Repeater>
Then in your code behind:
protected static FormatActive(int active)
{
return "Formated Active String...";
}
protected static FormatStatus(int status)
{
return "Formated StatusString...";
}
<asp:Repeater ID="Repeater1" runat="server" onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<div class="user">
Active: <asp:label id="lblActive" Text='<%# DataBinder.Eval(Container, "DataItem.Active")%>' runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
//Do modifications here
YourObjectName person = (YourObjectName)e.Item.DataItem;
//you can now ref the object this row is bound to
//example find a dom element
Label lblActive= (Label)e.Item.FindControl("lblActive");
if(person.Active == 2)
{
lblActive.Text = "This is great";
}
}
}
You could do something like:
<%# (int)DataBinder.Eval(Container, "DataItem.Active") == 0 ? "Active" : "Inactive" %>
no need to use the itemdatabound. Just add a method in your itemtemplate to do the conversion with the dataitem.active as parameter. Add a label and do the following:
Text='<%# String.Format("{0}",Conversion(Eval("dataitem.active")))%>'
Conversion is then a method you leave in your code behind or utility class where you do the conversion.