我在第一次点击时禁用了一个按钮,以防止多次提交交易。如果屏幕上出现错误,并将其发送回表单,则该按钮仍处于禁用状态,因此无法重新提交表单。
这是我的javascript形式:
@using SuburbanCustPortal.sessions
@model SuburbanCustPortal.Models.PaymentModel.WebPayment
@{
ViewBag.Title = "Make a payment!";
}
@if (CurrentCustomerSession.Current.TokenShowHideSettings.ShowPaymentScreenMessage)
{
<div class="CompanyMessage">
@Html.Raw(@CurrentCustomerSession.Current.TokenSettings.PaymentScreenMessage)
</div>
}
@using (Html.BeginForm("WebPaymentSubmit", "Payment", FormMethod.Post))
{
<div>
<fieldset>
<legend>Please enter the amount of the payment below.</legend>
<div class="paymentPageMargin">
<div class="paymentBlock">
<div class="block_container">
<div class="serviceBox1 paymentBlockTextLeft payment-label-nomargin">
Account Number:
</div>
<div class="serviceBox2 paymentBlockText payment-label-nomargin">
@CurrentCustomerSession.Current.Branch-@CurrentCustomerSession.Current.AccountNumber
</div>
</div>
@if (CurrentCustomerSession.Current.CurrentCustomer.BudgetRate > 0)
{
<div class="block_container">
<div class="serviceBox1 paymentBlockTextLeft payment-label-nomargin">
Budget Rate:
</div>
<div class="serviceBox2 paymentBlockText payment-label-nomargin">
$@string.Format("{0:F2}", CurrentCustomerSession.Current.CurrentCustomer.BudgetRate)
</div>
</div>
<div class="block_container">
<div class="serviceBox1 paymentBlockTextLeft payment-label-nomargin">
Budget Balance:
</div>
<div class="serviceBox2 paymentBlockText payment-label-nomargin">
$@string.Format("{0:F2}", CurrentCustomerSession.Current.CurrentCustomer.BudgetBalance)
</div>
</div>
}
else
{
<div class="block_container">
<div class="serviceBox1 paymentBlockTextLeft payment-label-nomargin">
Account Balance:
</div>
<div class="serviceBox2 paymentBlockText payment-label-nomargin">
@string.Format("{0:F2}", CurrentCustomerSession.Current.CurrentCustomer.TotalBalance)
</div>
</div>
}
</div>
@Html.ValidationSummary(true, "Submit was unsuccessful. Please correct the following errors.")
<div class="paymentCardTypesMargin">
@if ((bool)CurrentCustomerSession.Current.TokenSettings.CreditCardAcceptsVisa)
{
<img src="../Content/images/visa.jpg" alt="Visa Card" height="27" width="42" />
}
@if ((bool)CurrentCustomerSession.Current.TokenSettings.CreditCardAcceptsAmex)
{
<img src="../Content/images/amex.png" alt="Mastercard" height="27" width="42" />
}
@if ((bool)CurrentCustomerSession.Current.TokenSettings.CreditCardAcceptsMasterCard)
{
<img src="../Content/images/mastercard.jpg" alt="Mastercard" height="27" width="42" />
}
@if ((bool)CurrentCustomerSession.Current.TokenSettings.CreditCardAcceptsDiscover)
{
<img src="../Content/images/discover.gif" alt="Mastercard" height="27" width="42" />
}
</div>
<div class="payment-label width300">
Card Holder's Name
</div>
<div class="editor-field width200">
@Html.TextBoxFor(m => m.NameOnCard, new { @class = "makePaymentTextLeft width200" })
</div>
<div class="block_container">
<div class="payment-label-nomargin serviceBox1 width205">
<p>Billing Street Address</p>
</div>
<div class="payment-label-nomargin serviceBox2 width75">
<p>Billing Zip Code</p>
</div>
</div>
<div class="block_container">
<div class="serviceBox1 width200">
@Html.TextBoxFor(m => m.StreetAddress, new { @class = "makePaymentTextLeft width200" })
</div>
<div class="serviceBox2">
@Html.TextBoxFor(m => m.Zip, new { @class = "makePaymentTextLeft width75" })
</div>
</div>
<div class="payment-label">
Credit Card Number
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.CreditCardNumber, new { @class = "makePaymentTextLeft width200", autocomplete = "off" })
</div>
<div class="block_container">
<div class="serviceBox1 width120">
<p>Expiration Date</p>
</div>
<div class="serviceBox2 width150">
<p>Security Code</p>
</div>
</div>
<div class="block_container">
<div class="serviceBox1 width30">
@Html.TextBoxFor(m => m.CreditCardExpMonth, new { @class = "makePaymentTextLeft width30", @placeholder = "MM", autocomplete = "off" })
</div>
<div class="serviceBox3 width30">
@Html.TextBoxFor(m => m.CreditCardExpYear, new { @class = "makePaymentTextLeft width30", @placeholder = "YY", autocomplete = "off" })
</div>
<div class="serviceBox4 padLeftCvv">
@Html.TextBoxFor(m => m.CreditCardCcv, new { @class = "makePaymentTextLeft width40", autocomplete = "off" })
</div>
</div>
<div class="payment-label">
Payment Amount
</div>
<div class="payment-label-nomargin focus">
@Html.TextBoxFor(m => m.Amount, "{0:F2}", new {@class = "makePaymentTextRight width90", autocomplete = "off"})
</div>
<div class="paymentButton">
<p>
<input id="saveButton" class="typicalbutton" type="submit" value="Pay Now" />
</p>
<script>
// Find ALL <form> tags on your page
$('form').submit(function () {
// On submit disable its submit button
$('input[type=submit]', this).attr('disabled', 'disabled');
});
</script>
</div>
</div>
</fieldset>
</div>
}
如果由于表单上的错误导致表单无法提交,如何重新启用按钮?
EDIT1
这是我的控制器中的方法,在提交时调用:
[Authorize]
[SessionExpireFilter]
public ActionResult WebPaymentSubmit(PaymentModel.WebPayment model)
{
Console.WriteLine("WebPaymentSubmit Clicked!!");
var control = Logging.StartLog();
control.ClassName = System.Reflection.MethodBase.GetCurrentMethod().Name;
try
{
Logging.WriteLog(control, "Start WebPaymentSubmit");
var hasErrors = false;
if( model.Amount <= 0)
{
hasErrors = true;
ModelState.AddModelError("Amount", "Invalid amount.");
}
if (string.IsNullOrEmpty(model.CreditCardNumber) || LuhnsTest.IsValidCreditCardNumber(model.CreditCardNumber))
{
hasErrors = true;
ModelState.AddModelError("CreditCardNumber", "Invalid credit card number.");
}
if (hasErrors)
{
return View("WebPayment");
}
返回视图(&#34; WebPayment&#34;);是在价值检查后如何回送它。
EDIT2
好的,我弄明白为什么不发布。 PaymentModel [Required]正在停止表单的继续,这就是没有重新加载表单的原因。
如果是这种情况,如果我的PaymentModel上的所需失败,如何启用该按钮?
public class WebPayment
{
[Required]
[DataType(DataType.Text)]
public string StreetAddress { get; set; }
[Required]
[DataType(DataType.Text)]
public string Zip { get; set; }
[Required]
[DataType(DataType.Text)]
public string NameOnCard { get; set; }
[Required]
[DataType(DataType.Text)]
public string CreditCardNumber { get; set; }
[Required]
[DataType(DataType.Text)]
public string CreditCardExpMonth { get; set; }
[Required]
[DataType(DataType.Text)]
public string CreditCardExpYear { get; set; }
[Required]
[DataType(DataType.Text)]
public string CreditCardCcv { get; set; }
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)]
public decimal Amount { get; set; }
}
答案 0 :(得分:1)
如果您不想刷新页面,则需要使用Ajax调用来处理JavaScript中的响应。
http://jsbin.com/caguzejopu/1/edit?html,js,console,output
这意味着如果用户提出错误请求,则更新控制器以返回响应
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Payment declinded");
答案 1 :(得分:0)
这可能不是最好的方法,但是你不能只在页面加载时将按钮设置为启用吗?在初始加载时,它没关系,但在此之后的每个加载,它将被重置为启用。这样,每次加载页面时都会显式启用,然后您可以从那里操作它。虽然只有在表单无法提交后重新加载页面时才会有效。
答案 2 :(得分:0)
如果您在每次重新加载时都使用回复而不是此代码重新启用按钮:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(FormCollection collection)
{
return View();
}
如果您使用某种javascript发布,则必须在错误处理程序中重新启用。
我注意到的第二件事是你在内联代码块中使用jQuery。您必须确保该库已经加载。解决方法可能是将该代码放入scripts
部分并在jQuery
加载后进行渲染。
答案 3 :(得分:0)
您可以启用ajax调用的“完成”和“失败”功能中的按钮。
$('form').submit(function (e) {
e.preventDefault(); // Prevent default submit action
$('input[type=submit]', this).prop('disabled', true);
// If you're using client side validation as well
if ($(this).valid() === false) {
$('input[type=submit]', this).prop('disabled', false);
return;
}
// Submit manually with Ajax
$.ajax({
url: $('form').attr("action"),
type: $('form').attr("method"),
data: $('form').serialize(),
}).done(function (data) {
// If returning partial view
//$("#your-form-container").html(data);
// Else returning whole view
$(document.body).html(data); // Haven't tested
// I don't think you need this since the form is refreshed anyway
$('input[type=submit]', this).prop('disabled', false);
}).fail(function() {
$('input[type=submit]', this).prop('disabled', false);
});
});