Support for location picker
This commit is contained in:
parent
93dd68f0e8
commit
5e14d364ef
|
@ -474,6 +474,7 @@ INSERT INTO `".$prefix."_options` (`id`, `name`, `value`, `enabled`, `created_ti
|
|||
INSERT INTO `".$prefix."_options` (`id`, `name`, `value`, `enabled`, `created_time`, `last_edit`, `user_id`) VALUES (NULL, 'service_remove', 1, 1, current_timestamp(), current_timestamp(), '1');
|
||||
INSERT INTO `".$prefix."_options` (`id`, `name`, `value`, `enabled`, `created_time`, `last_edit`, `user_id`) VALUES (NULL, 'training_edit', 1, 1, current_timestamp(), current_timestamp(), '1');
|
||||
INSERT INTO `".$prefix."_options` (`id`, `name`, `value`, `enabled`, `created_time`, `last_edit`, `user_id`) VALUES (NULL, 'training_remove', 1, 1, current_timestamp(), current_timestamp(), '1');
|
||||
INSERT INTO `".$prefix."_options` (`id`, `name`, `value`, `enabled`, `created_time`, `last_edit`, `user_id`) VALUES (NULL, 'use_location_picker', 1, 1, current_timestamp(), current_timestamp(), '1');
|
||||
$option_check_cf_ip");
|
||||
mt_srand(10);
|
||||
$prep->bindValue(':hidden', ($visible ? 0 : 1), PDO::PARAM_INT);
|
||||
|
|
|
@ -11,7 +11,7 @@ import '../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.css'
|
|||
import 'time-input-polyfill/auto';
|
||||
import 'jquery-pjax';
|
||||
|
||||
$(document).pjax('a', '#content');
|
||||
$(document).pjax('a', '#content', {timeout: 100000});
|
||||
$(document).on('pjax:start', function() {
|
||||
if(window.loadTable_interval !== undefined){
|
||||
clearInterval(window.loadTable_interval);
|
||||
|
@ -71,6 +71,7 @@ $( document ).ready(function() {
|
|||
window.dispatchEvent(new Event("cookieAlertAccept"))
|
||||
});
|
||||
});
|
||||
|
||||
if (getCookie("authenticated")) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
|
@ -83,15 +84,29 @@ if (getCookie("authenticated")) {
|
|||
}
|
||||
}
|
||||
|
||||
function fillTable(data){
|
||||
function fillTable(data, replaceLatLngWithMap=false){
|
||||
$("#table_body").empty();
|
||||
$.each(data, function(num, item) {
|
||||
var row = document.createElement("tr");
|
||||
$.each(item, function(num, i) {
|
||||
$.each(data, function(row_num, item) {
|
||||
let row = document.createElement("tr");
|
||||
$.each(item, function(cell_num, i) {
|
||||
if(i !== null){
|
||||
var cell = document.createElement("td");
|
||||
cell.innerHTML = i;
|
||||
row.appendChild(cell);
|
||||
if(replaceLatLngWithMap && i.match(/[+-]?\d+([.]\d+)?[;][+-]?\d+([.]\d+)?/gm)){
|
||||
let lat = i.split(";")[0];
|
||||
let lng = i.split(";")[1];
|
||||
let mapDiv = document.createElement("div");
|
||||
mapDiv.className = "map";
|
||||
mapDiv.id = "map-"+row_num;
|
||||
var mapScript = document.createElement("script");
|
||||
mapScript.appendChild(document.createTextNode("load_map("+lat+", "+lng+", \"map-"+row_num+"\", false)"));
|
||||
mapDiv.appendChild(mapScript);
|
||||
let cell = document.createElement("td");
|
||||
cell.appendChild(mapDiv);
|
||||
row.appendChild(cell);
|
||||
} else {
|
||||
let cell = document.createElement("td");
|
||||
cell.innerHTML = i;
|
||||
row.appendChild(cell);
|
||||
}
|
||||
}
|
||||
});
|
||||
document.getElementById("table_body").appendChild(row);
|
||||
|
@ -101,8 +116,9 @@ function fillTable(data){
|
|||
var offline = false;
|
||||
var loadTable_interval = undefined;
|
||||
function loadTable(table_page, set_interval=true, interval=10000, onlineReload=false){
|
||||
let replaceLatLngWithMap = table_page == "services" || table_page == "trainings";
|
||||
$.getJSON( "resources/ajax/ajax_"+table_page+".php", function( data, status, xhr ) {
|
||||
fillTable(data);
|
||||
fillTable(data, replaceLatLngWithMap);
|
||||
var headers = new Headers();
|
||||
headers.append('date', Date.now());
|
||||
caches.open('tables-1').then((cache) => {
|
||||
|
@ -119,14 +135,14 @@ function loadTable(table_page, set_interval=true, interval=10000, onlineReload=f
|
|||
}
|
||||
}).fail(function(data, status) {
|
||||
if(status == "parsererror"){
|
||||
if($("#table_body").children().length == 0) {
|
||||
loadTable(table_page, set_interval, interval);
|
||||
if($("#table_body").children().length == 0) { //this is a server-side authentication error on some cheap hosting providers
|
||||
loadTable(table_page, set_interval, interval); //retry
|
||||
} // else nothing
|
||||
} else {
|
||||
caches.open('tables-1').then(cache => {
|
||||
cache.match("/table_"+table_page+".json").then(response => {
|
||||
response.json().then(data => {
|
||||
fillTable(data);
|
||||
fillTable(data, replaceLatLngWithMap);
|
||||
console.log("Table loaded from cache");
|
||||
$("#offline_update").text(new Date(parseInt(response.headers.get("date"))).toLocaleString());
|
||||
});
|
||||
|
@ -147,4 +163,6 @@ function loadTable(table_page, set_interval=true, interval=10000, onlineReload=f
|
|||
|
||||
window.loadTable_interval = loadTable_interval;
|
||||
window.fillTable = fillTable;
|
||||
window.loadTable = loadTable;
|
||||
window.loadTable = loadTable;
|
||||
window.setCookie = setCookie;
|
||||
window.getCookie = getCookie;
|
|
@ -0,0 +1,37 @@
|
|||
div#map {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.map {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
div#search {
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
bottom: 40px;
|
||||
left: 40px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
div#results {
|
||||
font-style: sans-serif;
|
||||
color: black;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.fa{
|
||||
vertical-align: middle;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.fa.fa-map-marker-alt,.fa.fa-spinner.fa-spin {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.leaflet-pane.leaflet-shadow-pane {
|
||||
display: none;
|
||||
}
|
|
@ -2,10 +2,200 @@ import L from 'leaflet';
|
|||
import 'leaflet.locatecontrol';
|
||||
import '../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css'
|
||||
import '../node_modules/leaflet/dist/leaflet.css';
|
||||
import './maps.css';
|
||||
|
||||
delete L.Icon.Default.prototype._getIconUrl;
|
||||
L.Icon.Default.mergeOptions({
|
||||
iconRetinaUrl: 'resources/dist/marker-icon-2x.png',
|
||||
iconUrl: 'resources/dist/marker-icon.png',
|
||||
shadowUrl: 'resources/dist/marker-shadow.png',
|
||||
});
|
||||
});
|
||||
|
||||
var marker;
|
||||
var map;
|
||||
function set_marker(LatLng){
|
||||
if(marker){
|
||||
console.log("Marker exists");
|
||||
//console.log(marker);
|
||||
marker.remove();
|
||||
}
|
||||
console.log(LatLng);
|
||||
if($("input[name='luogo']").val() !== undefined){
|
||||
$("input[name='luogo']").val(LatLng.lat + ";" + LatLng.lng);
|
||||
}
|
||||
marker = L.marker(LatLng).addTo(map);
|
||||
}
|
||||
|
||||
function load_map(lat=undefined, lng=undefined, selector_id=undefined, select=true) {
|
||||
if(lat == undefined && lng == undefined){
|
||||
lat = 45.5285; //TODO: replace hard-coded into cookie reading
|
||||
lng = 10.2956;
|
||||
}
|
||||
if(selector_id == undefined){
|
||||
selector_id = "map";
|
||||
}
|
||||
let zoom = select ? 10 : 17;
|
||||
let latLng = new L.LatLng(lat, lng);
|
||||
map = new L.Map(selector_id, {zoomControl: true});
|
||||
|
||||
let osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
osmAttribution = 'Map data © 2012 <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
|
||||
osm = new L.TileLayer(osmUrl, {maxZoom: 20, attribution: osmAttribution});
|
||||
|
||||
map.setView(latLng, zoom).addLayer(osm);
|
||||
|
||||
if(select){
|
||||
map.on('click', function(e) {
|
||||
set_marker(e.latlng);
|
||||
});
|
||||
|
||||
L.Control.CustomLocate = L.Control.Locate.extend({
|
||||
_drawMarker: function() {
|
||||
set_marker(this._event.latlng);
|
||||
},
|
||||
_onDrag: function(){},
|
||||
_onZoom: function(){},
|
||||
_onZoomEnd: function(){},
|
||||
});
|
||||
|
||||
let lc = new L.Control.CustomLocate({
|
||||
icon: "fa fa-map-marker",
|
||||
cacheLocation: false, //disabled for privacy reasons
|
||||
}).addTo(map);
|
||||
|
||||
if($("#addr").val() !== undefined){
|
||||
document.getElementById("addr").addEventListener("keydown", function(event) {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
document.querySelector("#search > button").click();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(getCookie("experimental_read_clipboard")){
|
||||
window.addEventListener("focus", function(event) {
|
||||
if($("#addr").val() == ""){
|
||||
console.log("Loading location from clipboard");
|
||||
navigator.clipboard.readText().then(text => {
|
||||
$("#addr").val(text);
|
||||
if(!addr_search()){
|
||||
$("#addr").val("");
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('Failed to read clipboard contents: ', err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
set_marker(latLng);
|
||||
}
|
||||
map.invalidateSize();
|
||||
}
|
||||
|
||||
// from unknown source in the Internet
|
||||
function chooseAddr(lat, lng, zoom=undefined, lat1=undefined, lng1=undefined, lat2=undefined, lng2=undefined, osm_type=undefined) {
|
||||
let lat = lat.replace(",", ".");
|
||||
let lng = lng.replace(",", ".");
|
||||
if(lat1 !== undefined && lng1 !== undefined && lat2 !== undefined && lng2 !== undefined && osm_type !== undefined){
|
||||
let loc1 = new L.LatLng(lat1, lng1);
|
||||
let loc2 = new L.LatLng(lat2, lng2);
|
||||
let bounds = new L.LatLngBounds(loc1, loc2);
|
||||
console.log(lat1, lng1, lat2, lng2, osm_type);
|
||||
set_marker(new L.LatLng(lat, lng));
|
||||
if (feature) {
|
||||
map.removeLayer(feature);
|
||||
}
|
||||
if (osm_type == "node") {
|
||||
map.fitBounds(bounds);
|
||||
map.setZoom(18);
|
||||
} else {
|
||||
let loc3 = new L.LatLng(lat1, lng2);
|
||||
let loc4 = new L.LatLng(lat2, lng1);
|
||||
feature = L.polyline( [loc1, loc4, loc2, loc3, loc1], {color: 'red'}).addTo(map);
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
} else if (lat !== undefined && lng !== undefined){
|
||||
let loc = new L.LatLng(lat, lng);
|
||||
console.log(loc);
|
||||
set_marker(loc);
|
||||
if(zoom !== undefined){
|
||||
map.setView(loc, zoom);
|
||||
} else {
|
||||
map.setView(loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// started from https://derickrethans.nl/leaflet-and-nominatim.html
|
||||
function addr_search(string_results_found=undefined, string_results_not_found=undefined) {
|
||||
function searchError(error, checkClipboard){
|
||||
if(!checkClipboard){
|
||||
$('<p>', { html: string_results_not_found }).appendTo('#results');
|
||||
console.error(error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
let inp = document.getElementById("addr").value;
|
||||
//if translation strings are not defined, skip the nominatim step and don't log errors (no console.error)
|
||||
let checkClipboard = string_results_found==undefined && string_results_not_found==undefined;
|
||||
$('#results').empty();
|
||||
|
||||
if(inp.match("\@(-?[\d\.]*)")){ //Google Maps
|
||||
try {
|
||||
inp = inp.split("@")[1].split(",");
|
||||
chooseAddr(inp[0], inp[1]);
|
||||
return true;
|
||||
} catch (error) {
|
||||
searchError(error, checkClipboard);
|
||||
}
|
||||
} else if(inp.includes("#map=")) { //OpenStreetMap website
|
||||
try {
|
||||
inp = inp.split("#map=")[1].split("/");
|
||||
chooseAddr(inp[1], inp[2], inp[0]);
|
||||
return true;
|
||||
} catch (error) {
|
||||
searchError(error, checkClipboard);
|
||||
}
|
||||
} else if(inp.match(/[0-9]+,\s[0-9]+/)) { //Bing
|
||||
try {
|
||||
inp = inp.split(", ");
|
||||
chooseAddr(inp[0], inp[1]);
|
||||
return true;
|
||||
} catch (error) {
|
||||
searchError(error, checkClipboard);
|
||||
}
|
||||
} else if(inp.match(/[0-9]+;[0-9]+/)) { //DB dump
|
||||
try {
|
||||
inp = inp.split(";");
|
||||
chooseAddr(inp[0], inp[1]);
|
||||
return true;
|
||||
} catch (error) {
|
||||
searchError(error, checkClipboard);
|
||||
}
|
||||
} else if(!checkClipboard) {
|
||||
$.getJSON('https://nominatim.openstreetmap.org/search?format=json&limit=5&q=' + inp, function(data) {
|
||||
let items = [];
|
||||
|
||||
$.each(data, function(key, val) {
|
||||
items.push("<li><a href='' onclick='chooseAddr(\"" + val.lat + "\", \"" + val.lon + "\", undefined, " + val.boundingbox[0] + ", " + val.boundingbox[2] + ", " + val.boundingbox[1] + ", " + val.boundingbox[3] + ", \"" + val.osm_type + "\"); return false;'>" + val.display_name + '</a></li>');
|
||||
});
|
||||
|
||||
if (items.length != 0) {
|
||||
$('<p>', { html: string_results_found+":" }).appendTo('#results');
|
||||
$('<ul/>', {
|
||||
'class': 'results-list',
|
||||
html: items.join('')
|
||||
}).appendTo('#results');
|
||||
} else {
|
||||
$('<p>', { html: string_results_not_found }).appendTo('#results');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
window.load_map = load_map;
|
||||
window.addr_search = addr_search;
|
||||
window.chooseAddr = chooseAddr;
|
|
@ -24,7 +24,7 @@ function fetchHandler(event, content_type, not_found_message){
|
|||
);
|
||||
}
|
||||
self.addEventListener('fetch', function (event) {
|
||||
console.log(event.request);
|
||||
//console.log(event.request);
|
||||
var request = event.request;
|
||||
|
||||
// https://stackoverflow.com/a/49719964
|
||||
|
|
|
@ -328,7 +328,7 @@
|
|||
xhr.send();
|
||||
}
|
||||
|
||||
check();
|
||||
//check();
|
||||
/* setInterval(function() {
|
||||
check();
|
||||
}, 30000); */
|
||||
|
|
|
@ -128,8 +128,20 @@ textarea {
|
|||
</div>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{% if option('use_location_picker') %}
|
||||
<label><b>{{ 'Service place'|t }}</b></label>
|
||||
<div id="map"></div>
|
||||
<div id="search">
|
||||
<input type="text" name="addr" value="" id="addr" size="10" />
|
||||
<button type="button" onclick="addr_search('{{ 'Search results'|t }}', '{{ 'No results found'|t }}');" class="btn btn-primary">{{ 'Search'|t }}</button>
|
||||
<div id="results"></div>
|
||||
</div>
|
||||
<input type="hidden" name="luogo" value="" />
|
||||
<script src="resources/dist/maps.js" onload="load_map();"></script>
|
||||
{% else %}
|
||||
<label><b>{{ 'Service place'|t }}</b></label>
|
||||
<input type="text" name="luogo" required value="{{ values.luogo }}">
|
||||
{% endif %}
|
||||
<br>
|
||||
<br>
|
||||
<label><b>{{ 'Others notes (ex. others infos)'|t }}</b></label><br>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<script src="resources/dist/maps.js"></script>
|
||||
<style>
|
||||
|
||||
#add {
|
||||
|
@ -87,7 +88,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<script>
|
||||
window.loadTable("services");
|
||||
window.loadTable("services", true, 120000);
|
||||
</script>
|
||||
</div>
|
||||
<br>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<script src="resources/dist/maps.js"></script>
|
||||
<style>
|
||||
|
||||
#add {
|
||||
|
@ -85,7 +86,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<script>
|
||||
window.loadTable("trainings");
|
||||
window.loadTable("trainings", true, 120000);
|
||||
</script>
|
||||
</div>
|
||||
<br>
|
||||
|
|
|
@ -74,5 +74,8 @@ return [
|
|||
"Add service" => "Add service",
|
||||
"Add training" => "Add training",
|
||||
"You are offline" => "You are offline",
|
||||
"Last update" => "Last update"
|
||||
"Last update" => "Last update",
|
||||
"Search" => "Search",
|
||||
"Search results" => "Search results",
|
||||
"No results found" => "No results found"
|
||||
];
|
||||
|
|
|
@ -74,5 +74,8 @@ return [
|
|||
"Add service" => "Aggiungi intervento",
|
||||
"Add training" => "Aggiungi esercitazione",
|
||||
"You are offline" => "Sei offline",
|
||||
"Last update" => "Ultimo aggiornamento"
|
||||
"Last update" => "Ultimo aggiornamento",
|
||||
"Search" => "Cerca",
|
||||
"Search results" => "Risultati della ricerca",
|
||||
"No results found" => "Nessun risultato trovato"
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue