I am still unable to solve this problem and i would be really grateful if anyone can help me. I have already successfully coded a product ordering form which will GET price of specific products from the products_table. My form layout is as:
new.html.erb
<h1>Add a new order for <%= #customer.name %></h1>
<div class="row">
<%= form_for(#order) do |f| %>
.
.
.
.
<h3>Order Details</h3>
<%= f.label :address_id, "Delivery Address" %>
<%= f.collection_select :address_id, #addresses, :id, :select_address, {:prompt => "Select delivery location"}, {:class => "form-control"} %></br>
<%= f.label :del_date, "Delivery Date" %>
<%= f.date_select :del_date, {:class => "form-control"} %></br>
<%= f.label :owner_id, "Person-In-Charge" %>
<%= f.collection_select :owner_id, #owners, :id, :name, {:prompt => "Who ordered?"}, {:class => "form-control"} %>
<%= f.label :telephone %>
<%= f.text_field :telephone, class: 'form-control' %>
<%= f.label :remark, "Order Remark" %>
<%= f.text_area :remark, class: 'form-control' %>
<%= f.label :t_price, "Total Amount" %>
<%= f.text_field :t_price, class: 'form-control' %></br>
<h3>What items would you like to place?</h3>
<%= f.add_nested_fields_link :single_orders, "Add Product" %>
<%= f.nested_fields_for :single_orders do |builder| %>
<div class = "form-inline">
<%= builder.collection_select :product_id, #products, :id, :select_product, {:prompt => "choose product"}, {:class => "product_selection form-control"} %>
<%= builder.text_field :ctn_price, placeholder: "Price/carton", readonly: true, class: 'ctn_price_field form-control' %>
<%= builder.text_field :qty, placeholder: "Quantity",id: "quantity", class: 'form-control' %>
<%= builder.text_field :price, placeholder: "Amount", id: "amount", readonly: true, class: 'form-control' %>
<%= builder.remove_nested_fields_link %>
</div>
<% end %>
<%= f.submit "place order", class: "btn btn-primary" %>
</div>
<% end %>
</div>
when the product is selected via collect_select, the order.js.coffee will run:
order.js.coffee
jQuery ->
$(".product_selection").on "change", ->
$.ajax
url: "/orders/get_product_prices"
type: "GET"
dataType: "script"
data:
product_id: $('.product_selection option:selected').val()
which will route to:
resources :orders, only: [:index, :new, :edit, :create, :update, :inactive, :active, :destroy] do
member do
post :create, :inactive, :active
end
collection do
get 'get_product_prices', to: "orders#get_product_prices"
end
end
which is run the file get_product_prices.js.erb
/* global $ */
$('.ctn_price_field').each(function(){
$(this).val(<%= #product.price %>)
});
The problem i am facing is that this codes only works for the first product element in the form. As I want this form to able to accept multiple products via the nested_field:single_order when i generate 3 of the same nested_fields via orders_controller.rb:
def new
#order = Order.new
#customer = Customer.find(params[:id])
#addresses = Address.where(customer_id: #customer.id)
#owners = Owner.where(customer_id: #customer.id)
#promotions = Promotion.where(status: "active")
#packages = Package.all
#products = Product.where(status: "active")
#package_products = PackageProduct.all
3.times do
#order.single_orders.build
end
end
def get_product_prices
#product = Product.find_by(id: params[:product_id])
end
This is the HTML codes when i inspect the element on chrome
<fieldset class="nested_fields nested_order_single_orders">
<div class="form-inline">
<select class="product_selection form-control" name="order[single_orders_attributes][0][product_id]" id="order_single_orders_attributes_0_product_id"><option value="">choose product</option>
<option value="2">Apple</option>
<option value="3">Orange</option>
<option value="4">Pear</option>
<option value="5">Watermelon</option>
<option value="6">Avocado</option>
<option value="7">Kiwi</option></select>
<input placeholder="Price/carton" readonly="readonly" class="ctn_price_field form-control" type="text" name="order[single_orders_attributes][0][ctn_price]" id="order_single_orders_attributes_0_ctn_price">
<input placeholder="Quantity" id="quantity" class="form-control" type="text" name="order[single_orders_attributes][0][qty]">
<input placeholder="Amount" id="amount" readonly="readonly" class="form-control" type="text" name="order[single_orders_attributes][0][price]">
<a class=" remove_nested_fields_link" data-delete-association-field-name="order[single_orders_attributes][0][_destroy]" data-object-class="single_order" href="">x</a>
</div>
</fieldset>
the other 2 ctn_price_field will duplicate the prices of whichever product is selected on the first nested_field element. Can anybody show where have i gone wrong with this codes? does the problem arise from my jQuery codes or my rails? thank you for any help provided..
Related
I've implemented a dynamic selection, where users will choose the project they are working on in one selection and then a dropdown with several "subtasks" will appear.
This works but only about 50% of the time, sometimes the second dropdown contains all projects with their subtasks, other times the subtasks will populate based on on the project selected.
This is my Task.js function:
function showForm() {
const btn = document.getElementById('new-task-form')
btn.style.display == "block" ? btn.style.display = "none" : btn.style.display = "block"
}
jQuery(function() {
let subtasks;
subtasks = $('#task_subproject_id').html();
return $('#task_project_id').change(function(){
let project, optons;
project = $('#task_project_id :selected').text();
options = $(subtasks).filter("optgroup[label='" + project + "']").html();
if(options) {
return $('#task_subproject_id').html(options);
} else {
return $('#task_subproject_id').empty();
}
});
});
This is the new partial where the collections are displayed:
<%= form_for(#task, method: :post, remote: true, html: {class: "form-group"}) do |f| %>
<%= f.label "Describe the task"%>
<%= f.text_field :comments, id: "task-comments", class: "form-control" %>
<br />
<%= f.label "Time in minutes" %>
<%= f.text_field :time, class: "form-control" %>
<%= f.label "Project" %>
<%= f.collection_select :project_id, Project.order(:name), :id, :name,
{prompt: "Select a project"}, {class: "form-control"} %>
<br />
<%= f.grouped_collection_select(:subproject_id, Project.order(:name), :subprojects, :name,
:id, :name, {prompt: "Select a subtask" },{class: "form-control"}) %>
<br / />
<%= f.label "Date" %>
<%= f.date_select :day, {class: "form-control"}%>
<br />
<%= f.label "Collaborators" %>
<ul class="list-group collaborators">
<%= f.collection_check_boxes(:user_ids, User.where.not(id: current_user.id), :id, :email_or_user_name) do |box| %>
<li class="list-group-item"> <%= box.check_box + box.text%> </li>
<% end %>
</ul>
<%= f.submit "Add Task", class: 'btn btn-primary' %>
<% end %>
Again this works about 50% of the time. I've tried it in multiple browsers; Safari, Chrome, IE, Opera does not seem to be a browser issue, and when it dosen't work there is not console error.
Although I'd like to add link_to_add with using simple_nested_form_for, the following error was displayed.
ArgumentError (Invalid association. Make sure that accepts_nested_attributes_for is used for :events association.):
There are similar questions in stackoverflow, but it doesn't work for me. So I post this as a new question.
The error was appeared when I add f.link_to_add in _schedule_form.html.erb.
_schedule_form.html.erb
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
<br>
<%= f.label :departure_date %>
<div class="input-group date" id="datetimepicker">
<%= f.text_field :departure_date, class: 'form-control' %>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker').datetimepicker({format:'MMM-DD-YYYY'});
});
</script>
<br>
<div id="room">
<%= f.simple_fields_for :rooms do |a| %>
<p class="day-number-element-selector"><b>Day <%= a.index.to_i + 1 %></b></p>
<div id="event">
<% a.simple_fields_for :events do |e| %>
<%= e.input :from %>
<% end %>
</div>
#add here!!!
<%= f.link_to_add "Add event", :events, data: {target: '#event'}, class: "btn btn-primary" %>
<%= a.input :room %>
<% end %>
</div>
new_html.erb
<div class="row">
<div class="col-md-12">
<p>Create schedule</p>
<%= simple_nested_form_for(#schedule) do |f| %>
<%= render 'schedule_form', f: f %>
<%= f.submit "Create my schedule", class: "btn btn-primary" %>
<br>
<% end %>
</div>
</div>
Give the following models:
class Schedule < ActiveRecord::Base
belongs_to :user
has_many :rooms
accepts_nested_attributes_for :rooms, allow_destroy: true
...
class Room < ActiveRecord::Base
belongs_to :schedule
has_many :events
accepts_nested_attributes_for :events, allow_destroy: true
...
class Event < ActiveRecord::Base
belongs_to :room
...
schedule_controller.rb
class SchedulesController < ApplicationController
...
before_action :set_schedule, only: %i(show edit update destroy)
...
def new
#schedule = Schedule.new
room = #schedule.rooms.build
room.events.build
end
def create
#schedule = current_user.schedules.build(schedule_params)
if #schedule.save
flash[:success] = "schedule created!"
redirect_to root_url
else
render 'new'
end
end
def edit
#day_max = Room.where("schedule_id = ?", #schedule.id).maximum(:day)
end
def update
#schedule.rooms.maximum(:day)
if #schedule.update(schedule_params)
flash[:success] = "schedule updated!"
redirect_to root_url
else
render 'edit'
end
end
private
def schedule_params
params.require(:schedule).permit(:title, :departure_date, rooms_attributes: [:id, :_destroy, :room, :day, events_attributes: [:id, :_destroy, :from, :to, :title, :detail]])
end
def set_schedule
#schedule = Schedule.find(params[:id])
end
No error have been displayed before adding link_to_add.
It would be appreciated if you could give me any suggestion.
SOLVED!!!
<div id="room">
<%= f.simple_fields_for :rooms do |a| %>
<div id="room_<%= a.object.object_id %>">
<p class="day-number-element-selector"><b>Day <%= a.index.to_i + 1 %></b></p>
<%= a.simple_fields_for :events do |e| %>
<span class="form-inline">
<%= e.input :from, label: false %>
<%= e.input :to, label: false%>
</span>
<%= e.input :title, label: 'event' %>
<% end %>
</div>
<%= a.link_to_add "Add event", :events, data: {target: "#room_#{a.object.object_id}"}, class: "btn btn-primary" %>
<%= a.input :room %>
<% end %>
</div>
div#room should be something like :
<div id="room">
<%= f.simple_fields_for :rooms do |a| %>
<p class="day-number-element-selector"><b>Day <%= a.index.to_i + 1 %></b></p>
<% a.simple_fields_for :events do |e| %>
<div id="event">
<%= e.input :from %>
</div>
<% end %>
#add here!!!
<%= a.link_to_add "Add event", :events, data: {target: '#event'}, class: "btn btn-primary" %>
<%= a.input :room %>
<% end %>
</div>
First of all nested_form gem is abandoned, so I would suggest to use cocoon which is up to date now
Also probably you attributes filtered
room_attributes: [..., events_attributes: [...]]
As your attributes for rooms should be in plural form rooms_attributes
And the last suggestion do not use multi nesting. Try to have a look on form objects pattern
Hope it helps
How do I combined the day and time into a "start_time" variable (and "end_time") before submitting? JS?
<%= form_for #task do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="time_selectors">
<%= f.label :start_time %>
<%= f.text_field :start_time, :class => 'datepicker' %>
<select class="form-control time_dropdown" id="start_hour">
<option>Select Date</option>
</select>
<div class="clear_both"></div>
<%= f.label :end_time %>
<%= f.text_field :end_time, :class => 'datepicker' %>
<select class="form-control time_dropdown" id="end_hour">
<option>Select Date</option>
</select>
</div>
<div class="clear_both"></div>
</div>
<div class="clear_both"></div>
<%= f.submit "Create Task", class: "btn btn-large btn-primary" %>
</div>
<% end %>
I have them combined in my Task model, and I'd prefer to leave them combined if I can.
My JS right now doesn't work. What am I missing?
$('#new-task').submit ()->
valuesToSubmit = $(this).serialize
console.log('test')
console.log(valuesToSubmit)
return false
$('button').click ()->
console.log ('test2')
What about something like this?
$('form').on 'submit', (event) ->
event.preventDefault()
start_time = ''
start_time += $(#).find('input[name=start_day]').val()
start_time += '_'
start_time += $(#).find('input[name=start_hour]').val()
$('<input/>', {type: 'hidden', name: 'start_time', value: start_time}).appendTo($(#))
#submit()
(*The CoffeeScript version hasn't been tested - use the working Fiddle as your guide.)
Fiddle
I want to pass the selected value from the drop down to fullcalendar plugin and the rails form
The select tag
<%= form_tag appointments_path, :html => {:id => "form-1"} do %>
<%= select_tag(:worker_id, options_from_collection_for_select(#client.workers, :id, :name), :selected => #a, :style=>"width:170px;", :prompt => "Select Staff Member")%>
<% end %>
I am passing the #a variable by ajax to
<script>
$('#worker_id').change(function (e) {
var a = parseInt($(this).val());
alert(a);
$.ajax({
type: "GET",
url:"/customers/new",
data : { id: a },
success:function(result){
$('#content1').html("<%= escape_javascript(render :partial =>'form', :locals => ????) %>");
}
});
$('#calendar').fullCalendar('destroy');
RenderCalendar($(this).val());
});
</script>
I am not sure whether i am doing it in right way. I want to pass the value in form which is here:
<%= form_for(#customer) do |f| %>
<%#= f.error_notification %>
<div class="field">
<%#= f.label :Service_Name %>
<%#= f.collection_select :service_id, Category.where(:client_id => #client).order(:name), :services, :name, :id, :service_name %>
</div>
<br /> <br />
<%= f.fields_for :appointments do |builder|%>
<fieldset>
<% if #a!=0 %>
<%= builder.hidden_field :worker_id, :value=> #customer.worker_id %>
<%= builder.hidden_field :client_id, :value=> #client.id%>
<%= builder.label :price %>
<%= builder.text_field :price %>
<%= builder.label :Service_Name %>
<%= builder.collection_select(:service_id, #a.order(:service_name), :id, :service_name, :include_blank => true, :multiple => true ) %>
<% end %>
<%= builder.label :appointment_date %>
<%= builder.date_select :appointment_date %> <br />
<%= builder.label :appointment_start_time %>
<%= builder.time_select :appointment_start_time, ampm: true %> <br />
<%= builder.label :appointment_end_time %>
<%= builder.time_select :appointment_end_time, ampm: true %>
</fieldset>
<%end%>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.hidden_field :worker_id, :value=>#customer.worker_id %>
</div>
<div class="form-actions">
<%= f.button :submit, :class=>"btn btn-primary" %>
</div>
<% end %>
If I understand correctly: you are trying to rerender the fullcalender jquery plugin with your ajax success callback based on the user selected from the select tag here:
<%= form_tag appointments_path, :html => {:id => "form-1"} do %>
<%= select_tag(:worker_id, options_from_collection_for_select(#client.workers, :id, :name), :selected => #a, :style=>"width:170px;", :prompt => "Select Staff Member") %>
<% end %>
There is an inherent issue with the way you're trying to do this. Any embedded ruby in your views will run only once at runtime. Essentially, your escape_javascript(render partial..... will not run because any embedded ruby is done running at that point.
What you could do is keep the ajax call you already have but run the render partial code in your '/customers/new', instead of trying to call it in the ajax callback -which is after runtime
render :partial =>'form', :locals => ????
This will return the partial code with which you want to then place on the page. With your ajax, simply place it on the page something like this:
success:function(result){
$('#content1').html(result);
}
I have a "room type" table full of values, I want to make it so that when a user selects a room type from the collection_select the rest of the form gets updated with that room type's values, I can detect when the selection is changed with javascript through $('#room_roomtype_id').change and which room type was selected through $('#room_roomtype_id :selected').text() but I have no idea, and my hours of searching have been futile, how to then update the other form fields with data from the room type table.
Here is my form code:
<%= form_for #room do |f| %>
<% if #room.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #room.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p id="roomtypes", data-url="<%= url_for :controller => 'rooms', :action => 'roomtypeupdate' %>">
<%= f.label :roomtype_id, "Room type" %><br />
<%= f.collection_select :roomtype_id, Roomtype.order(:name), :id, :name, include_blank: true %>
</p>
<p>
<%= f.label :number, "Room number" %><br />
<%= f.text_field :number %>
</p>
<p>
<%= f.label :maxcap, "Capacity" %><br />
<%= f.number_field :maxcap %>
</p>
<p>
<%= f.label :size, "Size" %><br />
<%= f.number_field :size %>
</p>
<p>
<%= f.label :description, "Description" %><br />
<%= f.text_area :description %>
</p>
<p>
<%= f.label :singlebeds, "Number of single beds" %><br />
<%= f.number_field :singlebeds %>
</p>
<p>
<%= f.label :bathrooms, "Number of bathrooms" %><br />
<%= f.number_field :bathrooms %>
</p>
<br />
<p class="button"><%= f.submit %></p>
<% end %>
Something like this should work:
$('#room_roomtype_id').on('change', function () {
// URL for the sake of example - yours will differ
$.get('/rooms/' + this.value + '.json', function (response) {
// dummy response for the sake of example
response = {
"number": "5A",
"maxcap": "10"
};
$.each(response, function (key, value) {
$('[name="room[' + key + ']"]').val(value);
});
});