html button elemenents and onserverclick attribute in asp.net - asp.net

I have been experiencing some very strange behavior using html buttons with the onserverclick attribute. What I am trying to do is use jQuery to designate the default button on the page. By default button I mean the button that is "clicked" when a user hits enter. In testing, I would hit enter while in an input field and sometimes the intended "default" button was clicked and the server side method defined in the corresponding onserverclick attribute was hit. Other times a post back was made without hitting the server method. In order to isolate the issue I created a minimal test case and found some very interesting results.
client side:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" src="/scripts/jquery-1.4.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
<asp:Label ID="_response" runat="server"></asp:Label>
<input id="input1" type="text" />
<input id="input2" type="text" />
<button id="first" type="button" class="defaultBtn" runat="server" onserverclick="ServerMethod1">test1</button>
<button id="second" type="button" runat="server" onserverclick="ServerMethod2">test2</button>
</form>
<script type="text/javascript">
jQuery('form input').keyup(
function(e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$('button.defaultBtn').click();
return true;
}
}
);
</script>
</body>
</html>
server side:
public partial class admin_spikes_ButtonSubmitTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ServerMethod1(object sender, EventArgs e)
{
_response.Text = "server method1 was hit";
}
protected void ServerMethod2(object sender, EventArgs e)
{
_response.Text = "server method2 was hit";
}
}
What I found was that everything worked as expected with this code except when I removed one of the input elements. In Firefox 3.6 and IE 8 when only one input exists on the page, hitting enter does not trigger the onserverclick, it makes a post back without even being jQuery "clicked" or actually "clicked". You can test this by starting with two inputs and clicking "test2". This will output "server method2 was hit". Then just hit enter and the output will be "server method1 was hit. Now take away an input and run the same test. Click "test2" see the results, then hit enter and you will see that nothing will change because the "test1" method was never hit. Does anyone know what is going on?
Thanks
p.s. Chrome worked as expected

Try this:
jQuery('form input').keyup(
function(e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$('#__EVENTTARGET').val($('.defaultBtn').attr('name') );
document.forms[0].submit();
return true;
}
}
);
Or you may use the DefaultButton form's attribute:
<asp:Form runat="server" id="form1" DefaultButton="first">
...
</asp:Form>

Related

ASPX - Reading master page element returns null

I have an anchor link in the master page and trying to assign its href in code behind, but the element is null.
Default.master
<body>
<header>
<asp:Hyperlink ID="ancLogout" runat="Server" Text="Logout" />
</header>
</body>
Default.master.cs
protected void Page_Load(object sender, EventArgs e)
{
if (ancLogout != null)
{
ancLogout.NavigateUrl = String.Format("{0}?logout=1", HttpContext.Current.Request.Url.AbsoluteUri);
}
}
The ancLogout is always null.
have just tried your exact code and theres no issues for me? ... maybe a lower case 'S' on server but shouldn't matter

PageLoad not working as expected in asp.Net Framework

