Add markers action to search results
This commit is contained in:
@@ -83,9 +83,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-overlay column is-hidden is-4 is-4-desktop is-5-mobile is-pulled-right is-overlay has-background-white-ter"
|
<div class="menu-overlay column is-hidden is-4 is-4-desktop is-5-mobile is-pulled-right is-overlay has-background-white-ter"
|
||||||
data-menu-target="search" data-controller="layer form">
|
data-menu-target="search" data-controller="layer search">
|
||||||
|
<button title="Chiudi ricerca" class="delete is-pulled-right" data-action="menu#closeSearch"></button>
|
||||||
<h1 class="is-size-5">Ricerca</h1>
|
<h1 class="is-size-5">Ricerca</h1>
|
||||||
<form id="search-form" method="POST" data-form-target="search" data-action="submit->form#submitSearch">
|
<form id="search-form" method="POST" data-search-target="search" data-action="submit->search#submitSearch">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Testo libero</label>
|
<label class="label">Testo libero</label>
|
||||||
<div class="control is-full-width">
|
<div class="control is-full-width">
|
||||||
@@ -99,7 +100,7 @@
|
|||||||
<select name="category">
|
<select name="category">
|
||||||
<option default value="">-- Scegliere la categoria del sito --</option>
|
<option default value="">-- Scegliere la categoria del sito --</option>
|
||||||
<option value="site">Sito conservato</option>
|
<option value="site">Sito conservato</option>
|
||||||
<option value="not_conserved">Sito non conservato</option>
|
<!--<option value="not_conserved">Sito non conservato</option>-->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -130,7 +131,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button class="button is-link is-light" type="reset">
|
<button class="button is-link is-light" type="reset" data-action="search#clearSearch">
|
||||||
<span>Cancella filtri</span>
|
<span>Cancella filtri</span>
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa fa-times"></i>
|
<i class="fa fa-times"></i>
|
||||||
@@ -139,7 +140,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<output data-form-target="results"></output>
|
<div class="content pt-2 mt-3 is-hidden" data-search-target="container">
|
||||||
|
<table class="table is-fullwidth is-striped">
|
||||||
|
<thead>
|
||||||
|
<tr><td class="has-text-centered has-text-weight-bold is-size-5" colspan="2">Risultati</td></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-search-target="results"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-overlay column is-hidden is-4 is-4-desktop is-5-mobile is-pulled-right is-overlay has-background-white-ter"
|
<div class="menu-overlay column is-hidden is-4 is-4-desktop is-5-mobile is-pulled-right is-overlay has-background-white-ter"
|
||||||
data-menu-target="menu" data-controller="layer">
|
data-menu-target="menu" data-controller="layer">
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
import { Controller } from "@hotwired/stimulus";
|
|
||||||
import { GisState } from "../state.js";
|
|
||||||
import UI from "../ui.js";
|
|
||||||
|
|
||||||
const html = String.raw;
|
|
||||||
|
|
||||||
export default class extends Controller {
|
|
||||||
static values = {
|
|
||||||
'coords': String,
|
|
||||||
'group': String,
|
|
||||||
'id': String,
|
|
||||||
};
|
|
||||||
|
|
||||||
static targets = ['search', 'results'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {Event} event
|
|
||||||
*/
|
|
||||||
async submitSearch(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const data = new FormData(event.target);
|
|
||||||
const body = {};
|
|
||||||
|
|
||||||
for (const entry of data.entries()) {
|
|
||||||
body[entry[0]] = entry[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch("https://caprigis-api.ddev.site:33001/search?" + new URLSearchParams(body));
|
|
||||||
const results = await response.json();
|
|
||||||
|
|
||||||
console.debug(results);
|
|
||||||
|
|
||||||
this.#injectResults(results);
|
|
||||||
this.#filterMap(results);
|
|
||||||
}
|
|
||||||
|
|
||||||
#injectResults(results) {
|
|
||||||
/**
|
|
||||||
* @type {HTMLOutputElement} output
|
|
||||||
*/
|
|
||||||
const output = this.resultsTarget;
|
|
||||||
output.innerHTML = '';
|
|
||||||
|
|
||||||
for (const result of results) {
|
|
||||||
const item = html`
|
|
||||||
<p class="p-1">${result.label}</p>
|
|
||||||
`;
|
|
||||||
|
|
||||||
output.innerHTML += item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {Array<Object>} results
|
|
||||||
*/
|
|
||||||
#filterMap(results) {
|
|
||||||
const map = GisState.map;
|
|
||||||
const labels = [];
|
|
||||||
results.forEach(r => labels.push(r.label));
|
|
||||||
|
|
||||||
for (const key of Object.keys(GisState.layers)) {
|
|
||||||
map.removeLayer(GisState.layers[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sites = GisState.markers.sites;
|
|
||||||
|
|
||||||
for (let key of Object.keys(sites)) {
|
|
||||||
// If map has layers from previous search results...
|
|
||||||
map.removeLayer(sites[key]);
|
|
||||||
for (const label of labels) {
|
|
||||||
if (sites[key].options.data.label === label) {
|
|
||||||
map.addLayer(sites[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -128,6 +128,10 @@ export default class extends Controller {
|
|||||||
this.cartographyTarget.classList.add('is-hidden');
|
this.cartographyTarget.classList.add('is-hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeSearch() {
|
||||||
|
this.searchTarget.classList.add('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
toggleList(id) {
|
toggleList(id) {
|
||||||
document.querySelector(`#${id}`).classList.toggle('is-hidden');
|
document.querySelector(`#${id}`).classList.toggle('is-hidden');
|
||||||
}
|
}
|
||||||
|
|||||||
122
webgis/js/controllers/search_controller.js
Normal file
122
webgis/js/controllers/search_controller.js
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import { Controller } from "@hotwired/stimulus";
|
||||||
|
import { GisState } from "../state.js";
|
||||||
|
import UI from "../ui.js";
|
||||||
|
|
||||||
|
const html = String.raw;
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
static targets = [
|
||||||
|
'search',
|
||||||
|
'results',
|
||||||
|
'clear',
|
||||||
|
'container',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
async submitSearch(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const data = new FormData(event.target);
|
||||||
|
const body = {};
|
||||||
|
|
||||||
|
for (const entry of data.entries()) {
|
||||||
|
body[entry[0]] = entry[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`${GisState.apiUrl}/search?` + new URLSearchParams(body));
|
||||||
|
const results = await response.json();
|
||||||
|
|
||||||
|
this.containerTarget.classList.remove('is-hidden');
|
||||||
|
this.#injectResults(results);
|
||||||
|
if (results.length) this.#filterMap(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearSearch() {
|
||||||
|
const map = GisState.map;
|
||||||
|
|
||||||
|
// Restore layer groups in map
|
||||||
|
for (const key of Object.keys(GisState.layers)) {
|
||||||
|
map.addLayer(GisState.layers[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty result set
|
||||||
|
this.resultsTarget.innerHTML = '';
|
||||||
|
this.containerTarget.classList.add('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
#injectResults(results) {
|
||||||
|
/**
|
||||||
|
* @type {HTMLOutputElement} output
|
||||||
|
*/
|
||||||
|
const output = this.resultsTarget;
|
||||||
|
output.innerHTML = '';
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
output.innerHTML = html`
|
||||||
|
<p class="has-background-white-bis p-4 mt-0 has-text-centered">
|
||||||
|
Nessun risultato trovato per i parametri di ricerca
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sites = GisState.markers.sites;
|
||||||
|
|
||||||
|
for (const result of results) {
|
||||||
|
let coordinates = ''
|
||||||
|
for (let key of Object.keys(sites)) {
|
||||||
|
if (sites[key].options.data.label === result.label) {
|
||||||
|
coordinates = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO The group value should be dynamic!!
|
||||||
|
const item = html`
|
||||||
|
<tr>
|
||||||
|
<td class="pt-4">${result.label}</td>
|
||||||
|
<td>
|
||||||
|
<button class="button is-link"
|
||||||
|
data-controller="marker"
|
||||||
|
data-action="marker#go"
|
||||||
|
data-marker-coords-value="${coordinates}"
|
||||||
|
data-marker-group-value="sites">
|
||||||
|
Vai al sito
|
||||||
|
<span class="ml-1 icon">
|
||||||
|
<i class="fa fa-chevron-right"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
output.innerHTML += item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Array<Object>} results
|
||||||
|
*/
|
||||||
|
#filterMap(results) {
|
||||||
|
const map = GisState.map;
|
||||||
|
const labels = [];
|
||||||
|
results.forEach(r => labels.push(r.label));
|
||||||
|
|
||||||
|
// Remove all layer groups first
|
||||||
|
for (const key of Object.keys(GisState.layers)) {
|
||||||
|
map.removeLayer(GisState.layers[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sites = GisState.markers.sites;
|
||||||
|
|
||||||
|
for (let key of Object.keys(sites)) {
|
||||||
|
// If map has layers from previous search results...
|
||||||
|
map.removeLayer(sites[key]);
|
||||||
|
for (const label of labels) {
|
||||||
|
if (sites[key].options.data.label === label) {
|
||||||
|
map.addLayer(sites[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,8 +7,7 @@ import MarkerController from './controllers/marker_controller.js';
|
|||||||
import BiblioController from './controllers/biblio_controller.js';
|
import BiblioController from './controllers/biblio_controller.js';
|
||||||
import TabsController from './controllers/tabs_controller.js';
|
import TabsController from './controllers/tabs_controller.js';
|
||||||
import LayerController from './controllers/layer_controller.js';
|
import LayerController from './controllers/layer_controller.js';
|
||||||
import FormController from './controllers/form_controller.js';
|
import SearchController from './controllers/search_controller.js';
|
||||||
import { GisState } from './state.js';
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
// Register Stimulus controllers
|
// Register Stimulus controllers
|
||||||
@@ -28,12 +27,6 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
|
|
||||||
UI.addCenterMapControl(map, GIS.CENTER_COORDS, GIS.INIT_ZOOM);
|
UI.addCenterMapControl(map, GIS.CENTER_COORDS, GIS.INIT_ZOOM);
|
||||||
UI.toggleBurger('navbar-burger');
|
UI.toggleBurger('navbar-burger');
|
||||||
|
|
||||||
// TEMP!!
|
|
||||||
const sites = GisState.markers.sites;
|
|
||||||
for (let key of Object.keys(sites)) {
|
|
||||||
//console.debug(sites[key].options.data);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function initStimulus() {
|
function initStimulus() {
|
||||||
@@ -44,5 +37,5 @@ function initStimulus() {
|
|||||||
Stimulus.register("biblio", BiblioController);
|
Stimulus.register("biblio", BiblioController);
|
||||||
Stimulus.register("tabs", TabsController);
|
Stimulus.register("tabs", TabsController);
|
||||||
Stimulus.register("layer", LayerController);
|
Stimulus.register("layer", LayerController);
|
||||||
Stimulus.register("form", FormController);
|
Stimulus.register("search", SearchController);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user