resources/views/admin/location-edit.phtml
<?php
declare(strict_types=1);
use Fisharebest\Webtrees\Http\RequestHandlers\MapDataSave;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\PlaceLocation;
use Fisharebest\Webtrees\View;
/**
* @var array<string,string> $breadcrumbs
* @var string $latitude
* @var object $leaflet_config
* @var string $longitude
* @var PlaceLocation $location
* @var array<array<float>> $map_bounds
* @var array<float> $marker_position
* @var PlaceLocation $parent
* @var string $title
* @var string $url
*/
?>
<?= view('components/breadcrumbs', ['links' => $breadcrumbs]) ?>
<h1><?= $title ?></h1>
<div class="row wt-location-edit-wrapper wt-fullscreen-container">
<div id="wt-map" class="col-sm-9 wt-ajax-load wt-map" dir="ltr"></div>
<div class="col-sm-3 wt-map-sidebar">
<form method="post" action="<?= e(route(MapDataSave::class)) ?>">
<input type="hidden" name="parent_id" value="<?= $parent->id() ?>">
<input type="hidden" name="place_id" value="<?= $location->id() ?>">
<input type="hidden" name="url" value="<?= e($url) ?>">
<label class="col-form-label col-sm-6" for="new_place_name">
<?= I18N::translate('Place') ?>
</label>
<input type="text" id="new_place_name" name="new_place_name" value="<?= e($location->locationName()) ?>" class="form-control" required="required" maxlength="120" pattern="[^,]+" dir="auto">
<label class="col-form-label col-sm-6" for="new_place_lati">
<?= I18N::translate('Latitude') ?>
</label>
<div class="input-group">
<input type="text" dir="ltr" id="new_place_lati" class="editable form-control" name="new_place_lati" placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($latitude) ?>">
</div>
<label class="col-form-label" for="new_place_long">
<?= I18N::translate('Longitude') ?>
</label>
<div class="input-group">
<input type="text" dir="ltr" id="new_place_long" class="editable form-control" name="new_place_long" placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($longitude) ?>">
</div>
<div class="mt-3">
<button class="btn btn-primary" type="submit">
<?= /* I18N: A button label. */
I18N::translate('save')
?>
</button>
<a class="btn btn-secondary" href="<?= e($url) ?>">
<?= I18N::translate('cancel') ?>
</a>
</div>
<?= csrf_field() ?>
</form>
</div>
</div>
<?php View::push('javascript') ?>
<script>
'use strict';
(function () {
const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
const add_place = <?= json_encode($location->id() === null, JSON_THROW_ON_ERROR) ?>;
let new_place_lati = document.getElementById('new_place_lati');
let new_place_long = document.getElementById('new_place_long');
// postcss_image_inliner breaks the autodetection of image paths.
L.Icon.Default.imagePath = <?= json_encode(asset('css/images/'), JSON_THROW_ON_ERROR) ?>;
// draggable marker
let marker = L.marker(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>, {
draggable: true,
})
.on('dragend', function () {
let coords = marker.getLatLng();
map.panTo(coords);
new_place_lati.value = Number(coords.lat).toFixed(5);
new_place_long.value = Number(coords.lng).toFixed(5);
});
/**
* Passed to resetControl to
* perform necessary reset actions on map
*
* @param {Event} event
*/
let resetCallback = function (event) {
event.preventDefault();
map.fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]});
marker.setLatLng(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>);
document.querySelector('form').reset();
}
// Geocoder (place lookup)
let geocoder = new L.Control.geocoder({
position: 'bottomleft',
defaultMarkGeocode: false,
expand: 'click',
showResultIcons: true,
query: <?= json_encode($location->locationName(), JSON_THROW_ON_ERROR) ?>,
placeholder: <?= json_encode(I18N::translate('Place'), JSON_THROW_ON_ERROR) ?>,
errorMessage: <?= json_encode(I18N::translate('Nothing found.'), JSON_THROW_ON_ERROR) ?>,
iconLabel: <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>
})
.on('markgeocode', function (result) {
let coords = result.geocode.center;
let place = result.geocode.name.split(',', 1).toString();
marker.setLatLng(coords);
map.panTo(coords);
if (add_place) {
document.getElementById('new_place_name').value = place
}
new_place_lati.value = Number(coords.lat).toFixed(5);
new_place_long.value = Number(coords.lng).toFixed(5);
});
const map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback)
.addControl(geocoder)
.addLayer(marker)
.fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]})
.on('zoomend', function () {
if (!map.getBounds().contains(marker.getLatLng())) {
map.panTo(marker.getLatLng());
}
});
document.querySelectorAll('.editable').forEach((element) => {
element.addEventListener('change', () => {
let lat = new_place_lati.value;
let lng = new_place_long.value;
marker.setLatLng([lat, lng]);
map.panTo([lat, lng]);
});
});
window.onload = function() {
let icon = document.querySelector('.leaflet-control-geocoder-icon');
icon.setAttribute('title', <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>);
}
})();
</script>
<?php View::endpush() ?>