2

3 つの同時問題:

  • モーダル フォームのインライン検証が表示されない
  • モーダルフォームが送信されていません
  • ajax送信後に発生するページへの変更をどこで定義しますか? UJS ファイル、js ルートの jquery など。

コンテキストについては、フローは次のとおりです。

  1. 非ユーザーが「購入」ボタンをクリック
  2. 'transactions/form' モーダル フォームが開きます: 新しいトランザクションを作成するフォームと、オプションで新しいユーザー (登録) を作成するフォームが含まれています。
  3. フォームにはストライプクレジットカードフィールドとオプションのパスワード/電子メールフィールドが含まれ、投稿に関する情報の非表示フィールド (ID、価格など...) も含まれています。
  4. ユーザーには次の 2 つのオプションがあります クレジットの詳細のみを入力します b. クレジットの詳細とパスワード/電子メールを入力します。つまり、登録します
  5. 送信をクリック
  6. IF: オプション a、クレジットの詳細のみが入力されている
    • カードを検証する
    • クレジットカードにチャージ
    • モーダルを閉じて、ページに適切な変更を加えます
  7. IF: オプション b、クレジット カード + 登録情報が入力されている
    • カードとユーザーの詳細を検証する
    • ユーザーを作成
    • 顧客を作成して顧客に請求する
    • モーダルを閉じて、ページに適切な変更を加えます
  8. 投稿が「アクティブ」から「非アクティブ」に変更された

client_side_validations ジェムを使用しています。

上記の手順の大まかな順序で、購入ボタン、モーダル フォーム、jquery、コントローラーの詳細を以下に示します。

表示: 購入ボタンとモーダル フォームを使用してアイテムを投稿します。

/button that opens modal form
%a.btn.buy-button{remote: :true,"data-toggle" => "modal", :href => "#buy_modal", :role => "button"} Buy

/the modal form
%div#buy_modal.modal{:role => "dialog",:style=>"display:none"}
  =render :partial => 'transactions/form'

モーダルフォーム:

  =form_for @transaction, :validate => true, :html => {:class => "form"} do |f|
    =yield(:user_validators)
    - if @user.errors.any?
      #error_explanation
      %h2= "#{pluralize(@user.errors.count, "error")} prohibited this group from being saved:"
      %ul
        - @user.errors.full_messages.each do |msg|
          %li= msg

    /POST DETAILS
    = f.hidden_field :stripe_card_token
    = f.hidden_field :price
    = f.hidden_field :tier_id
    = f.hidden_field :premium
    = f.hidden_field :notify_premium
    = f.hidden_field :user_id
    = f.hidden_field :customer_id
    /CREDIT CARD STUFF
    #credit-card{:style => @user.stripe_customer_id ? "display:none" : "display:block"}
      #credit-card-errors{:style => "display:none"}
        #stripe-error-message.alert-message.block-message.error
    %div.row-fluid
      = label_tag :credit_card_number
      = text_field_tag :credit_card_number, params[:credit_card_number], :class=>"credit-number span12"
    %div.row-fluid
      %div.span6
        = label_tag :expiry_date
        = date_select "", :expiry_date, {:discard_day => true, :order => [:month, :year], :use_month_numbers => true, :start_year => Date.today.year, :end_year => Date.today.year + 25}, {:class =>"credit-expiry inline"}
      %div.span3
      %div.span3.credit-cvv
        = label_tag :cvv, "CVV"
        = text_field_tag :cvv, params[:cvv], :class=>"credit-cvv input-block-level"

    /NEW USER STUFF
    =f.label :email
    =f.text_field :email
    =f.label :password
    =text_field_tag :password, params[:password]

    =f.submit "Save"

モーダルを管理する Jquery:

