Fixing multi-submission differently

Take into account dynamic forms
Client validation
This commit is contained in:
Sebastien Ros 2016-04-15 13:03:47 -07:00
parent ac3a0387fa
commit 8ebf58d27d
4 changed files with 98 additions and 82 deletions

View File

@ -8,7 +8,7 @@
Layout.Title = T("New {0}", Html.Raw(typeDisplayName)).Text;
}
@using (Html.BeginFormAntiForgeryPost(Url.Action("Create", new { ReturnUrl = Request.QueryString["ReturnUrl"] }), FormMethod.Post, new { enctype = "multipart/form-data" })) {
@using (Html.BeginFormAntiForgeryPost(Url.Action("Create", new { ReturnUrl = Request.QueryString["ReturnUrl"] }), FormMethod.Post, new { enctype = "multipart/form-data", @class = "no-multisubmit" })) {
@Html.ValidationSummary()
// Model is a Shape, calling Display() so that it is rendered using the most specific template for its Shape type
@Display(Model)

View File

@ -8,7 +8,7 @@
Layout.Title = pageTitle;
}
@using (Html.BeginFormAntiForgeryPost(Url.Action("Edit"), FormMethod.Post, new { enctype = "multipart/form-data" })) {
@using (Html.BeginFormAntiForgeryPost(Url.Action("Edit"), FormMethod.Post, new { enctype = "multipart/form-data", @class= "no-multisubmit" })) {
@Html.ValidationSummary()
// Model is a Shape, calling Display() so that it is rendered using the most specific template for its Shape type
@Display(Model)

View File

@ -81,14 +81,30 @@
$("input[type=checkbox]:not(:disabled)").prop('checked', $(this).prop("checked"))
});
//Prevent double-click on buttons of type "submit"
$("form button[type='submit'], form input[type='submit']").click(function (e) {
var form = $(this).closest("form")[0];
if (typeof(form.formSubmitted) != "undefined") {
//Prevent multi submissions on forms
$("body").on("submit", "form.no-multisubmit", function (e) {
var submittingClass = "submitting";
form = $(this);
if (form.hasClass(submittingClass)) {
e.preventDefault();
return;
}
form.formSubmitted = true;
form.addClass(submittingClass);
buttons = form.find("[type='submit']");
buttons.prop("disabled", true)
// safety-nest in case the form didn't refresh the page
setTimeout(function () {
form.removeClass(submittingClass);
buttons.prop("disabled", false)
}, 5000);
e.preventDefault();
return;
});
// Handle keypress events in bulk action fieldsets that are part of a single form.

View File

@ -8,10 +8,10 @@ Copyright: 2010, Orchard. All Rights Reserved
**************************************************************
Background: #f3f4f5
Borders:
Borders:
Text: #333333
Secondary Text:
Main Accent:
Secondary Text:
Main Accent:
Links: 1e5d7d
New Links: #3a822e;
*/
@ -52,7 +52,7 @@ blockquote:before, blockquote:after,
q:before, q:after { content: ""; }
blockquote, q { quotes: "" ""; }
/* HTML 5 elements as block */
/* HTML 5 elements as block */
header, footer, aside, nav, article { display: block; }
/* end: reset */
@ -71,8 +71,8 @@ header, footer, aside, nav, article { display: block; }
/* General
***************************************************************/
/* Default font settings.
The font-size 81.3% sets the base font to 13px
/* Default font settings.
The font-size 81.3% sets the base font to 13px
Pixels EMs Percent Points
1px 0.077em 7.7% 1pt
@ -104,17 +104,17 @@ Pixels EMs Percent Points
html, body { height:100%; }
html {
background:#f3f4f5 url(images/adminNavBackground.gif) repeat-y top left;
background:#f3f4f5 url(images/adminNavBackground.gif) repeat-y top left;
color:#333;
}
body {
font-size: 81.3%;
color: #333;
color: #333;
background:#f3f4f5 url(images/adminNavBackground.gif) repeat-y top left;
font-family: Segoe UI,Trebuchet,Arial,Sans-Serif;
line-height:1.6em;
margin:0 auto;
margin:0 auto;
min-width:74em; /* 946px */
padding:0;
}
@ -138,7 +138,7 @@ h1, h2, h3, h4, h5, legend {
font-weight:normal;
}
h1 img, h2 img, h3 img,
h1 img, h2 img, h3 img,
h4 img, h5 img, h6 img {
margin: 0;
}
@ -147,7 +147,7 @@ strong {font-weight:bold;}
.smallText {font-size:1em; line-height:1.4em;}
hr {border:0; height:1px; color:#e4e5e6; background-color:#e4e5e6;}
#header, #footer {
width:100%;
}
@ -258,7 +258,7 @@ ul.disc {list-style:disc inside; margin:12px 0;}
color:#fff;
float:left;
line-height:50px;
position:relative;
position:relative;
text-shadow: rgba(0,0,0,.9) 0px 0px 2px;
}
#page-title {
@ -266,7 +266,7 @@ ul.disc {list-style:disc inside; margin:12px 0;}
top:12px;
left:24px;*/
padding:14px 0 0 260px;
text-shadow:rgba(0,0,0,.1) 0px 0px 1px;
text-shadow:rgba(0,0,0,.1) 0px 0px 1px;
}
#login {
display:block;
@ -424,7 +424,7 @@ ul.menuItems {margin:6px 0 0 0;}
margin:8px 0 0 0;
border: 1px solid #e4e5e6;
clear:both;
/*CSS3 properties*/
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
@ -434,13 +434,13 @@ ul.menuItems {margin:6px 0 0 0;}
background:#2b2b2b;
border:1px solid #404040;
padding:6px 0;
/*CSS3 properties*/
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
box-shadow: inset 0px 0px 1px rgba(64, 64, 64, 1.0), 1px 1px 1px rgba(54, 54, 65, 1.0);
-webkit-box-shadow: inset 0px 0px 1px rgba(64, 64, 64, 1.0), 1px 1px 1px rgba(54, 54, 65, 1.0);
-webkit-box-shadow: inset 0px 0px 1px rgba(64, 64, 64, 1.0), 1px 1px 1px rgba(54, 54, 65, 1.0);
-moz-box-shadow: inset 0px 0px 1px rgba(64, 64, 64, 1.0), 1px 1px 1px rgba(54, 54, 65, 1.0);
}
.section-dashboard h3, .section-new h3,
@ -542,12 +542,12 @@ span.message {
background:#e68585; /* red */
color:#fff;
}
.info {
.info {
background: url(images/info.gif) no-repeat 6px 6px #fff;
border:1px solid #e4e8ee; /* blue */
padding:4px 4px 4px 26px;
}
.error {
.error {
background: url(images/error.gif) no-repeat 6px 6px #fff;
border:1px solid #e5cece; /* red */
padding-left:4px 4px 4px 26px;
@ -585,7 +585,7 @@ label { font-weight:normal; display:block; padding: 0 0 0.3em 0; }
label.forcheckbox { margin:0 0 0 .4em; display:inline; }
label.forradiobutton { margin:0 0 0 .4em; display:inline; }
label.required:after {margin-left: 1ex; content: "*"; color: red; }
legend.required:after {margin-left: 1ex; content: "*"; color: red; }
legend.required:after {margin-left: 1ex; content: "*"; color: red; }
form.inline, form.inline fieldset { /* todo: (heskew) need something other than .inline ... */
display:inline;
@ -707,19 +707,19 @@ button.remove:focus::-moz-focus-inner, .remove.button:focus::-moz-focus-inner {
/*CSS3 properties*/
text-shadow:none;
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0);
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0);
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0);
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0);
box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0);
/*----In ie the first couplet sets the alpha value so 00=transparent and ff=opaque)----*/
/*----In ie the first couplet sets the alpha value so 00=transparent and ff=opaque)----*/
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#fff5f5f5', endColorstr='#ffd9d9d9');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(245, 245, 245, 1.0)), to(rgba(217, 217, 217, 1.0)));
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(245, 245, 245, 1.0)), to(rgba(217, 217, 217, 1.0)));
background: -moz-linear-gradient(top, rgba(245, 245, 245, 1.0), rgba(217, 217, 217, 1.0));
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
border-radius: 2px;
}
button, .button, a.button {
background:#6a7b42;
@ -729,26 +729,26 @@ button, .button, a.button {
display: inline-block;
font: 12px Arial,Helvetica,sans-serif;
padding: 5px 14px 5px 14px;
/*position: relative;*/
text-align: center;
text-decoration: none;
/*----CSS3 properties----*/
text-shadow: rgba(40,53,9,.2) 0px 0px 1px;
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
/*----In ie the first couplet sets the alpha value so 00=transparent and ff=opaque)----*/
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(155, 179, 108, 1.0)), to(rgba(128, 159, 67, 1.0)));
/*----In ie the first couplet sets the alpha value so 00=transparent and ff=opaque)----*/
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(155, 179, 108, 1.0)), to(rgba(128, 159, 67, 1.0)));
background: -moz-linear-gradient(top, rgba(155, 179, 108, 1.0), rgba(128, 159, 67, 1.0));
/*test - base green in pallet is 155,179,108*/
background: -moz-linear-gradient(top, rgba(155, 179, 108, 1.0), rgba(133, 154, 93, 1.0));
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
@ -756,7 +756,7 @@ button, .button, a.button {
.button, a.button /* For link buttons */
{
padding: 5px 14px 5px 14px;
padding: 5px 14px 5px 14px;
}
button, input.button, x:-moz-any-link {
@ -766,25 +766,25 @@ button, input.button, x:-moz-any-link {
button:hover, .button:hover, a.button:hover {
border-color:#3a822e;
color:#eefcec;
text-decoration:none;
text-decoration:none;
background: #809f43;
/*CSS3 properties*/
/*CSS3 properties*/
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff6e7f45', endColorstr='#ff6a7b42');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), to(rgba(106, 123, 66, 1.0)));
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), to(rgba(106, 123, 66, 1.0)));
background: -moz-linear-gradient(top, rgba(110, 127, 69, 1.0), rgba(106, 123, 66, 1.0));
}
button:active, .buton:active, a.button:active {
text-decoration:none;
text-decoration:none;
background:#6a7b42;
border:1px solid #487328;
color:#fff;
/*CSS3 properties*/
text-shadow: rgba(0,0,0,.5) 0px 0px 1px;
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(155, 179, 108, 1.0)), to(rgba(128, 159, 67, 1.0)));
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(155, 179, 108, 1.0)), to(rgba(128, 159, 67, 1.0)));
background: -moz-linear-gradient(top, rgba(155, 179, 108, 1.0), rgba(128, 159, 67, 1.0));
}
button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner {
@ -796,11 +796,11 @@ button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner {
border:1px solid #ababab;
color:#ababab;
cursor:default;
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffeeeeee', endColorstr='#ffeeeeee');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(238, 238, 238, 1.0)), to(rgba(238, 238, 238, 1.0)));
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(238, 238, 238, 1.0)), to(rgba(238, 238, 238, 1.0)));
background: -moz-linear-gradient(top, rgba(238, 238, 238, 1.0), rgba(238, 238, 238, 1.0));
text-shadow: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
@ -812,10 +812,10 @@ button.link {
border:0;
padding:inherit;
text-shadow:none;
-webkit-box-shadow:none;
-moz-box-shadow:none;
-webkit-box-shadow:none;
-moz-box-shadow:none;
box-shadow:none;
filter:none;
filter:none;
-webkit-border-radius:0;
-moz-border-radius:0;
border-radius:0;
@ -852,7 +852,7 @@ button.link {
margin-left:4px;
}
.options
.options
{
margin: 12px 0px 12px 0px;
}
@ -894,7 +894,7 @@ table.items col {
border-spacing:0;
display:table-column;
}
table.items colgroup
table.items colgroup
{
border-spacing:0;
display:table-column-group;
@ -930,14 +930,14 @@ table.items th, table.items td {
padding:8px 12px;
}
table.items td .add
table.items td .add
{
float: right;
}
table.items tr.internal *{
background-color: #eee;
color: grey;
color: grey;
}
/* Content item lists
@ -1032,7 +1032,7 @@ table.items tr:nth-child(odd) {
#main .contentItems > ul > li:nth-child(even),
ul.contentItems > li:nth-child(even) ,
table.items tr:nth-child(even) ,
fieldset.manage-part:nth-child(even),
fieldset.manage-part:nth-child(even),
fieldset.manage-field:nth-child(even) {
background-color: #f9f9f9;
}
@ -1064,22 +1064,22 @@ html.dyn #submit-pager, html.dyn .apply-bulk-actions-auto { display:none; }
border: 1px solid #bdbcbc;
color: #333333;
cursor: pointer;
/*CSS3 properties*/
text-shadow: rgba(0,0,0,.2) 0px 0px 1px;
text-shadow: rgba(0,0,0,.2) 0px 0px 1px;
/*In ie the first couplet sets the alpha value so 00=transparent and ff=opaque)*/
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#fff5f5f5', endColorstr='#ffd9d9d9');
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(245, 245, 245, 1.0)), to(rgba(217, 217, 217, 1.0)));
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(245, 245, 245, 1.0)), to(rgba(217, 217, 217, 1.0)));
background: -moz-linear-gradient(top, rgba(245, 245, 245, 1.0), rgba(217, 217, 217, 1.0));
box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.1);
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.1);
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.1);
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.1);
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.1);
border-radius: 2px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
-moz-border-radius: 2px;
}
@ -1130,7 +1130,7 @@ html.dyn #submit-pager, html.dyn .apply-bulk-actions-auto { display:none; }
padding:0;
}
fieldset.publish-button, fieldset.delete-button, fieldset.save-button {
fieldset.publish-button, fieldset.delete-button, fieldset.save-button {
clear:none;
float:left;
}
@ -1148,12 +1148,12 @@ fieldset.delete-button {
/* Dashboard */
.dashboard
.dashboard
{
padding: 10px 0 0 0;
}
.dashboard .help-item
.dashboard .help-item
{
width: 245px;
min-height: 180px;
@ -1161,12 +1161,12 @@ fieldset.delete-button {
margin: 0 55px 55px 0;
}
.dashboard a:hover
.dashboard a:hover
{
text-decoration: underline;
}
.dashboard p
.dashboard p
{
padding: 0 8px 0px 8px;
}
@ -1230,7 +1230,7 @@ fieldset.delete-button {
color:#ccc;
font-style:italic;
}
#orchard-version
#orchard-version
{
position:relative;
float:right;
@ -1260,7 +1260,7 @@ fieldset.delete-button {
***************************************************************/
html.dir-rtl {
background:#f3f4f5 url(images/adminNavBackground.gif) repeat-y top right;
background:#f3f4f5 url(images/adminNavBackground.gif) repeat-y top right;
color:#333;
}
@ -1365,10 +1365,10 @@ html.dir-rtl {
.dir-rtl span.message {
margin:4px 4px 4px 0;
}
.dir-rtl .info {
.dir-rtl .info {
padding:4px 26px 4px 4px;
}
.dir-rtl .error {
.dir-rtl .error {
padding:4px 26px 4px 4px;
}
@ -1495,7 +1495,7 @@ html.dir-rtl {
margin-left:inherit;
margin-right:10px;
}
.dir-rtl fieldset.publish-button, fieldset.delete-button, .dir-rtl fieldset.save-button {
.dir-rtl fieldset.publish-button, fieldset.delete-button, .dir-rtl fieldset.save-button {
float:right;
}
.dir-rtl fieldset.save-button {
@ -1514,7 +1514,7 @@ html.dir-rtl {
/* Dashboard */
.dir-rtl .dashboard .help-item
.dir-rtl .dashboard .help-item
{
float: right;
margin: 0 0 55px 55px;
@ -1558,7 +1558,7 @@ html.dir-rtl {
/* RTL Fields
***************************************************************/
.dir-rtl #orchard-version
.dir-rtl #orchard-version
{
float:left;
right:inherit;