Prevent Form Resubmit - c#

I've been looking for this answer for a couple weeks now but many other questions/answers don't fit my project or simply don't work.
Let me explain my project.
It is a simple View Page which on page load it would set the Text to different fields throughout the page. On the bottom I have a container with buttons which control which div is displayed in the container. On each click of the button, I run some code to set data sources to grid views or fill fields with text. I noticed when I click F5 to refresh the page I get that pesky "form resubmission" popup which will cause the last button click such as appending a note to a listview to be duplicated.
Here is some code to understand what I am doing
HTML(Not complete, just necessary to understand my question)
<td style="vertical-align: top;" class="Flow-Sub-Menu">
<asp:Button ID="Button_Sub_Menu_Financial" runat="server" Text="Financial Info" OnClick="Button_Sub_Menu_Financial_Click" />
<asp:Button ID="Button_Sub_Menu_Indemnitors" runat="server" Text="Indemnitors" OnClick="Button_Sub_Menu_Indemnitors_Click" />
<asp:Button ID="Button_Sub_Menu_Court" runat="server" Text="Court Info" OnClick="Button_Sub_Menu_Court_Click" />
<asp:Button ID="Button_Sub_Menu_Forfeiture" runat="server" Text="Forfeiture Info" OnClick="Button_Sub_Menu_Forfeiture_Click" />
<asp:Button ID="Button_Sub_Menu_Collaterals" runat="server" Text="Collaterals" OnClick="Button_Sub_Menu_Collaterals_Click" />
<asp:Button ID="Button_Sub_Menu_Notes" runat="server" Text="Notes" OnClick="Button_Sub_Menu_Notes_Click" />
<asp:Button ID="Button_Sub_Menu_Documents" runat="server" Text="Documents" OnClick="Button_Sub_Menu_Documents_Click" />
</td>
<div id="Div_Sub_Menu_Notes" runat="server" visible="false">
<div class="row">
<div class="col-xs-4" style="min-width: 550px;">
<div class="Flow-Box">
<div class="Flow-Box-Content" style="height: 440px; overflow-y: scroll;">
<asp:ListView ID="LV_Notes" runat="server" ItemPlaceholderID="ItemPlaceHolder" DataKeyNames="Bond_Note_ID" OnPagePropertiesChanging="LV_Notes_PagePropertiesChanging" OnItemCommand="LV_Notes_ItemCommand">
<LayoutTemplate>
<table style="width: 500px; background-color: white;">
<tr id="ItemPlaceHolder" runat="server"></tr>
<tr>
<td colspan="2">
<asp:DataPager ID="DataPager_Notes" runat="server" PagedControlID="LV_Notes" PageSize="3">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="false" ShowPreviousPageButton="true"
ShowNextPageButton="false" />
<asp:NumericPagerField ButtonType="Link" />
<asp:NextPreviousPagerField ButtonType="Link" ShowNextPageButton="true" ShowLastPageButton="false" ShowPreviousPageButton="false" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td colspan="2" style="padding-left: 10px; padding-right: 10px;">
<div style="border: 2px solid grey; height: 75px; padding: 5px;">
<%# Eval("Note") %>
</div>
</td>
</tr>
<tr>
<td style="padding-left: 10px;" <%# (Eval("Document_ID").ToString() != "" ? "" : "hidden=\"hidden\"") %>>
<label>Document Attached : <%# Eval("Document_Title").ToString() %></label>
</td>
<td style="text-align: right; padding-right: 10px;" <%# (Eval("Document_ID").ToString() != "" ? "" : "hidden=\"hidden\"") %>>
<asp:Button ID="Button_View_Document" runat="server" Text="View/Download Document" CommandName="View_Document" CommandArgument='<%#Eval("Document_ID")%>' />
</td>
</tr>
<tr>
<td style="text-align: left; padding-left: 10px;">
<div>
<%# Convert.ToDateTime(Eval("Created_DateTime")).ToShortDateString() + " " + Convert.ToDateTime(Eval("Created_DateTime")).ToShortTimeString() %>
</div>
</td>
<td style="text-align: right; padding-right: 10px;">
<div>
<%# Eval("Full_Name") %>
</div>
</td>
</tr>
<tr>
<td colspan="2" style="height: 20px; border-top: 4px solid #009900;"></td>
</tr>
</ItemTemplate>
</asp:ListView>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-4" style="min-width: 500px;">
<div class="Flow-Box">
<div class="Flow-Box-Label">
New Note
</div>
<div class="Flow-Box-Content">
<table class="Flow-Box-Table">
<tr>
<td>
<textarea id="TextArea_New_Note" runat="server" style="width: 400px; height: 150px;"></textarea>
</td>
</tr>
<tr>
<td>
<asp:Button ID="Button_Append_New_Note" runat="server" OnClick="Button_Append_New_Note_Click" Text="Append Note" />
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
C# Codebehind
protected void Button_Sub_Menu_Notes_Click(object sender, EventArgs e)
{
resetSubMenuButtons();
Button_Sub_Menu_Notes.BackColor = System.Drawing.Color.Orange;
Div_Sub_Menu_Notes.Visible = true;
string bondID = Request.QueryString["BondID"];
bindNotes(bondID);
}
protected void bindNotes(string bondID)
{
DataTable dt = Common_Functions.GetData("SELECT * FROM View_Bond_Notes_With_Name WHERE Bond_ID='" + bondID + "' ORDER BY Created_DateTime DESC");
LV_Notes.DataSource = dt;
LV_Notes.DataBind();
}
protected void LV_Notes_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
(LV_Notes.FindControl("DataPager_Notes") as DataPager).SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
string bondID = Request.QueryString["BondID"];
bindNotes(bondID);
}
protected void LV_Notes_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "View_Document"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
string documentID = e.CommandArgument.ToString();
Session["BondDocumentID"] = documentID;
Page.ClientScript.RegisterStartupScript(GetType(), "openDocument", "window.open('/FileServing/Bond_Document_Server.aspx');", true);
}
}
protected void Button_Append_New_Note_Click(object sender, EventArgs e)
{
string bondID = Request.QueryString["BondID"];
string UserID = Request.Cookies["UserID"].Value;
string newNote = TextArea_New_Note.Value;
if (String.IsNullOrWhiteSpace(newNote))
{
return;
}
cmd = new SqlCommand("INSERT INTO Bond_Notes " +
"(Bond_ID, Created_DateTime, Created_By, Note) " +
"VALUES " +
"(#Bond_ID, #Created_DateTime, #Created_By, #Note)", conn);
cmd.Parameters.AddWithValue("#Bond_ID", bondID);
cmd.Parameters.AddWithValue("#Created_DateTime", DateTime.Now);
cmd.Parameters.AddWithValue("#Created_By", UserID);
cmd.Parameters.AddWithValue("#Note", (String.IsNullOrWhiteSpace(newNote) ? (object)DBNull.Value : newNote));
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
TextArea_New_Note.Value = "";
bindNotes(bondID);
}
So when the user clicks "Button_Append_New_Note", the code will fire to run the sqlcommand and then refreshes the ListView by calling the "bindNotes(bondID)". If the user clicks F5 or hits refresh for whatever reason, they are resubmitting that form and add duplicates. I've read many solutions to redirect to the same page, this will not work in my case since the div would be hidden again and I would prefer the Notes div to stay visible so the user can see their new note in the listview. I also prefer not to have an sql check to look for a duplicate and prevent an insert since I may want the user to insert duplicates if they chose to at another time, but the user would manually type in the duplicate.
Any recommendations or suggestions on how to avoid the form resubmission?
Also please no criticizing on the code, I am looking for answers, not a lecture on why its bad to build an SQL sentence with inline string addition. I will correct and optimize these faults eventually.
If you found my solution elsewhere, please ensure it would work in my case cause I have found my same question many times, but not with my scenario.
Thanks in advance.

