Stop multiple form submissions
#1
Posted 30 December 2009 - 10:56 AM
Is there a YII specific method to stop multiple form submissions (Ex. User double clicking on submit button).
Thanks,
Chamal.
#2
Posted 30 December 2009 - 12:35 PM
#3
Posted 01 January 2010 - 02:53 PM
Mike, on 30 December 2009 - 12:35 PM, said:
I think he was talking about after the user clicks submit but before the form is processed.
You change the action on the submit button so that when the user clicks it that it disables itself and then submits the form you'll probably want to run your client side form validation first before disabling the button. As for a Yii specific method their isn't one specifically that sets it up easily for you. However you can add to the beginform some html options to change the action of the form. something like
CHtml::beginform('yoururl', 'POST', array('onClick'=>'this.disabled=true;this.form.submit();');
#4
Posted 09 January 2010 - 05:52 AM
$cs=Yii::app()->clientScript;
$cs->registerScript('submit','
$(":submit").click(function() {
$(this).attr("disabled",true);
})',CClientScript::POS_READY);
EDIT: This doesn't work on IE (as usual...) so forget it
EDIT (again): This should work on IE too
$cs=Yii::app()->clientScript;
$cs->registerScript('submit','
$(":submit").mouseup(function() {
$(this).attr("disabled",true);
$(this).parents("form").submit();
})',CClientScript::POS_READY);
#5
Posted 23 January 2010 - 10:47 AM
E.g. <input type='submit' name='doAction' value='Send' />
in Controller I need to check:
if(!empty($_POST["MyModel"]) && isset($_POST["doAction"]))
{
$model->attributes = $_POST["MyModel"];
}
But it doesn't work, cos submit not exists in POST query.
#6
Posted 24 January 2010 - 07:43 AM
#7
Posted 01 December 2010 - 10:36 AM
This method works well, I can post code if needed
HYGEN Web Design
#8
Posted 25 January 2011 - 12:59 PM
makro, on 09 January 2010 - 05:52 AM, said:
I liked makro's solution best, thanks! I took it a bit further:
- Color the submit button gray when clicked
- Let the javascript event handler live in a file in the javascript directory, so that all of your javascript lives in one place, and does not live buried in php.
- Register the javascript client script in your main controller. I.e., rather than
cluttering the layout file, override the __construct() function for your default Controller class; so that your site as well as your modules can use it, and so that it works for all layouts.
Here's a working solution (except for Chrome!):
// 1. In your stylesheet, define the style "btn_gray":
btn_gray {
background-color: #efefef;
}
// 2. Create the javascript file, "my-jquery.js", in the /javascript directory:
$(document).ready( function() {
$(":submit").mouseup(function() {
$(this).attr("disabled",true)
.attr("class", "btn_gray")
.parent().attr("class", "btn_gray")
.parents("form").submit();
});
})
// 3. Register the client script, in the constructor for your main Controller
public function __construct($id, CWebModule $module=null) {
parent::__construct($id, $module);
$baseUrl = Yii::app()->request->baseUrl;
$clientScriptUrl = "{$baseUrl}/javascript/my-jquery.js";
$clientScript = Yii::app()->clientScript;
$clientScript->registerScriptFile($clientScriptUrl, CClientScript::POS_HEAD);
// more construct code
}
This works on Firefox, MSIE. It fails on Chrome. If anyone knows why a registered client script might fail on Chrome, kindly update this post!
#9
Posted 25 January 2011 - 08:30 PM
Try this
$(document).ready( function() {
$(":submit").click(function() {
$(this).attr("disabled",true)
.attr("class", "btn_gray")
.parent().attr("class", "btn_gray")
.parents("form").submit();
});
})
if also fails, do not use 'parents()', just use the normal way of submitting or grab the id of the form to do so.
this.form.submit();
$('#formid').submit();
Nite... 3 am here
www.ramirezcobos.com
#10
Posted 25 January 2011 - 10:43 PM
Antonio Ramirez, on 25 January 2011 - 08:30 PM, said:
Antonio, thanks SO much for replying at 3 a.m.!! (Or anytime.)
It turns out that the mouseup event is indeed the event to be handled; I just wasn't doing the form submission correctly, as you suggested. This works now:
$(document).ready( function() {
$(":submit").mouseup(function() {
$(this).attr("disabled",true)
.attr("class", "btn_gray")
.parent().attr("class", "btn_gray");
this.form.submit();
});
})
'Tis, now, a thing of beauty.
Thanks, again, for your help!
#11
Posted 26 January 2011 - 02:42 PM
Actually, this solution works--exactly as you've written it--but it only works if my form consists of one or more inputs, plus a submit button.
IF, however, I create a CActiveForm widget, and only give it a single button, and no inputs, my controller ends up with an empty $_POST. I find this of course by inserting logging into my controller:
if ( empty($_POST)) {
Yii::log("POST IS EMPTY!");
}
Any ideas?
Thanks so much...
Emily
#12
Posted 26 January 2011 - 03:20 PM
The clue you gave me, Antonio, that allowed me to figure this out, is that the submit button is being *disabled*. In the event handler below, we disable the button, color it gray, and then *re-enable* it.
$(document).ready( function() {
$("form").submit(function(event) {
var form = event.currentTarget;
// Disable the button, turn the background gray, and set the text to "Working..."
$("#" + form.id).find("input[type=submit]").attr("disabled",true)
.attr("class", "btn_gray")
.attr("value", "Working...");
// Submit
form.submit();
// Re-enable the button
$("#" + form.id).find("input[type=submit]").attr("disabled",false);
return true;
});
})
Works in FF, MSIE, and Chrome.
Thanks again Antonio and others!
Emily
#13
Posted 26 January 2011 - 07:52 PM
Nevertheless, about your question on the empty Form, weird to drop an empty form but you could easily avoid form submission if form.elements.length are just the total number of buttons.
Anyway, I am wondering why you re-enable your submission button after you have submitted the form? I never done that after submission, only on the AJAX cases, wher e I need to handle buttons state. Any reasons for that?
Thanks in advance
www.ramirezcobos.com
#14
Posted 26 January 2011 - 08:43 PM
I found that disabling button is indeed problematic. So a simpler approach is to unbind the submit button from "click"; change the text to "Working..."; and change the color to gray.
So, here's the final solution, which works on FF, MSIE, and Chrome:
// 1. In your stylesheet, define the style "btn_gray":
btn_gray {
background-color: #efefef;
}
// 2. Create the javascript file, "my-jquery.js", in the /javascript directory:
$(document).ready( function() {
$(":submit").click(function() {
// Only recolor the button if it's inside a "btn btn_green" div
var containingDivClass = $(this).parent().attr("class");
if (containingDivClass == 'btn btn_green') {
$(this).unbind("click").attr("value", "Working...").parent().attr("class", "btn btn_gray");
this.form.submit();
return false; // must do this!!
}
});
// 3. Register the client script, in the constructor for your main Controller
public function __construct($id, CWebModule $module=null) {
parent::__construct($id, $module);
$baseUrl = Yii::app()->request->baseUrl;
$clientScriptUrl = "{$baseUrl}/javascript/my-jquery.js";
$clientScript = Yii::app()->clientScript;
$clientScript->registerScriptFile($clientScriptUrl, CClientScript::POS_HEAD);
// more construct code
}
// 4. Use it, in a view. Explicitly name the button 'doit_button'
echo CHtml::submitButton('Doit', array('name'=>'doit_button'));
// 5. Check explicitly to see if form was submitted (this addresses
// iGrog's question about the $_POST array, above)
if (isset($_POST['doit_button']) )
// do stuff
}
#15
Posted 27 January 2011 - 04:33 PM
If a page contains more than one form, even though only one form got submitted, all of the buttons get disabled, turned gray, etc. A usability issue. Ideas anyone?
#16
Posted 27 January 2011 - 04:52 PM
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application
Gustavo Salomé Silva
#17
Posted 27 January 2011 - 10:32 PM
http://forum.jquery....form-submission
Thanks Antonio and Gustavo!
#18
Posted 27 January 2011 - 11:05 PM
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application
Gustavo Salomé Silva
#19
Posted 22 September 2011 - 02:30 PM
You just have to pass it the rigth selector for the submit button.
place this piece of code at the end of your _form.php partial views (and properly modify the button css selector).
<?php
$no_dbl_click=<<<EOD
$("the_button").click(function(event) {
//extra_js;
var target= $(event.currentTarget);
// console.dir(target);
if(!target.attr('disabled')){
target.attr('rel',target.val());
}
target.attr("disabled",true)
.attr("class", "btn_gray")
.attr("value", "Un moment...");
var the_expr="$('#" + target.attr('id') + "')";
var the_statement=the_expr + '.attr("disabled",false).val(' + the_expr + '.attr("rel"))';
setTimeout(the_statement,2000);
target.parents('form').submit();
return true;
});
EOD;
$js=str_replace('the_button','#form_submit',$no_dbl_click);
Yii::app()->clientScript->registerScript($this->id.'no_dbl_click',$js);
?>
Most important, this works with ajax and clientside validation, so the user may try again and again without reloading the page form. 2 secods is enough for the succesful post to redirect, and should be enough for validation messages to appear.
This code will disable the button for 2 seconds regardless if ajax/clientside form validation fails or succeeds.
It then attemps a submit on the parent form, which is the Yii generated form.

Help
This topic is locked












