2016-10-13 12 views
0

ユーザーの選択に応じてネストされたフォームのコピーを生成するフォームを作成しようとしています。私は3つのモデルを持っています:has_manyペインであるhas_many Rowsという可視化。ネストされたフォームでユーザーの選択に基づいて部分的なフォームを動的に生成する

私は、行を生成し、次に1つ、2つ、または3つのペインを選択する小さなドロップダウンメニューをクリックできるようにしたいと考えています。選択に応じて、レンダリングから選択した形式が生成されます。手始めに

here is an example where a user chose 3 panes (3 upload boxes for images) with just styled divs in place of the form

。コントローラを少し変更する必要があることは分かっていますが、ネストされたフォームを使用してどのように行うかはわかりません。今まで見たすべての例で何回「ビルドするのか」をあらかじめ決めておく必要があるため、ネストされたモデルフォーム(正しい用語であるかどうかはわかりません)。私はその部分を動的にする方法がわかりません。ここで

私が何を意味するかです:

:ここ

//visualization_controller.rb 
 

 
def new 
 
    @visualization = Visualization.new 
 
    rows = @visualization.rows.build 
 
    panes = rows.panes.build 
 
    end

はusrがちょうど1ペインで列を生成したい場合、レンダリングそれが呼ばれることになるの例です。

<div class="medium-12 columns one_box_wrapper first" style="display:none"> 
 
    <%= f.fields_for :rows, Row.new do |r| %> 
 
    <%= r.label :rowtitle %> 
 
    <%= r.text_field :rowtitle %> 
 
    <div class="nested" style="display:inline-block"> 
 
      <%= r.fields_for :panes, Pane.new do |p| %> 
 
      <%= p.label :text %> 
 
      <%= p.text_field :text %> 
 
      <div class="mehv"> 
 
       <img id="img_prev" width=300 height=300 src="#" alt="your image" class="img-thumbnail hidden"/> <br/> 
 
       <span class="meh"> 
 
       Upload Pane Image<%= p.file_field :pane_photo, id: "pane_photo" %> 
 
       </span> 
 
       <%= p.hidden_field :pane_photo_cache %> 
 
      </div> 
 
      <% end %> 
 
     </ul> 
 
    </div> 
 
    <% end %> 
 
    </div>

これはレールで可能ですか?私はJavaScriptが有効になるように感じていますが、私はあなたがJSを通してサーバーサイドのコードをレンダリングすることは許されていないと思います。

私はこれで私の頭の中で少し気がして、どんな助けも大歓迎です!

EDIT

私は私の人生はずっと楽しかし..私はインデックスページ上のすべてのディスプレイに視覚化を得ることができない作られているようだとして、繭の宝石を使用して終了!私は問題が何であるか分かりません..カバーのタイトルと画像が表示されますが、他に何も表示されません!

//schema.rb 
 

 
    create_table "panes", force: :cascade do |t| 
 
    t.integer "row_id",  null: false 
 
    t.text "text" 
 
    t.string "pane_photo" 
 
    end 
 

 
    create_table "rows", force: :cascade do |t| 
 
    t.integer "visualization_id", null: false 
 
    t.string "rowtitle" 
 
    end 
 

 
    create_table "visualizations", force: :cascade do |t| 
 
    t.string "title",  null: false 
 
    t.string "cover_image" 
 
    end

//controller.rb 
 

 
class VisualizationsController < ApplicationController 
 
    before_action :authenticate_user!, except: [:index, :show] 
 
    before_action :authorize_user, except: [:index, :show] 
 
    helper_method :resource 
 

 
    def index 
 
    @visualizations = Visualization.all 
 
    @visualization = Visualization.new 
 
    end 
 

 
    def new 
 
    @visualization = Visualization.new 
 
    rows = @visualization.rows.build 
 
    panes = rows.panes.build 
 
    end 
 

 
    def create 
 
    @visualization = Visualization.new(visualization_params) 
 

 
    if @visualization.save 
 
     redirect_to edit_visualization_path(@visualization) 
 
    else 
 
     render :new 
 
    end 
 
    end 
 

 
    def edit 
 
    @visualizations = Visualization.all 
 
    @visualization = Visualization.find(params[:id]) 
 
    end 
 

 
    protected 
 

 
    def visualization_params 
 
    params.require(:visualization).permit(:title, :cover_image, rows_attributes: [:visualization_id, :rowtitle, panes_attributes:[:text, :pane_photo]]) 
 
    end

//index.html 
 

 
<div class="visual_wrap text-center"> 
 
    <ul class="no-bullet text-center"> 
 
    <% @visualizations.each do |visualization| %> 
 
    <li class="text-center"> 
 
     <div class="row visualization text-center"> 
 
     <%= image_tag visualization.cover_image.to_s, id: "visualization_image", class: "output_image" %> 
 
     <p class="visualization_title"><%= visualization.title %></p> 
 
     <a href="#" id="visualization_link"><p>+</p></a> 
 
     </div> 
 
     <div class="placeholder"> 
 
     <% visualization.rows.each do |row| %> 
 
      <%= row.rowtitle %> 
 
      <% row.panes.each do |p| %> 
 
       <%= p.text %> 
 
       <%= image_tag p.pane_photo.to_s, id: "pane_image", class: "output_image" %> 
 
      <% end %> 
 
     <% end %> 
 
     </div> 
 
    </li> 
 
    <% end %> 
 
    </ul> 
 
