From d69f965f790653bcc6358694f8dd9eb496aa1dd6 Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Sat, 14 Jan 2023 22:31:39 +0100 Subject: [PATCH 1/8] Filters checkboxes using features' properties --- umap/static/umap/base.css | 1 + umap/static/umap/js/umap.controls.js | 110 ++++++++++++++++++++++++++- umap/static/umap/js/umap.core.js | 2 + umap/static/umap/js/umap.forms.js | 3 +- umap/static/umap/js/umap.js | 32 +++++++- umap/static/umap/map.css | 13 +++- 6 files changed, 153 insertions(+), 8 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index e4d9eed4..8e4c928f 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -508,6 +508,7 @@ i.info { .umap-layer-properties-container, .umap-footer-container, .umap-browse-data, +.umap-filter-data, .umap-browse-datalayers { padding: 0 10px; } diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index b7b9bff7..4884304a 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -695,7 +695,7 @@ L.U.Map.include({ var build = function () { ul.innerHTML = ''; datalayer.eachFeature(function (feature) { - if (filterValue && !feature.matchFilter(filterValue, filterKeys)) return; + if ((filterValue && !feature.matchFilter(filterValue, filterKeys)) || feature.properties.isVisible === false) return; ul.appendChild(addFeature(feature)); }); }; @@ -732,6 +732,114 @@ L.U.Map.include({ label.textContent = label.title = L._('About'); L.DomEvent.on(link, 'click', this.displayCaption, this); this.ui.openPanel({data: {html: browserContainer}, actions: [link]}); + }, + + _openFilter: function () { + var filterContainer = L.DomUtil.create('div', 'umap-filter-data'), + title = L.DomUtil.add('h3', 'umap-filter-title', filterContainer, this.options.name), + propertiesContainer = L.DomUtil.create('div', 'umap-filter-properties', filterContainer), + advancedFilterKeys = this.getAdvancedFilterKeys(); + + var advancedFiltersFull = {}; + var filtersAlreadyLoaded = true; + if (!this.getMap().options.advancedFilters) { + this.getMap().options.advancedFilters = {}; + filtersAlreadyLoaded = false; + } + advancedFilterKeys.forEach(property => { + advancedFiltersFull[property] = []; + if (!filtersAlreadyLoaded) { + this.getMap().options.advancedFilters[property] = []; + } + }); + this.eachDataLayer(function (datalayer) { + datalayer.eachFeature(function (feature) { + advancedFilterKeys.forEach(property => { + if (feature.properties[property]) { + if (!advancedFiltersFull[property].includes(feature.properties[property])) { + advancedFiltersFull[property].push(feature.properties[property]); + } + } + }); + }); + }); + + var addPropertyValue = function (property, value) { + var property_li = L.DomUtil.create('li', ''), + filter_check = L.DomUtil.create('input', '', property_li), + filter_label = L.DomUtil.create('label', '', property_li); + filter_check.type = 'checkbox'; + filter_check.id = `checkbox_${property}_${value}`; + filter_check.checked = this.getMap().options.advancedFilters[property] && this.getMap().options.advancedFilters[property].includes(value); + filter_check.setAttribute('data-property', property); + filter_check.setAttribute('data-value', value); + filter_label.htmlFor = `checkbox_${property}_${value}`; + filter_label.innerHTML = value; + L.DomEvent.on(filter_check, 'change', function (e) { + var property = e.srcElement.dataset.property; + var value = e.srcElement.dataset.value; + if (e.srcElement.checked) { + this.getMap().options.advancedFilters[property].push(value); + } else { + this.getMap().options.advancedFilters[property].splice(this.getMap().options.advancedFilters[property].indexOf(value), 1); + } + L.bind(filterFeatures, this)(); + }, this); + return property_li + }; + + var addProperty = function (property) { + var container = L.DomUtil.create('div', 'property-container', propertiesContainer), + headline = L.DomUtil.add('h5', '', container, property); + var ul = L.DomUtil.create('ul', '', container); + var orderedValues = advancedFiltersFull[property]; + orderedValues.sort(); + orderedValues.forEach(value => { + ul.appendChild(L.bind(addPropertyValue, this)(property, value)); + }); + }; + + var filterFeatures = function () { + var noResults = true; + this.eachDataLayer(function (datalayer) { + datalayer.eachFeature(function (feature) { + feature.properties.isVisible = true; + for (const [property, values] of Object.entries(this.map.options.advancedFilters)) { + if (values.length > 0) { + if (!feature.properties[property] || !values.includes(feature.properties[property])) { + feature.properties.isVisible = false; + } + } + } + if (feature.properties.isVisible) { + noResults = false; + if (!this.isLoaded()) this.fetchData(); + this.map.addLayer(feature); + this.fire('show'); + } else { + this.map.removeLayer(feature); + this.fire('hide'); + } + }); + }); + if (noResults) { + this.help.show('advancedFiltersNoResults'); + } else { + this.help.hide(); + } + }; + + propertiesContainer.innerHTML = ''; + advancedFilterKeys.forEach(property => { + L.bind(addProperty, this)(property); + }); + + var link = L.DomUtil.create('li', ''); + L.DomUtil.create('i', 'umap-icon-16 umap-caption', link); + var label = L.DomUtil.create('span', '', link); + label.textContent = label.title = L._('About'); + L.DomEvent.on(link, 'click', this.displayCaption, this); + this.ui.openPanel({ data: { html: filterContainer }, actions: [link] }); } }); diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index 02afe2cd..a6201360 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -455,6 +455,8 @@ L.U.Help = L.Class.extend({ sortKey: L._('Property to use for sorting features'), slugKey: L._('The name of the property to use as feature unique identifier.'), filterKey: L._('Comma separated list of properties to use when filtering features'), + advancedFilterKey: L._('Comma separated list of properties to use for checkbox filtering'), + advancedFiltersNoResults: L._('No results for these filters'), interactive: L._('If false, the polygon will act as a part of the underlying map.'), outlink: L._('Define link to open in a new window on polygon click.'), dynamicRemoteData: L._('Fetch data each time map view changes.'), diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 88c03703..0067b4c6 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -287,7 +287,8 @@ L.FormBuilder.onLoadPanel = L.FormBuilder.Select.extend({ selectOptions: [ ['none', L._('None')], ['caption', L._('Caption')], - ['databrowser', L._('Data browser')] + ['databrowser', L._('Data browser')], + ['datafilters', L._('Data filters')] ] }); diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 92ca44a2..4222ef49 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -210,6 +210,7 @@ L.U.Map.include({ this.onceDatalayersLoaded(function () { if (this.options.onLoadPanel === 'databrowser') this.openBrowser(); else if (this.options.onLoadPanel === 'caption') this.displayCaption(); + else if (this.options.onLoadPanel === 'datafilters') this.openFilter(); }); this.onceDataLoaded(function () { const slug = L.Util.queryString('feature'); @@ -893,6 +894,12 @@ L.U.Map.include({ }); }, + openFilter: function () { + this.onceDatalayersLoaded(function () { + this._openFilter(); + }); + }, + displayCaption: function () { var container = L.DomUtil.create('div', 'umap-caption'), title = L.DomUtil.create('h3', '', container); @@ -948,10 +955,15 @@ L.U.Map.include({ umapCredit.innerHTML = L._('Powered by Leaflet and Django, glued by uMap project.', urls); var browser = L.DomUtil.create('li', ''); L.DomUtil.create('i', 'umap-icon-16 umap-list', browser); - var label = L.DomUtil.create('span', '', browser); - label.textContent = label.title = L._('Browse data'); + var labelBrowser = L.DomUtil.create('span', '', browser); + labelBrowser.textContent = labelBrowser.title = L._('Browse data'); L.DomEvent.on(browser, 'click', this.openBrowser, this); - this.ui.openPanel({data: {html: container}, actions: [browser]}); + var filter = L.DomUtil.create('li', ''); + L.DomUtil.create('i', 'umap-icon-16 umap-add', filter); + var labelFilter = L.DomUtil.create('span', '', filter); + labelFilter.textContent = labelFilter.title = L._('Filter data'); + L.DomEvent.on(filter, 'click', this.openFilter, this); + this.ui.openPanel({data: {html: container}, actions: [browser, filter]}); }, eachDataLayer: function (method, context) { @@ -1057,6 +1069,7 @@ L.U.Map.include({ 'sortKey', 'labelKey', 'filterKey', + 'advancedFilterKey', 'slugKey', 'showLabel', 'labelDirection', @@ -1253,6 +1266,7 @@ L.U.Map.include({ 'options.labelKey', ['options.sortKey', {handler: 'BlurInput', helpEntries: 'sortKey', placeholder: L._('Default: name'), label: L._('Sort key'), inheritable: true}], ['options.filterKey', {handler: 'Input', helpEntries: 'filterKey', placeholder: L._('Default: name'), label: L._('Filter keys'), inheritable: true}], + ['options.advancedFilterKey', {handler: 'Input', helpEntries: 'advancedFilterKey', placeholder: L._('Example: key1,key2,key3'), label: L._('Advanced filter keys'), inheritable: true}], ['options.slugKey', {handler: 'BlurInput', helpEntries: 'slugKey', placeholder: L._('Default: name'), label: L._('Feature identifier key')}] ]; @@ -1435,6 +1449,10 @@ L.U.Map.include({ browser.href = '#'; L.DomEvent.on(browser, 'click', L.DomEvent.stop) .on(browser, 'click', this.openBrowser, this); + var filter = L.DomUtil.add('a', 'umap-open-filter-link', container, ' | ' + L._('Filter data')); + filter.href = '#'; + L.DomEvent.on(filter, 'click', L.DomEvent.stop) + .on(filter, 'click', this.openFilter, this); var setName = function () { name.textContent = this.getDisplayName(); }; @@ -1620,6 +1638,10 @@ L.U.Map.include({ text: L._('Browse data'), callback: this.openBrowser }, + { + text: L._('Filter data'), + callback: this.openFilter + }, { text: L._('About'), callback: this.displayCaption @@ -1698,6 +1720,10 @@ L.U.Map.include({ getFilterKeys: function () { return (this.options.filterKey || this.options.sortKey || 'name').split(','); + }, + + getAdvancedFilterKeys: function () { + return (this.options.advancedFilterKey || '').split(","); } }); diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 707821c7..c57f4596 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -729,20 +729,24 @@ a.add-datalayer:hover, margin-bottom: 14px; border-radius: 2px; } +.umap-browse-features h5, .umap-filter-data h5 { + margin-bottom: 0; + overflow: hidden; + padding-left: 5px; +} .umap-browse-features h5 { height: 30px; line-height: 30px; background-color: #eeeee0; - margin-bottom: 0; color: #666; - overflow: hidden; - padding-left: 5px; } .umap-browse-features h5 span { margin-left: 10px; } .umap-browse-features li { padding: 2px 0; +} +.umap-browse-features li, .umap-filter-data li { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -775,6 +779,9 @@ a.add-datalayer:hover, .umap-browse-features .polygon .feature-color { background-position: -32px -16px; } +.umap-filter-data .property-container:not(:first-child) { + margin-top: 14px; +} .show-on-edit { display: none!important; } From 57ba42061c7079e34cfc1566dea1c08efdaa9ab0 Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Sat, 14 Jan 2023 22:48:16 +0100 Subject: [PATCH 2/8] Permanent credits feature in the bottom left corner --- umap/static/umap/js/umap.controls.js | 41 ++++++++++++++++++++++++++++ umap/static/umap/js/umap.core.js | 1 + umap/static/umap/js/umap.js | 14 ++++++++-- umap/static/umap/map.css | 11 ++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 4884304a..eaed1b82 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -434,6 +434,47 @@ L.U.MoreControls = L.Control.extend({ }); +L.U.PermanentCreditsControl = L.Control.extend({ + + options: { + position: 'bottomleft' + }, + + initialize: function (map) { + this.map = map; + }, + + onAdd: function () { + var paragraphContainer = L.DomUtil.create('div', 'umap-permanent-credits-container'), + creditsParagraph = L.DomUtil.create('p', '', paragraphContainer); + + this.paragraphContainer = paragraphContainer; + this.setCredits(); + this.setBackground(); + + return paragraphContainer; + }, + + _update: function () { + this.setCredits(); + this.setBackground(); + }, + + setCredits: function () { + this.paragraphContainer.innerHTML = L.Util.toHTML(this.map.options.permanentCredit); + }, + + setBackground: function () { + if (this.map.options.permanentCreditBackground) { + this.paragraphContainer.style.backgroundColor = '#FFFFFFB0'; + } else { + this.paragraphContainer.style.backgroundColor = ''; + } + } + +}); + + L.U.DataLayersControl = L.Control.extend({ options: { diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index a6201360..30aaa4cb 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -452,6 +452,7 @@ L.U.Help = L.Class.extend({ fillColor: L._('Optional. Same as color if not set.'), shortCredit: L._('Will be displayed in the bottom right corner of the map'), longCredit: L._('Will be visible in the caption of the map'), + permanentCredit: L._('Will be permanently visible in the bottom left corner of the map'), sortKey: L._('Property to use for sorting features'), slugKey: L._('The name of the property to use as feature unique identifier.'), filterKey: L._('Comma separated list of properties to use when filtering features'), diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 4222ef49..6521c221 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -46,7 +46,8 @@ L.Map.mergeOptions({ slideshow: {}, clickable: true, easing: true, - permissions: {} + permissions: {}, + permanentCreditBackground: true, }); L.U.Map.include({ @@ -274,6 +275,7 @@ L.U.Map.include({ this._controls.measure = (new L.MeasureControl()).initHandler(this); this._controls.more = new L.U.MoreControls(); this._controls.scale = L.control.scale(); + if (this.options.permanentCredit) this.permanentCreditControl = (new L.U.PermanentCreditsControl(this)).addTo(this); if (this.options.scrollWheelZoom) this.scrollWheelZoom.enable(); else this.scrollWheelZoom.disable(); this.renderControls(); @@ -1076,6 +1078,8 @@ L.U.Map.include({ 'labelInteractive', 'shortCredit', 'longCredit', + 'permanentCredit', + 'permanentCreditBackground', 'zoomControl', 'datalayersControl', 'searchControl', @@ -1379,10 +1383,14 @@ L.U.Map.include({ var creditsFields = [ ['options.licence', {handler: 'LicenceChooser', label: L._('licence')}], ['options.shortCredit', {handler: 'Input', label: L._('Short credits'), helpEntries: ['shortCredit', 'textFormatting']}], - ['options.longCredit', {handler: 'Textarea', label: L._('Long credits'), helpEntries: ['longCredit', 'textFormatting']}] + ['options.longCredit', {handler: 'Textarea', label: L._('Long credits'), helpEntries: ['longCredit', 'textFormatting']}], + ['options.permanentCredit', {handler: 'Textarea', label: L._('Permanent credits'), helpEntries: ['permanentCredit', 'textFormatting']}], + ['options.permanentCreditBackground', {handler: 'Switch', label: L._('Permanent credits background')}] ]; var creditsBuilder = new L.U.FormBuilder(this, creditsFields, { - callback: function () {this._controls.attribution._update();}, + callback: function () { + this._controls.attribution._update(); + this.permanentCreditControl._update();}, callbackContext: this }); credits.appendChild(creditsBuilder.build()); diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index c57f4596..5939f335 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -117,6 +117,12 @@ a.umap-control-text { .leaflet-control-edit-enable a:hover { background-color: #4d5759; } +.umap-permanent-credits-container { + max-width: 20rem; + margin: 0!important; + padding: 0.5rem; + border-top-right-radius: 1rem; +} @@ -1366,6 +1372,11 @@ a.add-datalayer:hover, .leaflet-control-layers-expanded { margin-left: 10px; } + + .umap-permanent-credits-container { + max-width: 100%; + border-top-right-radius: 0; + } } /* ****** */ From 423084e9ea186fb50d6788e7eece837caa37db69 Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Sat, 14 Jan 2023 23:15:27 +0100 Subject: [PATCH 3/8] Interface option to hide caption menus --- umap/static/umap/js/umap.controls.js | 17 ++++++++----- umap/static/umap/js/umap.forms.js | 1 + umap/static/umap/js/umap.js | 38 ++++++++++++++++++---------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index eaed1b82..608f73a0 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -954,12 +954,14 @@ L.U.AttributionControl = L.Control.Attribution.extend({ if (this._map.options.shortCredit) { L.DomUtil.add('span', '', this._container, ' — ' + L.Util.toHTML(this._map.options.shortCredit)); } - var link = L.DomUtil.add('a', '', this._container, ' — ' + L._('About')); - L.DomEvent - .on(link, 'click', L.DomEvent.stop) - .on(link, 'click', this._map.displayCaption, this._map) - .on(link, 'dblclick', L.DomEvent.stop); - if (window.top === window.self) { + if (this._map.options.captionMenus) { + var link = L.DomUtil.add('a', '', this._container, ' — ' + L._('About')); + L.DomEvent + .on(link, 'click', L.DomEvent.stop) + .on(link, 'click', this._map.displayCaption, this._map) + .on(link, 'dblclick', L.DomEvent.stop); + } + if (window.top === window.self && this._map.options.captionMenus) { // We are not in iframe mode var home = L.DomUtil.add('a', '', this._container, ' — ' + L._('Home')); home.href = '/'; @@ -1150,7 +1152,8 @@ L.U.IframeExporter = L.Evented.extend({ embedControl: null, datalayersControl: true, onLoadPanel: 'none', - captionBar: false + captionBar: false, + captionMenus: true }, dimensions: { diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 0067b4c6..b3a37733 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -759,6 +759,7 @@ L.U.FormBuilder = L.FormBuilder.extend({ onLoadPanel: {handler: 'onLoadPanel', label: L._('Do you want to display a panel on load?')}, displayPopupFooter: {handler: 'Switch', label: L._('Do you want to display popup footer?')}, captionBar: {handler: 'Switch', label: L._('Do you want to display a caption bar?')}, + captionMenus: {handler: 'Switch', label: L._('Do you want to display caption menus?')}, zoomTo: {handler: 'IntInput', placeholder: L._('Inherit'), helpEntries: 'zoomTo', label: L._('Default zoom level'), inheritable: true}, showLabel: {handler: 'LabelChoice', label: L._('Display label'), inheritable: true}, labelDirection: {handler: 'LabelDirection', label: L._('Label direction'), inheritable: true}, diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 6521c221..fd59c5ea 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -43,6 +43,7 @@ L.Map.mergeOptions({ ], moreControl: true, captionBar: false, + captionMenus: true, slideshow: {}, clickable: true, easing: true, @@ -89,6 +90,7 @@ L.U.Map.include({ L.Util.setBooleanFromQueryString(this.options, 'displayDataBrowserOnLoad'); L.Util.setBooleanFromQueryString(this.options, 'displayCaptionOnLoad'); L.Util.setBooleanFromQueryString(this.options, 'captionBar'); + L.Util.setBooleanFromQueryString(this.options, 'captionMenus'); for (var i = 0; i < this.HIDDABLE_CONTROLS.length; i++) { L.Util.setNullableBooleanFromQueryString(this.options, this.HIDDABLE_CONTROLS[i] + 'Control'); } @@ -628,7 +630,8 @@ L.U.Map.include({ 'queryString.miniMap', 'queryString.scaleControl', 'queryString.onLoadPanel', - 'queryString.captionBar' + 'queryString.captionBar', + 'queryString.captionMenus' ]; for (var i = 0; i < this.HIDDABLE_CONTROLS.length; i++) { UIFields.push('queryString.' + this.HIDDABLE_CONTROLS[i] + 'Control'); @@ -1067,6 +1070,7 @@ L.U.Map.include({ 'popupContentTemplate', 'zoomTo', 'captionBar', + 'captionMenus', 'slideshow', 'sortKey', 'labelKey', @@ -1232,10 +1236,14 @@ L.U.Map.include({ 'options.scaleControl', 'options.onLoadPanel', 'options.displayPopupFooter', - 'options.captionBar' + 'options.captionBar', + 'options.captionMenus' ]); builder = new L.U.FormBuilder(this, UIFields, { - callback: this.renderControls, + callback: function() { + this.renderControls(); + this.initCaptionBar(); + }, callbackContext: this }); var controlsOptions = L.DomUtil.createFieldset(container, L._('User interface options')); @@ -1450,17 +1458,19 @@ L.U.Map.include({ name = L.DomUtil.create('h3', '', container); L.DomEvent.disableClickPropagation(container); this.permissions.addOwnerLink('span', container); - var about = L.DomUtil.add('a', 'umap-about-link', container, ' — ' + L._('About')); - about.href = '#'; - L.DomEvent.on(about, 'click', this.displayCaption, this); - var browser = L.DomUtil.add('a', 'umap-open-browser-link', container, ' | ' + L._('Browse data')); - browser.href = '#'; - L.DomEvent.on(browser, 'click', L.DomEvent.stop) - .on(browser, 'click', this.openBrowser, this); - var filter = L.DomUtil.add('a', 'umap-open-filter-link', container, ' | ' + L._('Filter data')); - filter.href = '#'; - L.DomEvent.on(filter, 'click', L.DomEvent.stop) - .on(filter, 'click', this.openFilter, this); + if (this.options.captionMenus) { + var about = L.DomUtil.add('a', 'umap-about-link', container, ' — ' + L._('About')); + about.href = '#'; + L.DomEvent.on(about, 'click', this.displayCaption, this); + var browser = L.DomUtil.add('a', 'umap-open-browser-link', container, ' | ' + L._('Browse data')); + browser.href = '#'; + L.DomEvent.on(browser, 'click', L.DomEvent.stop) + .on(browser, 'click', this.openBrowser, this); + var filter = L.DomUtil.add('a', 'umap-open-filter-link', container, ' | ' + L._('Filter data')); + filter.href = '#'; + L.DomEvent.on(filter, 'click', L.DomEvent.stop) + .on(filter, 'click', this.openFilter, this); + } var setName = function () { name.textContent = this.getDisplayName(); }; From ced62d8eedf6b5c44da6da023594fbda2efa883d Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Sun, 22 Jan 2023 00:28:56 +0100 Subject: [PATCH 4/8] Fix controls errors with permanent credits --- umap/static/umap/js/umap.controls.js | 8 ++------ umap/static/umap/js/umap.js | 7 +++---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 608f73a0..22294661 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -440,8 +440,9 @@ L.U.PermanentCreditsControl = L.Control.extend({ position: 'bottomleft' }, - initialize: function (map) { + initialize: function (map, options) { this.map = map; + L.Control.prototype.initialize.call(this, options); }, onAdd: function () { @@ -455,11 +456,6 @@ L.U.PermanentCreditsControl = L.Control.extend({ return paragraphContainer; }, - _update: function () { - this.setCredits(); - this.setBackground(); - }, - setCredits: function () { this.paragraphContainer.innerHTML = L.Util.toHTML(this.map.options.permanentCredit); }, diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index fd59c5ea..52fe051d 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -277,7 +277,7 @@ L.U.Map.include({ this._controls.measure = (new L.MeasureControl()).initHandler(this); this._controls.more = new L.U.MoreControls(); this._controls.scale = L.control.scale(); - if (this.options.permanentCredit) this.permanentCreditControl = (new L.U.PermanentCreditsControl(this)).addTo(this); + this._controls.permanentCredit = new L.U.PermanentCreditsControl(this); if (this.options.scrollWheelZoom) this.scrollWheelZoom.enable(); else this.scrollWheelZoom.disable(); this.renderControls(); @@ -310,6 +310,7 @@ L.U.Map.include({ if (status === undefined || status === null) L.DomUtil.addClass(control._container, 'display-on-more'); else L.DomUtil.removeClass(control._container, 'display-on-more'); } + if (this.options.permanentCredit) this._controls.permanentCredit.addTo(this); if (this.options.moreControl) this._controls.more.addTo(this); if (this.options.scaleControl) this._controls.scale.addTo(this); }, @@ -1396,9 +1397,7 @@ L.U.Map.include({ ['options.permanentCreditBackground', {handler: 'Switch', label: L._('Permanent credits background')}] ]; var creditsBuilder = new L.U.FormBuilder(this, creditsFields, { - callback: function () { - this._controls.attribution._update(); - this.permanentCreditControl._update();}, + callback: this.renderControls, callbackContext: this }); credits.appendChild(creditsBuilder.build()); From 2221806b7e7e263e42ce2893daec2dcff40f0caa Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Mon, 13 Feb 2023 17:33:50 +0100 Subject: [PATCH 5/8] Update permanent credits alignement and shape --- umap/static/umap/map.css | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 5939f335..91371c83 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -119,9 +119,9 @@ a.umap-control-text { } .umap-permanent-credits-container { max-width: 20rem; - margin: 0!important; + margin-left: 5px!important; + margin-bottom: 5px!important; padding: 0.5rem; - border-top-right-radius: 1rem; } @@ -1375,7 +1375,6 @@ a.add-datalayer:hover, .umap-permanent-credits-container { max-width: 100%; - border-top-right-radius: 0; } } From ce17f8dfe083621887fa917f069005e149acbef2 Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Wed, 15 Feb 2023 18:46:20 +0100 Subject: [PATCH 6/8] Fix undefined error without refreshing page after creating advanced filters --- umap/static/umap/js/umap.controls.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 22294661..2ca538b9 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -785,7 +785,7 @@ L.U.Map.include({ } advancedFilterKeys.forEach(property => { advancedFiltersFull[property] = []; - if (!filtersAlreadyLoaded) { + if (!filtersAlreadyLoaded || !this.getMap().options.advancedFilters[property]) { this.getMap().options.advancedFilters[property] = []; } }); From 6d900ac79f489c1b27ee538ddd93883d03e872e2 Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Sat, 18 Feb 2023 10:13:12 +0100 Subject: [PATCH 7/8] Show filters menu only if filter keys are defined --- umap/static/umap/js/umap.js | 43 ++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 52fe051d..89bcb857 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -964,12 +964,16 @@ L.U.Map.include({ var labelBrowser = L.DomUtil.create('span', '', browser); labelBrowser.textContent = labelBrowser.title = L._('Browse data'); L.DomEvent.on(browser, 'click', this.openBrowser, this); - var filter = L.DomUtil.create('li', ''); - L.DomUtil.create('i', 'umap-icon-16 umap-add', filter); - var labelFilter = L.DomUtil.create('span', '', filter); - labelFilter.textContent = labelFilter.title = L._('Filter data'); - L.DomEvent.on(filter, 'click', this.openFilter, this); - this.ui.openPanel({data: {html: container}, actions: [browser, filter]}); + var actions = [browser]; + if (this.options.advancedFilterKey) { + var filter = L.DomUtil.create('li', ''); + L.DomUtil.create('i', 'umap-icon-16 umap-add', filter); + var labelFilter = L.DomUtil.create('span', '', filter); + labelFilter.textContent = labelFilter.title = L._('Filter data'); + L.DomEvent.on(filter, 'click', this.openFilter, this); + actions.push(filter) + } + this.ui.openPanel({data: {html: container}, actions: actions}); }, eachDataLayer: function (method, context) { @@ -1285,6 +1289,7 @@ L.U.Map.include({ builder = new L.U.FormBuilder(this, optionsFields, { callback: function (e) { + this.initCaptionBar(); this.eachDataLayer(function (datalayer) { if (e.helper.field === 'options.sortKey') datalayer.reindex(); datalayer.redraw(); @@ -1465,10 +1470,12 @@ L.U.Map.include({ browser.href = '#'; L.DomEvent.on(browser, 'click', L.DomEvent.stop) .on(browser, 'click', this.openBrowser, this); - var filter = L.DomUtil.add('a', 'umap-open-filter-link', container, ' | ' + L._('Filter data')); - filter.href = '#'; - L.DomEvent.on(filter, 'click', L.DomEvent.stop) - .on(filter, 'click', this.openFilter, this); + if (this.options.advancedFilterKey) { + var filter = L.DomUtil.add('a', 'umap-open-filter-link', container, ' | ' + L._('Filter data')); + filter.href = '#'; + L.DomEvent.on(filter, 'click', L.DomEvent.stop) + .on(filter, 'click', this.openFilter, this); + } } var setName = function () { name.textContent = this.getDisplayName(); @@ -1650,15 +1657,17 @@ L.U.Map.include({ }); } } - items.push('-', - { - text: L._('Browse data'), - callback: this.openBrowser - }, - { + items.push('-', { + text: L._('Browse data'), + callback: this.openBrowser + }); + if (this.options.advancedFilterKey) { + items.push({ text: L._('Filter data'), callback: this.openFilter - }, + }) + } + items.push( { text: L._('About'), callback: this.displayCaption From eed12fdf875918d243a84557ff1fd305e71d37ac Mon Sep 17 00:00:00 2001 From: 3st3ban3 Date: Wed, 22 Feb 2023 17:36:22 +0100 Subject: [PATCH 8/8] Update wording to avoid confusion for data checkboxes --- umap/static/umap/js/umap.js | 6 +++--- umap/static/umap/locale/fr.js | 1 + umap/static/umap/locale/fr.json | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 89bcb857..7365afac 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -969,7 +969,7 @@ L.U.Map.include({ var filter = L.DomUtil.create('li', ''); L.DomUtil.create('i', 'umap-icon-16 umap-add', filter); var labelFilter = L.DomUtil.create('span', '', filter); - labelFilter.textContent = labelFilter.title = L._('Filter data'); + labelFilter.textContent = labelFilter.title = L._('Select data'); L.DomEvent.on(filter, 'click', this.openFilter, this); actions.push(filter) } @@ -1471,7 +1471,7 @@ L.U.Map.include({ L.DomEvent.on(browser, 'click', L.DomEvent.stop) .on(browser, 'click', this.openBrowser, this); if (this.options.advancedFilterKey) { - var filter = L.DomUtil.add('a', 'umap-open-filter-link', container, ' | ' + L._('Filter data')); + var filter = L.DomUtil.add('a', 'umap-open-filter-link', container, ' | ' + L._('Select data')); filter.href = '#'; L.DomEvent.on(filter, 'click', L.DomEvent.stop) .on(filter, 'click', this.openFilter, this); @@ -1663,7 +1663,7 @@ L.U.Map.include({ }); if (this.options.advancedFilterKey) { items.push({ - text: L._('Filter data'), + text: L._('Select data'), callback: this.openFilter }) } diff --git a/umap/static/umap/locale/fr.js b/umap/static/umap/locale/fr.js index 08d54ad8..bce3005f 100644 --- a/umap/static/umap/locale/fr.js +++ b/umap/static/umap/locale/fr.js @@ -262,6 +262,7 @@ var locale = { "See all": "Tout voir", "See data layers": "Voir les calques", "See full screen": "Voir en plein écran", + "Select data": "Sélectionner les données", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Désactiver pour masquer ce calque du diaporama, du navigateur de données…", "Shape properties": "Propriétés de la forme", "Short URL": "URL courte", diff --git a/umap/static/umap/locale/fr.json b/umap/static/umap/locale/fr.json index 176e8027..e1b11741 100644 --- a/umap/static/umap/locale/fr.json +++ b/umap/static/umap/locale/fr.json @@ -262,6 +262,7 @@ "See all": "Tout voir", "See data layers": "Voir les calques", "See full screen": "Voir en plein écran", + "Select data": "Sélectionner les données", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Désactiver pour masquer ce calque du diaporama, du navigateur de données…", "Shape properties": "Propriétés de la forme", "Short URL": "URL courte",