adrienpoly / stimulus-flatpickr

A modest, yet powerful wrapper of Flatpickr 📆 for Stimulus
MIT License
412 stars 30 forks source link

Can not use outlets when the controller inherits from stimulus flatpicker. #115

Open miguelperez opened 2 months ago

miguelperez commented 2 months ago

I have a filter controller that has different filtering controllers inside. The filtering controllers can submit the filter controller. I have two types of filter a date range using flatpicker and a users list that is a regular stimulus controller. each filter also provides a mechanism to "clear" its selection, after clearing they submit the form to update the results.

The issue I am seeing is that the date range picker controller does not recognize the outlets whereas the people filter controller does.

The following code is simplified and probably missing closing brackets.

Date range controller

import { Controller } from "@hotwired/stimulus";
import Flatpickr from 'stimulus-flatpickr'
import { Spanish } from "flatpickr/dist/l10n/es.js";
import { english } from "flatpickr/dist/l10n/default.js";

export default class extends Flatpickr {
  static outlets = ["filter-form"]
  static targets = [....]
  .....

clearAll(evt) {
    evt.preventDefault();
    this.fp.clear();
    const formattedDates = this.fp.selectedDates.map(date => {
      return date.toLocaleDateString('en-GB', {day: 'numeric', month: 'short', year: 'numeric'}).toLowerCase();
    });
    this.defaultStartDateTarget.value = this.checkDateValue(formattedDates[0]);
    this.defaultEndDateTarget.value = this.checkDateValue(formattedDates[1]);
    if (this.hasFilterFormOutlet) {
      this.filterFormOutlet.submit(evt);
    }
  }

The HTML is the following:

<div data-controller="date-range-picker" data-date-range-picker-filter-form-outlet=".filter-form" >

The HTML form (the filter stimulus controller) is defined like this:

<%= form_with url: some_path,
                method: :get,
                html: {
                  class: "filter-form"
                },
                data: {
                  turbo_action: "advance",
                  controller: "filter-form",
                  turbo_frame: "some_frame",
                } do |form| %>

There is another stimulus controller that declares the same outlet as the datepicker. Is for a list of checkboxes that upon selecting one, it will submit the form:

import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="people-picker-list"
export default class extends Controller {
  static targets = ["checkboxes", "searchInput", "selected"];
  static outlets = ["filter-form"];

clearAll(evt) {
    evt.preventDefault();
    this.checkboxesTargets.forEach((checkbox) => {
      checkbox.checked = false;
    });
    this.selectedTarget.value = "";

    if (this.hasFilterFormOutlet) {
      this.filterFormOutlet.submit(evt);
    }
  }