前提・実現したいこと
Railsアプリ作成中です。
edit.html.erbでユーザー入力機能をAjaxで実装しています。
ユーザーが文を入力するとそのページで遷移せずに部分テンプレートが一つ追加される形です。
edit.html.erbで入力
↓
item_controllerのcreate作動
↓
create.js.erbを返す
↓
create.js.erbでAjax処理
↓
部分テンプレートを1つ追加しedit.html.erbに帰る
おそらく、部分テンプレートを1つ追加しedit.html.erbを表示する最後の動作で、変数名_counterが定義されていないと出ているのだと思います。
発生している問題・エラーメッセージ
chromeの開発者ツールnetworkのPreviewに出てきたエラーです。
item_counterが違うとのこと。
しかし、edit.html.erbでは、ちゃんと連番でitem_counterが機能しています。
NameError in Items#create Showing /Users/onoryouma/projects/bucket_list/app/views/users/_item.html.erb where line #3 raised: undefined local variable or method `item_counter' for #<#<Class:0x007fe96bf14ee0>:0x007fe96f8e7af0> Did you mean? item_url Trace of template inclusion: app/views/items/create.js.erb
該当のソースコード
edit.html.erbの入力フォームと部分テンプレート呼び出し元です。
erb
1<!-- 入力フォーム--> 2<div class="content content-item"> 3 <ol> 4 <%= form_tag('/items', method: :post, remote: true) do %> 5 <input type="text" name="text" pattern=".*\S+.*" required placeholder="23文字以内で" size="23" maxlength="23" autocomplete="off" class="header-btn"> 6 <%= submit_tag "追加" ,:class => "header-btn margin-top10px" %> 7 <% end %> 8 </ol> 9</div> 10<!-- テンプレート呼び出し--> 11<div class="content content-item"> 12 <ol> 13 <% if @items.present? %> 14 <div id="item-content"> 15 <%= render partial: "item", collection: @items %> 16 </div> 17 <% end %> 18 </ol> 19</div>
item_controller該当部
rb
1def create 2 @item = Item.new(text: item_params[:text], user_id: current_user.id) 3 #Ajax仕様 4 respond_to do |format| 5 if @item.save 6 format.html { redirect_to @item, notice: '作成完了'} 7 format.json { render :show, status: :created, location: @item } 8 9 format.js 10 else 11 format.html { render :new } 12 format.json { render json: @item.errors, status: :unprocessable_entity } 13 end 14 end 15 end
create.js.erbの全部
javascript
1$("<%= escape_javascript(render partial: '/users/item', locals: { item: @item }) %>").appendTo("#item-content"); 2 3//二重送信防止のためのdisabledを取り除く 4$('form').find(':submit').removeAttr("disabled"); 5 6//submitの後に、フォームの中身を空にする 7$('form').find("textarea, :text, select").val("").end().find(":checked").prop("checked", false);
以下部分テンプレートです。
_item.html.erb
<li class="idea"> <div class="idea-text"> <div class="checked-item_<%= "#{item_counter}"%>" > <% if item.check == true %> <div class="delete-text"> <%= item.text %> </div> <% else %> <%= item.text %> <% end %> </div> </div> <div class="item-menu-right"> <%= link_to item_path(item), method: :delete , data:{ confirm: '本当によろしいですか?'}, remote: true do %> <i class="fa fa-trash fa-fw" aria-hidden="true"></i> <% end %> <!-- ここをモーダルにする --> <%= link_to edit_item_path(item), method: :get ,class: "fa-edit-margin", item_id: item.id do %> <i class="fa fa-edit fa-fw" aria-hidden="true" ></i> <% end %> <%= check_box_tag '', '', item.check, {'data-id' => item.id, 'data-user-id' => item.user_id ,class: "check_#{item_counter} option-input"} %> </div> </li> <!-- idからclass指定に変えた --> <!-- チェックつけたらdelete-textつける --> <!-- item_counterを使い、各テンプレートに連番を振っている --> <script> $(function() { $('.check_<%= "#{item_counter}"%>').on('click', function() { if ( $(this).prop('checked') == false ) { $('.checked-item_<%= "#{item_counter}"%>').removeClass("delete-text"); } else { $('.checked-item_<%= "#{item_counter}"%>').addClass("delete-text"); } }); }); </script>
試したこと
item_counterに関するviewを消したところ動きましたが、機能として必要なのでどうにかしたいです。