2016-10-11 7 views
0

最初のクリックでボタンを無効にして、トランザクションが複数回送信されないようにしています。画面にエラーがあり、それらをフォームに送り返すと、ボタンはまだ無効になっているため、フォームを再送信することはできません。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"> 
       @[email protected]rrent.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"> 
       [email protected]("{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"> 
       [email protected]("{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"); 
    } 

リターンビュー( "WebPayment");それが価値チェックの後に返送される方法です。

EDIT2

オーケー、それは投稿されていない理由を、私は考え出しました。 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; } 
} 
+0

私は、このボタンを有効にするために、タイムアウトを使用しているが、あなたがボタンをrenableするために、コールバックのいくつかの種類を必要とするフォームを送信し、エラーや成功のために見て、バック – Emil

+2

をボタンを有効にするには、ユーザAJAXをでしょう。 http://jsbin.com/cecibibuco/edit?html,js,console,output –

+0

@JonathanNewton jquery-1.5.1.min.jsを使用していますが、新しいjquery行を追加すると競合が発生します私のヘッダー? – ErocM

答えて

0

これは最善の方法ではないかもしれませんが、ページの読み込み時にボタンを有効にすることはできませんでしたか?最初の負荷では問題はありませんが、それ以降のすべての負荷は有効にリセットされます。こうすることで、ページを読み込むたびに明示的に有効になり、そこから好きなように操作することができます。これは、フォームが送信に失敗した後にページが再ロードされた場合にのみ機能します。

0

あなたは、このコードよりもポストバックを使用している場合は、すべてのリロードボタンを再び有効:

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

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

あなたはエラーハンドラ内で再度有効にする必要がありますジャバスクリプトのいくつかの並べ替えを掲載している場合。

私が気付いたことは、インラインブロックのコードでjQueryを使用することです。ライブラリが既にそこにロードされていることを確認する必要があります。回避策は、そのコードをscriptsセクションに置き、jQueryの読み込み後にレンダリングすることです。

+0

答えに応じて質問を更新しました。 – ErocM

+0

実際には、更新された設定でもボタンが無効になっていません。レンダリングする 'View'名を指定しています。私の場合は、' Action'によって見つけられます。とにかくページがリロードされるはずです。 – Michael

+0

私は混乱しています。そのような場合は、ボタンを有効にしませんか? – ErocM

1

ページを更新したくない場合は、JavaScriptの応答をAjaxコールを使用して処理する必要があります。使用は不正な要求

​​
0

を作る場合は、[完了]のボタンを有効にし、AJAXの機能を「失敗」可能性が応答を返すために、あなたのコントローラーを更新する意味

http://jsbin.com/caguzejopu/1/edit?html,js,console,output

コール。

$('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); 
    }); 
}); 
関連する問題