How to add a "confirm delete" option in ASP.Net Gridview ?
This should do it.
I found it here: http://forums.asp.net/p/1331581/2678206.aspx
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:ImageButton ID="DeleteButton" runat="server" ImageUrl="~/site/img/icons/cross.png"
CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this event?');"
AlternateText="Delete" />
</ItemTemplate>
</asp:TemplateField>
If your Gridview used with AutoGenerateDeleteButton="true" , you may convert it to LinkButton:
Click GridView Tasks and then Edit Columns.
Select Delete in Selected fields, and click on Convert this field into a TemplateField. Then click OK:
Now your LinkButton will be generated. You can add OnClientClick event to the LinkButton like this:
OnClientClick="return confirm('Are you sure you want to delete?'); "
I did this a bit different. In my gridview I set the AutoGenerateDeleteButton="true". To find the delete button I use jQuery and add a click event to the found Anchors.
jQuery("a").filter(function () {
return this.innerHTML.indexOf("Delete") == 0;
}).click(function () { return confirm("Are you sure you want to delete this record?");
});
This is quick and simple for what I need to do. Just be mindful that Every Anchor in the page that displays Delete will be selected by jQuery and will have the event added to it.
I like this way of adding a confirmation prompt before deleting a record from a gridview. This is the CommandField definition nested within a GridView web control in the aspx page. There's nothing fancy here--just a straightforward Commandfield.
<asp:CommandField ShowEditButton="true" UpdateText="Save" ShowDeleteButton="True">
<ControlStyle CssClass="modMarketAdjust" />
</asp:CommandField>
Then, all I had to do was add some code to the RowDeleting event of the GridView control. This event fires before the row is actually deleted, which allows you to get the user's confirmation, and to cancel the event if he doesn't want to cancel after all. Here is the code that I put in the RowDeleting event handler:
Private Sub grdMarketAdjustment_RowDeleting(sender As Object, e As GridViewDeleteEventArgs) Handles grdMarketAdjustment.RowDeleting
Dim confirmed As Integer = MsgBox("Are you sure that you want to delete this market adjustment?", MsgBoxStyle.YesNo + MsgBoxStyle.MsgBoxSetForeground, "Confirm Delete")
If Not confirmed = MsgBoxResult.Yes Then
e.Cancel = True 'Cancel the delete.
End If
End Sub
And that seems to work fine.
I didn't want any image so i modified the answer given by #statmaster to make it simple entry along with the other columns.
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this entry?');">Delete </asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
The colour of the text can be changed using the Forecolor Property.
You can do using OnClientClick of button.
OnClientClick="return confirm('confirm delete')"
I quite like adding the code in the GridView RowDataBound event to inform the user exactly which item they are trying to delete. Slightly better user experience?
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkBtnDelete = e.Row.FindControl("lnkBtnDelete") as LinkButton;
// Use whatever control you want to show in the confirmation message
Label lblContactName = e.Row.FindControl("lblContactName") as Label;
lnkBtnDelete.Attributes.Add("onclick", string.Format("return confirm('Are you sure you want to delete the contact {0}?');", lblContactName.Text));
}
}
Try this:
I used for Update and Delete buttons. It doesn't touch Edit button. You can use auto generated buttons.
protected void gvOperators_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType != DataControlRowType.DataRow) return;
var updateButton = (LinkButton)e.Row.Cells[0].Controls[0];
if (updateButton.Text == "Update")
{
updateButton.OnClientClick = "return confirm('Do you really want to update?');";
}
var deleteButton = (LinkButton)e.Row.Cells[0].Controls[2];
if (deleteButton.Text == "Delete")
{
deleteButton.OnClientClick = "return confirm('Do you really want to delete?');";
}
}
This is my preferred method. Pretty straight forward:
http://www.codeproject.com/KB/webforms/GridViewConfirmDelete.aspx
Although many of these answers will work, this shows a straightforward example when using CommandField in GridView using the OnClientClick property.
ASPX:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="OnRowDataBound"... >
<Columns>
<!-- Data columns here -->
<asp:CommandField ButtonType="Button" ShowEditButton="true" ShowDeleteButton="true" ItemStyle-Width="150" />
</Columns>
</asp:GridView>
ASPX.CS:
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != GridView1.EditIndex)
{
(e.Row.Cells[2].Controls[2] as Button).OnClientClick = "return confirm('Do you want to delete this row?');";
}
}
I was having problems getting a commandField Delete button to honor the 'return false' response to when a user clicked cancel on the 'Are you sure' pop-up that one gets with using the javascript confirm() function. I didn't want to change it to a template field.
The problem, as I see it, was that these commandField Buttons already have some Javascript associated with them to perform the postback. No amount of simply appending the confirm() function was effective.
Here's how I solved it:
Using JQuery, I first found each delete button on the page (there are several), then manipulated the button's associated Javascript based on whether the visitor agreed or canceled the confirming pop-up.
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$('input[type="button"]').each(function() {
if ($(this).val() == "Delete") {
var curEvent = $(this).attr('onclick');
var newContent = "if(affirmDelete() == true){" + curEvent + "};"
$(this).attr('onclick',newContent);
}
});
}
function affirmDelete() {
return confirm('Are you sure?');
}
</script>
This code is working fine for me.
jQuery("a").filter(function () {
return this.innerHTML.indexOf("Delete") == 0;
}).click(function () { return confirm("Are you sure you want to delete this record?");
});
I love the JavaScript solution and have some updates to work with dynamic ajax loading:
$(document).on("click", "a", function () {
if (this.innerHTML.indexOf("Delete") == 0) {
return confirm("Are you sure you want to delete this record?");
}
});
Hope it help ;)
This is my method and it works perfectly.
asp
<asp:CommandField ButtonType="Link" ShowEditButton="true" ShowDeleteButton="true" ItemStyle-Width="5%" HeaderStyle-Width="5%" HeaderStyle-CssClass="color" HeaderText="Edit"
EditText="<span style='font-size: 20px; color: #27ae60;'><span class='glyphicons glyph-edit'></span></span>"
DeleteText="<span style='font-size: 20px; color: #c0392b;'><span class='glyphicons glyph-bin'></span></span>"
CancelText="<span style='font-size: 20px; color: #c0392b;'><span class='glyphicons glyph-remove-2'></span></span>"
UpdateText="<span style='font-size: 20px; color: #2980b9;'><span class='glyphicons glyph-floppy-saved'></span></span>" />
C# (replace 5 with the column number of the button)
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
}
else {
((LinkButton)e.Row.Cells[5].Controls[2]).OnClientClick = "return confirm('Do you really want to delete?');";
}
Related
I've been trying to follow this answer: How to implement full row selecting in GridView without select button?
But I'm still slightly confused. After following that question, my rows are now clickable. But how do I implement it to do something after being clicked? Currently, I use a button to do what I need to the database per row:
Here is the .aspx code:
<Columns>
<asp:ButtonField Text = "Click Me" CommandName = "Clicked" ButtonType = "Button" />
...other columns stuff
</Columns>
C# code behind:
protected void RowCommand(object sender, GridViewCommandEventArgs e)
{
//if button is clicked
if (e.CommandName == "Clicked")
{
//go find the index on the gridview
int selectedIndex = MsgInbox.SelectedIndex;
if (int.TryParse(e.CommandArgument.ToString(), out selectedIndex))
{
//do something with database
}
Now that works beautifully. However, I don't want a button to be clickable, I want a entire row to be clickable. I know this is currently wrong, but this is what I have so far for the code:
.aspx code
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="SelectRow" runat="server" ForeColor="red" CommandName="Clicked"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
C# code:
protected void Gridview_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
var selectButton = e.Row.FindControl("SelectRow") as Button;
e.Row.Attributes["onclick"] = ClientScript.GetPostBackEventReference(selectButton, "");
I get a simple null pointer exception when I do this, but I'm not really familiar with e.Row.Attributes so I really have no idea where this is failing and what I need to do to add the database logic.
Thanks
It would be a lot simpler if you are ready to use jquery. For example,
<asp:GridView rowStyle-CssClass="row" ...
...
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="SelectRow" runat="server" CommandName="Clicked" CssClass="selButton" />
</ItemTemplate>
</asp:TemplateField>
Note that each data row will have css class row and select button will have selButton
CSS would be some-thing like
tr.row { } /* normal row styling */
tr.row-highlight { background-color: blue; } /* highlighted row styling */
tr.row .selButton { display:none; visibility:hidden; } /* select button styling, I am using hidden button */
Finally the java-script
$(document).ready(function() {
$('tr.row').click(
function() {
// simulate click of select button
$(this).find('.selButton').click();
}).hover(
// add/remove css class to highlight on mouse over/out
function() { $(this).addClass('row-highlight'); },
function() { $(this).removeClass('row-highlight'); });
});
So I figured it out, and I'm sure there are better ways to implement it via jquery or javascript but I am not too good at either yet.
For my .aspx file, for the gridview, I simply added:
AutoGenerateSelectButton ="true"
In my C#, under MsgInbox_SelectedIndexChanged, I put all my RowCommand logic.
Finally, in C#, under my Gridview_RowCreated, I added this line to hide the Select link:
e.Row.Cells[0].Style["display"] = "none";
I have a legacy asp.net 3.5 application. I need to bind a filed to CssClass so that i can utilize it via jquery.
Basically, in the datagrid, there are 2 buttons. Button one is visible and button two is not visible. On click of button one, i want to perform action and then make button two visible and hide button one. How can i do this? I just need a kick in the right direction...
<asp:LinkButton ID="lnkDelete" runat="server"
ToolTip="Delete Order <%# DataBinder.Eval(Container.DataItem, "TransID")%>"
OnClientClick="return DeleteOrder();"
OnClick="OrderDelete" CommandArgument='<%# Eval("TransID")'
CssClass="">
<asp:Image ID="Image1" runat="server" ImageUrl="~/images/icons/delete.gif"
BorderStyle="None" />
</asp:LinkButton>
My current binding inside the tooltip results in an error, "the server tag is not well formed".
On the code behind OrderDelete, i can disable the delete link, but how can i make the other button visible?
//delete indivisual order
protected void OrderDelete(object sender, EventArgs e)
{
string transactionID = String.Empty;
LinkButton lnkDelete = (LinkButton)sender;
if (lnkDelete != null)
transactionID = lnkDelete.CommandArgument;
if (!String.IsNullOrEmpty(transactionID))
{
//do delete
}
//refresh results
}
For the server tag not well-formed error, try something like this:
ToolTip='<%# String.Format("Delete Order {0}", DataBinder.Eval(Container.DataItem, "TransID")%>'
For the second part of your question, a little more of your code might help to give you a more specific answer, but in lieu of that, if you know which row of the DataGrid you're in, you should be able to do a FindControl in that row for the second button and make it visible.
Update
You might try setting the tooltip in the codebehind, using the RowDataBound event. Something like this:
protected void gv1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton btn = e.Row.FindContorl("lnkDelete") as LinkButton;
// You'll need to retrieve the values you want to dynamically populate
// the ToolTip with from other controls in the row;
// I don't know if you'd be able to use the DataSource or not, but you might.
btn.ToolTip = "Delete Order ";
}
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Link Button on the page and set it as default button, work fine in IE but not in Mozila
How to set linkbutton as default button for asp:panel in asp.net? I know a button can be set as default but my application uses linkbuttons for all forms. Any suggestion how it can be done.
EDIT:
Now i tried this,
It works in firefox as well but my javascript validation (ie) onclient click of my linkbutton doesn't work why?
var __defaultFired = false;
function WebForm_FireDefaultButton(event, target) {
var element = event.target || event.srcElement;
if (!__defaultFired && event.keyCode == 13 && !(element && (element.tagName.toLowerCase() == "textarea"))) {
var defaultButton;
if (__nonMSDOMBrowser)
defaultButton = document.getElementById(target);
else
defaultButton = document.all[target];
if (defaultButton) {
if (typeof (defaultButton.click) != "undefined")
defaultButton.click();
else
eval(unescape(defaultButton.href.replace("javascript:", "")));
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return false;
}
}
return true;
}
Second EDIT:
I was able make my custom linkbutton control work but couldn't able to hook OnClientClick to it. Source using-panel-defaultbutton-property-with-linkbutton-control-in-asp-net.
and i did this,
<%# Register Namespace="App_Code" TagPrefix="ac" %>
<asp:Label runat="server" ID="lblHello" />
<asp:Panel runat="server" DefaultButton="lbHello">
First name: <asp:TextBox runat="server" ID="txtFirstName" />
<ac:LinkButtonDefault ID="lbHello" runat="server" Text="Click me"
OnClientClick="javascript:alert('hai');" OnClick="lbHello_Click" />
</asp:Panel>
My Clientside function doesn't work why? Any suggestion.
Rather than use a custom control you could take the simple approach of adding an attribute to handle the textbox's onKeyPress event. This correctly handles pressing Enter from the textbox and triggering the LinkButton's event. The downside to this approach is that any LinkButton OnClientClick event will not be triggered in Firefox, which is related to the issue described in that blog post you linked to. It will only be triggered when the user actually clicks on the link with their mouse. However, in IE, it will trigger from both the textbox and from being clicked on directly.
Solution #1 - The code to add the attribute is as follows:
protected void Page_Load(object sender, EventArgs e)
{
txtFirstName.Attributes.Add("onKeyPress",
"javascript:if (event.keyCode == 13) __doPostBack('" + lbHello.ClientID + "','')");
}
Try that and see if it fits your needs. Just bear in mind the limitation I described earlier.
Now, if you want the above limitation to go away, one of the comments from that blog post showed an approach that appears to work correctly. I've modified it to get rid of the StringBuilder and converted it to C#.
Solution #2 - The code to add the function and register it is as follows:
protected void Page_PreRender(object sender, EventArgs e)
{
string addClickFunctionScript = #"function addClickFunction(id) {
var b = document.getElementById(id);
if (b && typeof(b.click) == 'undefined')
b.click = function() {
var result = true;
if (b.onclick) result = b.onclick();
if (typeof(result) == 'undefined' || result)
eval(b.getAttribute('href'));
}
};";
string clickScript = String.Format("addClickFunction('{0}');", lbHello.ClientID);
Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true);
Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + lbHello.ClientID, clickScript, true);
}
Page Markup -
The page mark-up is the same for both of the aforementioned solutions:
<asp:Label runat="server" ID="lblHello" />
<asp:Panel ID="Panel1" runat="server" DefaultButton="lbHello">
First name:
<asp:TextBox runat="server" ID="txtFirstName" />
<asp:LinkButton ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click"
OnClientClick="javascript:alert('Hello, World!');"/>
</asp:Panel>
In both cases a custom control is not needed to achieve this type of functionality. Keep it simple.
Take a look at this
<asp:Panel runat="server" DefaultButton="lbHello">
First name: <asp:TextBox runat="server" ID="txtFirstName" />
<asp:LinkButton ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click" />
</asp:Panel>
The rest of the answer can be found here. It shows how to fix the problem that arises with FireFox
http://kpumuk.info/asp-net/using-panel-defaultbutton-property-with-linkbutton-control-in-asp-net/
Another approach could be to fake the onclick event like this.
jQuery(document).ready(function () {
jQuery('#<%= txtFirstName.ClientID %>').keypress(function (event) {
if (event.keyCode == 13) {
eval($('#<%=lbHello.ClientID %>').attr('href'));
}
});
});
The downside is that you need to use this for all places you need to make default buttons.
See this
Link Button on the page and set it as default button, work fine in IE but not in Mozila
The dummy button answer is the cleanest solution IMO.
I have created a gridview with a column of checkboxes. I want the user to select the checkboxes, click the register button (outside the gridview), and have a title from the selected row displayed. From what I've read I should put the checkbox check in the button click event. I have done so, but apparently the only time it enters that event is at page load and right before the page loads, all the selected checkboxes are wiped. Therefore, my check for a selected checkbox never comes out true. Is there an event that would a better time to run this check, or perhaps a way to hold these values through the page load? The following isn't all my code, just the affected portions.
protected void regButton_Click(Object sender, EventArgs e)
{
StringBuilder regClasses = new StringBuilder();
for (int i = 0; i < SQLQueryClassListings.Rows.Count; i++)
{
//Response.Write(SQLQueryClassListings.Rows[i].Cells[0].Text + " checkbox check ");
GridViewRow checkRow = SQLQueryClassListings.Rows[i];
bool reg = ((CheckBox)(checkRow.FindControl("RowCheckBox"))).Checked;
if (reg)
{
regClasses.Append(SQLQueryClassListings.Rows[i].Cells[0].Text + " ");
}
}
Response.Write(regClasses);
}
<asp:GridView ID="SQLQueryClassListings" AutoGenerateColumns="false" runat="server"
BorderWidth="1px" BackColor="White" CellPadding="5" BorderColor="Black" RowStyle-BorderColor = "Black"
HeaderStyle-BackColor="#0D69F2" HeaderStyle-ForeColor="White" AlternatingRowStyle-BackColor="#E8E8E8" HeaderStyle-BorderColor="Black" GridLines="Both">
<Columns>
<asp:BoundField HeaderText="Classes" DataField="LeafName" HeaderStyle-HorizontalAlign="Left" ItemStyle-Width="250"
ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:BoundField HeaderText="Teacher" DataField="TeacherName" HeaderStyle-HorizontalAlign="Left" ItemStyle-Width="200"
ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:BoundField HeaderText="Available" DataField="SemesterEnds" HeaderStyle-HorizontalAlign="Center"
ItemStyle-HorizontalAlign ="Center" ItemStyle-Width="150" ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:HyperLinkField HeaderText="Course Description & Career Tracks" DataNavigateUrlFields="ApplicableTracks"
Text="See Description" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign ="Center" ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:TemplateField HeaderText="Register" HeaderStyle-BorderColor="Black" ItemStyle-BorderColor = "#ADADAD" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox runat="server" ID="RowCheckBox"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<p>
<asp:Button ID="Button1" runat="server" Text="Register" OnClientClick="return confirm('You have sucessfully registered!')"
OnClick="regButton_Click" />
You need to get on the ItemDataBound event of the GridView control, find the CheckBox by ID, and do whatever you need.
It's hard to know for sure without seeing more of your code, but it sounds like your page is re-binding the GridView on postbacks (such as your regButton_Click event). So it rebuilds the GridView every time the page loads - even after your user clicks the register button.
If that is the case, you can fix this by changing the code you use to bind your GridView like this:
if (!this.IsPostback) {
SQLQueryClassListings.DataBind();
}
(This presumes that you have ViewState enabled for the page (or at least the GridView). There are other mechanisms you can use to communicate the client's state (such as checkbox selections) to the server, but ViewState (for all its faults) is the default tool for doign so in ASP.NET.)
A consequence is that the data shown in the GridView won't be completely up-to-date, but if you can tolerate that, this is a simple way to accomplish what you want.
You must read the checkboxes from the GridView.
So this code will bring back the IDs of the rows checked. It will give you the idea and then you can change it for what you need.
protected string getCheckedIds(GridView gv)
{
StringBuilder sb = new StringBuilder();
foreach (GridViewRow gvr in gv.Rows)
{
if (!gvrIsChecked(gvr)) // see below for this method
continue;
if (sb.Length > 0)
sb.Append(",");
sb.Append(gv.DataKeys[gvr.DataItemIndex].Value);
}
return sb.ToString();
}
protected bool gvrIsChecked(GridViewRow gvr)
{
// The location of your checkbox may be different.
object cb = gvr.Cells[0].Controls[gvr.Cells[0].Controls.Count - 2];
if (cb.GetType() != typeof(CheckBox))
return false;
if (!((CheckBox)cb).Checked)
return false;
return true;
}
I have GridView which I can select a row. I then have a button above the grid called Edit which the user can click to popup a window and edit the selected row. So the button will have Javascript code behind it along the lines of
function editRecord()
{
var gridView = document.getElementById("<%= GridView.ClientID %>");
var id = // somehow get the id here ???
window.open("edit.aspx?id=" + id);
}
The question is how do I retrieve the selected records ID in javascript?
I worked it out based on JasonS response. What I did was create a hidden field in the Grid View like this:
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:HiddenField ID="hdID" runat="server" Value='<%# Eval("JobID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="False">
<ItemTemplate>
<asp:LinkButton ID="lnkSelect" runat="server" CommandName="select" Text="Select" />
</ItemTemplate>
</asp:TemplateField>
Then on the OnRowDataBind have code to set the selected row
protected virtual void Grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Click to highlight row
Control lnkSelect = e.Row.FindControl("lnkSelect");
if (lnkSelect != null)
{
StringBuilder click = new StringBuilder();
click.AppendLine(m_View.Page.ClientScript.GetPostBackClientHyperlink(lnkSelect, String.Empty));
click.AppendLine(String.Format("onGridViewRowSelected('{0}')", e.Row.RowIndex));
e.Row.Attributes.Add("onclick", click.ToString());
}
}
}
And then in the Javascript I have code like this
<script type="text/javascript">
var selectedRowIndex = null;
function onGridViewRowSelected(rowIndex)
{
selectedRowIndex = rowIndex;
}
function editItem()
{
if (selectedRowIndex == null) return;
var gridView = document.getElementById('<%= GridView1.ClientID %>');
var cell = gridView.rows[parseInt(selectedRowIndex)+1].cells[0];
var hidID = cell.childNodes[0];
window.open('JobTypeEdit.aspx?id=' + hidID.value);
}
</script>
Works a treat :-)
1) change your javascript function to use a parameter
function editRecord(clientId)
{ ....
2) output the call in your editRecord button... if you want to avoid dealing with the .net generated ids, just use a simple
<input type="button" onclick="editRecord(your-rows-client-id-goes-here)" />
Based off of your comments to #DaveK's response, in javascript you can set the id of a hidden field to the clientId of the selected row when the user selects it. Then have your editRecord function use the value set on the hidden form field.
one could avoid javascript altogether, by setting anchor tags pre-populated with the query string for each row (although this will effect your table layout, it will need only one click rather than 2 from the user)
insert in the gridview template:
<asp:HyperLink runat="server" ID="editLink" Target="_blank"
NavigateURL='<%# Eval("JobID","edit.aspx?id={0}") %>'>
Edit..
</asp:HyperLink>