As you probably know, ASP.NET Web Forms send POST requests back to the server and then re-render the Page in the same request. This is why we see the form re-submission message when we click "reload".
To avoid this issue, we should employ the post-then-redirect pattern used by many web applications. Here's a quick overview:
A user clicks a button which submits the form as a POST request.
The server receives the request and saves the data.
The server issues a redirect response along with any needed state.
The browser receives the redirect and loads the appropriate page by sending a GET request.
Because we redirect the browser to a new (or the same) location, this clears the POST data from the previous request so we can hit "reload" without re-submitting the same data again. The URL that we redirect to should contain only the data needed for the server to interpret what to display on the page. This pattern provides a durable way to maintain state between requests in HTTP.
To apply this to the Web Form in the question, we need to change some assumptions about how the page loads. Instead of binding the notes to the page after running each POST action, we'll redirect the user first, and then bind the notes:
protected void Button_Append_New_Note_Click(object sender, EventArgs e)
{
string bondID = Request.QueryString["BondID"];
// Save the new note...
Response.Redirect("http://example.com/Page.aspx?BondID=" + bondID);
}
Then, when the browser loads the redirect:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindNotes(Request.QueryString["BondID"]);
}
}
We'll need to change each of the post-back methods to use this pattern. Some of the methods may need to add additional parameters to the redirect URL that the page reads to configure the display.

