Husky fixes for Search/SearchFavorites

This commit is contained in:
Marcus Jaschen 2021-11-14 10:46:54 +01:00 committed by Gautier P
parent f1557a1d5c
commit 1551fec917

View file

@ -23,7 +23,6 @@ BR.Search = class extends L.Control.Geocoder {
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this); L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
} }
markGeocode(result) { markGeocode(result) {
this._map.fitBounds(result.geocode.bbox, { this._map.fitBounds(result.geocode.bbox, {
maxZoom: 17, maxZoom: 17,
@ -53,57 +52,58 @@ BR.Search = class extends L.Control.Geocoder {
} }
} }
/* Search favorites handling */ /* Search favorites handling */
onAdd(map) { onAdd(map) {
if (!BR.Util.localStorageAvailable()) return super.onAdd(map);
if(!BR.Util.localStorageAvailable()) let container = super.onAdd(map);
return super.onAdd(map); new SearchFavorites(this, container);
return container;
let container=super.onAdd(map); }
new SearchFavorites(this,container);
return container;
}
}; };
class SearchFavorites { class SearchFavorites {
constructor(geocoder, container) {
//because eslint does not support instance var declaration
this.searchInput = undefined;
this.autocompleteContainer = undefined;
this.autocompleteSelect = undefined;
this.autocompleteMenu = undefined;
this.geocoderForm = undefined;
this.geocoder = undefined;
this.favElements = undefined;
this.isFiltered = true;
this.arFavitems = [];
this.arFavitemsLC = [];
constructor(geocoder,container) { this.geocoder = geocoder;
//because eslint does not support instance var declaration this.searchInput = $(container).find('.leaflet-control-geocoder-form input[type=text]');
this.searchInput=undefined; this.searchInput.after(`<span class="search-fav-ctrls btn-group btn-group-sm">
this.autocompleteContainer=undefined;
this.autocompleteSelect=undefined;
this.autocompleteMenu=undefined;
this.geocoderForm=undefined;
this.geocoder=undefined;
this.favElements=undefined;
this.isFiltered=true;
this.arFavitems=[];
this.arFavitemsLC=[];
this.geocoder=geocoder;
this.searchInput=$(container).find(".leaflet-control-geocoder-form input[type=text]");
this.searchInput.after(`<span class="search-fav-ctrls btn-group btn-group-sm">
<button id="search-fav-add" <button id="search-fav-add"
title="${i18next.t("searchfav.addfavorite")}" title="${i18next.t('searchfav.addfavorite')}"
class="fa fa-star-o border-0"> class="fa fa-star-o border-0">
</button><button data-toggle="collapse" </button><button data-toggle="collapse"
href="#search-autocomplete-container" href="#search-autocomplete-container"
id="search-fav-expand" id="search-fav-expand"
title="${i18next.t("searchfav.openfavorites")}" title="${i18next.t('searchfav.openfavorites')}"
class="fa fa-angle-double-down border-0"> class="fa fa-angle-double-down border-0">
</button> </button>
</span> </span>
`); `);
//otherwise parent catches event and click is never fired //otherwise parent catches event and click is never fired
$(container).find(".leaflet-control-geocoder-form .search-fav-ctrls").on("mousedown", $(container)
(e) => { e.stopPropagation();e.preventDefault(); }); .find('.leaflet-control-geocoder-form .search-fav-ctrls')
.on('mousedown', (e) => {
e.stopPropagation();
e.preventDefault();
});
$(container).find(".leaflet-control-geocoder-form .search-fav-ctrls").click((e) => this.onCtrlsClick(e)); $(container)
.find('.leaflet-control-geocoder-form .search-fav-ctrls')
.click((e) => this.onCtrlsClick(e));
$(container).find(".leaflet-control-geocoder-form").append(` $(container).find('.leaflet-control-geocoder-form').append(`
<div class="collapse autocomplete-container filtered" id="search-autocomplete-container"> <div class="collapse autocomplete-container filtered" id="search-autocomplete-container">
<div class="autocomplete-select-container"> <div class="autocomplete-select-container">
<div class="list-group autocomplete-select" id="search-autocomplete-select" ></div> <div class="list-group autocomplete-select" id="search-autocomplete-select" ></div>
@ -114,243 +114,234 @@ class SearchFavorites {
</div> </div>
<div class="btn-group btn-group-sm collapse" id="autocomplete-btngroup"> <div class="btn-group btn-group-sm collapse" id="autocomplete-btngroup">
<button id="search-fav-deleteall" <button id="search-fav-deleteall"
title="${i18next.t("searchfav.removeall")}" title="${i18next.t('searchfav.removeall')}"
class="fa fa-eraser border"> class="fa fa-eraser border">
</button> </button>
<button id="search-fav-export" <button id="search-fav-export"
title="${i18next.t("searchfav.export")}" title="${i18next.t('searchfav.export')}"
class="fa fa-floppy-o border"> class="fa fa-floppy-o border">
</button> </button>
<button id="search-fav-import" <button id="search-fav-import"
class="fa fa-folder-open-o border" class="fa fa-folder-open-o border"
title="${i18next.t("searchfav.import")}" > title="${i18next.t('searchfav.import')}" >
<input id="search-fav-file" type="file" class="d-none" accept=".json"> <input id="search-fav-file" type="file" class="d-none" accept=".json">
</button> </button>
</div> </div>
</div> </div>
`); `);
this.autocompleteContainer=$(container).find("#search-autocomplete-container"); this.autocompleteContainer = $(container).find('#search-autocomplete-container');
this.autocompleteSelect=this.autocompleteContainer.find("#search-autocomplete-select"); this.autocompleteSelect = this.autocompleteContainer.find('#search-autocomplete-select');
this.autocompleteMenu=this.autocompleteContainer.find("#autocomplete-btngroup"); this.autocompleteMenu = this.autocompleteContainer.find('#autocomplete-btngroup');
this.geocoderForm=$(container).find(".leaflet-control-geocoder-form"); this.geocoderForm = $(container).find('.leaflet-control-geocoder-form');
this.autocompleteContainer.on("mousedown", this.autocompleteContainer.on('mousedown', (e) => {
(e) => { e.stopPropagation();e.preventDefault(); }); e.stopPropagation();
e.preventDefault();
});
this.autocompleteContainer.find("#search-fav-menu-toggle").on("mousedown touchend", this.autocompleteContainer.find('#search-fav-menu-toggle').on('mousedown touchend', (e) => {
(e) => { e.stopPropagation();e.preventDefault();}); e.stopPropagation();
e.preventDefault();
});
this.autocompleteContainer.find("#search-fav-menu-toggle").on("click touchend", this.autocompleteContainer.find('#search-fav-menu-toggle').on('click touchend', (e) => {
(e) => { e.stopPropagation();
e.stopPropagation();e.preventDefault(); e.preventDefault();
this.autocompleteMenu.collapse('toggle'); this.autocompleteMenu.collapse('toggle');
}); });
this.autocompleteContainer.find(".autocomplete-select-container").on("wheel", this.autocompleteContainer.find('.autocomplete-select-container').on('wheel', (e) => {
(e) => { e.stopPropagation(); }); e.stopPropagation();
});
this.autocompleteContainer.on("shown.bs.collapse", (e) => this.geocoderForm.addClass("stayvisible")); this.autocompleteContainer.on('shown.bs.collapse', (e) => this.geocoderForm.addClass('stayvisible'));
this.autocompleteContainer.on("hidden.bs.collapse", (e) => { this.autocompleteContainer.on('hidden.bs.collapse', (e) => {
this.geocoderForm.removeClass("stayvisible"); this.geocoderForm.removeClass('stayvisible');
this.autocompleteMenu.collapse('hide'); this.autocompleteMenu.collapse('hide');
});
}); this.autocompleteSelect.click((e) => this.onFavItemClicked(e));
this.autocompleteContainer.find('.autocomplete-menu').click((e) => this.onFavMenuClicked(e));
this.autocompleteContainer.find('#search-fav-file').on('change', (e) => this.onImportFavFile(e));
let strFavitems = localStorage['searchFavItems'];
if (strFavitems) {
this.arFavitems = JSON.parse(strFavitems);
this.arFavitemsLC = this.arFavitems.map((x) => x.toLowerCase()); //copy to Lowercase
}
this.autocompleteSelect.click((e) => this.onFavItemClicked(e)); this.updateFavList();
this.autocompleteContainer.find(".autocomplete-menu").click((e) => this.onFavMenuClicked(e)); this.searchInput.on('keyup', (e) => this.onInput(e));
this.autocompleteContainer.find("#search-fav-file").on("change",(e) => this.onImportFavFile(e)); }
let strFavitems=localStorage['searchFavItems']; updateFavList() {
if(strFavitems) { if (this.arFavitems.length > 0) {
this.arFavitems=JSON.parse(strFavitems); let opts = this.arFavitems.join(
this.arFavitemsLC = this.arFavitems.map(x => x.toLowerCase()); //copy to Lowercase '</button><button class="list-group-item list-group-item-action rounded-0 favitem"><span class="fa fa-trash-o mr-1 del-favitem"></span>'
} );
this.autocompleteSelect.html(
`<button class="list-group-item list-group-item-action rounded-0 favitem"><span class="fa fa-trash-o mr-1 del-favitem"></span>${opts}</button>`
);
} else this.autocompleteSelect.empty();
this.updateFavList(); this.favElements = this.autocompleteSelect.find('button');
}
this.searchInput.on("keyup",(e) => this.onInput(e)); appendFavorite(strFav) {
this.arFavitems.push(strFav);
} this.arFavitems = [...new Set(this.arFavitems)]; //remove duplicates
this.arFavitems.sort();
this.arFavitemsLC = this.arFavitems.map((x) => x.toLowerCase()); //copy to Lowercase
updateFavList() { localStorage['searchFavItems'] = JSON.stringify(this.arFavitems);
if(this.arFavitems.length > 0){ this.updateFavList();
let opts=this.arFavitems.join('</button><button class="list-group-item list-group-item-action rounded-0 favitem"><span class="fa fa-trash-o mr-1 del-favitem"></span>'); }
this.autocompleteSelect.html(`<button class="list-group-item list-group-item-action rounded-0 favitem"><span class="fa fa-trash-o mr-1 del-favitem"></span>${opts}</button>`);
}
else
this.autocompleteSelect.empty();
this.favElements=this.autocompleteSelect.find("button"); deleteFavorite(strFav) {
} let pos = this.arFavitems.indexOf(strFav);
if (pos >= 0) {
this.arFavitems.splice(pos, 1);
this.arFavitems = [...new Set(this.arFavitems)]; //remove duplicates
this.arFavitems.sort();
this.arFavitemsLC = this.arFavitems.map((x) => x.toLowerCase()); //copy to Lowercase
appendFavorite(strFav) { localStorage['searchFavItems'] = JSON.stringify(this.arFavitems);
this.arFavitems.push(strFav);
this.arFavitems=[... new Set(this.arFavitems)]; //remove duplicates this.updateFavList();
this.arFavitems.sort(); }
this.arFavitemsLC = this.arFavitems.map(x => x.toLowerCase()); //copy to Lowercase }
localStorage['searchFavItems']=JSON.stringify(this.arFavitems); onInput(e) {
this.updateFavList(); if (e.keyCode == 13) {
} this.autocompleteContainer.collapse('hide');
return;
}
deleteFavorite(strFav) { if (e.keyCode <= 45 && e.keyCode != 8) return;
let pos=this.arFavitems.indexOf(strFav);
if(pos >= 0) {
this.arFavitems.splice(pos, 1);
this.arFavitems=[... new Set(this.arFavitems)]; //remove duplicates
this.arFavitems.sort();
this.arFavitemsLC = this.arFavitems.map(x => x.toLowerCase()); //copy to Lowercase
localStorage['searchFavItems']=JSON.stringify(this.arFavitems); let srch = this.searchInput.val().toLowerCase();
this.updateFavList(); if (!srch || srch.length < 2) {
} this.autocompleteContainer.collapse('hide');
return;
}
} if (!this.isFiltered) {
this.autocompleteContainer.addClass('filtered');
this.isFiltered = true;
}
onInput(e) { let matches = false;
if(e.keyCode == 13) { this.favElements.removeClass('match');
this.autocompleteContainer.collapse('hide'); this.arFavitemsLC.forEach((val, idx) => {
return; if (val.indexOf(srch) != -1) {
} this.favElements.eq(idx).addClass('match');
matches = true;
}
});
if(e.keyCode <=45 && e.keyCode != 8) return; if (matches) this.autocompleteContainer.collapse('show');
else this.autocompleteContainer.collapse('hide');
}
let srch=this.searchInput.val().toLowerCase(); onCtrlsClick(e) {
e.stopPropagation();
e.preventDefault();
switch (e.target.id) {
case 'search-fav-add':
this.appendFavorite(this.searchInput.val());
break;
if(!srch || srch.length < 2) { case 'search-fav-expand':
this.autocompleteContainer.collapse('hide'); if (this.autocompleteContainer.hasClass('show')) {
return; if (this.isFiltered) {
} this.autocompleteContainer.removeClass('filtered');
this.isFiltered = false;
} else {
this.autocompleteContainer.collapse('hide');
this.autocompleteContainer.addClass('filtered');
this.isFiltered = true;
}
} else {
this.autocompleteContainer.removeClass('filtered');
this.isFiltered = false;
this.autocompleteContainer.collapse('show');
}
break;
if(!this.isFiltered) { default:
this.autocompleteContainer.addClass("filtered"); break;
this.isFiltered=true; }
} }
let matches=false; onFavItemClicked(e) {
this.favElements.removeClass("match"); e.stopPropagation();
this.arFavitemsLC.forEach((val,idx) => { e.preventDefault();
if(val.indexOf(srch) != -1) {
this.favElements.eq(idx).addClass("match");
matches=true;
}
});
if(matches) if ($(e.target).hasClass('favitem')) {
this.autocompleteContainer.collapse('show'); this.autocompleteContainer.collapse('hide');
else this.geocoder.setQuery(e.target.innerText);
this.autocompleteContainer.collapse('hide'); this.searchInput.focus();
}
this.geocoder._keydown({ keyCode: 13 });
} else if ($(e.target).hasClass('del-favitem')) {
this.deleteFavorite($(e.target).closest('button').text());
}
}
onCtrlsClick(e) { onFavMenuClicked(e) {
e.stopPropagation();e.preventDefault(); switch (e.target.id) {
switch(e.target.id) { case 'search-fav-deleteall':
case "search-fav-add": if (confirm(i18next.t('searchfav.ask_removeall'))) {
this.appendFavorite(this.searchInput.val()); this.arFavitems = [];
break; this.arFavitemsLC = [];
localStorage['searchFavItems'] = JSON.stringify(this.arFavitems);
this.updateFavList();
}
break;
case "search-fav-expand": case 'search-fav-export':
if(this.autocompleteContainer.hasClass("show")) { let exp = JSON.stringify(this.arFavitems, null, 2);
if(this.isFiltered) { const blob = new Blob([exp], {
this.autocompleteContainer.removeClass("filtered"); type: 'application/json;charset=utf-8',
this.isFiltered=false; });
} const objectUrl = URL.createObjectURL(blob);
else const link = document.createElement('a');
{ link.href = objectUrl;
this.autocompleteContainer.collapse('hide') link.download = 'SearchFavorites.json';
this.autocompleteContainer.addClass("filtered"); link.click();
this.isFiltered=true; break;
}
}
else
{
this.autocompleteContainer.removeClass("filtered");
this.isFiltered=false;
this.autocompleteContainer.collapse('show');
}
break;
default: case 'search-fav-import':
break; $(e.target).find('input[type=file]').click();
} e.preventDefault();
} break;
onFavItemClicked(e) { default:
e.stopPropagation();e.preventDefault(); break;
}
}
if($(e.target).hasClass("favitem")) { onImportFavFile(e) {
this.autocompleteContainer.collapse('hide'); if (!e.target.files[0]) return;
this.geocoder.setQuery(e.target.innerText);
this.searchInput.focus();
this.geocoder._keydown({keyCode: 13 }); let r = new FileReader();
} r.onload = (f) => {
else if($(e.target).hasClass("del-favitem")) { let importFavItems = JSON.parse(f.target.result);
this.deleteFavorite($(e.target).closest("button").text()); this.arFavitems = this.arFavitems.concat(importFavItems);
} this.arFavitems = [...new Set(this.arFavitems)]; //remove duplicates
} this.arFavitems.sort();
this.arFavitemsLC = this.arFavitems.map((x) => x.toLowerCase()); //copy to Lowercase
localStorage['searchFavItems'] = JSON.stringify(this.arFavitems);
this.updateFavList();
};
onFavMenuClicked(e) { r.readAsText(e.target.files[0]);
switch(e.target.id) { e.target.value = '';
case "search-fav-deleteall": }
if(confirm(i18next.t("searchfav.ask_removeall")) ) {
this.arFavitems=[];
this.arFavitemsLC=[];
localStorage['searchFavItems']=JSON.stringify(this.arFavitems);
this.updateFavList();
}
break;
case "search-fav-export":
let exp=JSON.stringify(this.arFavitems,null,2);
const blob = new Blob([exp], {
type: 'application/json;charset=utf-8',
});
const objectUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = objectUrl;
link.download = 'SearchFavorites.json';
link.click();
break;
case "search-fav-import":
$(e.target).find("input[type=file]").click();
e.preventDefault();
break;
default:
break;
}
}
onImportFavFile(e) {
if(!e.target.files[0]) return;
let r=new FileReader();
r.onload=(f) => {
let importFavItems=JSON.parse(f.target.result);
this.arFavitems=this.arFavitems.concat(importFavItems);
this.arFavitems=[... new Set(this.arFavitems)]; //remove duplicates
this.arFavitems.sort();
this.arFavitemsLC = this.arFavitems.map(x => x.toLowerCase()); //copy to Lowercase
localStorage['searchFavItems']=JSON.stringify(this.arFavitems);
this.updateFavList();
};
r.readAsText(e.target.files[0]);
e.target.value='';
}
} }