I have seen many posts on this but I still cannot find out why my code is still doing this.
I have 1 aspx page with 2 buttons on. In the pageload I check if it is the first time it loads using (!IsPostBack) and set a few variables I then go on to use in this page.
For some reason that I cannot explain this was working as expected and perfectly, but all of a sudden this section of the code is now being hit every time the page reloads after a button click. Meaning the variables are being newed up again and again and I lose the data every button click now, which is not what I want.
Here is the web form
<!DOCTYPE html>
<%-- --%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script type="text/javascript" src="BrowserTalking.js"></script>
<link href="LandingPage.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="#"/>
<title>Home Page</title>
</head>
<body onload="speaking();">
<form id="form1" runat="server" class="wholeScreenDiv">
<div class="mainColumn">
<asp:Label ID="questionLabel" runat="server" CssClass="questionText"></asp:Label>
<div class="answerRow">
<asp:Button ID="Button1" runat="server" Text="Yes" CssClass="myButton1" OnClick="Button1_Click" />
<asp:Button ID="Button2" runat="server" Text="No" CssClass="myButton2" OnClick="Button2_Click" />
</div>
</div>
<asp:HiddenField runat="server" ID="questionNumber" />
<asp:HiddenField runat="server" ID="SpeechSynthNeeded" />
</form>
</body>
</html>
The JavaScript Method called onload is just using a speech synthesis API and again this was the same before when it was working perfectly.
function speaking() {
var questionNum = document.getElementById("questionNumber").value;
var actualQuestion = "";
var utterance = new SpeechSynthesisUtterance();
utterance.rate = 0.7;
if (document.getElementById("SpeechSynthNeeded").value == "1") {
if (questionNum == 0) {
actualQuestion = 'Can you read and understand this text clearly';
} else if (questionNum == 1) {
actualQuestion = 'Would you still like the information spoken to you?';
} else if (questionNum == 2) {
actualQuestion = "Do you suffer from Aphasia?";
} else if (questionNum == 3) {
actualQuestion = "Do you suffer from Hemianopia";
} else if (questionNum == 4) {
actualQuestion = "Would you like to setup an account?";
}
utterance.text = actualQuestion;
speechSynthesis.speak(utterance);
}
}
and the code behind looks like this
public partial class WebForm1 : System.Web.UI.Page
{
public ApplicationQuestion _Question;
public ApplicationUser _User;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) // Do all of this on the first time this page lods
{
_User = new ApplicationUser();
_Question = new ApplicationQuestion();
questionLabel.Text = _Question.GenerateQuestion(0);
Session["Question"] = _Question;
Session["User"] = _User;
questionNumber.Value = "0";
SpeechSynthNeeded.Value = "1";
}
else // Do all within this else every time a question is answered
{
_Question = (ApplicationQuestion)Session["Question"];
_User = (ApplicationUser)Session["User"];
if (int.TryParse(questionNumber.Value, out int number))
{
number++;
questionNumber.Value = number.ToString();
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if(int.TryParse(questionNumber.Value, out int number))
{
//Generate Next Question
questionLabel.Text = _Question.GenerateQuestion(number);
}
// Add 1 to the questions results list meaning the user answered Yes
_User._QuestionResults.Add(1);
if (int.TryParse(questionNumber.Value, out int number2))
{
// if it is on the first question and they answer yes then set SpeechSynthe Value to 0 so it isnt used in javascript for next question
if (number2 == 1)
{
SpeechSynthNeeded.Value = "0";
}
// if it is on the second question and they answer yes then set SpeechSynthe Value will be set back to 1 so its reactivated
if (number2 == 2)
{
SpeechSynthNeeded.Value = "1";
}
// After Final question redirect to User login page
if (number2 == 5)
{
Response.Redirect("UserLogin.aspx?synthNeeded=" + SpeechSynthNeeded.Value);
}
}
}
When debugging through the issue I get now is when I first click the button it goes into the pageLoad and goes into the Else (Which is what i want), but then the button click method is called and once this is finished it comes back into the page load and goes into the first part of the If/Else, and therefore sets up all the variables again and I lose the data I need.
I don't know if this is something tiny I have changed or I have just lost my mind from looking at it too long, but all Im trying to do is set up an object in the page load, then every button click I add a value to that object and then use that value later down the line. I am putting this object in the session to pull it back down when I need it.
Can anyone tell me why Im hitting the "First" page load again and again even with the use of (!IsPostBack) even after a button click?
Solved,
One of the weirdest and most annoying things that has happened to me yet.
The removal of the line from the aspx page stopped the double page loading and now it works as normal.
Thanks to https://forums.asp.net/t/1004939.aspx?Page_Load+called+twice+ I found someone else had solved the issue from playing around with src="" image tags.
I had added this for a speech recognition API and did not consider this to be making this happen and I still don't know why it does.

Is possible to fire __doPostBack twice?

I'm maintaining an ASP .Net Application that seems somehow duplicate a records e.g. using a page add-user. I was unable to reproduce but I found some code that do something crazy like, on submit:
if(crazy-code()){
__doPostBack() // 2nd
}
and crazy-code also do something like
function crazy-code()
{
...
__doPostBack() // 1st
...
return true;
}
To find out this piece of code is causing the problem, I have been trying to fire both __doPostBack but I was unable to do it.
In theory, what should always happens is when it fire the (1st) __doPostBack, it should send the request and stop/ignore any client code afterward.
if __doPostBack is fired twice, what will be the reasons? the browsers? the speed? ???
The __doPostBack() call will submit the form and it should not call the second one.
I might be wrong, but I think you can reproduce your issue if you hit "Submit" on your web page and after the page reloads hit "F5". Depending on the browser, it will ask something like "resend the from data?". Select "Yes" and check whether your records have been duplicated.
In any case, i think you need to add the checks for duplicated values when you insert the data on the server side.
I was able to create a testing code. in FF and chrome seems to work fine (1 submit) but the IE9 (and compatibility version) seems to hit 1, 2 or 3 times.
NOTE: the submit() cause the postback.
CASE 1. delay in Javascript
Page:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>testing</title>
<script type="text/javascript">
function submitForm() {
document.forms[0].submit();
alert("delay");
document.forms[0].submit();
}
</script>
</head>
<body>
<form id="form1" name="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server" Width="220px"></asp:TextBox>
<button onclick="submitForm(this)">CLICK</button>
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack)
{
incrementVal();
}
}
private void incrementVal()
{
var val = (int)(Session["val_" + TextBox1.Text] ?? 0);
val++;
Label1.Text += TextBox1.Text + ": " + val.ToString("00") + " - " + DateTime.Now.ToLongTimeString() + "<br/>";
Session["val_" + TextBox1.Text] = val;
}
CASE 2: Slow Response
remove JS Alert:
function submitForm() {
document.forms[0].submit();
document.forms[0].submit();
}
add delay in the server side:
if(IsPostBack)
{
incrementVal();
Thread.Sleep(500);
}

