Utilizing the Flatpickr's onChange event to dynamically update the end date

I am utilizing two date pickers, start_time and end_time, both implemented with the flatpickr() function. When a date is selected for the start_time, I want the end_time to automatically update to match that value.

To achieve this functionality, I am attempting to make use of the onChange hook which is detailed in the documentation available at .

Date Picker Forms

<div class="start_time_result mb-6" style ="width: 30vw;">
  <%= form.label :start_time, class: 'label' %>
  <div class="flex items-center justify-between max-w-md">
    <%= form.text_field :start_time, data: { behavior: "flatpickr" }, placeholder: "Date and time select ...", class: "form-control" %>
  </div>
</div>
<div class="field" style ="width: 30vw;">
  <%= form.label :end_time, class: 'label' %>
  <div class="end_time_result flex items-center justify-between max-w-md">
    <%= form.text_field :end_time, data: { behavior: "flatpickr" }, placeholder: "Date and time select ...", class: "form-control required" %>
  </div>
</div>

Javascript Code Block

document.addEventListener('turbolinks:load', function() {
  document.querySelector('#recurring_event a')
    .addEventListener("ajax:success", function(data, status, xhr) {
      flatpickr("[data-behavior='flatpickr']", {
        enableTime: false,
        altInput: true,
        altFormat: "F j, Y",
        minDate: "today",
        onChange: function(dateObj, dateStr) {
          end_time.set('minDate', dateStr)
        }
      })
    });
});

Answer №1

You can utilize the onChange event of #start_time to set the minimum date (minDate) for end_time.

Here is an example:

$(document).ready(function() {
  let start_time = $('#start_time');
  let end_time = $('#end_time');

  start_time.flatpickr({
    altInput: true,
    altFormat: "F j, Y",
    onChange: function(selectedDates) {
      end_time.flatpickr({
        altInput: true,
        altFormat: "F j, Y",
        minDate: new Date(selectedDates),
      });
    }
  });

  end_time.flatpickr({});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.11/flatpickr.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.maskedinput/1.4.1/jquery.maskedinput.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.11/flatpickr.min.js"></script>

<input id="start_time">
<input id="end_time">

Answer №2

After encountering the same challenge, I finally managed to make it work just half an hour ago. My approach involved using a Stimulus controller in a Rails 6 application with the Flatpickr package integrated through Webpacker.

Since my flatpickr instances were used globally on the site, I handled instantiation in the application js file:

//application.js
import { Application } from "@hotwired/stimulus";
import { definitionsFromContext } from "@hotwired/stimulus-webpack-helpers";
import flatpickr from "flatpickr";
window.Stimulus = Application.start()
Stimulus.load(definitionsFromContext(context))

document.addEventListener("turbo:load", () => {
  flatpickr("[data-datetimepicker='flatpickr']", {
    enableTime: true, 
    dateFormat: "Z",
    minDate: "today",
    altInput: true,
    altFormat: "M. j, Y h:i K", 
    allowInput: true, 
    onOpen: function(selectedDates, dateStr, instance) {
        $(instance.altInput).prop('readonly', true);
    },
    onClose: function(selectedDates, dateStr, instance) {
        $(instance.altInput).prop('readonly', false);
        $(instance.altInput).blur();
    },
  })
})

Both my start_time and end_time inputs utilized the same flatpickr instances (not ideal, I know), causing JavaScript errors in the console when trying to update the onChange configuration of the start_time input post turbo:load. Specifically, the start_time instance was undefined when attempting another turbo:load event to replicate the datetime value, resulting in a console error of 'Uncaught TypeError (Cannot read properties of undefined)'.

The Turbo handbook provided essential guidance that led me to the solution: "When possible, avoid attaching additional event listeners directly to elements on the page body using the turbo:load event." Hence, I developed a Stimulus controller to duplicate the flatpickr dateObj value from one instance to another:

//dup_datetime_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["mirror"]
  
  dup(event){
     let origin = event.target._flatpickr
     let mirror = this.mirrorTarget._flatpickr
     
     origin.config.onChange.push(function(dateObj) {
        mirror.set("minDate", dateObj)
        mirror.setDate(dateObj)
     })
  }
}

...inserted the controller reference into the containing div of the input elements:

//_form.html.erb
<div class="card-body" data-controller="dup-datetime">

...included a data-action attribute for the start_time input:

//_form.html.erb
<%= form_with(model: @ask) do |f| %>
<%= f.text_field :start_time, required: true, data: { datetimepicker: "flatpickr", action: "input->dup-datetime#dup" }, class: 'form-control bg-white', id: "quick_starttime", readonly:'readonly' %>

...and added the Stimulus target data attribute to the end_time input:

//_form.html.erb
<%= f.text_field :end_time, required: true, data: { datetimepicker: "flatpickr", dup_datetime_target: "mirror" }, class: 'form-control bg-white', id: "quick_endtime", readonly:'readonly' %>

I hope this solution spares someone else several hours (or even days... weeks...) of their life.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

An issue has been identified with the functionality of an Ajax request within a partial view that is loaded through another Ajax request specifically in

Here is the current scenario within my ASP.NET MVC application: The parent page consists of 3 tabs, and the following javascript code has been implemented to handle the click events for each tab: Each function triggers a controller action (specified in t ...

tips for successfully transferring date and time data between json and nosql databases like firestore

Input: Created_At:Monday, 29 April 2019 15:07:59 GMT+05:30 Updated_At:Monday, 29 April 2019 15:07:59 GMT+05:30 I attempted to export data in JSON format from Firestore using the npm package firestore-export-import. However, the output I received was: ...

How can you create a smooth transition between two images in React Native?

I'm looking to create a cool effect with two images that gradually fade into each other. My initial approach involved layering one image over the other and adjusting its opacity using timing or animation functions, but I've been struggling to ge ...

IconButton function in ReactJS malfunctioning specifically in Firefox browser

There seems to be an issue with the click function of IconButton from Material UI not working in any version of FireFox. Below is the code snippet in question: <div className='floating-button visible-xs'> <IconButton touch={true} tool ...

Tips for utilizing the "Sign In with Apple" feature through Apple JS

For implementing "Sign In with Apple" on a web platform using Apple JS, you can refer to the code example available at this link. Now, the query arises: where can I find the Client ID required for this process? I have tried using the app id identifier fro ...

Are the frameworks Vue, Angular, and React known for

During a conversation, I came across an interesting viewpoint criticizing popular frameworks such as Angular, Vue, and React. It was argued that these frameworks have a significant disadvantage: apart from the API part that interacts with the server's ...

Encountering a display issue within a port using Express

Recently, I enrolled in an advanced ExpressJS course. While exploring the course website, I stumbled upon the "hello world" section. Intrigued, I decided to copy and paste the code provided below: const express = require('express') const app = ex ...

What is the correct way to apply styles universally instead of using "*" as a selector?

With Nextron, I was able to successfully run my code, but upon opening the window, I noticed that the body tag had a margin of 8px. Although I managed to change this using the dev tools, I am unsure how to permanently apply this change in my code. When att ...

Express Module Paths Failing to Function Properly

When I first started building my routes, I had everything in one api.js file. However, I realized there might be a better approach, so I did some research online to see how others handle it. After following a few tutorials, I decided on a new layout with s ...

Utilizing properties to transfer a reference object to a nested component

Is it safe to do the following in React: function Parent() { const myRef = useRef([1, 2, 3]); console.log("parent: " + myRef.current); return <Child myList={myRef.current} />; } function Child({ myList }) { const [currInt, setCurrInt] = useS ...

CSS3 transition applied to a jQuery direction-aware hover effect

I'm encountering difficulties making direction-aware hover and css transitions function correctly. Specifically, I am attempting to create a grid of elements with front and back faces, and on hover, have a css transition that flips the element to disp ...

Cursor hovers over button, positioned perfectly in the center

I am facing a challenge with implementing a hover function for a set of buttons on the screen. The goal is to display the mouse pointer at the center of the button upon hovering, rather than the actual position of the cursor being displayed. I have tried u ...

The output from the Angular .then function is not showing up on the webpage

Within my stucontrollers.j, I have the following code: /// <reference path="../angular.js" /> var stucontrollers = angular.module("stucontrollers", []); stucontrollers.controller("GetStudentsList", function GetStudentsList($scope, $http) { $ ...

Enhance the functionality of your React app by making the `<Paper>` component in Material UI clickable

I'm trying to figure out how to make a Paper component clickable. I attempted to set an id property in the tag like () and then utilize the DOM to add an event listener, but it's not working. I've hit a roadblock and I'm running out of ...

Boost the frequency of updates in Meteor.observe

When Python writes to a database (mongo) every second in the setup, Meteor.js is expected to react immediately to the new record insertion. Issue: However, the use of cursor.observe() results in the console outputting only 4-5 seconds after the new record ...

How can the input validation be displayed in Ajax when the user interacts with it?

When utilizing Ajax, I only want to display validation for the input field that the user is interacting with, not all validations at once. Currently, my script shows all validations simultaneously when any input is filled out. How can I modify my code so t ...

Creating two separate divs that can scroll independently while also limiting each other's scroll depth can be achieved by utilizing

I am attempting to replicate the unique scrolling feature seen on this particular page. Essentially, there are two columns above the fold that can be scrolled independently, but I want their scroll depths to be linked. When a certain depth is reached whil ...

Creating an if statement that validates whether all variables have non-null values

I am still getting the hang of javascript and working on some coding projects from my textbooks. The current task involves creating an if statement to check if the values of the elements referenced by the names fname, lname, and zip are all not null. Here ...

Tips for confirming date is earlier than current date in Reactjs?

Looking for guidance on how to ensure a date selected by a user is always before the current date when using Material UI in my project. For instance, if it's January 6th, 2021 and the user selects either January 5th or 6th that would be acceptable. Ho ...

Error occurs when attempting to read the 'map' properties of null because the JSON array is double nested

Within my code, I am attempting to access the URLs of two thumbnails in the JSON data below. Currently, I can only retrieve the information from the first array: <>{post.attributes.description}</> However, I am encountering difficulty retrievi ...