Vue.js clearing data after if is evaluated - ruby-on-rails

I am making a multi-step form in Rails 5 with Vue.js. I noticed that when a v-if is re-evaluated, the text in the input field gets cleared out. Is there a way to persist the info through the form steps and through other v-if evaluations?
Here's what my form looks like:
<fieldset class="listing-step" v-if="activeStep === 0">
<h2>Basics</h2>
<input type='button' value="Next" name='next' #click="activeStep++" :disabled="activeStep === stepList.length - 1" class="btn btn-secondary" />
<div class="row">
<div class="col">
<div class="form-group">
<strong><%= f.label :name %></strong><br>
<%= f.text_field :name, class: 'form-control' %>
</div>
</div>
</div>
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 1">
<h2>Location</h2>
<input type='button' value="Previous" name='prev' #click="activeStep--" :disabled="activeStep === 0" class="btn btn-secondary" />
<input type='button' value="Next" name='next' #click="activeStep++" :disabled="activeStep === stepList.length - 1" class="btn btn-secondary" />
<div class="row">
<div class="col">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="map_search" id="map_search_address" value="address" v-on:click="by_address = true" checked>
Set by address
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="map_search" id="map_search_coords" value="coords" v-on:click="by_address = false">
Set by coordinates
</label>
</div>
</div>
</div>
<div id="listing-location">
<transition name="fade">
<fieldset id="listing-location-child" name="address" v-if="by_address">
<div class="row">
<div class="col">
<div class="form-group">
<strong><%= f.label :city %></strong><br>
<%= f.text_field :city, class: 'form-control', 'v-bind:readonly': '!by_address' %>
</div>
</div>
<div class="col">
<div class="form-group">
<strong><%= f.label :state %></strong><br>
<%= f.text_field :state, class: 'form-control', 'v-bind:readonly': '!by_address' %>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<strong><%= f.label :address %></strong><br>
<%= f.text_field :address, class: 'form-control', 'v-bind:readonly': '!by_address' %>
</div>
</div>
</div>
</fieldset>
</transition>
<transition name="fade">
<fieldset id="listing-location-child" name="coords" v-if="!by_address">
<div class="row">
<div class="col">
<div class="form-group">
<strong><%= f.label :lat, 'Latitude' %></strong><br>
<%= f.number_field :lat, in: -90.0..90.0, step: :any, class: 'form-control', 'v-bind:readonly': 'by_address' %>
</div>
</div>
<div class="col">
<div class="form-group">
<strong><%= f.label :lng, 'Longitude' %></strong><br>
<%= f.number_field :lng, in: -180.0..180.0, step: :any, class: 'form-control', 'v-bind:readonly': 'by_address' %>
</div>
</div>
</div>
</fieldset>
</transition>
</div>
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 2">
<h2>Amenities</h2>
<input type='button' value="Previous" name='prev' #click="activeStep--" :disabled="activeStep === 0" class="btn btn-secondary" />
<input type='button' value="Next" name='next' #click="activeStep++" :disabled="activeStep === stepList.length - 1" class="btn btn-secondary" />
<div class="row">
<div class="col">
<div class="form-group">
<strong>Amenities</strong><br>
...
</div>
</div>
</div>
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 3">
<h2>Images</h2>
<input type='button' value="Previous" name='prev' #click="activeStep--" :disabled="activeStep === 0" class="btn btn-secondary" />
<div class="row">
<div class="col">
<div class="form-group">
<strong>Images</strong><br>
...
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="actions">
<%= f.submit class: 'btn btn-success' %>
</div>
</div>
</div>
</fieldset>
and my Vue initialization:
const progress = new Vue({
el: '#vue-listing',
data: {
activeStep: 0,
by_address: true,
stepList: [
{id: 0, text: 'Basics'},
{id: 1, text: 'Location'},
{id: 2, text: 'Amenities'},
{id: 3, text: 'Images'}
]
}
})
Thanks in advance!

change v-if to v-show OR preserve the input value in Data() and add v-model directive to every input field. So when the v-ifed control gets rendered again the v-model value will change its html value

