xref: /webtrees/resources/views/admin/location-edit.phtml (revision afc2d1902ecd3bf5ad093d4f0c848f540e3f1cc8)
1d70512abSGreg Roach<?php
2d70512abSGreg Roach
394e35917SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\MapDataList;
490949315SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\MapDataSave;
5d70512abSGreg Roachuse Fisharebest\Webtrees\I18N;
69a9dfcf7SGreg Roachuse Fisharebest\Webtrees\PlaceLocation;
7d70512abSGreg Roachuse Fisharebest\Webtrees\View;
8d70512abSGreg Roach
99a9dfcf7SGreg Roach/**
109a9dfcf7SGreg Roach * @var array<string,string> $breadcrumbs
119a9dfcf7SGreg Roach * @var string               $latitude
12c9c6f2ecSGreg Roach * @var object               $leaflet_config
139a9dfcf7SGreg Roach * @var string               $longitude
149a9dfcf7SGreg Roach * @var PlaceLocation        $location
159a9dfcf7SGreg Roach * @var array<array<float>>  $map_bounds
1690949315SGreg Roach * @var array<float>         $marker_position
179a9dfcf7SGreg Roach * @var PlaceLocation        $parent
189a9dfcf7SGreg Roach * @var string               $title
199a9dfcf7SGreg Roach */
209a9dfcf7SGreg Roach
21d70512abSGreg Roach?>
22dd6b2bfcSGreg Roach
23dd6b2bfcSGreg Roach<?= view('components/breadcrumbs', ['links' => $breadcrumbs]) ?>
24dd6b2bfcSGreg Roach
25dd6b2bfcSGreg Roach<h1><?= $title ?></h1>
26dd6b2bfcSGreg Roach
27*afc2d190SGreg Roach<div class="row form-group mb-3">
28e340fe65SGreg Roach    <div class="col-sm-12">
290b4092edSGreg Roach        <div id="osm-map" class="wt-ajax-load col-sm-12 osm-admin-map" dir="ltr"></div>
30dd6b2bfcSGreg Roach    </div>
31dd6b2bfcSGreg Roach</div>
32dd6b2bfcSGreg Roach
332a93faa6SGreg Roach<form method="post" action="<?= e(route(MapDataSave::class)) ?>">
34dd6b2bfcSGreg Roach    <?= csrf_field() ?>
352a93faa6SGreg Roach    <input type="hidden" name="parent_id" value="<?= e($parent->id()) ?>">
362a93faa6SGreg Roach    <input type="hidden" name="place_id" value="<?= e($location->id()) ?>">
37dd6b2bfcSGreg Roach
38*afc2d190SGreg Roach    <div class="row form-group mb-3">
39dd6b2bfcSGreg Roach        <label class="col-form-label col-sm-1" for="new_place_name">
40dd6b2bfcSGreg Roach            <?= I18N::translate('Place') ?>
41dd6b2bfcSGreg Roach        </label>
42e340fe65SGreg Roach        <div class="col-sm-3">
437dca5265SGreg Roach            <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">
44dd6b2bfcSGreg Roach        </div>
45dd6b2bfcSGreg Roach    </div>
46dd6b2bfcSGreg Roach
47*afc2d190SGreg Roach    <div class="row form-group mb-3">
4856a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_lati">
49dd6b2bfcSGreg Roach            <?= I18N::translate('Latitude') ?>
50dd6b2bfcSGreg Roach        </label>
51dd6b2bfcSGreg Roach        <div class="col-sm-3">
52dd6b2bfcSGreg Roach            <div class="input-group">
5390949315SGreg Roach                <input type="text" dir="ltr" id="new_place_lati" class="editable form-control" name="new_place_lati" placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($latitude) ?>">
54dd6b2bfcSGreg Roach            </div>
55dd6b2bfcSGreg Roach        </div>
56e340fe65SGreg Roach    </div>
57dd6b2bfcSGreg Roach
58*afc2d190SGreg Roach    <div class="row form-group mb-3">
5956a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_long">
60dd6b2bfcSGreg Roach            <?= I18N::translate('Longitude') ?>
61dd6b2bfcSGreg Roach        </label>
62dd6b2bfcSGreg Roach        <div class="col-sm-3">
63dd6b2bfcSGreg Roach            <div class="input-group">
6490949315SGreg Roach                <input type="text" dir="ltr" id="new_place_long" class="editable form-control" name="new_place_long" placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($longitude) ?>">
65dd6b2bfcSGreg Roach            </div>
66dd6b2bfcSGreg Roach        </div>
67dd6b2bfcSGreg Roach    </div>
68dd6b2bfcSGreg Roach
69*afc2d190SGreg Roach    <div class="row form-group mb-3">
70dd6b2bfcSGreg Roach        <div class="col-sm-10 offset-sm-1">
71dd6b2bfcSGreg Roach            <button class="btn btn-primary" type="submit">
72dd6b2bfcSGreg Roach                <?= /* I18N: A button label. */
73dd6b2bfcSGreg Roach                I18N::translate('save')
74dd6b2bfcSGreg Roach                ?>
75dd6b2bfcSGreg Roach            </button>
7694e35917SGreg Roach            <a class="btn btn-secondary" href="<?= e(route(MapDataList::class, ['parent_id' => $parent->id()])) ?>">
77dd6b2bfcSGreg Roach                <?= I18N::translate('cancel') ?>
78dd6b2bfcSGreg Roach            </a>
79dd6b2bfcSGreg Roach        </div>
80dd6b2bfcSGreg Roach    </div>
81dd6b2bfcSGreg Roach</form>
82dd6b2bfcSGreg Roach
83dd6b2bfcSGreg Roach<?php View::push('styles') ?>
84dd6b2bfcSGreg Roach<style>
85dd6b2bfcSGreg Roach    .osm-admin-map {
86dd6b2bfcSGreg Roach        height: 55vh;
87dd6b2bfcSGreg Roach        border: 1px solid darkGrey
88dd6b2bfcSGreg Roach    }
89dd6b2bfcSGreg Roach</style>
90dd6b2bfcSGreg Roach<?php View::endpush() ?>
91dd6b2bfcSGreg Roach
92dd6b2bfcSGreg Roach<?php View::push('javascript') ?>
9374b9ba3fSGreg Roach<script>
94caa53803SDavid Drury    'use strict';
95dd6b2bfcSGreg Roach
96dd6b2bfcSGreg Roach    window.WT_OSM_ADMIN = (function () {
97728c8c27SGreg Roach        const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
98728c8c27SGreg Roach        const add_place = <?= json_encode($location->id() === null, JSON_THROW_ON_ERROR) ?>;
992cbb0620SDavid Drury
10075e7614aSGreg Roach        // postcss_image_inliner breaks the autodetection of image paths.
101728c8c27SGreg Roach        L.Icon.Default.imagePath = <?= json_encode(asset('css/images/'), JSON_THROW_ON_ERROR) ?>;
10275e7614aSGreg Roach
103caa53803SDavid Drury        // draggable marker
104728c8c27SGreg Roach        let marker = L.marker(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>, {
105caa53803SDavid Drury            draggable: true,
106caa53803SDavid Drury        })
1079a9dfcf7SGreg Roach            .on('dragend', function () {
108dd6b2bfcSGreg Roach                let coords = marker.getLatLng();
109dd6b2bfcSGreg Roach                map.panTo(coords);
11062be603fSGreg Roach                $('#new_place_lati').val(Number(coords.lat).toFixed(5));
11162be603fSGreg Roach                $('#new_place_long').val(Number(coords.lng).toFixed(5));
112dd6b2bfcSGreg Roach            });
113dd6b2bfcSGreg Roach
114caa53803SDavid Drury        //reset map to initial state
115caa53803SDavid Drury        let resetControl = L.Control.extend({
116caa53803SDavid Drury            options: {
117caa53803SDavid Drury                position: 'topleft'
118caa53803SDavid Drury            },
119caa53803SDavid Drury            onAdd: function (map) {
120caa53803SDavid Drury                let container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
121caa53803SDavid Drury                container.onclick = function () {
122728c8c27SGreg Roach                    map.fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]});
123728c8c27SGreg Roach                    marker.setLatLng(<?= json_encode([$location->latitude(), $location->longitude()], JSON_THROW_ON_ERROR) ?>);
124caa53803SDavid Drury                    $('form').trigger('reset');
125caa53803SDavid Drury                    return false;
126caa53803SDavid Drury                };
127c9c6f2ecSGreg Roach                let reset = config.i18n.reset;
128caa53803SDavid Drury                let anchor = L.DomUtil.create('a', 'leaflet-control-reset', container);
129caa53803SDavid Drury                anchor.setAttribute('aria-label', reset);
130caa53803SDavid Drury                anchor.href = '#';
131caa53803SDavid Drury                anchor.title = reset;
132caa53803SDavid Drury                anchor.role = 'button';
133caa53803SDavid Drury                let image = L.DomUtil.create('i', 'fas fa-redo', anchor);
134caa53803SDavid Drury                image.alt = reset;
135dd6b2bfcSGreg Roach
136caa53803SDavid Drury                return container;
137caa53803SDavid Drury            }
138caa53803SDavid Drury        });
139dd6b2bfcSGreg Roach
140caa53803SDavid Drury        // Geocoder (place lookup)
141caa53803SDavid Drury        let geocoder = new L.Control.geocoder({
142c9c6f2ecSGreg Roach            position: 'bottomleft',
143caa53803SDavid Drury            defaultMarkGeocode: false,
14422b076ddSGreg Roach            expand: 'click',
145caa53803SDavid Drury            showResultIcons: true,
146728c8c27SGreg Roach            query: <?= json_encode($location->locationName(), JSON_THROW_ON_ERROR) ?>,
147728c8c27SGreg Roach            placeholder: <?= json_encode(I18N::translate('Place'), JSON_THROW_ON_ERROR) ?>,
148728c8c27SGreg Roach            errorMessage: <?= json_encode(I18N::translate('Nothing found.'), JSON_THROW_ON_ERROR) ?>,
149728c8c27SGreg Roach            iconLabel: <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>
150caa53803SDavid Drury        })
151caa53803SDavid Drury            .on('markgeocode', function (result) {
152caa53803SDavid Drury                let coords = result.geocode.center;
153164ab4fbSDavid Drury                let place = result.geocode.name.split(',', 1).toString();
154caa53803SDavid Drury                marker.setLatLng(coords);
155caa53803SDavid Drury                map.panTo(coords);
15662be603fSGreg Roach                if (add_place) {
157164ab4fbSDavid Drury                    $('#new_place_name').val(place);
158caa53803SDavid Drury                }
15962be603fSGreg Roach                $('#new_place_lati').val(Number(coords.lat).toFixed(5));
16062be603fSGreg Roach                $('#new_place_long').val(Number(coords.lng).toFixed(5));
16162be603fSGreg Roach            });
162caa53803SDavid Drury
163caa53803SDavid Drury        /**
164caa53803SDavid Drury         * @private
165caa53803SDavid Drury         */
166dd6b2bfcSGreg Roach        $(function () {
167caa53803SDavid Drury            // geocoder button tooltip
168caa53803SDavid Drury            $('.leaflet-control-geocoder-icon')
169728c8c27SGreg Roach                .attr('title', <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>);
170caa53803SDavid Drury
1719a9dfcf7SGreg Roach            $('.editable').on('change', function () {
172caa53803SDavid Drury                let lat = $('#new_place_lati').val();
173caa53803SDavid Drury                let lng = $('#new_place_long').val();
174dd6b2bfcSGreg Roach                marker.setLatLng([lat, lng]);
175dd6b2bfcSGreg Roach                map.panTo([lat, lng]);
176dd6b2bfcSGreg Roach            });
177dd6b2bfcSGreg Roach        });
178dd6b2bfcSGreg Roach
179c9c6f2ecSGreg Roach      const map = webtrees.buildLeafletJsMap('osm-map', config)
180caa53803SDavid Drury            .addControl(new resetControl())
181caa53803SDavid Drury            .addControl(geocoder)
182caa53803SDavid Drury            .addLayer(marker)
183728c8c27SGreg Roach            .fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]})
1849a9dfcf7SGreg Roach            .on('zoomend', function () {
185d3a6a36aSGreg Roach              if (!map.getBounds().contains(marker.getLatLng())) {
186d3a6a36aSGreg Roach                map.panTo(marker.getLatLng());
187d3a6a36aSGreg Roach              }
188caa53803SDavid Drury            });
189dd6b2bfcSGreg Roach
190caa53803SDavid Drury        return 'Leaflet map interface for webtrees-2';
191dd6b2bfcSGreg Roach    })();
192dd6b2bfcSGreg Roach</script>
193dd6b2bfcSGreg Roach<?php View::endpush() ?>
194