I have a GridView (see below) which uses ButtonField buttons to launch modal popup windows.
Here is the GridView
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_ButtonClick" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" CssClass="mGrid" AllowPaging="True" PagerStyle-CssClass="pgr"
AlternatingRowStyle-CssClass="alt" OnRowEditing="GridView1_RowEditing" AutoGenerateColumns="False">
<AlternatingRowStyle BackColor="#F7F7F7" CssClass="alt" />
<HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
<Columns>
<asp:BoundField HeaderText="BeaconID" ShowHeader="True" Visible="True" DataField="beaconObjectid" />
<asp:BoundField DataField="aliasName" HeaderText="My Beacon Name" />
<asp:ButtonField ButtonType="Button" CommandName="AssignName" Text="Assign Name"/>
<asp:BoundField HeaderText="Action Type" DataField="actionType" />
<asp:BoundField DataField="actionContent" HeaderText="Action Content" />
<asp:ButtonField ButtonType="Button" CommandName="AssignAction" Text="Assign/Change Action"/>
</Columns>
<PagerStyle CssClass="pgr" />
</asp:GridView>
This works fine to open the modal window like this one, using the C# code shown further down:
<asp:Button ID="showModal3" runat="server" Text="Show Modal" CssClass="hiddenButton"/>
<asp:Panel ID="Panel3" runat="server" CssClass="modalPopup">
<div class="header">
Set Alias Name
</div>
<div class="body">
Set a new name for your beacon
<br />
<br />
<div style="float: none;">
<asp:TextBox ID="AliasNameTextBox" runat="server" Height="21px" Width="300px"></asp:TextBox>
</div>
</div><br/>
<div class="footer" align="right">
<asp:Button ID="setAliasOK" runat="server" Text="OK" CssClass="yes" OnClick="setAliasOK_Click" CausesValidation="False" />
<asp:Button ID="setAliasCancel" runat="server" Text="Cancel" CssClass="no" />
</div></asp:Panel>
<ajaxToolkit:ModalPopupExtender ID="SetAliasNameModalPopupExtender" runat="server" CancelControlID="setAliasCancel" DropShadow="True" PopupControlID="Panel3" TargetControlID="showModal3" BackgroundCssClass="modalBackground"></ajaxToolkit:ModalPopupExtender>
In my C# code, i'm getting the index of the buttons like this so i know which row was clicked, which all works well:
protected void GridView1_ButtonClick(object sender, GridViewCommandEventArgs e)
{
GridViewRow row = GridView1.Rows[Convert.ToInt32(e.CommandArgument)]; // this gets the row
string id = row.Cells[0].Text;
string name = row.Cells[1].Text;
string actionText = row.Cells[3].Text;
if (e.CommandName == "AssignName")
{
SetAliasNameModalPopupExtender.Show();
AliasNameTextBox.Text = name;
}
if (e.CommandName == "AssignAction")
{
ChooseActionModalPopupExtender.Show();
}
Label1.Text = name;
Label2.Text = actionText;
Label3.Text = id;
currentlySelectedRow = Convert.ToInt32(e.CommandArgument);
beaconIDnumber = id;
}
The problem is when i click the 'OK' button from my modal popup window. I need to have access to the row index from the gridview buttonfield that called it. My OK button click event looks like this:
protected void setAliasOK_Click(object sender, EventArgs e)
{
var newName = AliasNameTextBox.Text;
ParseChangeAliasName(beaconIDnumber, newName);
SetAliasNameModalPopupExtender.Hide();
}
So ultimately what i'm asking, is how do i pass the gridview row to the modal window so i can use data from the respective row cell - in this case the beacon ID (DataField="beaconObjectid" in the gridview).
I've even tried setting global variables in the GridView1_ButtonClick method, and then referencing them in the setAliasOK_Click method, but they get wiped as soon as the modal window opens.
Ideally i want to do this without using Javascript if possible.
in the same way you get
GridViewRow row = GridView1.Rows[Convert.ToInt32(e.CommandArgument)];
you can set your Button attributes:
setAliasOK.CommandName = "AliasOK" ;
setAliasOK.CommandArgument = e.CommandArgument ;
But you need to process your button's RowCommand event rather than the Click event to get to the Button's Command parameters
Related
I am trying to set the value of a textbox to the value of a column in a gridview. I am getting the row from a LinkButton.
The first TextBox1.Text line below works correctly to set the value of the textbox to the row number.
The second TextBox1.Text line below does nothing to my textbox. I am expecting the value of the row(index) and column(1), but I get nothing. There is definitely data in the gridview. The gridview is 10+ columns wide, and I have checked the value from 0-5 and get nothing in the textbox.
I am not running it with both lines uncommented out at once.
I am doing all of this to troubleshoot an issue being caused by it.
protected void lnkbtnPassRowData_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)sender;
GridViewRow gvr = (GridViewRow)btn.NamingContainer;
if (gvr != null)
{
int index = Convert.ToInt32(gvr.RowIndex.ToString());
TextBox1.Text = GridStaffMyJobs.Rows[index].RowIndex.ToString();
TextBox1.Text = GridStaffMyJobs.Rows[index].Cells[1].Text;
}
}
Here is the code from the gridview that contains the link button.
<form id="StaffMyJobs" runat="server">
<div>
<h3>My Jobs</h3>
</div>
<div>
<asp:Label ID="lblHired" runat="server" Text="Rows in green indicate jobs that have been filled." Visible="False" BorderColor="#FF0909" Font-Bold="True" Font-Underline="True" ForeColor="YellowGreen"></asp:Label>
<br />
<asp:Label ID="lblOffers" runat="server" Text="Rows in red indicate jobs that have pending offers." Visible="False" BorderColor="#FF0909" Font-Bold="True" Font-Underline="True" ForeColor="Red"></asp:Label>
<br />
<asp:Button ID="btnAddJob" runat="server" Text="Add a Job" OnClick="btnAddJob_Click" Visible="true" />
<br />
<br />
</div>
<div>
<asp:GridView ID="GridMoreJobs" runat="server" AutoGenerateColumns="False" DataSourceID="SQLMoreJobs" >
<Columns>
<asp:BoundField DataField="more_jobs" HeaderText="more_jobs" SortExpression="more_jobs" Visible="false" />
</Columns>
</asp:GridView>
</div>
<div>
<asp:GridView ID="GridStaffMyJobs" runat="server" AutoGenerateColumns ="False" DataSourceID="SQLStaffMyJobs" ShowFooter="True" OnRowDataBound="GridMoreJobs_RowDataBound" HorizontalAlign="Center" >
<Columns>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton ID="lnkbtnPassRowData" Text='Reopen'
runat="server"
OnClick="lnkbtnPassRowData_Click" Visible='<%#
CanReopen((object)Eval("student_hired")) %>' />
</ItemTemplate>
</asp:TemplateField>
</form>
Here is a screenshot of executing the page and letting the line run that puts the index of the row in the textbox.
I have a site that uses master pages.
One of my content pages is basically a large UpdatePanel. Inside that UpdatePanel is a regular Panel. Inside the regular Panel is a Gridview. Inside the Gridview is a Linkbutton that points to a pdf stored in my database.
When I click the Linkbutton to retrieve the pdf, nothing happens.
I have this working on another page that has no UpdatePanel.
I have already tried firing an 'external' button from the Linkbutton and registering this button as a PostBack event. The page posts back when I click the Linkbutton but the pdf is not being sent to the user.
Here is some sample code:
<asp:UpdatePanel ID="UpdatePanelClaims" runat="server">
<ContentTemplate>
<asp:Panel ID="upClaimAttachment" runat="server" Visible="false" >
<table id="gridClaimAttachmentTable" runat="server" class="table" >
<tr>
<td >
<asp:GridView ID="grdClaimAttachment" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" CssClass="table table-striped table-bordered table-condensed table-hover" EmptyDataText="No Attachments for this Claim."
EnableTheming="False" onpageindexchanging="grdClaimAttachment_PageIndexChanging" PageSize="15" OnRowCommand="grdClaimAttachment_RowCommand"
OnRowDataBound="grdClaimAttachment_RowDataBound" >
<PagerStyle CssClass="bs-pagination" />
<AlternatingRowStyle CssClass="alternateColor" />
<RowStyle CssClass="rowsStyle" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-CssClass="hideColumn" HeaderStyle-CssClass="hideColumn" >
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:TemplateField HeaderText="File Name">
<ItemTemplate>
<asp:LinkButton ID="btnViewAttachment" Text='<%#Eval("FileName") %>' CommandName="ViewAttachment"
CommandArgument="<%# Container.DataItemIndex %>" runat="server"></asp:LinkButton></ItemTemplate>
</asp:TemplateField>
<asp:ButtonField ButtonType="Button" CommandName="btnDelete" Text="Delete">
<ControlStyle CssClass="btn btn-info btn-xs " />
</asp:ButtonField>
</Columns>
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#E9E7E2" />
<SortedAscendingHeaderStyle BackColor="#506C8C" />
<SortedDescendingCellStyle BackColor="#FFFDF8" />
<SortedDescendingHeaderStyle BackColor="#6F8DAE" />
</asp:GridView>
</td>
</tr>
<tr >
<td>
<div class="container">
<div class="form-group form-group-sm form-groupNoSpace">
<div class="row">
<div class=" col-xs-4 col-xs-offset-4 text-right">
<asp:Button ID="btnClaimAttachmentAdd" runat="server" CssClass="btn btn-primary btn-sm btn-block" Text="Add Attachment" OnClick="btnClaimAttachmentAdd_Click"/>
</div>
</div>
</div>
</div>
</td>
</tr>
</table>
</asp:Panel> <%-- Attachment Update Panel --%>
<asp:Button ID="btnClickMe" runat="server" OnClick="btnClickMe_Click" Visible="false" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnClickMe" />
</Triggers>
</asp:UpdatePanel> <%-- UpdatePanelClaims --%>
In the code behind I have this:
protected void btnClickMe_Click(object sender, EventArgs e, ClaimAttachment objAttachment)
{
ViewAttachment(objAttachment);
}
private void ViewAttachment(ClaimAttachment objAttachment)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AppendHeader("content-disposition", "attachment;filename=" + objAttachment.FileName);
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(objAttachment.Attachment);
Response.Flush();
Response.End();
}
UPDATE: Forgot some critical code!
protected void grdClaimAttachment_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
int index = Convert.ToInt32(e.CommandArgument);
if (index >= grdClaimAttachment.Rows.Count)
return;
int IDkey = Convert.ToInt32(grdClaimAttachment.Rows[index].Cells[0].Text);
ClaimAttachment objClaimAttachment = ClaimAttachment.RetrieveById((string)Session["Username"], IDkey);
if (e.CommandName == "btnDelete")
{
ltlDeleteID.Text = IDkey.ToString();
ltlRecordType.Text = "attachment";
confirmDialog(string.Format("DELETE Attachment: {0} ?", objClaimAttachment.FileName));
}
else if (e.CommandName == "ViewAttachment")
{
//btnClickMe.CommandArgument = IDkey.ToString();
//btnClickMe_Click(sender, e);
btnClickMe.Click += new EventHandler((s1, e1) => btnClickMe_Click(s1, e1, objClaimAttachment));
btnClickMe_Click(sender, e, objClaimAttachment);
}
}
catch (BLException be)
{
errDialog(be.Message);
}
}
The Linkbutton in the grid is actually calling the Click event of an external button to perform the pdf download...
What am I missing?? Like I said, this works if I remove all UpdatePanels but I need them for other things...
thx!
The PostBackTrigger class is key to your solution, as it can be used to trigger the full page reload required for the download reponse to work. Downloads simply will not work from a partial postback.
However, as the buttons that should trigger the postback are inside your grid, using a single PostBackTrigger in the page markup is not enough, you need a specific trigger for each button / row.
Use something like this (call it from your Page_Load)
private void RegisterPostBackControls()
{
foreach (GridViewRow row in grdClaimAttachment.Rows)
{
LinkButton button = row.FindControl("btnViewAttachment") as LinkButton;
ScriptManager.GetCurrent(this).RegisterPostBackControl(button);
}
}
here is my aspx view
<asp:GridView ID="gvdatasubcategory" runat="server" AllowPaging="false" AllowSorting="false"
CssClass="gvdatarow" ShowHeader="false" AutoGenerateColumns="False" OnRowCommand="gvdatasubcategory_RowCommand">
<Columns>
<asp:TemplateField ItemStyle-Font-Names="Estrangelo Edessa" HeaderStyle-Font-Names="Estrangelo Edessa">
<ItemTemplate>
<div class="subcategory_type">
<div id="abd" runat="server">
<asp:LinkButton ID="button1" runat="server" CssClass="subcategory_name"
Width="80px" Height="26px" Text='<%#DataBinder.Eval(Container.DataItem, "SubCategory")%>'
CommandName="Test"></asp:LinkButton>
</div>
</div>
</ItemTemplate>
<HeaderStyle Font-Names="Estrangelo Edessa" Width="5px" />
<ItemStyle Font-Names="Estrangelo Edessa" Width="5px" Wrap="false" HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="button2 " runat="server" CssClass="category_name" Text="getid"
OnClick="button2 _Click" />
these buttons are in gridview and i need to get the first button id on second button click in code behind
Thank you in advance
Raveendra
If you are looking for Linkbutton object, thenyou can use FindControl method as:
LinkButton button1 = (LinkButton)gvdatasubcategory.Rows[0].Cells[0].FindControl("button1");
string buttonid = button1.ClientID; //gives client side id of the Linkbutton
But keep in mind that grid should contain th rows, otherwise you will get null. If you need all Linkbutton instances, then you can loop through the datarows to get each linkbutton ids.
You can try this code below:
protected void button2_Click(object sender, EventArgs e)
{
foreach(GridViewRow row in gvdatasubcategory.Rows)
{
LinkButton btn = (LinkButton)row.FindControl("button1");
string strClientID = string.Empty;
strClientID = btn.ClientID;
}
}
Here is my gridview and the event that fires when a user clicks on the edit button within the row. for some reason my datakey value is crashing the program saying it is null. im not sure why. the DataKeyNames in the gridview is exactly what I want it to be, formID. this is correct because the last column in the gridview, as you can see, shows me the formID and it displays just fine. so i have no idea where i am going wrong.
<asp:GridView ID="gvHistory" runat="server" DataSourceID="ObjectDataSource"
AutoGenerateColumns="False" CellPadding="10" CellSpacing="5"
CssClass="userHistory" DataKeyNames="formID">
<Columns>
<asp:BoundField DataField="clientName" HeaderText="User" />
<asp:BoundField DataField="formName" HeaderText="Form" />
<asp:BoundField DataField="dateCreated" HeaderText="Date Created" />
<asp:BoundField DataField="dateRevised" HeaderText="Last Revision Date" />
<asp:BoundField DataField="dateSubmitted" HeaderText="Date Submitted" />
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="edit" runat="server" CausesValidation="false" CommandName="editForm"
Text="Edit" OnDataBinding="btnEdit_DataBinding" OnClick="btnEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="delete" runat="server" CausesValidation="false" CommandName=""
Text="Delete" OnDataBinding="btnDelete_DataBinding" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="formID" />
</Columns>
</asp:GridView>
protected void btnEdit_Click(object sender, System.EventArgs e)
{
Session["formID"] = gvHistory.SelectedDataKey.Value;
Label1.Text = Session["formID"].ToString();
}
If you are using CommandName with your item template then You can simply use Row_Command event, you don't need to create separate handler for button click.
protected void grdView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "editForm")
{
GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
string value=grdView.DataKeys[row.RowIndex].Values["myDataKey"].ToString();
}
}
Button btn = (Button)sender;
GridViewRow gvrow = (GridViewRow)btn.NamingContainer;
if (gvrow != null)
{
//Get the Row Index
int rowIndex = gvrow.RowIndex;
//Get the DataKey value
Session["formID"] = gvHistory.DataKeys[rowIndex].Value.ToString();
Label1.Text = Session["formID"].ToString();
}
I have a GridView bound to an object datasource and a hover menu extender over that. On the panel that pops up I have two buttons - one for delete and one for edit. The problem I'm having is identifying which row triggered the hover menu so I know what to delete. I've searched all over the site and found similar issues but I wasn't able to apply them properly. I followed this video, and was able to get a hidden field to maintain the ID but only of the last row that was created, so my delete button always removed the last entry. I hope that was somewhat clear..
Here is my gridview code:
<asp:GridView runat="server" AutoGenerateColumns="False"
DataSourceID="source_Layout_view" ID="GridView1"
onrowdatabound="GridView1_RowDataBound"
onrowcreated="GridView1_RowCreated">
<Columns>
<asp:BoundField DataField="type" HeaderText="type" SortExpression="type" />
<asp:BoundField DataField="code" HeaderText="code" SortExpression="code" />
<asp:BoundField DataField="description" HeaderText="description"
SortExpression="description" />
<asp:BoundField DataField="position" HeaderText="position"
SortExpression="position" />
<asp:BoundField DataField="sequence" HeaderText="sequence"
SortExpression="sequence" />
<asp:TemplateField>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("ID") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Image ID="img_edit" runat="server" ImageUrl='~/ui/images/wrench.png' Width="25px" Height="25px" />
<asp:HoverMenuExtender ID="gridview_options_extender" runat="server" PopupControlID="gridview_options_popup" TargetControlID="img_edit"
OffsetX="10" OffsetY="10" PopupPosition="Right" PopDelay="50" HoverDelay="50" >
</asp:HoverMenuExtender>
<asp:Panel ID="gridview_options_popup" runat="server">
<asp:Button ID="btn_popup_delete" runat="server" Text="Delete Unit" OnClick="deleteRow"/>
<br />
<asp:Button ID="btn_popup_edit" runat="server" Text="Edit Unit" />
<asp:HiddenField ID="tellmeRow" runat="server" Value='Eval("ID")'/>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and here is my code behind
protected void deleteRow(object sender, EventArgs e)
{
Button b = sender as Button;
Panel x = b.Parent as Panel;
HiddenField whatiwant = (HiddenField)x.FindControl("tellmeRow");
int idForDeletion = Int32.Parse(whatiwant.Value);
using (var context = new cocoEntities())
{
context.CoCo_Current.DeleteObject(context.CoCo_Current.Single(o => o.ID == idForDeletion));
context.SaveChanges();
}
Response.Redirect("default.aspx");
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
}
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HoverMenuExtender menu = (HoverMenuExtender)e.Row.FindControl("gridview_options_extender");
e.Row.ID = e.Row.RowIndex.ToString();
menu.TargetControlID = e.Row.ID;
}
}
}
Don't use button click handler to do some action on a GridView. Assign instead apropriate CommandName property value for button and handle GridView's RowCommand event. GridView.RowCommand Event