diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 01b20ebb8..4c2f9d602 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -180,9 +180,8 @@ export default class Browser { ], ['options.inBbox', { handler: 'Switch', label: translate('Current map view') }], ] - const builder = new Form(this, fields, { - callback: () => this.onFormChange(), - }) + const builder = new Form(this, fields) + builder.on('set', () => this.onFormChange()) let filtersBuilder this.formContainer.appendChild(builder.build()) DomEvent.on(builder.form, 'reset', () => { @@ -190,9 +189,8 @@ export default class Browser { }) if (this._umap.properties.facetKey) { fields = this._umap.facets.build() - filtersBuilder = new Form(this._umap.facets, fields, { - callback: () => this.onFormChange(), - }) + filtersBuilder = new Form(this._umap.facets, fields) + filtersBuilder.on('set', () => this.onFormChange()) DomEvent.on(filtersBuilder.form, 'reset', () => { window.setTimeout(filtersBuilder.syncAll.bind(filtersBuilder)) }) diff --git a/umap/static/umap/js/modules/data/features.js b/umap/static/umap/js/modules/data/features.js index 707398041..18ce98f95 100644 --- a/umap/static/umap/js/modules/data/features.js +++ b/umap/static/umap/js/modules/data/features.js @@ -226,15 +226,11 @@ class Feature { `icon-${this.getClassName()}` ) - let builder = new MutatingForm( - this, - [['datalayer', { handler: 'DataLayerSwitcher' }]], - { - callback() { - this.edit(event) - }, // removeLayer step will close the edit panel, let's reopen it - } - ) + let builder = new MutatingForm(this, [ + ['datalayer', { handler: 'DataLayerSwitcher' }], + ]) + // removeLayer step will close the edit panel, let's reopen it + builder.on('set', () => this.edit(event)) container.appendChild(builder.build()) const properties = [] @@ -734,16 +730,15 @@ export class Point extends Feature { ['ui._latlng.lat', { handler: 'FloatInput', label: translate('Latitude') }], ['ui._latlng.lng', { handler: 'FloatInput', label: translate('Longitude') }], ] - const builder = new MutatingForm(this, coordinatesOptions, { - callback: () => { - if (!this.ui._latlng.isValid()) { - Alert.error(translate('Invalid latitude or longitude')) - builder.restoreField('ui._latlng.lat') - builder.restoreField('ui._latlng.lng') - } - this.pullGeometry() - this.zoomTo({ easing: false }) - }, + const builder = new MutatingForm(this, coordinatesOptions) + builder.on('set', () => { + if (!this.ui._latlng.isValid()) { + Alert.error(translate('Invalid latitude or longitude')) + builder.restoreField('ui._latlng.lat') + builder.restoreField('ui._latlng.lng') + } + this.pullGeometry() + this.zoomTo({ easing: false }) }) const fieldset = DomUtil.createFieldset(container, translate('Coordinates')) fieldset.appendChild(builder.build()) diff --git a/umap/static/umap/js/modules/data/layer.js b/umap/static/umap/js/modules/data/layer.js index 6fced9d11..e35e51b16 100644 --- a/umap/static/umap/js/modules/data/layer.js +++ b/umap/static/umap/js/modules/data/layer.js @@ -667,14 +667,12 @@ export class DataLayer extends ServerStored { ], ] DomUtil.createTitle(container, translate('Layer properties'), 'icon-layers') - let builder = new MutatingForm(this, metadataFields, { - callback: (helper) => { - console.log(helper) - this._umap.onDataLayersChanged() - if (helper.field === 'options.type') { - this.edit() - } - }, + let builder = new MutatingForm(this, metadataFields) + builder.on('set', (helper) => { + this._umap.onDataLayersChanged() + if (helper.field === 'options.type') { + this.edit() + } }) container.appendChild(builder.build()) diff --git a/umap/static/umap/js/modules/form/builder.js b/umap/static/umap/js/modules/form/builder.js index e16b9b7a3..ea78a10f6 100644 --- a/umap/static/umap/js/modules/form/builder.js +++ b/umap/static/umap/js/modules/form/builder.js @@ -3,8 +3,9 @@ import * as Utils from '../utils.js' import { SCHEMA } from '../schema.js' import { translate } from '../i18n.js' -export class Form { +export class Form extends Utils.WithEvents { constructor(obj, fields, properties) { + super() this.setProperties(properties) this.defaultProperties = {} this.obj = obj diff --git a/umap/static/umap/js/modules/form/fields.js b/umap/static/umap/js/modules/form/fields.js index ea0740a98..a74de302e 100644 --- a/umap/static/umap/js/modules/form/fields.js +++ b/umap/static/umap/js/modules/form/fields.js @@ -97,7 +97,7 @@ class BaseElement { sync() { this.set() - this.onPostSync() + this.builder.fire('set', this) } set() { @@ -116,13 +116,6 @@ class BaseElement { finish() {} - onPostSync() { - if (this.properties.callback) { - this.properties.callback(this) - } - this.builder.onPostSync(this) - } - undefine() { this.root.classList.add('undefined') this.clear() diff --git a/umap/static/umap/js/modules/share.js b/umap/static/umap/js/modules/share.js index 6a0a49cee..ccf936366 100644 --- a/umap/static/umap/js/modules/share.js +++ b/umap/static/umap/js/modules/share.js @@ -126,9 +126,8 @@ export default class Share { exportUrl.value = window.location.protocol + iframeExporter.buildUrl() } buildIframeCode() - const builder = new MutatingForm(iframeExporter, UIFields, { - callback: buildIframeCode, - }) + const builder = new MutatingForm(iframeExporter, UIFields) + builder.on('set', buildIframeCode) const iframeOptions = DomUtil.createFieldset( this.container, translate('Embed and link options') diff --git a/umap/static/umap/js/modules/umap.js b/umap/static/umap/js/modules/umap.js index aff442282..ab4d94fe6 100644 --- a/umap/static/umap/js/modules/umap.js +++ b/umap/static/umap/js/modules/umap.js @@ -1029,13 +1029,6 @@ export default class Umap extends ServerStored { ], ] const slideshowBuilder = new MutatingForm(this, slideshowFields, { - callback: () => { - this.slideshow.load() - // FIXME when we refactor formbuilder: this callback is called in a 'postsync' - // event, which comes after the call of `setter` method, which will call the - // map.render method, which should do this redraw. - this.bottomBar.redraw() - }, umap: this, }) slideshow.appendChild(slideshowBuilder.build()) @@ -1351,6 +1344,10 @@ export default class Umap extends ServerStored { } this.topBar.redraw() }, + 'properties.slideshow.active': () => { + this.slideshow.load() + this.bottomBar.redraw() + }, numberOfConnectedPeers: () => { Utils.eachElement('.connected-peers span', (el) => { if (this.sync.websocketConnected) { diff --git a/umap/static/umap/js/modules/utils.js b/umap/static/umap/js/modules/utils.js index 69d5721a4..b705f2c09 100644 --- a/umap/static/umap/js/modules/utils.js +++ b/umap/static/umap/js/modules/utils.js @@ -449,6 +449,29 @@ export function eachElement(selector, callback) { } } +export class WithEvents { + constructor() { + this._callbacks = {} + } + + on(eventType, callback) { + if (typeof callback !== 'function') return + if (this._callbacks[eventType] === undefined) { + this._callbacks[eventType] = [] + } + + this._callbacks[eventType].push(callback) + } + + fire(eventType, ...args) { + if (this._callbacks[eventType] === undefined) return + + for (const callback of this._callbacks[eventType]) { + callback(...args) + } + } +} + export const COLORS = [ 'Black', 'Navy',