This is quite easy and blocks the pop up asking for form resubmission on refresh once the form is submitted. Just place this line of javascript code at the footer of your file and see the magic.
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>

Related

FindControl() always returns null from DataList Textbox

I have 8 items in a SQL table with a Description, ItemNumber, and ImagePath.
protected void Page_Load(object sender, EventArgs e)
{
//fill the datalist for the Signs Table
string tCallFrom = "Program." + System.Reflection.MethodBase.GetCurrentMethod().Name;
string tQry = #"SELECT * FROM [js_Signs]";
DataTable tblSigns = objCommMethods.fReturnTableFromQry(clsDBSelect.enumDBSelect.ProjectMaster, tQry, tCallFrom);
SignsList.DataSource = tblSigns;
SignsList.DataBind();
}
I am using a DataList to show all of the items along with a textbox that will allow a user to input the number of items they want:
<asp:DataList ID="SignsList" runat="server" RepeatColumns="4" CellPadding="2" Width="90%" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<table>
<tr>
<th>
<%#DataBinder.Eval(Container.DataItem, "Description") %>
</th>
</tr>
<tr>
<th>
<%#DataBinder.Eval(Container.DataItem, "ItemNumber") %>
</th>
</tr>
<tr>
<td>
<asp:Image ID="SignImage" runat="server" ImageUrl='<%#DataBinder.Eval(Container.DataItem, "ImagePath") %>' />
</td>
</tr>
<tr style="text-align: center;">
<td>
<asp:TextBox ID="txtSignQuantity" runat="server" CssClass="txtBox" BackColor="White" Enabled="true"
type="number" min="0" ToolTip="Please choose quantity of signs needed."/>
</td>
</tr>
<tr>
<td>
<p> </p>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
<div class="btnGroup">
<div class="btnDiv">
<asp:Button ID="btnSave" runat="server" Text="Save" CssClass="btnSave" Width="90px" Visible="true" OnClick="btnSave_Click"/>
</div>
<div class="btnDiv">
<asp:Button ID="btnCancel" runat="server" Text="Clear" CssClass="btnCancel" Width="90px" Visible="true" OnClick="btnCancel_Click"/>
</div>
</div>
After the saved button is clicked in C# I want to find out the value that a user entered but it is always returning null:
protected void btnSave_Click(object sender, EventArgs e)
{
TextBox txtSignQuantity;
string tempSignQuantity;
try
{
foreach (DataListItem item in SignsList.Items)
{
txtSignQuantity = item.FindControl("txtSignQuantity") as TextBox;
tempSignQuantity = txtSignQuantity.Text;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
I also checked and the Count of SignsList.Items was 8, so I know that it is retrieving the correct information. Sorry, I've never used a Data List before so I'm not really sure how to go about this...
The short answer is that data binding on postback is causing the problem. Check the Page.IsPostBack property before doing data binding:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//fill the datalist for the Signs Table
string tCallFrom = "Program." + System.Reflection.MethodBase.GetCurrentMethod().Name;
string tQry = #"SELECT * FROM [js_Signs]";
DataTable tblSigns = objCommMethods.fReturnTableFromQry(clsDBSelect.enumDBSelect.ProjectMaster, tQry, tCallFrom);
SignsList.DataSource = tblSigns;
SignsList.DataBind();
}
}
ASP.NET WebForms attempts to abstract away the fact that the control instances that were used to render the page are not the same instances it has when handling postback events. Data binding compounds the abstraction because it has to create controls in response to the DataBind call, and then on postback, recreate them based on the ViewState it saved.
Initializing controls from ViewState happens on the Init event, so when the Load event is fired later in the page lifecycle and you call DataBind on the control, everything it restored gets wiped out and recreated.
As for why you were getting null, it may have been that the controls were wiped out but not recreated; it may have had to do with other event handlers that didn't get rewired after the second data binding.

ASP.NET passing a function return value from a modalpopupextender to the main form

I have looked at a number of solutions to my basic issue, but have not found any solution that I either understand or that would work.
I have a page that takes in two items of information, filename and a store. The user then clicks on a button to execute a function that will update a database and send back a resulting string that I want to display on a textbox on the main form.
However, when they press the button I call a modalpopupextender using an UpdatePanel panel. That gets a value into the modalpopup. If the user validates that the correct store is selected they click an 'okay' button which then call the dbprocessing function that returns a result. The page is small so I'll give the complete aspx and c# code.
The function doProcess() returns a List of values which I convert to String for display. I left the session variables in for that was my last attempt at trying to get this to work.
Where I am confused is that when the first button on the main form (Process) is clicked, there is a postback which obviously hits the page load before the button click. That is when I display the popup. Then when the user clicks on the button Okay, another postback is perform hitting page load before the button click and in that second button I originally tried to set the textbox on the main page because there is no other action after the second click, but no data displayed.
What is strange, if I repeat the process, when I click to display the popup, my data displays. This is not making sense.
This is the aspx page
<%# Page Title="Product Rank Loader" Language="C#" MasterPageFile="~/OMnested.master" AutoEventWireup="true" CodeBehind="ProductRankLoader.aspx.cs" Inherits="OrderManager.ProductRankLoader" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajax" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<script type="text/javascript" src="Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="Scripts/local.js"></script>
<script type="text/javascript">
function callme(thisone)
{
$("#ddlStores").prop('disabled', false);
}
</script>
<div>
<table style="width: 500px">
<tr>
<td>
<asp:Label ID="lblMessage" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:FileUpload ID="fulRanks" runat="server" Width="315px" />
</td>
</tr>
<tr>
<td>
<asp:DropDownList ID="ddlStores" runat="server" Height="16px" Width="155px">
<asp:ListItem Value="0">Select Store</asp:ListItem>
<asp:ListItem Value="10101">Parkseed</asp:ListItem>
<asp:ListItem Value="10151">Wayside</asp:ListItem>
<asp:ListItem Value="10201">Jackson (JP)</asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td style="height: 20px; padding-top: 15px; padding-bottom: 15px; padding-left: 20px;">
<asp:Button ID="btnProcess" runat="server" Text="Process" Width="89px" OnClick="btnProcess_Click" />
</td>
</tr>
<tr>
<td>
**<asp:TextBox ID="txtResults" runat="server" Height="200px" ReadOnly="True" TextMode="MultiLine"></asp:TextBox>**
</td>
</tr>
</table>
<asp:HiddenField ID="hdnFilename" runat="server" />
</div>
<asp:UpdatePanel id="updVerifyChoice" runat="server">
<ContentTemplate>
<div style="display: none;">
<asp:Button ID="btnDummy" UseSubmitBehavior="true" OnClientClick="ShowModalPopup" OnClick="btnDummy_Click" runat="server" />
<%--Dummy Button added to assign the target controlid of PopupExtender--%>
<asp:Button ID="btnDummyButton" UseSubmitBehavior="true" runat="server" Text="DummyButton" Style="display: none;" />
</div>
<asp:Panel ID="pnlVerifyRequestPopup" runat="server">
<div style="background: #fff; padding-left: 3px; border: 1px solid #989898; border-top: 1px solid #989898 !important;">
<table style="background-color: #F7F5F4; width: 300px;">
<tr>
<td><label>Verify Process Request</label></td>
<td style="text-align: right;">
<label class="lbl_3">
<asp:LinkButton ID="lBtnVerifyRequestClose" CssClass="lnkCloseheaderedit" Text="Cancel"
runat="server" OnClick="lBtnBillUpdPopClose_Click" /></label>
</td>
</tr>
<tr>
<td style="width: 150px;" colspan="2">
<asp:Label ID="lblWarn" runat="server" Text="" Font-Size="Medium" ForeColor="#CC3300"></asp:Label>
</td>
</tr>
<tr>
<td colspan="2" class="align_right">
<asp:Button ID="btnPopVerify" runat="server" CssClass="order_searchbtn" Text="Okay"
OnClick="btnPopVerify_Click" />
</td>
</tr>
</table>
<asp:HiddenField ID="hdnReturnData" runat="server" />
</div>
</asp:Panel>
<ajax:ModalPopupExtender ID="extVerifyProcess" runat="server" BehaviorID="extndPopBillUpdBehId"
TargetControlID="btnDummyButton" PopupControlID="pnlVerifyRequestPopup" CancelControlID="lBtnVerifyRequestClose">
</ajax:ModalPopupExtender>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
The field in question that should get the returned values from the function is called txtResults.
Here is the c# code (I cut out unneeded code)
namespace OrderManager
{
public partial class ProductRankLoader : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var currentUser = Request.LogonUserIdentity.Name.Split('\\')[1];
// Session.Add("returnText", "");
var header = Master.FindControl("lblpageheading") as Label;
header.Text = "Product Rank Loader";
if (IsPostBack)
{
try
{
//if (Session["Verified"].ToString() != "")
//{
Session["returnText"] = doProcess();
if (Session["returnText"].ToString() != "")
{
txtResults.Text = Session["returnText"].ToString();
lblMessage.Text = "";
}
//}
}
catch { }
} else
{
Session.Add("returnText", "");
Session.Add("Verified", "");
}
}
protected void btnProcess_Click(object sender, EventArgs e)
{
Boolean fileOK = false;
string filename = Path.GetFileName(fulRanks.FileName);
hdnFilename.Value = filename;
if (fulRanks.HasFile)
{
ddlStores.Enabled = true;
String fileExtension =
System.IO.Path.GetExtension(fulRanks.FileName).ToLower();
String[] allowedExtensions = { ".txt", ".log" };
for (int i = 0; i < allowedExtensions.Length; i++)
{
if (fileExtension == allowedExtensions[i])
{
fileOK = true;
fulRanks.SaveAs(#"c:\temp\" + filename);
}
}
}
if (!fileOK || ddlStores.SelectedIndex <= 0)
{
lblMessage.Text = "Either the file name is incorrect or a store has not been selected.";
return;
} else { }
lblWarn.Text = "You are going to update item Ranks for store <br />" + ddlStores.SelectedItem + ".<br /><br />Press 'Okay' to process";
Session.Add("Verified", "true");
extVerifyProcess.Show();
}
protected void lBtnBillUpdPopClose_Click(object sender, EventArgs e)
{
Session["Verified"] = "";
Session["returnText"] = "";
Response.Redirect("ProductRankLoader.aspx");
}
protected void btnPopVerify_Click(object sender, EventArgs e)
{
//Session["returnText"] = doProcess();
Session.Remove("returnText");
Session.Remove("Verified");
}
private string doProcess()
{
string tmpResults = "";
Int32 store = 0;
if (ddlStores.SelectedIndex > 0)
{
Int32.TryParse(ddlStores.SelectedValue.ToString(), out store);
string filename = hdnFilename.Value;
ProductRankLoaderDLL.ProductRankLoaderDLL newRanks = new ProductRankLoaderDLL.ProductRankLoaderDLL(xxx);
List<string> results = newRanks.ProcessRanks();
foreach (string result in results)
{
tmpResults += result + '\r';
}
// txtResults.Text = tmpResults;
lblMessage.Text = "";
}
else
{
lblMessage.Text = "";
}
return tmpResults;
}
protected void btnDummy_Click(object sender, EventArgs e)
{
}
}
}
If I don't misunderstand your request your problem is caused by the postbacks. I think you can handle better your logic with jquery. For example you can use jquery to close the popup without performing postback:
$('#lBtnVerifyRequestClose').click(function (event) {
event.preventDefault();
$('#pnlVerifyRequestPopup').dialog('close');
});
the event.preventDefault() ensure that postback are not executed.
If you need server logic to put data on your popup you can bind a jquery function to the dialog on open event and retrieve there data / perform your logic. In this way your form will be submitted to the server only once at the end of the process.

