Datetimepicker & Cocoon Showing multiple time toggle - ruby-on-rails

I have a nested form which is currently working, except that everytime I would add a nested form, it will display the calendar for each field on a click. Meaning, if there are 5 nested form each with a Start and End date, once the user clicks on the calendar icon, it will open 10 datetimepicker.
<div class="input-group date datepicker">
<%= f.text_field(:start, value: f.object.start ? f.object.start.strftime('%B %d, %Y') : nil, class: "form-control datetimepicker", data: {target: ".datetimepicker"}, placeholder: "#{t :From}", required: true) %>
<div class="input-group-append" data-target=".datetimepicker" data-toggle="datetimepicker">
<div class="input-group-text"><span class="fas fa-calendar-alt"></span></div>
</div>
</div>
</tr>
<tr>
<div class="input-group date datepicker">
<%= f.text_field(:end, value: f.object.end ? f.object.end.strftime('%B %d, %Y') : nil, class: "form-control datetimepicker", data: {target: ".datetimepicker"}, placeholder: "#{t :End_time_or_until}", required: true) %>
<div class="input-group-append" data-target=".datetimepicker" data-toggle="datetimepicker">
<div class="input-group-text"><span class="fas fa-calendar-alt"></span></div>
</div>
</div>
</tr>
Anybody knows how to integrate this ?
I have this in my main form's JS :
$(document).on('ready page:change', function() {
insertedItem.find('.datepicker').datepicker()
$('#invsessions').on('cocoon:after-insert', function() {
$('.datetimepicker').datetimepicker();
})
})
On this case, I add the nested form twice.

Related

Params disappearing when using Tempus dominus bootstrap4

I'm trying to use the Tempus Dominus Datetime picker in my app. Everything seems to work fine, but when I try to convert the submitted string into a datetime object in my controller, I get a TypeError (no implicit conversion of nil into String). I've also tried to puts the parameters into the logs, but get a blank line. The odd thing is, during the submission of the form, the parameters do seem to be present.
Processing by EventsController#create as HTML
Parameters: {"utf8"=>"✓", >"authenticity_token"=>"yuP08tdkavDAzcbJImZXeL0EZ1dp6D13dnLyW/lU+frPVej0tiUmavI>0GKvs66z7+ca2GynI1WWs2d5aSJX5zA==", "event"=>{"title"=>"aaaaa", >"game"=>"bbbb", "start_time"=>"02/21/2020 1:26 PM", "end_time"=>"02/28/2020 >10:46 PM", "description"=>"sasasa"}, "button"=>""}
Here's all relevant code.
Controller:
class EventsController < ApplicationController
def new
#event = Event.new
end
def create
#user = current_user
if #user
#user.events.create(title: params[:title], game: params[:game],
start_time: time_parse(params[:start_time]),
end_time: time_parse(params[:start_time]),
description: params[:description])
end
end
private
def event_params
params.require(:event).permit(:title, :game, :start_time,:end_time, :description)
end
def time_parse(time)
DateTime.strptime(time, '%m/%d/%Y %M:%S %p')
end
end
View:
<div class="col-lg-6">
<%= form_for #event, url: events_path do |form| %>
<div class="form-row">
<div class="col-md-6 form-group">
<%= form.text_field :title, class: "form-control", placeholder: "Party Title" %>
</div>
<div class="col-md-6 form-group">
<%= form.text_field :game, class: "form-control", placeholder: "Game" %>
</div>
</div>
<div class="row">
<div class='col-md-6'>
<div class='form-group'>
<%= form.label :start_time, 'Start Date and Time', class: 'control-label' %><br>
<div class="input-group date" id="datetimepicker1" data-target-input="nearest">
<%= form.text_field(:start_time,
value: form.object.start_time ? form.object.start_time.strftime('%B %d, %Y %I:%M %p') : nil,
class: "form-control datetimepicker-input", data: {target:"#datetimepicker1"}) %>
<div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fas fa-calendar-plus"></i></div>
</div>
</div>
</div>
</div>
<div class='col-md-6'>
<div class='form-group'>
<%= form.label :end_time, 'End Date and Time', class: 'control-label' %><br>
<div class="input-group date" id="datetimepicker2" data-target-input="nearest">
<%= form.text_field(:end_time,
value: form.object.end_time ? form.object.end_time.strftime('%B %d, %Y %I:%M %p') : nil,
class: "form-control datetimepicker-input", data: {target:"#datetimepicker2"}) %>
<div class="input-group-append" data-target="#datetimepicker2" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fas fa-calendar-plus"></i></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 form-group">
</div>
<%= form.text_area :description, class: "form-control", size: "24x6", placeholder: "Describe your meetup"%>
</div>
<div class="text-center "><%= form.button "Sign up", class: "sub-but" %></div>
<% end %>
</div>
Javascript for view:
$('#datetimepicker1').datetimepicker({
format: 'MMMM D, YYYY h:mm A',
stepping: 15,
minDate: Date(),
maxDate: new Date(Date.now() + (365 * 24 * 60 * 60 * 1000)),
sideBySide: true,
icons: {
up: 'fas fa-arrow-up',
down: 'fas fa-arrow-down',
previous: 'fas fa-chevron-left',
next: 'fas fa-chevron-right',
close: 'fas fa-times'
},
buttons: {showClose: true }
});
$('#datetimepicker2').datetimepicker({
format: 'MMMM D, YYYY h:mm A',
stepping: 15,
useCurrent: false,
sideBySide: true,
icons: {
up: 'fas fa-arrow-up',
down: 'fas fa-arrow-down',
previous: 'fas fa-chevron-left',
next: 'fas fa-chevron-right',
close: 'fas fa-times'
},
buttons: {showClose: true }
});
$("#datetimepicker1").on("change.datetimepicker", function (e) {
$('#datetimepicker2').datetimepicker('minDate', e.date);
console.log(e.date);
});
$("#datetimepicker2").on("change.datetimepicker", function (e) {
$('#datetimepicker1').datetimepicker('maxDate', e.date);
});
I think you are not linking to the params correctly, also I noticed you have the :start_time going into both in your code above, I assume that is a typo so I changed it in my answer. If it isn't a typo then keep that as is.
...
start_time: time_parse(params[:event][:start_time]),
end_time: time_parse(params[:event][:end_time]),
...

Not able to make linked datetimepicker working on rails app

I have the following datetimepicker, which work well and pass the params to the controller. But I would like to make sure that the user cannot select a end date that is before the start date.
<div class="row">
<div class="col-md-2" style="text-align: right;">
</div>
<div class="col-md-3">
<div class="input-group date" id="datetimepicker4" data-target-input="nearest" style="margin-bottom: 20px">
<%= form.text_field(:start, class: "form-control datetimepicker-input", data: {target:"#datetimepicker4"}, placeholder: "#{t :From}") %>
<div class="input-group-append" data-target="#datetimepicker4" data-toggle="datetimepicker">
<div class="input-group-text"><span class="fas fa-calendar-alt"></span></div>
</div>
</div>
</div>
<div class="col-md-2 col-md-offset-1" style="text-align: right;">
</div>
<div class="col-md-3">
<div class="input-group date" id="datetimepicker5" data-target-input="nearest" style="margin-bottom: 20px">
<%= form.text_field(:end, class: "form-control datetimepicker-input", data: {target:"#datetimepicker5"}, placeholder: "#{t :End_time_or_until}") %>
<div class="input-group-append" data-target="#datetimepicker5" data-toggle="datetimepicker">
<div class="input-group-text"><span class="fas fa-calendar-alt"></span></div>
</div>
</div>
</div>
<div class="col-md-1" style="margin-bottom: 20px; text-align: right">
<%= form.button "#{t :Refresh}", class: "btn btn-primary" %>
</div>
</div>
I have the following scripts:
<script>
$(".end_at").change(function (e) {
end_at = $(e.target).val();
start_at = $(".start_at").val();
$.ajax({
type: "POST",
url: "index",
data: {
start_at: start_at,
end_at: end_at,
},
success: function (data) {
$(".chart-container").html(data);
},
});
});
$(function() {
$('#datetimepicker4').datetimepicker({
viewMode: 'days',
dropdownParent: $("#modal-window")
});
$('#datetimepicker5').datetimepicker({
viewMode: 'days',
useCurrent: false,
dropdownParent: $("#modal-window")
});
$('#datetimepicker4').on('dp.change', function (e) {
$('#datetimepicker5').data('DateTimePicker').minDate(e.date);})
$('#datetimepicker5').on('dp.change', function (e) {
$('#datetimepicker4').data('DateTimePicker').maxDate(e.date);
});
});
</script>
Anybody knows what is missing please ? It does look like the form is not connecting to the scripts.
datetimepicker once initiated won't change configurations , so i think on change of start_date datetimepicker you need to destroy end_date's datetimepicker and then reinitiate with the new configs, set minDate in initiation of the end_date datetimepicker.

Rails Radio button is only allowing me to select only first option and not the other

What would be the cause of me only being able to select the first radio button, but not the second. Here is what my form looks like.
`
<%= form_for [#item, Calendar.new] do |f| %>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<%= f.text_field :start_date, readonly: true, value: Date.today, class: "form-control datepicker" %>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<%= f.text_field :end_date, readonly: true, value: Date.today, class: "form-control datepicker" %>
</div>
</div>
</div>
<div class="form-group">
<div class="btn-group" data-toggle="buttons-radio">
<%= f.collection_radio_buttons :status, Calendar.statuses, :first, :first, checked: Calendar.statuses.first do |b|
b.radio_button + b.label {b.text.split("_").join("").capitalize}
end %>
</div>
</div>
<div class="row new-pricing">
<div class="col-md-10">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">$</span>
<%= f.text_field :item_price, class: "form-control", value: #item.item_price, required: true %>
</div>
</div>
</div>
<div class="col-md-2">
<p style="margin-top: 10px"> Per Day </p>
</div>
</div>
<div class="no-pricing hide">
</div>
<div class="form-group">
<%= f.button "Save", type: :submit, class: "btn btn-success" %>
</div>
<% end %>`
Here is what the html looks like when I click on the "Not available" button. The checked always remains on the first value input button.
The html in the inspection window.
How can I go about fixing this. Sorry if this was an easy question.

Rails Submit button not submitting

I've moved from BS3 to Materialize so I am going through and changing my forms - I have 4 forms that are extremely similar, but as I switched the first one over it's no longer submitting. The button doesn't even seem like it's getting clicked, but I tied a generic 'logMe' function to it and sure enough it is.
My routes are the exact same for both, the new form is
<div class="row">
<%= form_with(model: #statement, local: true) do |form| %>
<% if #statement.errors.any? %>
<% #statement.errors.full_messages.each do |message| %>
<script>
$(function() {
Materialize.toast("<%= message %>", 3000);
});
</script>
<% end %>
<% end %>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">account_circle</i>
<!--<label for="icon_prefix">SoW Type:</label>-->
<%= form.label :statement_type, 'Type:' %>
<%= form.text_field :statement_type, :id => "disabled", :value => (params[:statement_type]), readonly: true, :disabled => true %>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<i class="material-icons prefix">contacts</i>
<%= form.label :name, "Name:" %>
<%= form.text_field :name, :id => 'required_field1' %>
</div>
<div class="input-field col s6">
<i class="material-icons prefix">contacts</i>
<%= form.label :cost, "Cost:" %>
<%= form.text_field :cost, :id => 'required_field2' %>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<i class="material-icons prefix">date_range</i>
<%= form.label :start_date, "Start Date" %>
<%= form.text_field :start_date, :class => 'datepicker', "data-provide" => 'datepicker', :id => 'required_field4', :placeholder => "YYYY-MM-DD" %>
</div>
<div class="input-field col s6">
<i class="material-icons prefix">date_range</i>
<%= form.label :end_date, "End Date" %>
<%= form.text_field :end_date, :class => 'datepicker', "data-provide" => 'datepicker', :id => 'required_field5', :placeholder => "YYYY-MM-DD" %>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">perm_contact_calendar</i>
<%= form.collection_select(:client_id, current_user.clients.order(:name),:id,:name, :class => "browser-default", :prompt => "Choose a client" ) %>
</div>
</div>
<div class="row">
<div class="col s12">
<%= form.submit 'Submit', :class =>'btn btn-default', :id => 'register', :onclick => "testMe()"%>
</div>
</div>
<% end %>
</div>
<script type="text/javascript">
$(document).ready(function (){
$('select').material_select();
validate();
$('#required_field1, #required_field2').change(validate);
});
function testMe(){
console.log('hi')
}
function validate(){
if ($('#required_field1').val().length > 0 &&
$('#required_field2').val().length > 0
){
$("input[type=submit]").prop("disabled", false);
}
else {
$("input[type=submit]").prop("disabled", true);
}
}
var from_$input = $('#required_field4').pickadate({
selectMonths: true, // Creates a dropdown to control month
selectYears: 15, // Creates a dropdown of 15 years to control year,
today: 'Today',
clear: 'Clear',
close: 'Ok',
closeOnSelect: true,
format: 'yyyy-mm-dd'
}),
from_picker = from_$input.pickadate('picker')
var to_$input = $('#required_field5').pickadate({
selectMonths: true, // Creates a dropdown to control month
selectYears: 15, // Creates a dropdown of 15 years to control year,
clear: 'Clear',
close: 'Ok',
closeOnSelect: true,
format: 'yyyy-mm-dd'
}),
to_picker = to_$input.pickadate('picker')
// Check if there’s a “from” or “to” date to start with.
if ( from_picker.get('value') ) {
to_picker.set('min', from_picker.get('select'))
}
if ( to_picker.get('value') ) {
from_picker.set('max', to_picker.get('select'))
}
// When something is selected, update the “from” and “to” limits.
from_picker.on('set', function(event) {
if ( event.select ) {
to_picker.set('min', from_picker.get('select'))
}
else if ( 'clear' in event ) {
to_picker.set('min', false)
}
})
to_picker.on('set', function(event) {
if ( event.select ) {
from_picker.set('max', to_picker.get('select'))
}
else if ( 'clear' in event ) {
from_picker.set('max', false)
}
})
</script>
I've tried commenting out all JS, switching it to a regular button, linting it and using Rubocop but I don't see anything off. I went through the HTML to make sure the button was inside the form, and it is.
This isn't the first form I've transitioned, but the first I'm having issues with.
(I assume only the view is relevant since it isn't getting to the controller at this point.)
Just to be safe - The view rendering the form is
<div class="row">
<div class="col s12"><span class="flow-text" style="text-align: center;"><h1>New <%= params[:statement_type] %></h1></span></div>
</div>
<% if params[:statement_type] == 'Proposal' %>
<%= render 'proposal_form' %>
<% elsif params[:statement_type] == 'Concept' %>
<%= render 'concept_form' %>
<% elsif params[:statement_type] == 'SoW' %>
<%= render 'sow_form' %>
<% elsif params[:statement_type] == 'Misc' %>
<%= render 'misc_form' %>
<% end %>
<%= link_to 'Back', statements_path %>
SoW + Proposal work. SoW doesn't.
My issue ended up not being HTML based, but Rails based in the end.
My static element that is populated by a param was causing the issue.
<%= f.text_field :statement_type, :id => "disabled", :value => (params[:statement_type]), readonly: true %>
By removing the id: disabled it resolved the inability for the Submit button to submit. Unfortunately, it also makes MaterializeCSS back to highlighting the field when I select it, but my issue was the Submit button not working.

Bootstrap modal nested model form view messed up

Here is what happens
Here is my views code
Form
<%= simple_form_for([:supplier, #fuel_price],remote: true, :html => {:class => 'form-vertical' }) do |f| %>
<%= f.simple_fields_for :fuel_products do |fuel_products_form| %>
<div class="field">
<%= render partial: 'fuel_products_fields', locals: {f: fuel_products_form} %>
</div>
<% end %>
<%= link_to_add_fields "Add more", f, :fuel_products %>
<div class="modal-footer">
<%= f.button :submit, "Update", class: "btn btn-success"%>
</div>
<%end%>
Fuel Products Field Partial
<div class="col-md-6">
<%= f.input :fuel, label: "Fuel Type", :collection => fuel_types, class: "form-control select",:selected => "87 RFG" %>
</div>
<div class="col-md-3">
<%= f.input :price, class: "form-control", placeholder: "$1.25" %>
</div>
<%= f.hidden_field :_destroy %>
<ul class="list-unstyled">
<li><%= link_to '#', class: "btn btn-danger btn-xs remove_fields" do %>
Remove
<%end%></li>
</ul>
Javascript code
ready = ->
$('#FuelmodelBody').on 'click', '.remove_fields', (event) ->
$(this).prev('input[type=hidden]').val('1')
$(this).closest('.field').hide()
event.preventDefault()
$('#FuelmodelBody').on 'click', '.add_fields', (event) ->
console.log('It is really happening ....')
time = new Date().getTime()
regexp = new RegExp($(this).data('id'), 'g')
$(this).before($(this).data('fields').replace(regexp, time))
event.preventDefault()
$(document).ready(ready)
$(document).on('page:load', ready)
Views Modal code
<div class="modal inmodal" id="newFuelPrice" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content animated bounceInRight">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
<i class="fa fa-usd modal-icon" style="color:#1ab394"></i>
<h4 class="modal-title">Add New Fuel Price</h4>
<span class="font-bold">Your contacts will get text message of your latest price</span>
</br>
<span class="font-bold">As (your fuel price + the formula).</span>
</div>
<div class="modal-body" id="FuelmodelBody">
<!-- form -->
</div>
</div>
</div>
</div>
I also have a helper function for link_to_add_fields
def link_to_add_fields(name, f, association)
# creates a new instance of the 'has_many' object
new_object = f.object.send(association).klass.new
# new_object = f.object.association.klass.new
# f.object.association.klass # => Document
# new_object = f.object.documents.build Document(user_id: f.object.id)
# gets the object id
id = new_object.object_id
# creates a new form for the association
fields = f.fields_for(association, new_object, child_index: id) do |builder|
render(association.to_s + '_fields', f: builder)
end
link_to(name, '#', class: 'add_fields', data: { id: id, fields: fields.delete("\n") })
end
Moving around code since morning and still could not figure out how to fix those buttons by aligning side by add, the add more will also be button in blue, i was just playing around and converted it to link. I am Using simple Form
If you want to align your "Remove" buttons with their corresponding Fuel type and Price fields, then you need to put them all in a single Bootstrap row like so:
<div class="row">
<div class="col-md-6">
<%= f.input :fuel, label: "Fuel Type", :collection => fuel_types, class: "form-control select",:selected => "87 RFG" %>
</div>
<div class="col-md-3">
<%= f.input :price, class: "form-control", placeholder: "$1.25" %>
</div>
<div class="col-md-3">
<%= f.hidden_field :_destroy %>
<ul class="list-unstyled">
<li><%= link_to '#', class: "btn btn-danger btn-xs remove_fields" do %>
Remove
<%end%></li>
</ul>
</div>
</div>
Also, you probably don't need that extra ul tag. It does not carry any additional meaning, since you have just one button in there. It is not a list.
<div class="row">
<div class="col-md-6">
<%= f.input :fuel, label: "Fuel Type", :collection => fuel_types, class: "form-control select",:selected => "87 RFG" %>
</div>
<div class="col-md-3">
<%= f.input :price, class: "form-control", placeholder: "$1.25" %>
</div>
<div class="col-md-3">
<%= f.hidden_field :_destroy %>
<%= link_to 'Remove', '#', class: "btn btn-danger btn-xs remove_fields" %>
</div>
</div>

Resources