$(document).ready(function() {
  var $buy_dialog = $('#buy_modal').dialog({ 
    autoOpen: false, 
    title: 'Edit',
    modal: true,
    draggable: false,
    buttons: {
                "Save": function() {
                        $("#new_transaction").submit(function(){
                            var valuesToSubmit = $(this).serialize();
                            $.ajax({
                                url: $(this).attr('action'), //sumbits it to the given url of the form
                                data: valuesToSubmit,
                                type: 'POST',
                                dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
                            }).success(function(json){
                                //act on result.
                            });
                            return false;
                        });
                        $('#buy_modal').dialog( "close" );
                },
                Cancel: function() {
                    $( this ).dialog( "close" );
                }
            }

    });

モーダル インライン検証を管理する Jquery

$(document).ready(function(){
    $('.form').enableClientSideValidations();
    $('.form').on('shown', function() {
      $(ClientSideValidations.selectors.forms).validate();
    });
};

トランザクション コントローラ、createアクション:

  def create
    @transaction = Transaction.new(params[:transaction])
    @user = User.new(:email => params[:transaction][:email], :password => params[:password])

    respond_to do |format|
      if params[:password]
        #let's make a user and a transaction object
        if @transaction.save
          @user.save_with_payment
          format.html { redirect_to @transaction, notice: 'Transaction was successfully created.' }
          format.json { render json: @transaction, status: :created, location: @transaction }
        else
          format.html { render action: "new" }
          format.json { render json: @transaction.errors, status: :unprocessable_entity }
        end
      else
        if @transaction.save
          @transaction.payment(params[:transaction][:tier_id],params[:transaction][:price],params[:transaction][:premium],params[:transaction][:premium_notify])
          format.html { redirect_to @transaction, notice: 'Transaction was successfully created.' }
          format.json { render json: @transaction, status: :created, location: @transaction }
        else
          format.html { render action: "new" }
          format.json { render json: @transaction.errors, status: :unprocessable_entity }
        end
      end
    end
  end

ユーザーコントローラー、createアクション:

def create
    @user = User.new(params[:user])
    respond_to do |format|

      #OPTION A, explained above
      if params[:user][:password].nil?
        # Charge the card and don't make a user
        # get the credit card details submitted by the form
        token = params[:stripeToken]

        # create the charge on Stripe's servers - this will charge the user's card
        charge = Stripe::Charge.create(
          :amount => 1000, # amount in cents, again
          :currency => "usd",
          :card => token,
          :description => params[:email]
        )

      #OPTION B, explained above
      else
        # create user, customer, and charge them
        token = params[:stripeToken]
        if @user.save_with_payment(token)
          @user.payment()
          format.html { redirect_to @user, notice: 'User was successfully created.' }
          format.json { render json: @user, status: :created, location: @user }
        else
          #error message
          format.html { render action: "new" }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end
  end

これは膨大な質問だと思いますが、これは非常に一般的なプロジェクト要素です。各コンポーネントへの回答を見つけるためにスタック オーバーフローを調べましたが、その法案に適合するものは何もありませんでした。

jqueryを使用してAjaxの方法でRailsにフォームを送信します

Jquery モーダル ウィンドウと編集オブジェクト

Jquery モーダル ボックス フォームの検証(レールではなく車輪の再発明を試み、ガイダンスは正規のものではありません)

jquery を使用してモーダル ウィンドウでフォーム入力を検証する際の問題(ここには MVC がなく、実際には質問に回答されていません)

jqueryモーダルビューでformtasticを使用したclient_side_validations gemが機能しない(回答なし)

4

1 に答える 1

2

部分的な答え:

モーダル フォームのインライン検証が表示されない

これについてはあなたを助けることはできません

モーダルフォームが送信されていません

  • Rails には CSRF 保護が組み込まれています。必要な CSRF トークンを渡さないため、リクエストが追い出される可能性があります
  • remote: trueフォーム オプションに追加する必要があります。邪魔にならない Rails ドライバーがリクエストを管理し (フォームのシリアル化は必要ありません)、応答に応じてカスタム イベントをトリガーします。詳細については、Rails 3 リモート リンクとフォーム、または単にRails AJAX ガイドを参照してください。

ajax送信後に発生するページへの変更をどこで定義しますか? UJS ファイル、js ルートの jquery など。

html.erb ファイルと同じように、クライアント コンテキストで実行される jQuery ロジックを内部に含む js.erb ファイルで応答できます。

これにもっと詳しく答えようとしましたが、あなたのロジックは非常にビザンチンです(このオプションには保存/フォーマットがないため、コピー/貼り付け中にオプションAのいくつかのステートメントが失われたと思います)。補足として、この種のケースでは、Data-Context-Interaction アーキテクチャが適切になります。

于 2013-02-27T19:53:08.413 に答える