Disable asp imagebutton

I am trying to get the image button in this table to get hidden via the code behind in C# (so that I can hide it after an action).
<asp:UpdatePanel runat="server" ID="upEmpListContainer" UpdateMode="Conditional"
OnPreRender="upEmpListContainer_PreRender" OnInit="upEmpListContainer_Oninit">
<ContentTemplate>
<asp:ListView ID="lvEmpList" OnItemDataBound="lvEmpList_ItemDataBound" OnDataBound="lvEmpList_DataBound"
OnLayoutCreated="lvEmpList_LayoutCreated" runat="server" OnPreRender="lvEmpList_PreRender">
<LayoutTemplate>
<table class="formData_tb" cellspacing="0" style="margin: 0px; width: 100%;">
<tr>
<th colspan="9" class="currentManagerLabel" style="text-align: center">
<span>Currently displaying
<asp:Label ID="lblManager" runat="server" />
employees </span>
<asp:ImageButton ID="DrillUp" AlternateText="Move up in reporting heirarchy" runat="server"
CommandName="DrillDown" ImageUrl="~/images/icoDoubleArrowUp.gif" OnCommand="butDrillDown_Click" />
</th>
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
I just can't seem to access it from its ID. I've tried DrillUp.Enabled = false; but Visual Studio is saying that it can't resolve symbol 'DrillUp'.
Your imagebutton is inside layout template, you cant access it directly.
Try this
ImageButton b = (ImageButton)lvEmpList.FindControl("DrillUp");
b.Visible = false;
In your code behind method lvEmpList_ItemDataBound, you need to use the following:
((e.Item.FindControl("DrillUp")) as ImageButton).Visible = false;
Also, you should add a check that this is done only for the DataItem items like this:
if (e.Item.ItemType == ListViewItemType.DataItem)
{
((e.Item.FindControl("DrillUp")) as ImageButton).Visible = false;
}
Try to:
1-remove that imagebutton from aspx
1-clean the solution
2- Write manually again that asp:imagebutton...
It will work fine

