3

Rails アプリ内で Twitter Bootstrap フレームワークを使用しています。私が解決しようとしているのは、ウィンドウ内でエラーをレンダリングし、ページをリロードしない方法です。

以下に例を示します。

#modalEvent.modal.hide
  .modal-header
    %button.close{"data-dismiss" => "modal", :type => "button"} ×
    %h3 Schedule Form
  = form_for(@schedule, :html => { :class => "form-horizontal"})  do |f|
    .modal-body
      - if @schedule.errors.any?
        #notice.alert.alert-error
          %button.close{"data-dismiss" => "alert"} ×
          %strong Error:
          = pluralize(@schedule.errors.count, "error")
          prohibited #{event_display(@schedule.event)} from being
          saved:
          %ul
            - @schedule.errors.full_messages.each do |msg|
              %li= msg
      .widget-content.nopadding
        .control-group
          = f.label :event_type, :class =>'control-label'
          .controls
            = f.select :event, Schedule::EVENT_TYPES
        #3{:style => 'display:none'}
          .control-group
            = f.label :name, :class =>'control-label'
            .controls
              = f.text_field :result_id, :class => "required error"
        .control-group
          = f.label :date_and_time, :class =>'control-label'
          .controls
            = f.text_field :time, :class => "datepicker", :required => :required, :type => :datetime, "data-date-format" =>"dd/mm/yyyy"
        .control-group
          = f.label :duration, :class =>'control-label'
          .controls
            .input-append
              = f.number_field :duration, :placeholder => 'Time in Minutes', :required => :required
              %span.add-on
                %i.icon-time
            %span.help-block Duration of event in minutes
        .control-group
          = f.label :arrival_time, :class =>'control-label'
          .controls
            .input-append
              = f.number_field :arrival_time, :placeholder => 'Time in Minutes', :required => :required
              %span.add-on
                %i.icon-time
            %span.help-block Time in minutes before event
        .control-group
          = f.label :location, :class =>'control-label'
          .controls
            = select("schedule", "location_id", Location.all.collect { |p| [p.name, p.id] }, {:include_blank => 'None'})
        .control-group
          = f.label :players, :class =>'control-label'
          .controls
            = select(:schedule, :selected_players, @players.map { |p| [full_name(p), p.id] }, {:include_blank => false}, "data-placeholder" => 'Add Players to Lineup', :prompt => 'Add Players to Lineup', :multiple => "multiple")
        #1{:style => 'display:block'}
          -if current_user.admin?
            .control-group
              = f.label :team, :class =>'control-label'
              .controls
                = select("schedule", "team_id", Team.all.collect { |p| [p.name, p.id] }, {:include_blank => 'None'})
          - else
            =f.hidden_field :team_id, :value => current_user.team_id
          .control-group
            = f.label :opponent, :class =>'control-label'
            .controls
              = select("schedule", "opponent_id", Opponent.all.collect { |p| [p.name, p.id] }, {:include_blank => 'None'})
          .control-group
            = f.label :home_or_away, :class =>'control-label'
            .controls
              = f.select :home_or_away, Schedule::HOME_OR_AWAY, {:include_blank => 'None'}
    .modal-footer
      = f.submit 'Save Event', :class => 'btn btn-primary'
      %a.btn.btn-danger{"data-dismiss" => "modal", :href => "#"} Cancel

コントローラ

def create
    @schedule = Schedule.new(params[:schedule])
    @user = User.find(current_user)
    @players = User.where(:team_id => current_user[:team_id]).all

    respond_to do |format|
      if @schedule.save
        Notifier.event_added(@user,@schedule).deliver
        format.html { redirect_to(schedules_url,
                                  :notice => "#{event_display_c(@schedule.event)} vs #{@schedule.opponent.name} was successfully created.") }
        format.json { render :json => @schedule, :status => :created, :location => @schedule }
      else
        format.html { render :action => "new" }
        format.json { render :json => @schedule.errors, :status => :unprocessable_entity }
      end
    end
  end
