简体   繁体   中英

dynamically generated nested form with cocoon rails

I have a nested form with cocoon, but am having an issue trying to calculate my total price from the JavaScript. And when I check my view source page the generated attribute from the fields have no value attributes. If I use the @invoice.line_items.build ,the total price is calculated but the dynamic fields fro the cocoon is not being seen. Thanks and awaiting any help I can get soon.

   class InvoicesController < ApplicationController

     before_action :set_invoice,:set_line_item, only: [:show, :edit, :update, :destroy]

     def index
       @invoices = Invoice.all
     end

     def show
     end

     def new
       @invoice = Invoice.new
      @invoice.line_items.build
     end

     # GET /invoices/1/edit
     def edit

     end

     def create
       @invoice = Invoice.new(invoice_params)
       respond_to do |format|
        if @invoice.save
          format.html { redirect_to @invoice, notice: 'Invoice was successfully created.' }
          format.json { render :show, status: :created, location: @invoice }
        else
          format.html { render :new }
          format.json { render json: @invoice.errors, status: :unprocessable_entity }
        end
      end
    end

    def update
      respond_to do |format|
        if @invoice.update(invoice_params)
          format.html { redirect_to @invoice, notice: 'Invoice was successfully updated.' }
          format.json { render :show, status: :ok, location: @invoice }
        else
          format.html { render :edit }
          format.json { render json: @invoice.errors, status: :unprocessable_entity }
        end
      end
    end

    def destroy
      @invoice.destroy
      respond_to do |format|
        format.html { redirect_to invoices_url, notice: 'Invoice was successfully destroyed.' }
        format.json { head :no_content }
      end
    end


    private

    # Use callbacks to share common setup or constraints between actions.
    def set_invoice
      @invoice = Invoice.find(params[:id])
    end

    def set_line_item
      @line_item = LineItem.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.    
     def invoice_params
       params.require(:invoice).permit(:amount, :date, :currency, {line_items_attributes: 
        [:id,:quantity,:net_amount, :description, :unit_cost]})
     end

   end

 <tbody class='line_items'>
                <%= f.fields_for :line_items do |builder| %>
                <%= render 'line_item_fields', :f => builder %>
                <% end %> 
           </tbody>
      </table>
        <%= link_to_add_association 'add item', f, :line_items, class: "btn btn- 
  primary",data: {"association-insertion-node" => "tbody.line_items", "association-insertion-method" => "append"} %>
        <%= f.submit  class:"btn btn-primary" %>

  <tr class="nested-fields">
     <div class="container">
       <div class="row row-cols-5">
       <div class="col"> <td><%= f.text_field :description, class: "form-control item_desc" %></td></div><br/>
    <div class="col"> <td><%= f.text_field :quantity,  class: "form-control quantity" %></td></div><br/>
    <div class="col"> <td><%= f.text_field :unit_cost, class: "form-control unit_cost"%></td></div><br/>
    <div class="col"> <td class="price_td"><%= f.text_field  :net_amount, class: "form-control price", :readonly => true %></span> <span class= "subtotal_currency"></span></td></div><br/>
    <div class="col"> <td><%= link_to_remove_association 'Delete', f, class: 'remove_record btn btn-danger' %></td></div>
  </div>
</div>

This is the javascript

  function update_price(){ 
      var row = $(this).parents('.nested-fields');
      var price = row.find('.unit_cost').val() * row.find('.quantity').val();
      price = price.toFixed(2);
      isNaN(price) ? row.find('.price').val('is not a number') : 
      row.find('.price').val(price);
      update_subtotal();

  }

You attach the events using the following code:

$('.unit_cost').blur(update_price); 
$('.quantity').blur(update_price); 

However, this will only bind the event-handlers to the elements on the page at the moment this command was run, and there is a better to achieve the same:

$(document).on('blur', '.unit_cost, .quantity', update_price)

I attach the event to top-level document (so this would even be turbolinks compatible, but you could also use the enclosing form or div), we respond to blur events but only if the triggering element has class .unit_cost or .quantity .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM