gitcoinco/code_fund_ads

View on GitHub
app/javascript/controllers/select_controller.js

Summary

Maintainability
A
0 mins
Test Coverage
// Bootstrap requires jQuery
// Our use of it here is simply because its already a dependency
// The verbose use of the `jQuery` variable instead of `$` is intentional so its use is easier to identify
// This controller includes hacks to ensure that jQuery based libs like Select2 work with Turbolinks
import 'select2'
import { Controller } from 'stimulus'

function create (element) {
  const created = element.classList.contains('select2-hidden-accessible')
  if (created) return

  jQuery(element).select2({
    theme: 'bootstrap',
    width: '100%',
    closeOnSelect: !element.multiple
  })
  element.dispatchEvent(new Event('select:created'))
  jQuery(element).on(
    'change.select2',
    (() =>
      element.dispatchEvent(
        new Event('cf:select:changed', { bubbles: true })
      )).bind(this)
  )
}

function destroy (element) {
  const created = element.classList.contains('select2-hidden-accessible')
  if (created) jQuery(element).select2('destroy')
  element.dispatchEvent(new Event('select:destroyed'))
}

document.addEventListener('cable-ready:before-morph', () => {
  document
    .querySelectorAll('[data-controller="select"]')
    .forEach(element => destroy(element))
})

document.addEventListener('cable-ready:after-morph', () => {
  document
    .querySelectorAll('[data-controller="select"]')
    .forEach(element => create(element))
})

export default class extends Controller {
  connect () {
    create(this.element)

    this.element.addEventListener('select:create', () => {
      create(this.element)
    })

    this.element.addEventListener('select:destroy', () => {
      destroy(this.element)
    })

    document.addEventListener('turbolinks:before-cache', () => {
      destroy(this.element)
    })
  }
}