4

2 に答える 2

2

ページのリロードを回避し、サーバーが提供するエラーメッセージを表示したい場合は、何らかの方法でAJAXを使用する必要があります。それを行う正しい方法はまだ1つではないと思います。まず、 PJAXをグーグルで検索する必要があります。あなたが学ぶべきもう一つのことは、Railsが控えめなJavaScriptを提供することです

また、 simple_form gemを試してみることをお勧めします。これは、AJAXとは関係ありませんが、ビューを単純化するでしょう;)

于 2012-10-29T12:32:13.630 に答える
0

Rails の代わりに PHP/CodeIgniter を使用していますが、これと非常によく似ていますが、モーダル ウィンドウ内でブートストラップを使用しています。

私がしていることは、フォームの送信時にフォーム データをプロセス スクリプトに ajax し、データを検証することです。検証が失敗した場合は、(JSON オブジェクトを介して) エラーとオプションのエラー メッセージを含むコントロール グループ クラスを返します。表示する。検証が成功すると、実行したいアクションが実行され、成功メッセージを表示してモーダルを閉じるようにプログラムに通知する「成功」フラグが返されます。

このサンプルが役に立つかどうか教えてください。そうであれば、私が実行するサーバー側の検証と出力のサンプルを提供できますが、それは ruby​​ ではありません。

ブートストラップ モーダル形式のサンプル フォームを次に示します。

<div class="modal-header">
  <button type="button" class="close" data-dismiss="modal">&times;</button>
  <h3>Add Something</h3>
</div>
<div class="modal-body">
  <form id="your_form">
      <fieldset class="control-group id-group">
        <label>Some ID:</label><input type="text" name="SomeID" /><div class="clear"></div>
        <label>Another ID:</label><input type="text" name="Another ID" /><div class="clear"></div>
      </fieldset>
      <fieldset class="control-group category-group">
        <label>Category 1:</label><input type="text" name="Cat1" /><div class="clear"></div>
        <label>Category 2:</label><input type="text" name="Cat2" /><div class="clear"></div>
      </fieldset>
      <fieldset class="control-group description-group">
        <label>Description:</label><input type="text" name="Description" /><div class="clear"></div>
      </fieldset>
      <div class="clear"></div>
  </form>
  <div class="clear"></div>
  <div class="alert alert-error" id="addError">
  </div>
  <div class="alert alert-success" id="addSuccess">
  </div>
</div>
<div class="modal-footer">
  <a href="#" class="btn" data-dismiss="modal">Cancel</a>
  <a href="#" class="btn btn-primary" id="saveSomethingButton" data-loading-text="Please Wait...">Save</a>
</div>

フォーム送信時の JavaScript 呼び出しのサンプルを次に示します。

$("#saveSomethingButton").click(function() {

  //hide any previous errors should this be a second submit
  $(".alert").hide();
  $(".control-group").removeClass('error');
  $("input").blur();
  //set the save button to a "please wait" state to prevent double submission
  $("#saveSomethingButton").button('loading');

  //post to the validation script - if 
  $.post("<?php echo base_url();?>somecontroller/processfunction", $("#your_form").serialize(), function(data) {

    //if we were successful, show the happiness message and close the modal
    if (data.success == 1) {

      $("#addSuccess").html("<strong>Success! </strong> Something successfully added to database.");
      $("#addSuccess").fadeIn(300, function() {

        setTimeout(function() {

          $("#someModal").modal('hide');
        }, 2000);
      });
    //otherwise, highlight the problem fields and display the error
    } else {

      $("#addError").html("<strong>Error: </strong> "+data.message);
      $("."+data.fieldset).addClass("error");
      $("#addError").fadeIn(300);
      $("."+data.fieldset+":first input:first").focus();
    }
    //reset the button state so that they can correct errors and submit again
    $("#saveSomethingButton").button('reset');
  }, "json");

    //return false to prevent default form submission, which would reload the page
    return false;
});
于 2012-11-03T18:29:45.803 に答える