Source: control/ControlLayerFilters.js

import OlControl from 'ol/control/Control'
import OlExtElement from 'ol-ext/util/element'
import { unByKey } from 'ol/Observable'

/** Ihm pour controler l'interaction LayersFilters du viewer */

const texts = {
  title: 'Filtres cartographiques',
  noFilters: 'Aucun filtre défini dans cette carte',
  closeMenu: 'Fermer ce menu',
}

class ControlLayerFilters extends OlControl {
  listeners = []
  constructor (options) {
    if (!options) options = {}

    const className = options.className !== undefined ? options.className : ''

    const classNames = (className || '') + ' kmapv-bottom-tools kmapv-layer-filters top-of-bottom-bar hidden' + (options.target ? '' : ' ol-unselectable ol-control')
    const element = OlExtElement.create('DIV', {
      className: classNames,
    })

    super({
      element,
      target: options.target,
    })

    if (!options.viewer) {
      console.error('[ControlModifyTools] options.viewer non présent')
      return
    }
    this.viewer = options.viewer

    // menu principal
    this.menuMain = OlExtElement.create('DIV', {
      className: 'tools',
    })

    // header du menu template
    const headerTemplateMenu = OlExtElement.create('DIV', {
      className: 'header',
      // style: { display: 'none' },
      html: `<div>${texts.title}</div>`,
    })

    OlExtElement.create('I', {
      className: 'kmapv-icon xs kmapv-icon-cancel',
      title: texts.closeMenu,
      parent: headerTemplateMenu,
      on: {
        click: () => {
          this.hide()
        },
      },
    })

    element.appendChild(headerTemplateMenu)
    element.appendChild(this.menuMain)

    this.drawMenu()

    // redessine le menu dés qu'on ajoute des filtres
    this.viewer.layerFilterInteraction.on('filters:change', this.drawMenu.bind(this))
  }

  /** parcours le LayerFilter de layerFilterInteraction */
  drawMenu () {
    // cleans des listeners liés au menu
    this.listeners.forEach(unByKey)
    this.menuMain.innerHTML = ''
    const groupAndFilters = this.viewer.layerFilterInteraction.getGroupAndFilters()
    if (groupAndFilters.getLength() === 0) {
      OlExtElement.create('span', {
        text: texts.noFilters,
        parent: this.menuMain,
      })
    }

    const ul = OlExtElement.create('ul', {
      parent: this.menuMain,
    })
    groupAndFilters.getArray().forEach(groupOrLayer => {
      if (groupOrLayer.type === 'group') {
        const groupElement = this.addGroup(ul, groupOrLayer)
        groupOrLayer.filters.getArray().forEach(filter => {
          this.addFilter(groupElement, filter)
        })
      } else {
        this.addFilter(ul, groupOrLayer)
      }
    })
  }

  addGroup (element, group) {
    const li = OlExtElement.create('li', {
      className: 'group',
      parent: element,
    })
    const groupDiv = OlExtElement.create('div', {
      parent: li,
    })
    OlExtElement.create('label', {
      text: `${group.label}`,
      parent: groupDiv,
    })

    if (group.sublabel) {
      OlExtElement.create('label', {
        className: 'sublabel',
        text: `${group.sublabel}`,
        parent: groupDiv,
      })
    }

    const ul = OlExtElement.create('ul', {
      parent: li,
    })
    return ul
  }

  addFilter (element, filter) {
    const li = OlExtElement.create('li', {
      className: 'filter',
      parent: element,
    })
    const chk = OlExtElement.createCheck({
      name: 'control-layer-switcher',
      type: 'checkbox',
      on: {
        change: (event) => {
          // actionne ou non le filtre lorsque l'on clic dans le menu
          if (event.target.checked) {
            this.viewer.layerFilterInteraction.applyFilter(filter.id)
          } else {
            this.viewer.layerFilterInteraction.clear()
          }
        },
      },
      after: `${filter.label}`,
      parent: li,
    })

    this.listeners.push(this.viewer.layerFilterInteraction.on('change:visible', (event) => {
      // on écouter le gestionnaire de filtre pour refleter l'état de la checkbox
      if (event.filter === filter) {
        chk.checked = event.visible
      }
    }))

    if (filter.sublabel) {
      OlExtElement.create('label', {
        className: 'sublabel',
        text: `${filter.sublabel}`,
        parent: li,
      })
    }
  }

  show () {
    this.element.classList.remove('hidden')
    this.dispatchEvent({ type: 'change:visible', visible: true })
  }

  hide () {
    this.element.classList.add('hidden')
    this.dispatchEvent({ type: 'change:visible', visible: false })
  }
}

export default ControlLayerFilters