0

Rails 3.2.13 と Nested_Form gem を使用して、出荷ヘッダー レコードと複数の出荷詳細レコードを作成しています。すべてがうまく機能し、詳細項目を追加、削除して正しく保存できます。ここでやりたいことは、フォームのネストされた fields_for セクションの一部である Material 選択ボックスに UJS または Ajax を追加することです。材料が選択されると、その横にある「現在の残高」ラベルが、各品目の正しい在庫数で更新されます。

ここに画像の説明を入力

これは UJS と Ajax への私の最初の進出であり、このタスクを達成する方法について少し迷っています。これまでのところ、私のフォームの関連部分は次のようになります。

new.html.erb:

<div class="col-md-12 form-group">
<div class="panel panel-default">
    <table class="table table-striped table-hover" id="details" >
        <th>Material</th>
        <th>Current Balance</th>    
        <th>Net Weight</th>
        <th>Gross Weight</th>
        <th></th>       
        <%= f.fields_for :downstreamDetails, :wrapper => false do |dd| %>


        <tr class="fields">
        <td><%= dd.select :tb_product_type_id, options_from_collection_for_select( @productTypes, :id, :product_type), { :prompt => "Select Material"} , {:class =>"form-control col-sm-2", :data => { remote: true, :url => url_for(:controller => 'downstreams', :action => 'getInventoryData', :paroductType => @productType ,format: 'js') }  }   %></td>       
        <td nowrap="true"><label> <%= number_with_delimiter(@currentBal) %> lbs</label></td>

        <td><%= dd.text_field :ship_total_net_weight, :class =>"form-control col-sm-2" %></td>
        <td><%= dd.text_field :ship_total_gross_weight, :class =>"form-control col-sm-2" %></td>
        <td><%= dd.link_to_remove "Remove", :data => {:target => "#details"}, :class => "btn btn-primary btn-small btn-block" %></td>
        </tr>       

        <% end %>   
    </table>
    </div>

    <div class="row">   
    <div class="col-md-2"><%= f.link_to_add "Add Material" ,:downstreamDetails, :data => {:target => "#details"}, :class => "btn btn-primary btn-small btn-block" %></div>  
    </div>



    </div>
    <div class="row" >
    <div class="col-md-9"></div>    
    <div class="col-md-3"><%= f.submit "Submit", class: "btn btn-small btn-primary" %></div> 
    </div>
<% end %>
</div>

そして私のコントローラーアクション:

def getInventoryData

 @tb_product_type = Downstream.new(params[:downstream])
 @product_id = @tb_product_type.downstreamDetails.first.tb_product_type_id
 @product = ProductType.find(@product_id)
 @downstream_ids = Downstream.select("id").where(:to_company_id => current_user.company_id, :is_verified => true).accessible_by(current_ability)
 @currentBal = DownstreamDetail.select("sum(receive_total_net_weight) as currentBal").where(:downstream_id => @downstream_ids, :tb_product_type_id => @product )

 respond_to do |format|
    format.html { redirect_to create_url }
    format.js 
 end  

end

私は getInventoryData.js.erb を持っていますが、現在何を入れるか迷っています。現在、それは機能するアラートを出すだけです。

私が持っている質問は次のとおりです。

  • 選択ボックスから材料を選択したときに、tb_product_type_id だけを送信する方法はありますか? 現在、id を取得するには、params[:downstream] (親レコード) を介して params をナビゲートする必要があります。コントローラーのアクションで @tb_product_type_id = param[:tb_product_type_id] と言えるようにしたい

  • コントローラーとビューで @currentBal を使用する既存のコードは、複数の項目を追加すると機能するとは思いません... 1 つ以上の項目を処理するようにリファクタリングするにはどうすればよいですか?

  • 複数の項目を処理する必要があることを認識して、「現在の残高」列のラベルを正しく変更するには、getInventory.js.erb ファイルに何が必要ですか? (Nested_Form Gem を使用していることを思い出してください)

  • 私は正しい方向に向かっていますか、それともはるかに簡単でクリーンな別の方法がありますか?

前もって感謝します!

アップデート

getInventory.js.erb ファイル以外はすべて動作していますが、ここでヘルプを探しています。最初の項目で「現在の残高」ラベルを更新することができましたが、当初は複数の項目で機能しないと思っていました。そこで、次のようにすべてのマテリアルの合計を取得するようにコントローラー コードを変更しました。

def getInventoryData


 @downstream_ids = Downstream.select("id").where(:to_company_id => current_user.company_id, :is_verified => true).accessible_by(current_ability)
 @currentBals = DownstreamDetail.select("tb_product_type as material, sum(receive_total_net_weight) as currentBal").where(:downstream_id => @downstream_ids).group(:tb_product_type)

 respond_to do |format|
    format.html { redirect_to create_url }
    format.js 
 end  

end

このコントローラ コードでは、結果セットを反復処理して選択したマテリアルと一致させ、選択タグの直後に続くラベル タグを更新するだけでよいと思います。jquery を使用して DOM をナビゲートし、更新する正しいラベルを見つけるにはどうすればよいですか? このJavaScriptを使用してすべての選択ボックスの値を見つけましたが、次の要素を取得して更新できないようです:

$('select > option:selected').each(function() {
    alert($(this).text() + ' ' + $(this).val());

    <% @currentBals.each do |c| %>
    if( $(this).text() == '<%= c.material %>' ) {   
    alert(document.getElementById($(this).parent()))
    $(this).parent().next("label").innerHTML = "<%=  number_with_delimiter(c.currentBal) %> lbs"
    alert("<%= c.material %>");
    }
    <% end %>    

});
4

1 に答える 1

0

以前に行った更新 (特にコントローラー コード) を念頭に置いて、最初に述べたようにnested_form gem と ajax+UJS を使用してこの問題を解決しました。パズルの最後のピースは、getInventory.js.erb ファイル内の次のコードです。

$( ".fields" ).each( function(){    
    <% @currentBals.each do |c| %>
        if( $(this).find("option:selected").text() == '<%= c.material %>' ) {   
            $(this).find("label").html("<%=  number_with_delimiter(c.currentBal) %> lbs")   
        }
    <% end %>    

});

「fields」クラス (nested_form で必要) の下の要素を反復処理し、各行項目で選択されたオプションを見つけて、コントローラー アクションに入力された currentBals ハッシュの各項目と比較する必要がありました。材料が一致したら、選択ボックスのすぐ隣にあるラベル タグを正しいバランスで更新します。

これが、私のように ajax/ujs を初めて使用する人や、nested_form gem に既に組み込まれている機能に少し機能を追加しようとしている人の助けになることを願っています。

于 2014-04-23T06:02:50.823 に答える