How to restrict user from submitting the form twice? - c#

I have an asp.net form, which allow users to submit a registration form which internally sends/store all these values on SharePoint list using the web-service and hence on submit the page process time is a little lengthier then the normal form.
Mean time before the page gets redirect to a thanks page, user's tend to click the submit button again, which is causing the multipul submission of the same record.
Please suggest a way to restrict this submission, on button click I am using a jquery function for data validation, I have tried using the btn.disable = true method there, but once it reach's the else block (after passing the validation and this is where the disable = true code is) it doesn't submit's the form after reading btn.disable = true statement.
Experts, please show me a path.
Thanks in advance.

See Nathan Long's plugin: https://stackoverflow.com/a/4473801/1414562
{modified to allow re-submit form if an input change}
// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function() {
var $form = $(this);
$form.on('submit',function(e){ //on here instead of bind
if ($form.data('submitted') === true) {
// Previously submitted - don't submit again
e.preventDefault();
} else {
// Mark it so that the next submit can be ignored
$form.data('submitted', true);
}
}).find('input').on('change',function(){
$form.data('submitted',false);
});
// Keep chainability
return this;
};
Use it like this:
$('form').preventDoubleSubmission();

As you've found, if you disable the button in the onclick handler it won't send the request to the server. The simple "hack" to get around this is to, rather than disabling the button right away, use setTimeout to schedule a function to run in, say, 5ms that will disable the button; this will allow the request to be sent to the server before the button is disabled, while not leaving enough time for a person to actually click it twice.

Two ways
Either in Jquery or through C#
Jquery
$("#btnSubmit").live("click",(function(e) {
this.disabled = true;
/Do Something /
this.disabled = false;
return false;}));
C#
protected void btnSubmitClick(object sender, EventArgs e)
{
btnSubmit.Enabled = false;
/Do Something/
btnSubmit.Enabled = true;
}
Hope this helps
Many Thanks
Anna

Related

Hiding browser popups - Watin