Disable buttons on post back using jquery in .net app

I have a asp.net app that I want to disable the buttons as soon as they are clicked in order to prevent multiple submissions. I'd like to use jquery for this as the site already liberally uses it anyway.
What I've tried is:
$(document).ready(function () {
$("#aspnetForm").submit(function () {
$('input[type=submit]', $(this)).attr("disabled", "disabled");
})
});
The above will disable the button, and the page submits, but the asp.net button on click handler is never called. Simply removing the above and the buttons work as normal.
Is there a better way? Or, rather, what am I doing wrong?
UPDATE
Okay, I finally had a little time to put a very simple page together.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="SubTest.aspx.cs" Inherits="MyTesting.SubTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#form1").submit(function () {
$('input[type=submit]', $(this)).attr("disabled", "disabled");
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
<asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button 2" />
</div>
</form>
</body>
</html>
The code behind looks like:
using System;
namespace MyTesting {
public partial class SubTest : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (IsPostBack) {
// this will execute when any button is pressed
Response.Write("postback");
}
}
protected void Button1_Click(object sender, EventArgs e) {
// never executes
System.Threading.Thread.Sleep(1000);
Response.Write("Button 1 clicked<br />");
} // method::Button1_Click
protected void Button2_Click(object sender, EventArgs e) {
// never executes
System.Threading.Thread.Sleep(1000);
Response.Write("Button 2 clicked<br />");
} // method::Button2_Click
}
}
When you click on a button it obviously disables the buttons, but NEITHER of the button clicks are run.
Rendered HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#form1").submit(function () {
$('input[type=submit]', $(this)).attr("disabled", "disabled");
});
});
</script>
</head>
<body>
<form name="form1" method="post" action="SubTest.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTcxODU4OTc0MWRkParC5rVFUblFs8AkhNMEtFAWlU4=" />
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKB57WhCAKM54rGBgK7q7GGCC6LlWKFoij9FIBVuI0HOVju/fTy" />
</div>
<div>
<input type="submit" name="Button1" value="Button" id="Button1" />
<input type="submit" name="Button2" value="Button 2" id="Button2" />
</div>
</form>
</body>
</html>
You can do it a slightly different way, like this:
$(function () {
$("#aspnetForm").submit(function () {
$('input[type=submit]').click(function() { return false; });
});
});
What this does is makes future clicks ineffective, basically making them do nothing. When you disable an input, it also removes the key/value pair from being submitted with the <form>, so your server-side action which is triggered by it doesn't work.
It's worth noting, in jQuery 1.4.3 you'll be able to shorten this down to:
$(function () {
$("#aspnetForm").submit(function () {
$('input[type=submit]').click(false);
});
});
The approach of disabling the button before the submit has two effects: -
a) The button takes on the disabled appearance.
b) The button's value is not posted in the form parameters.
If the button's value is not being posted to the server, ASP.Net does not know which button was pressed and thus it does not run the relevent OnClick handler.
To verify add the following to your code behind
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Load " + IsPostBack + "<br />");
foreach (string s in Request.Form.AllKeys)
{
Response.Write(string.Format("s:'{0}' = {1}<br />", s, Request.Form[s]));
}
}
And then run the page (both with J.S. to disable the buttons and without).
If the button's value is not being posted to the server, ASP.Net does not know which button was pressed and thus it does not run the relevent OnClick handler.
Just another observation. Alternatively, you can lock UI with a nice overlay busy message.
The Mark-up part:
$(function() { // when document has loaded
($.unblockUI); //unlock UI
//Show busy message on click event and disable UI
$('#btnHelloWorld').click(function() {
$.blockUI({ message: '<h4><img src="busy.gif" />Please wait...</h4>' });
});
});
<asp:Button ID="btnHelloWorld" runat="server" Text="Hello World" /><br/>
The Code behind:
Protected Sub btnHelloWorld_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnHelloWorld.Click
Label1.Text = "Hello World"
Threading.Thread.Sleep(5000)
End Sub
Check out jQuery BlockUI Plugin
I just wanted to add an additional resolution. We decided to just completely remove the button once it was clicked and replace it with some text.
To do this we did:
$(function () {
$(".DisableButton").click(function () {
$(this).hide();
$(this).after('<p>Please Wait. Retrieving information. This may take up to 60 seconds.</p>');
});
});
Note that this hides the button then injects some html after the buttons code. Hiding it allows .Net to go ahead and run the onclick handler during post back while removing it as a clickable thing on the screen.
Add this attribute to your button:
usesubmitbehavior="False"
This will insert something like the following into onclick:
javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$Main$Tabs$SaveTab$Cancel", "", true, "", "", false, false))
This code will cause a post back even if the button is disabled. Showing a confirmation dialog and allowing the post back to be cancelled gets a little more interesting:
var click = $("[id$='_Cancel']")[0].onclick;
$("[id$='_Cancel']")[0].onclick = null;
$("[id$='_Cancel']").bind('click', function (event) { addFeeSchedule.onCancelClick(event) });
$("[id$='_Cancel']").bind('click', click);
In order to prevent the post back from occurring immediately, remove the onclick code inserted by .net and bind it after your own function using jQuery. Use event.stopImmediatePropagation(), to prevent the post back:
onCancelClick: function (event) {
var confirmResponse;
confirmResponse = confirm('No fee schedule will be created.\n\nAre you sure you want to cancel?');
if (confirmResponse == true) {
showWait();
event.target.disabled = 'true';
} else {
event.stopImmediatePropagation();
}
},
The answer provided by Nick Craver is by far the best solution that I've found anywhere on the net. There is one situation, however, where the solution does not work well - when the form contains submit buttons within an UpdatePanel with it's UpdateMode property set to "Conditional" and/or ChildrenAsTriggers property set to false.
In these situations, the contents of the update panels are not automatically refreshed when the async postback has completed. So if these update panels contained any submit buttons then the given solution would effectively leave these buttons permanently disabled.
The following enhancement to the solution handles this problem by re-enabling the buttons after an async, or 'partial', postback:
var canProcessClicks = true;
if (typeof (Sys) != 'undefined') {
// handle partial-postback
var requestManager = Sys.WebForms.PageRequestManager.getInstance();
requestManager .add_initializeRequest(function() {
// postback started
canProcessClicks = false;
});
requestManager .add_endRequest(function() {
// postback completed
canProcessClicks = true;
});
}
$(function () {
$('input[type=submit]').on("click", function () {
return canProcessClicks ;
});
$("#aspnetForm").submit(function () {
if (typeof (Sys) != 'undefined' && Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
// this is an async postback so ignore because this is already handled
} else {
// full postback started
canProcessClicks = false;
}
});
});
For this you have to use input button attribute disable all the controls
<script language="javascript" type="text/javascript">
function MyDisableFunction() {
alert(`Now You Postback Start`);
$(":input").attr("disabled", true);
return true;
}
</script>
Fore more detail check this link