How to display DIV popup on Gridview row click event in asp.net

I am using a web page which contains a grid view with the list of datas in that. I want to display the selected grid view row details into a popup or dialogue window on row click event.For that I have created one DIV and design it with proper control values. But I am not able to display the DIV on row click event.
Here is my Source code:
<div id="divPopup" runat="server" style="border:1px solid black;display:none ">
<fieldset>
<legend>Disabling User Account</legend>
<table style="height: 112px; font-weight: 700; font-size: medium; font-family: Cambria; color: #000000; width: 316px">
<tr>
<td>
<asp:Label ID="lblGlobalId1" runat="server" Text="Global ID" />
</td>
<td>
</td>
<td>
<asp:Label ID="lblGlobalIdValue1" runat="server" Text="80007929" />
</td>
</tr>
.......
.......
<asp:Button ID="btnContinue1" runat="server" Height="26px" style="font-weight: 700"
Text="Continue" Width="92px" />
</table>
</fieldset>
</div>
.aspx Code is,
protected void grdADActionList_RowDataBound(object sender, GridViewRowEventArgs e)
{
foreach (GridViewRow gvr in grdADActionList.Rows)
{
e.Row.Attributes["onmouseover"] = "this.style.cursor='hand';this.style.background='#eeff00';";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';this.style.background='#ffffff';";
e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.grdADActionList, "Select$" + e.Row.RowIndex);
}
}
protected void grdADActionList_SelectedIndexChanged(object sender, EventArgs e)
{
//lblGlobalIDValue.Text = "278900078";
//lblGivenNameValue.Text = "Surya";
//lblEmailValue.Text = "surya#abc.com";
divPopup.Visible = true;
}
On page load event I am disabling that DIV visibility and on SelectedIndexChanged event I am enabling the DIV control visibility but the DIV control could not appear on the page. Can you please let me know How can i display the DIV popup control on my page? also I want to display it on the page center.
Please suggest me about the problem and tell me the solution for the same.
Thanks.