I'm using Watin library in a windows forms app. In order to hide the browser I use this instruction :
Settings.Instance.MakeNewIeInstanceVisible = false;
However, it doesn't hide the popups (when simulating a click on an element that opens a popup).
Is there a way to hide them?
You can do it programmatically by running some javascript code and make window.open function to do nothing!
Example
Here is a test page I made that has a very simple form and when the user clicks the Sum button, it sums up numA + numB and it displays the result inside a <span id="result"></span> element. After the result text update, it opens a popup window by calling window.open. In order to make this popup window disappear, we need to eliminate the window.open function:
window['open'] = function() { return false; }
To do that using Watin, we have to use the Eval function and inject the javascript code like this:
browser.Eval("window['open'] = function() { return false; }");
Then all popups are gone for that page load only and we have the wanted result.
Sample C# code
private void buttonPopupdEnabled_Click(object sender, EventArgs e)
{
WatiN.Core.Settings.Instance.MakeNewIeInstanceVisible = false;
IE ie = new IE();
ie.GoTo("http://zikro.gr/dbg/html/watin-disable-popups/");
ie.Eval("window['open'] = function() { return false; }");
ie.TextField(Find.ById("numA")).TypeText("15");
ie.TextField(Find.ById("numB")).TypeText("21");
ie.Button(Find.ById("sum")).Click();
string result = ie.Span(Find.ById("result")).Text;
ie.Close();
labelResult.Text = String.Format("The result is {0}", result);
}
Program running before javascript injection (Popup shows up)
Program running after javascript injection (Popup is gone)
I've checked released notes and found this:
By default WatiN tests make the created Internet Explorer instances
visible to the user. You can run your test invisible by changing the
following setting. Be aware that HTMLDialogs and any popup windows
will be shown even if you set this setting to false (this is default
behavior of Internet Explorer which currently can't be suppressed).
IE.Settings.MakeNewIeInstanceVisible = false; // default is true
Since WatIN haven't updated since 2011, I think you wouldn't expect any new feature support what you want.
I don't know if this could be a workaround but If those popups are not important to you why just don't block all popups?
How to turn off popup blocker through code in Watin?
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WEBOC_POPUPMANAGEMENT
Value = 0 for Off
Value = 1 for On

Prevent Page Caching and Back Button

I am trying to prevent the back button being used by expiring the pages.
I have been trying to find an article on here to help and nothing works.
I have the function below that I call as the first thing on all my pages.
I call it in the Page_Load handler, is that the right place ?
I see no errors which is good, but my application just reacts as if there is no change. The back/forward buttons work and the pages display as normal and don't expire.
UPDATE:
As an added layer of security, what I want is the page to time out so if they use the "back" button they won't get the previous page. I have F5 covered so that doesn't repeat posts, and login is covered, if as I abandon the Session when they log out. But I want to stop the back button showing the previous page and force them to use the app navigation to get around my application.
I've known this functionality to fail penetration testing so I want to cover that off before I get to that point.
J
protected void Page_Load(object sender, EventArgs e)
{
MyWebApplication.SetPageStatus(Response);
....
}
internal static void SetPageStatus(System.Web.HttpResponse oResponse)
{
oResponse.ClearHeaders();
oResponse.ExpiresAbsolute = DateTime.Now;
oResponse.Expires = 0;
oResponse.CacheControl = "no-cache";
oResponse.Buffer = true;
oResponse.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
oResponse.Cache.SetExpires(DateTime.UtcNow);
oResponse.Cache.SetNoStore();
oResponse.Cache.SetRevalidation(System.Web.HttpCacheRevalidation.AllCaches);
}

check if button is disabled

I'm working on an application where the users guesses on a number (7 trues). The app contains of an input field as well as a button, and if the user hasn't got more guesses the input field as well as the button is disabled, and a new button appears (restart).
In my code behind-file is the code for checking if the user has more guesses or not, and if not the following code takes care of the disabling/enabling of the buttons:
code behind-file:
...
btnCheckNr.Enabled = false;
inputBox.Enabled = false;
newGame.Visible = true;
...
I'm not using ViewState but Session state, and every time a postpack is done the fields is back as they were from the start, ie. enabled. Every time the user has made a guess the input field gets focus and the content inside (eg. last guess made) gets selected. This works accept for when the field and button gets disabled, and by that reason I've added a check to see if the input field is disabled or not. If so, focus and selection shall not be done (otherwise I get an error).
However, with this code the input field never gets focus, why is that? Is it something that I'm doing wrong and in that case how could this be accomplished?
Thanks in advance!
external.js:
var Capsule = {
init: function() {
var input = $('#inputBox');
if (!input.is(":disabled"))
input.focus();
input.select();
}
}
}
window.onload = Capsule.init;
Try triggering a click instead:
input.click().select();
Demo.

Changing button event after button click in C#