</div>

//new.html.erb 
 

 
<% if user_signed_in? %> 
 
<% if current_user.admin? %> 
 
<div class="try"> 
 
    <div class="breadcrumb-wrapper"> 
 
    <ul class="breadcrumbs"> 
 
     <%= form_for @visualization, :html => {:multipart => true} do |f| %> 
 
     <li><a href="#" class="preview button secondary">Preview</a></li> 
 
     <li><div class="separating-bar">|</div> 
 
     <li><input type="submit" name="commit" value="Save" class="save button secondary"></li> 
 
     </ul> 
 
    </div> 
 
    <div class="cover_image text-center"> 
 
     <div class="row pre_img_prev"> 
 
     <div class="gray_bar"></div> 
 
     <div class="img_prev"> 
 
      <img id="img_preview" src="#" alt="your image" class="img-thumbnail hidden text-center"/> 
 
      <input type="text" name="visualization[title]" id="visualization[title]" class="inputtext" /> 
 
      <label for="visualization[title]" id="text_preview">+ Add Title</label> 
 
      <div class="trash-can_title"> 
 
      <a href="#" id="trash-can_title"><i class="fa fa-trash fa-3x" aria-hidden="true"></i></a> 
 
      </div> 
 
     </div> 
 
     <input type="file" name="visualization[cover_image]" id="visualization_cover_image" class="inputfile" /> 
 
     <label for="visualization_cover_image">+ Add Cover Image</label> 
 
     <%= f.hidden_field :cover_image_cache %> 
 
     <div class="trash-can_cover"> 
 
      <a href="#" id="trash-can_cover"><i class="fa fa-trash fa-3x" aria-hidden="true"></i></a> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    <div class="row linkstest"> 
 
    <div class="rows"> 
 
     <%= f.fields_for :rows, Row.new do |task| %> 
 
     <%= render 'row_fields', f: task %> 
 
     <% end %> 
 
     <div class="links"> 
 
     <%= link_to_add_association "Add Row", f, :rows %> 
 
     </div> 
 
    </div> 
 
    <% end %> 
 
    <% end %> 
 
    <% end %> 
 
    </div> 
 
    </div>

答えて

0

JSをもっと必要とする必要はありません。あなたが探しているのは、入れ子になったフォームだと思います。

RaisCastをご覧ください。少し古くなっていますが、それは良い基礎です。

新しいフィールドを動的に作成する場合は、Cocoon gemを参照してください。

Rails nested_form inside nested_form

更新

あなたがすべてではJavaScriptを使用したくない場合は、あなたが(ビルド)を初期化するために、それを伝えるために、コントローラへの余分な要求をする必要がある行とペインビューの空のフィールドをレンダリングするようにします。行の属性の内部パラメータはでなければならないので、あなたはまた、各行のペインの数を持っている必要がある

def new 
    @visualization = Visualization.new 
    num_rows = params[:num_rows] 
    num_rows.each { @visualization.rows.build } 
end 

、例えば:例えば params[:visualization][:rows][0][:num_panes]とし、そのパラメータを使用して行のペインを初期化します。そのロジックをFactoryサービスに入れるのが最善の方法です。

しかし、JSを使用して空のフィールドを作成すると、余分なリクエストとそのロジックをすべて保存する必要がなくなります。そして、あなたがあなたのコントローラで行う必要があり、すべてがある

{ 
    visualization: { 
    rows_attributes: { 
     # These are the attributes from an existing record 
     0: { 
     id: 39, 
     panes_attributes: { 
      0: { 
      id: 992 
      } 
     } 
     }, 
     # This is a new set of attributes for a new record 
     # passed by the fields generated by cocoon where xxx 
     # and yyy are random numbers 
     xxxx: { 
     panes_attributes: { 
      yyyy: { 
      } 
     } 
     } 
    } 
    } 
} 

def new 
    # visualization_params are the permitted attributes 
    @visualization = Visualization.new(visualization_params) 
end 
+0

私、あなたがそれをのような権利の属性を与える場合Railsは自動的に行とペインを初期化(構築)するためです実際にそれを見て、それを検討しています..私の視覚化の作成時に、ページを編集して行を追加するようにリダイレクトすることができますか? – scotchpasta

+0

私のコメントは完了しませんでした。なぜ私は本当にJSが必要ないのか尋ねるのですか?私はそれを使わないで新しいフィールドをどのようにレンダリングできますか?繭はそれを処理しますか? – scotchpasta

+0

私の答えが更新されました。 – guzart

関連する問題