Passing variables to javascript in onclientclick

Okay, i think i've tried 3-4 methods here from stackoverflow, but none seems to work.
I've got:
OnClientClick='<%# Eval("albumName", "doConfirm(\"delete\", \"{0}\");").ToString() %>'
but in html it renders as:
onclick="doConfirm("delete", "Test");"
Also tried making a method to call:
public string CreateConfirmation(String action, String item) {
return String.Format(#"return confirm('Sikker på du vil {0}: {1}');", action, item);
}
With this:
OnClientClick='<%# CreateConfirmation("delete", (string)Eval(albumName)) %>'
But gives me exact same problem....
So im pretty lost?
I apologize in advance for such a long answer, but I wanted to be thorough.
This is apparently a "security" feature in .Net 4.0 (and higher). You can read more about it at:
http://avinashsing.sunkur.com/2010/10/29/asp-net-html-encoding-attributes-in-server-controls/
http://forums.asp.net/p/1554455/3818604.aspx
Stop the tag builder escaping single quotes ASP.NET MVC 2
All of the above links also recommend declaring a public class to override the behavior:
public class HtmlAttributeNoEncoding : System.Web.Util.HttpEncoder
{
protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
{
output.Write(value);
}
}
and then adding this to the <system.web> element in your web.config:
<httpRuntime encoderType="HtmlAttributeNoEncoding"/>
This definitely fixes the rendering problem, so that quotes and apostrophes render as " and ' (as expected).
That said, I tested your problem with the following:
<script type="text/javascript">
var doConfirm = function (action, item) {
alert('Sikker på du vil ' + action + ': ' + item);
return false;
};
</script>
<p>Some "arbitrary" text. <asp:Button ID="Button3" runat="server" Text="Button" OnClientClick="doConfirm('delete', 'myalbum');" /></p>
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick='<%# Eval("albumName", "doConfirm(\"delete\", \"{0}\");").ToString() %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Album Name" DataField="albumName" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="Button2" runat="server" Text="Button" OnClientClick='<%# CreateConfirmation("delete", (string)Eval("albumName")) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and in the code-behind:
public partial class _Default : System.Web.UI.Page
{
public string CreateConfirmation(String action, String item)
{
return String.Format(#"return doConfirm('{0}', '{1}');", action, item);
}
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
DataColumn dc = new DataColumn("albumName", typeof(string));
DataRow dr = null;
dt.Columns.Add(dc);
dr = dt.NewRow();
dr["albumName"] = "Zen Arcade";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["albumName"] = "New Day Rising";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["albumName"] = "Candy Apple Grey";
dt.Rows.Add(dr);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
I was able to duplicate your rendering problem:
<p>Some "arbitrary" text.
<input type="submit" onclick="doConfirm('delete', 'myalbum');" value="Button" name="ctl00$MainContent$Button3" id="MainContent_Button3" />
</p>
<div>
<table cellspacing="0" rules="all" border="1" id="MainContent_GridView1"
style="border-collapse:collapse;">
<tr>
<th scope="col"> </th>
<th scope="col">Album Name</th>
<th scope="col"> </th>
<th scope="col">albumName</th>
</tr>
<tr>
<td>
<input type="submit" onclick="doConfirm("delete", "Zen Arcade");" value="Button" name="ctl00$MainContent$GridView1$ctl02$Button1" id="MainContent_GridView1_Button1_0" />
</td>
<td>Zen Arcade</td>
<td>
<input type="submit" onclick="return doConfirm('delete', 'Zen Arcade');" value="Button" name="ctl00$MainContent$GridView1$ctl02$Button2" id="MainContent_GridView1_Button2_0" />
</td>
<td>Zen Arcade</td>
</tr>
<tr>
<td>
<input type="submit" onclick="doConfirm("delete", "New Day Rising");" value="Button" name="ctl00$MainContent$GridView1$ctl03$Button1" id="MainContent_GridView1_Button1_1" />
</td>
<td>New Day Rising</td>
<td>
<input type="submit" onclick="return doConfirm('delete', 'New Day Rising');" value="Button" name="ctl00$MainContent$GridView1$ctl03$Button2" id="MainContent_GridView1_Button2_1" />
</td>
<td>New Day Rising</td>
</tr>
<tr>
<td>
<input type="submit" onclick="doConfirm("delete", "Candy Apple Grey");" value="Button" name="ctl00$MainContent$GridView1$ctl04$Button1" id="MainContent_GridView1_Button1_2" />
</td>
<td>Candy Apple Grey</td>
<td>
<input type="submit" onclick="return doConfirm('delete', 'Candy Apple Grey');" value="Button" name="ctl00$MainContent$GridView1$ctl04$Button2" id="MainContent_GridView1_Button2_2" />
</td>
<td>Candy Apple Grey</td>
</tr>
</table>
</div>
When any of the buttons were clicked, the JavaScript function ignored the HTML encoding, alerting me to:
Sikker på du vil delete: Zen Arcade
so while it looks funky in the source, having quotes and apostrophes render as " and ' doesn't really appear to affect anything.
Try the following:
<asp:Button OnClientClick="Delete(this);" Text='<%# Eval("albumName"); %>' />
JS:
function Delete(element) {
var value = element.value;
return confirm('Delete' + value + '?');
}
Just attach the event server side inside rowDataBound event like, (you can replace linkbutton with Button)
LinkButton myLinkButton=(LinkButton)e.row.FindControl("yourButtonName");
if(myLinkButton!=null)
{
myLinkButton.Attributes.Add("onclick","javascript:return confirm ('Are you sure you want to delete "+ DataBinder.Eval(e.row.DataItem, "YourDbField") + " ?');");
}
Even though this question is 5 years old, I wanted to follow up as I had the same issue with an ImageButton and was able to resolve it using a HiddenField.
Background: I have a Web User Control which I wanted to have a help button displayed if there was help available.
I added a HiddenField and an ImageButton to the User Control. I then created a property on the control so the developer may add help text.
ASPX Page
<asp:HiddenField ID="hidHelpText" runat="server" />
<asp:ImageButton ID="imgHelp" runat="server" ImageUrl="~/images/help.png" Visible="False" />
Code Behind (CS File)
public string HelpText
{
get { return hidHelpText.Value; }
set { hidHelpText.Value = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
imgHelp.Visible = !string.IsNullOrEmpty(HelpText);
imgHelp.OnClientClick = string.Format("MsgBox({0}.value, MessageButtons.OK); return false;", hidHelpText.ClientID);
}
This gets around the issue as the text belongs to the hidden field instead of trying to include it within the JavaScript for the OnClientClick property.
BTW: I cannot copy and paste so this code may contain some typos but I believe it is correct. At least it points the way so you may be able to work around the issue.

Categories