You need to change v-if to v-show.
v-if is “real” conditional rendering because it ensures that event
listeners and child components inside the conditional block are
properly destroyed and re-created during toggles.
v-if is also lazy: if the condition is false on initial render, it
will not do anything - the conditional block won’t be rendered until
the condition becomes true for the first time.
In comparison, v-show is much simpler - the element is always rendered
regardless of initial condition, with just simple CSS-based toggling.
Generally speaking, v-if has higher toggle costs while v-show has
higher initial render costs. So prefer v-show if you need to toggle
something very often, and prefer v-if if the condition is unlikely to
change at runtime.
Reference

Related

Pass object id thought nested forms in rails

I am using loop in nested forms in rails and i wanted to pass object id through render partial form
app/model/contract_booking_attached_trips.rb
class ContractBookingAttachedTrip < ApplicationRecord
has_many :contract_attached_trip_sheets
accepts_nested_attributes_for :contract_attached_trip_sheets ,allow_destroy: true
belongs_to :booking_history
belongs_to :duty_type
belongs_to :vehicle_make
belongs_to :vehicle_category
end
app/model/contract_attached_trip_sheet.rb
class ContractAttachedTripSheet < ApplicationRecord
belongs_to :contract_booking_attached_trip
end
app/controller/contract_booking_attached_trips_controller
def edit
#contract_booking_attached_trip = ContractBookingAttachedTrip.find(params[:id])
booking_history_id = #contract_booking_attached_trip.booking_history_id
#booking_history = BookingHistory.find(booking_history_id)
#booking_trips = #booking_history.transport_plans
#trip_count = #booking_history.transport_plans.count
#contract_booking_attached_trip.contract_attached_trip_sheets.build
end
app/views/ContractBookingAttachedTrips/_form.html.erb
<div class="container-fluid">
<%= form_for(#contract_booking_attached_trip, :html => {class: "form-horizontal",id: "contract_trip_sheet_validate"}) do |f| %>
<div class="card">
<div class="card-header">
<h5 class="panel-title float-left" style="padding-top: 7.5px;">Duty Slip</h5
</div> <!-- /.card header -->
<div class="card-body">
<div class="card">
<div class="card-body" style="margin-bottom: -50px;">
<div class="row">
<div class="col-md-6 col-lg-6 mb-4 mb-lg-4">
<div class="table-responsive ">
<!--Table-->
<table id="dataTable" class="table table-borderless table-sm" cellspacing="0">
<!--Table body-->
<tbody>
<tr>
<th>Customer</th>
<th><b><%= User.find(#contract_booking_attached_trip.booking_history.try(:user_id)).try(:username) %></b></th>
</tr>
</tbody>
<!--Table body-->
</table>
<!--Table-->
</div> <!-- table -->
</div>
<div class="col-md-6 col-lg-6 mb-4 mb-lg-4">
<div class="table-responsive ">
<!--Table-->
</div> <!-- table -->
</div>
</div><!-- row1 -->
</div> <!-- inner card body -->
</div> <!-- inner card -->
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h6 class="float-left">Trip Sheet</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-11">
<% #booking_history.transport_plans.each do |transport_plan| %>
<%= f.fields_for :contract_attached_trip_sheets ,transport_plan do |builder| %>
<h3><%= transport_plan.id %> </h3>
<%= render 'contract_attached_trip_sheet_fields', f: builder, transport_plan: transport_plan %>
<% end %>
<% end %>
</div>
<div class="col-md-1">
<%= link_to_add_association "+", f, :contract_attached_trip_sheets, class: "fa fa-user fa-lg" %>
</div>
</div>
</div> <!-- /.inner card body -->
</div> <!-- /.inner card -->
</div> <!-- /. col 12 -->
</div> <!-- /.inner card row -->
</div>
</div>
<div class="card-footer ">
<div class="btn-group float-right">
<%= f.submit "submit", class:"btn btn-primary btn-sm button", id:"generateInvoice" %>
</div>
</div>
</div><!-- /.card -->
<% end %>
</div> <!-- /.container fluid -->
app/views/contract_booking_attached_trips/_contract_attached_trip_sheet_fields.html.erb
<fieldset>
<div class="nested-fields">
<div class="row">
<%= transport_plan %>
<div class="col-md-2">
<label class="label" for="">Initial Odo Reading<span class="star"></span></label>
<div class="md-form form-group">
<%= f.text_field :initial_odo_reading, class: "form-control" %>
</div>
</div>
<div class="col-md-2">
<label class="label" for=""> Trip Start Date<span class="star"></span></label>
<div class="md-form form-group">
<%= f.text_field :trip_start_date_time, class: "form-control"%>
</div>
</div>
<div class="col-md-2">
<label class="label" for=""> Final Odo Reading<span class="star"></span></label>
<div class="md-form form-group">
<%= f.text_field :final_odo_reading, class: "form-control" %>
</div>
</div>
<div class="col-md-2">
<label class="label" for=""> Trip Stop Date<span class="star"></span></label>
<div class="md-form form-group">
<%= f.text_field :trip_stop_date_time, class: "mobile form-control" %>
</div>
</div>
<div class="col-md-2">
<label class="label" for=""> Toll Cost<span class="star"></span></label>
<div class="md-form form-group">
<%= f.text_field :toll_cost, class: "form-control", placeholder:"" %>
</div>
</div>
<div class="col-md-2">
<label class="label" for=""> Permit Cost<span class="star"></span></label>
<div class="md-form form-group">
<%= f.text_field :permit_cost, class: "form-control", placeholder:"" %>
</div>
</div>
<div class="col-md-2">
<label class="label" for="">Parking Cost<span class="star"></span></label>
<div class="md-form form-group">
<%= f.text_field :parking_cost, class: "form-control", placeholder:"" %>
</div>
</div>
<%= f.hidden_field :transport_plan_id, value: transport_plan %>
<div class="col-md-1">
<br/>
<%= link_to_remove_association " " ,f, class:"fa fa-trash ", style: "color:red; font-size:20px; top:14px; " %>
</div>
</div>
<br />
</div>
</fieldset>
i am tryinh to pass transport_plan_id in hidden field but am gettting the following error in
please tell me how to pass the id through nested render partial
In your _form you write
<%= render 'contract_attached_trip_sheet_fields', :f => builder,{ :transport_plan =>transport_plan} %>
and that should be
<%= render 'contract_attached_trip_sheet_fields', :f => builder, :transport_plan =>transport_plan %>
There are two ways to pass data to partials, either you write:
render partial: 'partial_name', locals: {f: builder, a: 123}
or the simple form is just
render 'partial_name', f: builder, transport_plan: transport_plan

how to fix missing template , application/create in rails

i keep getting this missing template error
" Missing template listings/create, application/create with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in: * "/home/codio/workspace/app/views" * "/var/lib/gems/2.2.0/gems/kaminari-0.16.3/app/views" * "/var/lib/gems/2.2.0/gems/commontator-4.10.3/app/views" * "/home/codio/.bundler/ruby/2.2.0/devise-a9d90503e903/app/views" * "/home/codio/.bundler/ruby/2.2.0/koudoku-9e73e64e5520/app/views" * "/var/lib/gems/2.2.0/gems/mailboxer-0.12.4/app/views"
,anytime i tried to create an object,after a couple of search in stack overflow , some suggest to redirect or render , initially in my create action , there was no explicit redirect and after object creation the redirect was done to the show page (the intended behavior).Tried both solutions , but still getting the same error and in my understanding there's no need to have a corresponding views for the create action.
How do i got the create action redirect to the show page without creating a
a view?.
listings_controller.rb
class ListingsController < ApplicationController
...
def create
#listing = Listing.new(listing_params)
if #listing.save
if params[:images]
params[:images].each { |image|
#listing.pictures.create(image: image)
}
end
(#users - [current_user]).each do |user|
Notification.create(recipient: user, actor: current_user, action: "posted", notifiable: #listing)
end
flash[:notice]= "L'annonce #{#listing.listing_number} a eté publiee avec succès."
respond_with(#listing)
end
end
...
end
The form that trigger the create action is rendered via a modal
_form.html.erb
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Publication d'annonce</h4>
</div>
<div class="modal-body">
<%= form_for :listing, :url => {:action => :create} do |f| %>
<div class="form-group row">
<%= f.label :name,"Titre de l'annonce", class: 'col-4 col-form-label'%>
<div class="col-8">
<%= f.text_field :name, placeholder: "Titre de l'annonce",class: "form-control here" %>
</div>
</div>
<div class="form-group row">
<%= f.label :price,"Prix d'offre", class:'col-4 col-form-label'%>
<div class="col-8">
<div class="input-group">
<div class="input-group-addon">
<i class="fa fa-usd"></i>
</div>
<%= f.text_field :price,placeholder: "Prix d'offre" ,class:"form-control here"%>
</div>
</div>
</div>
<div class="form-group row">
<%= f.label :display_usd ,'Prix en USD', class: 'col-4' %>
<div class="col-8">
<div class="form-check form-check-inline">
<label class="form-check-label">
<%= f.check_box :display_usd, class:'form-check-input' %>
USD
</label>
</div>
</div>
</div>
<div class="form-group row">
<%= f.label :category_id,class:"col-4 col-form-label" %>
<div class="col-8">
<%= f.collection_select :category_id, Category.all, :id, :name, {prompt: "choose a category"}, {class: "form-control here"}%>
</div>
</div>
<div class="form-group row">
<label for="select1" class="col-4 col-form-label">Localisation</label>
<div class="col-8">
<select id="select1" name="select1" class="form-control">
<option value="rabbit">Rabbit</option>
<option value="duck">Duck</option>
<option value="fish">Fish</option>
</select>
</div>
</div>
<div class="form-group row">
<%= f.label :image, "Image Principale", class:'col-4 col-form-label' %>
<div class="col-8">
<%= f.file_field :image, class:'form-control here'%>
</div>
</div>
<div class="form-group row">
<label class="col-4">Condition</label>
<div class="col-8">
<div class="form-check form-check-inline">
<label class="form-check-label">
<input name="radio1" type="radio" class="form-check-input" value="rabbit">
Usé
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input name="radio1" type="radio" class="form-check-input" value="duck">
Neuf
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input name="radio1" type="radio" class="form-check-input" value="fish">
normal
</label>
</div>
</div>
</div>
<div class="form-group row">
<%= f.label :description,'Produit Description', class:'col-4 col-form-label' %>
<div class="col-8">
<%= f.text_area :description,class:" form-control here " do%>
<span id="textareaHelpBlock" class="form-text text-muted">veuillez donner une description exacte de votre produit.</span>
<%end%>
</div>
</div>
<div class="form-group row">
<%= f.label :image, "Image additionel", class:'col-4 col-form-label' %>
<div class="col-8">
<%= file_field_tag "images[]", type: :file, multiple: true, class:'form-control here'%>
</div>
</div>
<div class="form-group row">
<label class="col-4">Sauvegarder sans publier</label>
<div class="col-8">
<div class="form-check form-check-inline">
<label class="form-check-label">
<input name="radio" type="radio" class="form-check-input" value="rabbit">
Unpublished
</label>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
<%= f.button "Publier Produit" , class: 'btn btn-primary pull-right', data: {disable_with: "<i class='fa fa-spinner fa-spin'></i> Publication en cours..."} %>
</div>
<%end%>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
This error comes if you're hitting the create action using HTML. create doesn't typically have an associated view; you use it to process an entity, and redirect the user elsewhere.
Therefore, you should just be able to use:
redirect_to #listing
at the end of your controller code.
Using #listing is a bit of Rails magic - it would more commonly appear as redirect_to listing_path(#listing).
I.E.
def create
#listing = Listing.new(listing_params)
if #listing.save
if params[:images]
params[:images].each { |image|
#listing.pictures.create(image: image)
}
end
(#users - [current_user]).each do |user|
Notification.create(recipient: user, actor: current_user, action: "posted", notifiable: #listing)
end
flash[:notice]= "L'annonce #{#listing.listing_number} a eté publiee avec succès."
redirect_to #listing
end
end
Does that do it?
Another common practice is to have different approaches depending on whether or not an object successfully saves to the db. For example:
def create
#listing = Listing.new(listing_params)
if #listing.save
...
redirect_to #listing, notice: "..."
else
flash.now[:alert] = "Listing failed to save"
render :new
end
end
A good way to play about with this is to use the generator to see how Rails handles things by default - you can use the following in the terminal to have a dig around: rails g controller test_controller.
Hope that helps - let me know if you've any questions.

Rails form get input value before submitting

I have a rails form which is separated in 3 steps, the first step is for the date selected, second step the time select and last step user info's.
Here is the form code :
<%= form_for [#school, Meeting.new], html: { id: 'meeting_form' } do |f| %>
<!-- one step -->
<div class="step">
<section class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="input-group date" id="datetimepicker1">
<%= f.text_field :date, class: 'form-control date_value', :required => true %>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</section>
<button type="button" class="btn btn-primary next-step" style="width: 100%;"> Suite </button>
</div>
<!-- end one step -->
<!-- second step -->
<div class="step">
<section class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker2'>
<%= f.hidden_field :mhour, required: true, class: "Vroomvroom-timepicker--value-js", :value => "" %>
<div class="scheduler--picker">
<% for time in 8..20 %>
<% if time < 10 %>
<div class="scheduler--picker-line-item <% if #school.meeting_already_booked?("0#{time}:00") %>scheduler--picker-line-item--disabled <% end %>" data-value="0<%= time %>:00">
<p>0<%= time %>:00</p>
</div>
<% else %>
<div class="scheduler--picker-line-item <% if #school.meeting_already_booked?("#{time}:00") %>scheduler--picker-line-item--disabled <% end %>" data-value="<%= time %>:00">
<p><%= time %>:00</p>
</div>
<% end %>
<% end %>
</div>
</div>
</div>
</div>
</div>
</section>
<button type="button" class="btn btn-primary previous-step" style="width: 49%;"> Retour </button>
<button type="button" class="btn btn-primary next-step" style="width: 49%;"> Suite </button>
</div>
<!-- end second step -->
<!-- third step -->
<div class="step">
<section class="container">
<div class="row">
<div class='col-sm-6' style="padding-left: 0;">
<div class="form-group">
<label for="name"> Nom </label>
<%= f.text_field :name, html: 'form-control', :required => true, placeholder: 'Votre nom de famille' %>
</div>
<div class="form-group">
<label for="firstname"> Prénom </label>
<%= f.text_field :firstname, html: 'form-control', :required => true, placeholder: 'Votre prénom' %>
</div>
<div class="form-group">
<label for="email"> Adresse email </label>
<%= f.email_field :email, html: 'form-control', :required => true, placeholder: 'Votre adresse mail, ex: jean.marc#gmail.com' %>
</div>
<div class="form-group">
<label for="phone"> Numéro de téléphone</label>
<%= f.text_field :phone, html: 'form-control', :required => true, placeholder: 'Votre numéro de téléphone, ex: 0606060606', :maxlength => 14 %>
</div>
<div class="form-group">
<label> Pour quel type de permis : </label>
<%= f.select :category do %>
<option value="code">Code uniquement</option>
<option value="moto">Permis A (moto)</option>
<option value="voiture">Permis B (voiture)</option>
<option value="am">Permis AM </option>
<option value="formation">Formations 125 cm3 </option>
<option value="autre">Une autre formation</option>
<% end %>
</div>
</div>
</div>
</section>
<button type="button" class="btn btn-primary previous-step" style="width: 49%;"> Retour </button>
<%= button_tag 'Envoyer', :type => :submit, :class => 'btn btn-primary end' %>
</div>
<!-- end thirs step -->
<% end %>
for the date picker, I use bootstrap-datetimepicker for rails, but I create my own time picker, generated with div and data-attributes. I need to get the value of date before submitting the form to know which hours are already taken in DB to disable them.
I have created a method in the model School:
# meetings
def meeting_already_booked?(date, hour)
if Meeting.where(:date => date).where(:time => hour)
return true
else
return false
end
end
And I use the method here :
<div class="scheduler--picker-line-item <% if #school.meeting_already_booked?("0#{time}:00") %>Vroomvroom-scheduler--picker-line-item--disabled <% end %>" data-value="0<%= time %>:00">
I have the time, but I need the date that user selects the step just before to search in my DB if this hour is already taken.
Your best bet is to save the date locally on click of next button, something like
$("#next_step_button").on("click", function(event) {
localStorage.setItem("date", $(#datetimepicker1).val());
});
To get the value back,
localStorage.getItem("date");

Nested form not properly generate

Webpage
-> Sections (Has Many)
-> Header (Has One)
-> HeaderTabs (Has Many)
I make nested form for above structure and it's display me properly,
But When I'm adding new header_tabs on click of 'Add new Header Tab', It's add new fields but the indexing value is same as first one.
<div class="header_tabs_forms">
<div class="form-group">
<label class="control-label col-lg-3"> </label>
<div class="col-lg-1">
<input type="hidden" value="false" name="webpage[section_headers_attributes][0][header_attributes][header_tabs_attributes][0][_destroy]" id="webpage_section_headers_attributes_0_header_attributes_header_tabs_attributes_0__destroy"><a class="btn btn-danger btn-xs rmhdrtab remove_nested_fields" data-association="header_tabs" href="javascript:void(0)"><i class="fa fa-close"></i></a>
</div>
<div class="col-lg-6 header_tabs">
<input placeholder="Write Tab Name" class="form-control form-ctr100 required" require="true" style="width:100%;" type="text" name="webpage[section_headers_attributes][0][header_attributes][header_tabs_attributes][0][tab_name]" id="webpage_section_headers_attributes_0_header_attributes_header_tabs_attributes_0_tab_name">
<div class="error"></div>
</div>
<div class="col-lg-2 header_tabs">
<input class="form-control form-ctr2 required" min="1" require="true" type="text" value="1" name="webpage[section_headers_attributes][0][header_attributes][header_tabs_attributes][0][position]" id="webpage_section_headers_attributes_0_header_attributes_header_tabs_attributes_0_position">
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-3"> </label>
<div class="col-lg-1">
<input type="hidden" value="false" name="webpage[section_headers_attributes][0][header_attributes][header_tabs_attributes][0][_destroy]" id="webpage_section_headers_attributes_0_header_attributes_header_tabs_attributes_0_header_tabs__destroy"><a class="btn btn-danger btn-xs rmhdrtab remove_nested_fields" data-association="header_tabs" href="javascript:void(0)"><i class="fa fa-close"></i></a>
</div>
<div class="col-lg-6 header_tabs">
<input placeholder="Write Tab Name" class="form-control form-ctr100 required" require="true" style="width:100%;" type="text" name="webpage[section_headers_attributes][0][header_attributes][header_tabs_attributes][0][tab_name]" id="webpage_section_headers_attributes_0_header_attributes_header_tabs_attributes_0_header_tabs_tab_name">
<div class="error"></div>
</div>
<div class="col-lg-2 header_tabs">
<input class="form-control form-ctr2 required" min="1" require="true" type="text" value="1" name="webpage[section_headers_attributes][0][header_attributes][header_tabs_attributes][0][position]" id="webpage_section_headers_attributes_0_header_attributes_header_tabs_attributes_0_header_tabs_position">
</div>
</div>
</div>
check - webpage[section_headers_attributes][0][header_attributes][header_tabs_attributes][0]
the index value [header_tabs_attributes][0] are same for tabs.
Can you please why is it same ? and what is the solutions ?
Update 2 - Code for the form.
<%= nested_form_for webpage, html: {class: 'form-horizontal header-validation-webpage'}, remote: true do |form_webpage| %>
<%= hidden_field_tag :type, params[:type] %>
<%= form_webpage.fields_for :sections do |form_section| %>
<div class="form-group">
<%= form_section.label :name, class: 'control-label col-lg-3' %>
<div class="col-lg-8">
<%= form_section.text_field :name, placeholder: 'Write your section name!', class: 'form-control' %>
</div>
</div>
<div class="form-group">
<%= form_section.label :position, class: 'control-label col-lg-3' %>
<div class="col-lg-8">
<%= form_section.number_field :position, placeholder: 'Position', class: 'form-control', min: 1 %>
</div>
</div>
<%= form_section.fields_for :header do |form_header| %>
<legend><small>Tab Name & Position Detail</small></legend>
<div class="header_tabs_forms">
<%= form_header.fields_for :header_tabs, :wrapper => false do |form_htab| %>
<%# index = Time.now().strftime("%d%m%Y%I%M%S%3N") %>
<div class="form-group">
<label class="control-label col-lg-3"> </label>
<div class="col-lg-1">
<%= form_htab.link_to_remove "<i class='fa fa-close'></i>".html_safe, class: 'btn btn-danger btn-xs rmhdrtab' %>
</div>
<div class="col-lg-6 header_tabs">
<%= form_htab.text_field :tab_name, placeholder: 'Write Tab Name', class: 'form-control form-ctr100 required', require: true, style: 'width:100%;' %>
<div class='error'><%= display_error_messages webpage.errors, [:'header.header_tabs.tab_name'] %></div>
</div>
<div class="col-lg-2 header_tabs">
<%= form_htab.text_field :position, class: 'form-control form-ctr2 required', min: 1, require: true %>
</div>
</div>
<% end %>
</div>
<p class="text-right">
<%= form_header.link_to_add "<i class='fa fa-plus'></i> Add New Tab".html_safe, :header_tabs, data: {target: '.header_tabs_forms'} %>
</p>
<% end %>
<% end %>
<hr>
<div class="form-group">
<div class="col-lg-offset-3 col-lg-9">
<%= form_webpage.submit 'Save', class: 'btn btn-primary', data: {disable_with: 'Loading...'} %>
</div>
</div>
<% end %>

Stuck trying to use dropzone gem on rails for multiple upload

I have 1 form which use dropzone gem, what i am trying to achieve is
i want to upload my image inside a form which have 1 to many relationship, i've been struggle to make it work with no luck.
here is my database structure :
apartement:
id
name
desc
unitplan:
id
unitplanphoto
apartement_id
an apartement has many unit plans, instead an unit plan only belong to 1 apartement,
<div class="container-fluid">
<div class="animated fadeIn">
<!--/.row-->
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<strong>Apartement Form</strong>
</div>
<%= form_for #apt, html: {class: "form-horizontal", :multipart=>true} do |f| %>
<div class="card-block">
<div class="form-group row">
<%= f.label 'Apartement Name', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :apt_name, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Apartement Address', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_area :apt_address, rows: 5, cols: 46 , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Latitude', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :apt_lat, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Longtitude', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :apt_long, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Thumbnail', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.file_field :thumbnail, accept: 'image/jpeg,image/gif,image/png' %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Appartement Description', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_area :apt_desc, rows: 5, cols: 46 , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Developer', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_select(:apt, :developer_id, #developers, :id, :devname, {:prompt => false}, class: "form-control") %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Area', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_select(:apt, :area_id, #areas, :id, :area_desc, {:prompt => false}, class: "form-control") %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Status', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :apt_status, options_for_select(#apt_statuses.collect { |s| [s[0].humanize, s[0]] }, selected: #apt.apt_status), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Facility', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_check_boxes(:apt, :facility_ids, #facilities, :id, :facility_desc) %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Point of Interest', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_check_boxes(:apt, :poi_ids, #pois, :id, :poi_name) %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Floor plan photos', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= file_field_tag "images[]", type: :file, multiple: true %>
</div>
</div>
<% end %>
<div class="form-group row">
<div class="col-md-8">
<input id="unitplans_ids" name="unitplans_ids" type="hidden" value="">
<!--<input data-url="/photos" id="unitplans_upload" multiple="multiple" name="unitplans[]" type="file" ></input>-->
<!--<form action="/unitplans/create" id="dzCover" method="post" enctype="multipart/form-data" class="dropzone">-->
<%= form_for #unitplan, html: {class: "dropzone", :multipart=>true, id: "dzCover"} do |f| %>
<div id="actionsCover" class="row">
<div class="col-lg-8">
<label for="image">Unit plan photos : </label>
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button2">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
</span>
<button type="button" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="button" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
</div>
<div class="col-lg-5">
<!-- The global file processing state -->
<span class="fileupload-process">
<div id="total-progress" class="progress progress-striped active" style="display:none" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
</div>
</span>
</div>
</div>
<div class="form-group">
<!-- HTML heavily inspired by http://blueimp.github.io/jQuery-File-Upload/ -->
<div class="table table-striped" class="files" id="previewsCover">
<div id="templateCover" class="file-row">
<!-- This is used as the file preview template -->
<div>
<span class="preview"><img data-dz-thumbnail /></span>
</div>
<div>
<p class="name" data-dz-name></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</div>
<div>
<p class="size" data-dz-size></p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
</div>
</div>
<div>
<button type="button" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start</span>
</button>
<button type="button" data-dz-remove class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
<button type="button" data-dz-remove class="btn btn-danger delete">
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
</div>
</div>
</div>
<br>
</div>
<!-- </form>-->
<% end %>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
</div>
</div>
</div>
<!--/col-->
</div>
<!--/.row-->
</div>
</div>
my js file :
$( document ).ready(function()
{
var previewNode1 = document.querySelector("#templateCover");
console.log(previewNode1);
console.log(previewNode1.id);
previewNode1.id = "";
var previewTemplate1 = previewNode1.parentNode.innerHTML;
previewNode1.parentNode.removeChild(previewNode1);
var myDropzoneCover = new Dropzone("#dzCover", { // Make the whole body a dropzone
url: "/unitplans/create", // Set the url
thumbnailWidth: 80,
thumbnailHeight: 80,
parallelUploads: 20,
paramName: "unitplanphoto",
previewTemplate: previewTemplate1,
autoQueue: false, // Make sure the files aren't queued until manually added
previewsContainer: "#previewsCover", // Define the container to display the previews
clickable: ".fileinput-button2", // Define the element that should be used as click trigger to select files.
maxFilesize: 5,
acceptedFiles: ".png, .jpg, .jpeg", //is this correct? I got an error if im using this
init: function() {
this.on("success", function(file, response)
{
console.log(response);
file.serverId = response;
//alert(response);
});
this.on("removedfile", function(file)
{
//console.log(file);
//console.log(file.serverId);
if (!file.serverId)
{
return;
}
else
$.post("/unitplans/destroy?id=" + file.serverId);
});
this.options.previewaDropzone = false;
}
});
myDropzoneCover.on("addedfile", function(file) {
// Hookup the start button
file.previewElement.querySelector("#previewsCover .start").onclick = function() { myDropzoneCover.enqueueFile(file); };
//console.log(file);
});
// Update the total progress bar
myDropzoneCover.on("totaluploadprogress", function(progress) {
document.querySelector("#actionsCover #total-progress .progress-bar").style.width = progress + "%";
});
myDropzoneCover.on("sending", function(file) {
// Show the total progress bar when upload starts
document.querySelector("#actionsCover #total-progress").style.opacity = "1";
// And disable the start button
file.previewElement.querySelector("#previewsCover .start").setAttribute("disabled", "disabled");
//alert("sending");
});
// Hide the total progress bar when nothing's uploading anymore
myDropzoneCover.on("queuecomplete", function(progress) {
document.querySelector("#actionsCover #total-progress").style.opacity = "0";
//alert("complete");
});
// Setup the buttons for all transfers
// The "add files" button doesn't need to be setup because the config
// `clickable` has already been specified.
document.querySelector("#actionsCover .start").onclick = function() {
myDropzoneCover.enqueueFiles(myDropzoneCover.getFilesWithStatus(Dropzone.ADDED));
};
document.querySelector("#actionsCover .cancel").onclick = function() {
myDropzoneCover.removeAllFiles(true);
};
} );
controller file:
class UnitplansController < ApplicationController
def create
#unitplan = Unitplan.new(unitplan_params)
#respond_to do |format|
if #unitplan.save
render json: {message: "sukses", unitplanID: #unitplan.id}, status: 200
else
render json: { error: #unitplan.errors.full_messages.join(", ") }, status: 400
end
end
private
def unitplan_params
params.require(:unitplan).permit(:unitplanphoto)
end
end
somehow i can not make it to work,if i check dropzone request when i click submit, it always throw this error :
ActionController::ParameterMissing in UnitplansController#create
param is missing or the value is empty: unitplan
Your params appear to be missing the unitplan key that your unitplan_params method is looking for.
Try changing your paramNamevalue in your js file to this:
paramName: "unitplan[unitplanphoto]",
unitplan_params is acting as a whitelist for params to ensure you only pass approved params to your controller method, so you need to make sure your incoming params match the require and permit rules.

Resources