Open dynasource opened 8 years ago
Haven't tried this yet, but pretty sure this:
$brother.insertAfter($button);
Should be:
$brother.after($button);
There is an insertAfter
but it seems by your code you need the after
version :)
Also, the value of $brother
seems inconsistent...
Here:
var $brother = $(document.createElement($button[0].tagName));
You are setting it to an element, but here:
var $brother = $button.data('brother');
You are setting it to a string value.
Lastly, this bit:
$button.data('brother', $brother)
At this point, as noted above, $brother
is set to an element, but you're setting the value of the data type there so it should be a string. :)
Haven't tried this yet
You should. I am not posting a non-working version here ;)
No, I meant I haven't tried the version you posted yet; just made my observations :)
Now I'm update code from #12814 using this solution (brother button)
This is my worked solution
$('.jsBeforeSubmitFormBtn').click(function(){
var $this = $(this);
var $next = $this.next();
if($next.hasClass('jsBeforeSubmitFormBtnBrother')) {
$brotherBtn = $next;
} else {
$brotherBtn = $this.clone();
$brotherBtn.attr('type', 'button');
$brotherBtn.addClass('jsBeforeSubmitFormBtnBrother');
$brotherBtn.removeClass('jsBeforeSubmitFormBtn');
$brotherBtn.insertAfter($this);
$brotherBtn.attr('disabled', 'disabled');
$brotherBtn.prepend('<i class="glyphicon glyphicon-refresh"></i> ');
}
$this.hide();
$brotherBtn.show();
});
$('.jsBeforeSubmitFormBtn').parents('form').on('afterValidate', function (event, messages, errorAttributes) {
if(errorAttributes.length > 0) {
$('.jsBeforeSubmitFormBtn').show();
$('.jsBeforeSubmitFormBtnBrother').hide();
}
});
Spinner and some styles
.jsBeforeSubmitFormBtnBrother {
cursor: progress;
}
.jsBeforeSubmitFormBtnBrother .glyphicon{
-webkit-animation: glyphicon-spin 2s infinite linear;
animation: glyphicon-spin 2s infinite linear;
}
@wartur, thanks for sharing. Nice to see the similarities in this example.
One thing thats left to discuss is how to install this kind of script in an application.
We don't want to add .jsBeforeSubmitFormBtn to all of the buttons so you want a site-wide allocation with a generic CSS selector. IMO the most logical thing to put this locic is inside a SubmitOnceAsset with configuration options for the
@dynasource this is just by business solution. I do not think about deep architechure feaches. If this need to do as framework architecture solution, I think (not holywar) what moust usefull is use some js code attached via class (as I to do in my busintess sulution). That button need to have next feaches (via data attributes):
RUS: Это просто мое бизнес решение. Я особе не задумывался над некой архитектурой.
Если это делать как архитектурное решение, то мое мнение (не холиварю), что удобнее всего сделать такой функционал как я это сделал в моем бизнес решении - через подключаемый класс кнопки. Дополнительные же данные передавать через data-параметры, среди них:
If using jquery how about .one() click function ?
@muhammadcahya I think that would only be useful if you were using jQuery to submit the form in the first place; on regular submissions it wouldn't do anything since you aren't binding any submit events to the button.
perhabs its even better to make this a vanilla script. Not every app uses jquery.
Currently I'm using this approach on my projects:
// Handles beforeSubmit event (after all validations have passed)
jQuery('form.prevent-double-submit').on('beforeSubmit', function(event){
if(jQuery(this).data('submitting')) {
event.preventDefault();
return false;
}
jQuery(this).data('submitting', true);
return true;
});
just experienced that a jQuery version is also not to be preferable in high traffic websites in which jQuery is left out.
As this is quite a hot topic (https://github.com/yiisoft/yii2/issues/10498#issuecomment-253542255, https://github.com/yiisoft/yii2/issues/12803 and more) its a good a idea not to wait too long with solutions. Many hours can be wasted to solve the problem and it is more complex than you would think at first hand.
The problem of this topic is the following:
There are many perspectives to tackle this problem from both serverside and clientside. From clientside, many people try to fix this with disabled buttons. However, disabling will not always prevent a submission. Multiple events can still be triggered, executing the submission anyway.
Another solution is a solution in which a 'ghost' button is used. This one is created on the fly and has the same CSS as its brother. This brother has no functionality and no events attached to it. You can click what you want but its just clicking on a 'useless' dummy. Depending on your configuration:
I have a first version of this solution ready. Its a draft which has not been in production yet. Mabye it already works perfectly, maybe it doesnt, so be advised. Of course, please share improvements.
With respect to installing this script. You only need to have this one installed once so I have 1 asset (SubmitOnceAsset) implementing this script and this asset is loaded through a dependency in my app\common\Asset.php