How to show a message box in an ASP.NET page?

As I was a Windows programmer it was so easy to show a message box on a form.
But on an ASP.NET page I don't know how can I show it?
Actually I have some condition and based on that I want to show a message box to the user to get his/her response and based on that response I want to continue.
For example I want to ask the user "Do you want to continue?" with two buttons "Yes" & "No".
You can do this using JavaScript. Include this snippet in your code -
<script type='text/javascript'>
document.getElementById("someButtonId").onclick = function() {
var confirmation = window.confirm("Are you sure?"); //confirmation variable will contain true/false.
if(confirmation) { /* Write code for Yes */ }
else { /* Write code for No */ }
}
</script>
The only way to show a Yes No dialog, is to design a custom one (Javascript confirm can only produce OK and Cancel).
Luckily, ASP.NET Ajax controls (Ajaxcontroltoolkit) makes this job easy, as you can have a panel as your messagebox with the buttons you want, and have a ModalPopupExtender to imitate a dialog.
EDIT:
For what you ask with javascript, you can do it (and it is a much simpler solution than any seen so far), but prepared to only have OK and Cancel as the two possible answers. UI Designer Nightmare ! :(
Basically, have the following two properties in your aspx page for that button or whatever:
onClientClick = "javascript:confirm('you sure you wanna do this?');" onClick="myButton_Click"
onClick will only run if OK is pressed on the msg dialog.
window.alert(); window.confirm(); and window.prompt();
This is I guess what you are looking for.
You can use
window.confirm
for this.
It displays a modal dialog with a message and two buttons, OK and Cancel.
window.confirm
Eg:
if (window.confirm("Want to see my mood ring?"))
{
// wants to continue
}
else
{
// cancel the action
}
Edit:
You can also develop custom message boxes using jQuery. Here is a nice one
jQuery Impromptu
.aspx markup
<head runat="server">
<title>Sample Page</title>
<script type="text/javascript">
function doSubmit(){
var confirmation = window.confirm("Are you sure?");
document.getElementById("HiddenField1")["value"]=confirmation;
return true;
}
</script>
</head>
<body>
<form id="form1" runat="server" onsubmit="return doSubmit()" >
<div>
<asp:HiddenField ID="HiddenField1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
</form>
</body>
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
if (HiddenField1.Value == "true")
{
}
else
{
}
}
If you REALLY want to have "yes"/"no" buttons (or any buttons that are not your standard OK/Cancel for that matter) you can do the following:
Main page:
<html>
<body>
<script>
function ShowYesNo() {
var answer = window.showModalDialog("myModalDialog.htm", '', "dialogWidth:300px; dialogHeight:200px; center:yes");
document.write('Clicked yes');
} else {
document.write('Clicked no');
}
}
ShowYesNo();
</script>
</body>
</html>
MyModalDialog.htm
<html>
<body>
<p> Do you want to proceed?" </p>
<input type = "button" id = "buttonYes" value = "Yes" onclick = "buttonOnClick('yes')">
<input type = "button" id = "buttonNo" value = "No" onclick = "buttonOnClick('no')">
<script type = "text/javascript">
function buttonOnClick(message) {
window.returnValue = message;
window.close();
}
</script>
</body>
</html>
You can use the confirm JavaScript function, but that will be limited to OK/Cancel as options. If this is not what you want, you can lean on the VBScript MsgBox client-side function. Bear in mind that doing so will only work with Internet Explorer.
function PerformDelete(id)
{
if(confirm("I am about to delete this record. Is this ok?"))
{
//your code here
}
}
i have a solution for you, may be it help you, for using that same message box or conformation dialog of c# in Asp.Net, first you should add namespace,
Using System.Windows.Forms;
then, where you want to call a message box or conformation dialog, you can just call it as simple as in c#, like:
DialogResult dialogResult = MessageBox.Show("Are you shure?", "Some Title",
MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
Response.Redirect("Page.aspx");
}
else if (dialogResult == DialogResult.No)
{
MessageBox.Show("You Select Nothing to do... :(");
}
I think, I explained properly, sorry for any mistake....

Resources