简体   繁体   English

被javascript禁用的“启用”按钮

[英]Enable button that was disabled by javascript

I am disabling a button on first click to prevent a transaction from being submitted multiple times. 我禁用了第一次单击的按钮,以防止多次提交交易。 If there is an error on screen, and I send them back to the form, the button is still disabled so they cannot resubmit the form. 如果屏幕上出现错误,并且我将其发送回表单,则该按钮仍处于禁用状态,因此他们无法重新提交表单。

This is my form with my javascript: 这是我的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>
}

How do I reenable the button when the form fails to submit due to errors on the form? 当由于表单错误而导致表单提交失败时,如何重新启用按钮?

EDIT1 编辑1

This is my method in my controller that is being called on submit: 这是在提交时被调用的控制器中的方法:

[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");
    }

The return View("WebPayment"); 返回View(“ WebPayment”); is how it is being sent back after the value checks. 是在值检查后将其发送回去的方式。

EDIT2 编辑2

Okay, I figured out why it is not posting. 好的,我弄清楚了为什么它不发布。 The PaymentModel [Required] is stopping the form from continuing which is why the form is not being reloaded. PaymentModel [必需]正在阻止表单继续,这就是为什么不重新加载表单的原因。

If this is the case, how do enable the button if the required failed on my PaymentModel? 在这种情况下,如果我的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; }
}

You would need to handle the response in the JavaScript using an Ajax call if you didn't want to page to refresh. 如果您不想刷新页面,则需要使用Ajax调用来处理JavaScript中的响应。

http://jsbin.com/caguzejopu/1/edit?html,js,console,output http://jsbin.com/caguzejopu/1/edit?html,js,控制台,输出

That means updating your controller to return a response if the use makes a bad request 这意味着如果使用了错误的请求,则更新控制器以返回响应

return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Payment declinded");

This might not be the best way, but couldn't you just set the button to enabled on page load? 这可能不是最好的方法,但是您是否不能仅将按钮设置为在页面加载时启用? On the initial load, it wouldn't matter, but every load after that, it would be reset to enabled. 对于初始负载,这并不重要,但是此后的每次负载都将重置为启用状态。 That way every time you load the page it is explicitly enabled and then you can manipulate it however you like from there. 这样,每次加载页面时,都会显式启用该页面,然后您可以从那里进行任意操作。 Though this would only work if the page is reloaded after the form fails to submit. 虽然这仅在表单提交失败后重新加载页面时才有效。

If you are using postbacks than this code reenables button on every reload: 如果您使用回发,则每次重新加载时此代码都会重新启用按钮:

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(FormCollection collection)
    {
        return View();
    }

If you are posting with some sort of javascript you will have to reenable within error handler. 如果您使用某种JavaScript进行发布,则必须在错误处理程序中重新启用。

The second thing I've notices is that you use jQuery in inline block of code. 我注意到的第二件事是您在内联代码块中使用jQuery。 You have to be sure that the library is already loaded there. 您必须确保该库已在那里加载。 The workaround might be to put that code into the scripts section and render it after jQuery loading. 解决方法可能是将该代码放入scripts部分,并在jQuery加载后呈现。

You could enable the buttons in the 'done' and 'fail' functions of an ajax call. 您可以启用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);
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM