Search code examples
javascriptruby-on-railsmodel-view-controllerflatpickr

Rails and JS, how to best get an input date in my view


I created a calendar, where a user can click on an arrow to the right and consequently the next 2 weeks are shown (because the start_date is updated by 2 weeks). This works like a charm (for dates near the current date).

Goal

Now I'm trying to also add a calendar, so users are able to select a date far away and consequently this date will be used to update the calendar. I'm trying to follow the same approach as before, by using the selected calendar date as the start_date.

Issue

I'm using flatpickr on an input field with JS, but I don't know how to use the picked value to update the calendar. More concretely:

  • Do I need to go to my controller action calendar and update the start_date (and how can I do this?)
  • Can I use the selected date directly as start_date in my view (and how can I do this?)
  • Or is there a better way to reach my goal?

Code

controller

  def calendar
    @hotel = Hotel.find(params[:hotel_id])
    @room_categories = @hotel.room_categories
    @rooms = []
    @room_categories.each do |room_cat|
      @rooms << room_cat.rooms
    end
    @reservations = @hotel.reservations
    # @start_date = Date.today
    @start_date = params[:start_date] ? Date.parse(params[:start_date]) : Date.today
    authorize @reservations
  end

js for calendar

import flatpickr from 'flatpickr';

const toggleDateInputs2 = function() {
  const startDateInput = document.getElementById('input-calendar');

  if (startDateInput) {

    flatpickr(startDateInput, {
    format: "d-m-Y",
    altFormat: "d-m-Y",
    dateFormat: 'd-m-Y',
    onChange: function(selectedDates, selectedDate) {
      // Send selectedDate as start_date to view
    }
  });
  }
};

export { toggleDateInputs2 }

calendar view

<!-- Arrow left on click, previous 2 weeks -->
<div class="arrow-container d-flex align-text-center">
  <%= link_to(calendar_hotel_reservations_path(@hotel, start_date: @start_date - 14))  do %>
    <i class="fas fa-arrow-circle-left"></i>
  <% end %>

  <!-- Begin calendar -->
    <i class="far fa-calendar-alt fa-2x"></i>
  <input type="text" name="fname" placeholder="Pick date" id="input-calendar">

<!-- Arrow right on click, next 2 weeks -->
  <%= link_to(calendar_hotel_reservations_path(@hotel, start_date: @start_date + 14))  do %>
    <i class="fas fa-arrow-circle-right"></i>
  <% end %>
</div>

<!-- rest of calendar which is based on start_date -->
..........

Solution

  • Judging by what you say I think that the "best way" would be to leverage what you already have. You can make use of flatpickr's onChange and send the selectedDate value as a parameter. :

    flatpickr(startDateInput, {
    format: "d-m-Y",
    altFormat: "d-m-Y",
    dateFormat: 'd-m-Y',
    onChange: function(selectedDates, selectedDate) {
      window.location.replace( "thecalendarhotelreservationsurl/<%=@hotel%>/"+selectedDate )
    }
    

    Creating the url string manually is a quick way to achieve what you want if you don't mind getting your hands a little dirty, but maybe a fancier way to do this would be creating a POST route that accepts the hotel_id and start_date as params and use an AJAX call inside the onchange.