I've a form that navigates webpage and access data. It looks like something below.
private void LoginButton_Click(object sender, EventArgs e)
{
if(LoginButton.Text == Login)
{
LoginButton.Text = "Logging in...";
....
...
Login process goes here...
..
if(Login Successed)
{
LoginButton.Text ="Download";
}
else
{
LoginButton.Text = "Login";
}
}
else if(LoginButton.Text==Download)
{
Download data here...
}
}
Same button(And same event too), doing two process and seems like different events with a label.
1) If there any problem like inefficiency run?
2) Any alternate ways to do this like different flag schemes?
3) Any method to have with more than one event for same button to achieve same idea?
Thanks.
1) If there any problem like inefficiency run?
Button clicks run at human time. You can burn half a billion cpu instructions without inconveniencing the user.
2) Any alternate ways to do this like different flag schemes?
Using the Text property of the button is fragile, your code will break when somebody decides to change the button text or when you localize your app to another language. A simple private bool field in your class is much better.
3) Any method to have with more than one event for same button to achieve same idea?
No. You could of course use two buttons, placed on top of each other and one of them always hidden. Makes localization much simpler and you'll get that bool field for free.
like Daniel A. White said
have two buttons
may be on some event like oncreate/onload do check..jst a pseudo code
if process is login then
do
//then showLoginButton
btnlogin.visible
else
//download
btndonload.visible
inside the login button
if(Login Successed)
{
btndonload.visible
}
else
{
LoginButton.Text = "Login";
}
this may be better with two buttons then single..and cleaner also
Write custom event handlers for the mouseClick
Write separate methods for login and download.
Register your custom event handlers to the button click event
I assume there is some logic that decides that the button text should be "download" or "login". At that point, set the button text of course, but also register the appropriate event handler.
This will allow you to have a single button that does anything
protected void Login_MouseClickHandler (object obj ,MouseClickEventArgs e) {
// login logic
// this would be the logic you say is "inside the login button"
}
protected void Download_MouseClickHandler (object obj ,MouseClickEventArgs e) {
// download logic
}
// pseudo code
// note that there is only one button
if process is login then
theButton.text = "login"
theButton.MouseClick += new MouseClickEventHandler(Login_MouseClickHandler)
else
button.text = "download"
theButton.MouseClick += new MouseClickEventHandler (Download_MouseClickHandler)
end if
Software Design Thoughts
Easier to extend. We don't need another button for every new thing to do
Separation of Concerns - All login code, for example, is in a separate method that does only login stuff.
Change is isolated and minimized. Writing new, separate methods is less error prone than in-lining that code in your if else structure. And consequently the if else structure is kept simple and comprehensible.
It is generally a bad idea use the text as the state. Ideally, you should have 2 buttons that fire different events and call out the main logic to a presenter in the MVP pattern.
Use control containers such as Panel and GroupBox. You can have a whole bunch of Panels for controls in different states.

Force a validation group to fail if a condition isn't met

I have a group of text boxes that have required field validation hooked up to them. Obviously they all share the same validation group name. I have a check box for terms of service that needs to be checked before clicking on the submit button actually does anything.
Is there some C# code that will say if this box isn't checked, fail the validation group?
Or is there a better way?
edit:
I added a custom validator and used this in my code behind. Does not work.
protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = false;
if (cbxTerms.Checked)
args.IsValid = true;
}
If I were to do this, I would just use JavaScript. When the page loads, attach a client side event handler to the buttons submit. Inside the handler check to see if the checkbox is checked, if so then return true otherwise return false which should cancel the submit. If JavaScript is turned off then thats OK too because you should have some server side validation happening because people can sumbit forms in other ways as well.
You can do what you did above but with a return if not checked like that
if (!cbxTerms.Checked)
{requiredlabel.text="*";
return;}
You can set a label manually to tell the user that ths field is needed
you can even prevent postback if checkbox is not checked
Button1.Attributes["onclick"] =
"if (!$get('" + CheckBox1.ClientID + "').checked){alert('Agree with us,plz!');return false;}";
why doing all the validation stuff if it can be prevented :)
or if you thurst for forcing group to invalid tou can do it win your own validation on client side:
function myStartUpValidation(group){
var result=true;
//Page_ClientValidate(group); to validate group
for (var i = 0; i < Page_Validators.length; i++) {
if(Page_Validators[i].validationGroup==group){
try{
ValidatorValidate(Page_Validators[i]); //this forces validation in all groups
if(Page_Validators[i].isvalid==false){result=false;}
}catch(err){}
}
}
return result;
}
or an extra validator...
Scott Mitchell had an article on this.
https://web.archive.org/web/20211020153238/https://www.4guysfromrolla.com/articles/121907-1.aspx
https://web.archive.org/web/20210304131838/https://www.4guysfromrolla.com/articles/092006-1.aspx
I think it's a slightly different approach, but I used it a while ago to handle a similar situation and it seemed to work pretty well.
I figured out how to do it. I made a textbox, assigned a req field validator to it. Put the textbox 99999px off the screen. In my c# i said if the check box is checked, the textbox.text = ""; in the checkbox check changed event I said if the check box is checked then the textbox.text = "1";. Much easier than any other solution I could find
Edit: Better to use a hidden field.

Categories

Resources