xref: /webtrees/resources/views/admin/location-edit.phtml (revision 75f2a4831adecfe14c5b50312beb437d05654f96)
1d70512abSGreg Roach<?php
2d70512abSGreg Roach
310e06497SGreg Roachdeclare(strict_types=1);
410e06497SGreg Roach
590949315SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\MapDataSave;
6d70512abSGreg Roachuse Fisharebest\Webtrees\I18N;
79a9dfcf7SGreg Roachuse Fisharebest\Webtrees\PlaceLocation;
8d70512abSGreg Roachuse Fisharebest\Webtrees\View;
9d70512abSGreg Roach
109a9dfcf7SGreg Roach/**
119a9dfcf7SGreg Roach * @var array<string,string> $breadcrumbs
129a9dfcf7SGreg Roach * @var string               $latitude
13c9c6f2ecSGreg Roach * @var object               $leaflet_config
149a9dfcf7SGreg Roach * @var string               $longitude
159a9dfcf7SGreg Roach * @var PlaceLocation        $location
169a9dfcf7SGreg Roach * @var array<array<float>>  $map_bounds
1790949315SGreg Roach * @var array<float>         $marker_position
189a9dfcf7SGreg Roach * @var PlaceLocation        $parent
199a9dfcf7SGreg Roach * @var string               $title
200e54db38SGreg Roach * @var string               $url
219a9dfcf7SGreg Roach */
229a9dfcf7SGreg Roach
23d70512abSGreg Roach?>
24dd6b2bfcSGreg Roach
25dd6b2bfcSGreg Roach<?= view('components/breadcrumbs', ['links' => $breadcrumbs]) ?>
26dd6b2bfcSGreg Roach
27dd6b2bfcSGreg Roach<h1><?= $title ?></h1>
28dd6b2bfcSGreg Roach
29d43b95f5SGreg Roach<div class="row wt-location-edit-wrapper wt-fullscreen-container">
30*75f2a483SDavid Drury    <div id="wt-map" class="col-sm-9 wt-ajax-load wt-map" dir="ltr"></div>
316c98ae6bSDavid Drury
32*75f2a483SDavid Drury    <div class="col-sm-3 wt-map-sidebar">
332a93faa6SGreg Roach        <form method="post" action="<?= e(route(MapDataSave::class)) ?>">
340e54db38SGreg Roach            <input type="hidden" name="parent_id" value="<?= $parent->id() ?>">
350e54db38SGreg Roach            <input type="hidden" name="place_id" value="<?= $location->id() ?>">
360e54db38SGreg Roach            <input type="hidden" name="url" value="<?= e($url) ?>">
37dd6b2bfcSGreg Roach
38d43b95f5SGreg Roach            <label class="col-form-label col-sm-6" for="new_place_name">
39dd6b2bfcSGreg Roach                <?= I18N::translate('Place') ?>
40dd6b2bfcSGreg Roach            </label>
417dca5265SGreg 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">
42dd6b2bfcSGreg Roach
43d43b95f5SGreg Roach            <label class="col-form-label col-sm-6" for="new_place_lati">
44dd6b2bfcSGreg Roach                <?= I18N::translate('Latitude') ?>
45dd6b2bfcSGreg Roach            </label>
46dd6b2bfcSGreg Roach            <div class="input-group">
4790949315SGreg 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) ?>">
48dd6b2bfcSGreg Roach            </div>
49dd6b2bfcSGreg Roach
50d43b95f5SGreg Roach            <label class="col-form-label" for="new_place_long">
51dd6b2bfcSGreg Roach                <?= I18N::translate('Longitude') ?>
52dd6b2bfcSGreg Roach            </label>
53dd6b2bfcSGreg Roach            <div class="input-group">
5490949315SGreg 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) ?>">
55dd6b2bfcSGreg Roach            </div>
56dd6b2bfcSGreg Roach
57d43b95f5SGreg Roach            <div class="mt-3">
58dd6b2bfcSGreg Roach                <button class="btn btn-primary" type="submit">
59dd6b2bfcSGreg Roach                    <?= /* I18N: A button label. */
60dd6b2bfcSGreg Roach                    I18N::translate('save')
61dd6b2bfcSGreg Roach                    ?>
62dd6b2bfcSGreg Roach                </button>
630e54db38SGreg Roach                <a class="btn btn-secondary" href="<?= e($url) ?>">
64dd6b2bfcSGreg Roach                    <?= I18N::translate('cancel') ?>
65dd6b2bfcSGreg Roach                </a>
66dd6b2bfcSGreg Roach            </div>
6781443e3cSGreg Roach
6881443e3cSGreg Roach            <?= csrf_field() ?>
69dd6b2bfcSGreg Roach        </form>
70d43b95f5SGreg Roach    </div>
71d43b95f5SGreg Roach</div>
72dd6b2bfcSGreg Roach
73dd6b2bfcSGreg Roach<?php View::push('javascript') ?>
7474b9ba3fSGreg Roach<script>
75caa53803SDavid Drury  'use strict';
76dd6b2bfcSGreg Roach
7704a72e8fSDavid Drury  (function () {
78728c8c27SGreg Roach    const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
79728c8c27SGreg Roach    const add_place = <?= json_encode($location->id() === null, JSON_THROW_ON_ERROR) ?>;
802cbb0620SDavid Drury
8104a72e8fSDavid Drury    let new_place_lati = document.getElementById('new_place_lati');
8204a72e8fSDavid Drury    let new_place_long = document.getElementById('new_place_long');
8304a72e8fSDavid Drury
8475e7614aSGreg Roach    // postcss_image_inliner breaks the autodetection of image paths.
85728c8c27SGreg Roach    L.Icon.Default.imagePath = <?= json_encode(asset('css/images/'), JSON_THROW_ON_ERROR) ?>;
8675e7614aSGreg Roach
87caa53803SDavid Drury    // draggable marker
88728c8c27SGreg Roach    let marker = L.marker(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>, {
89caa53803SDavid Drury      draggable: true,
90caa53803SDavid Drury    })
919a9dfcf7SGreg Roach    .on('dragend', function () {
92dd6b2bfcSGreg Roach      let coords = marker.getLatLng();
93dd6b2bfcSGreg Roach      map.panTo(coords);
9404a72e8fSDavid Drury      new_place_lati.value = Number(coords.lat).toFixed(5);
9504a72e8fSDavid Drury      new_place_long.value = Number(coords.lng).toFixed(5);
96dd6b2bfcSGreg Roach    });
97dd6b2bfcSGreg Roach
98f352d954SDavid Drury    /**
99f352d954SDavid Drury     * Passed to resetControl to
100f352d954SDavid Drury     * perform necessary reset actions on map
101b2e5f20eSGreg Roach     *
102b2e5f20eSGreg Roach     * @param {Event} event
103f352d954SDavid Drury     */
104b2e5f20eSGreg Roach    let resetCallback = function (event) {
105b2e5f20eSGreg Roach      event.preventDefault();
106728c8c27SGreg Roach      map.fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]});
10760f8717eSDavid Drury      marker.setLatLng(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>);
10804a72e8fSDavid Drury      document.querySelector('form').reset();
109caa53803SDavid Drury    }
110dd6b2bfcSGreg Roach
111caa53803SDavid Drury    // Geocoder (place lookup)
112caa53803SDavid Drury    let geocoder = new L.Control.geocoder({
113c9c6f2ecSGreg Roach      position: 'bottomleft',
114caa53803SDavid Drury      defaultMarkGeocode: false,
11522b076ddSGreg Roach      expand: 'click',
116caa53803SDavid Drury      showResultIcons: true,
117728c8c27SGreg Roach      query: <?= json_encode($location->locationName(), JSON_THROW_ON_ERROR) ?>,
118728c8c27SGreg Roach      placeholder: <?= json_encode(I18N::translate('Place'), JSON_THROW_ON_ERROR) ?>,
119728c8c27SGreg Roach      errorMessage: <?= json_encode(I18N::translate('Nothing found.'), JSON_THROW_ON_ERROR) ?>,
120728c8c27SGreg Roach      iconLabel: <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>
121caa53803SDavid Drury    })
122caa53803SDavid Drury    .on('markgeocode', function (result) {
123caa53803SDavid Drury      let coords = result.geocode.center;
124164ab4fbSDavid Drury      let place = result.geocode.name.split(',', 1).toString();
125caa53803SDavid Drury      marker.setLatLng(coords);
126caa53803SDavid Drury      map.panTo(coords);
12762be603fSGreg Roach      if (add_place) {
12804a72e8fSDavid Drury        document.getElementById('new_place_name').value = place
129caa53803SDavid Drury      }
13004a72e8fSDavid Drury      new_place_lati.value = Number(coords.lat).toFixed(5);
13104a72e8fSDavid Drury      new_place_long.value = Number(coords.lng).toFixed(5);
13262be603fSGreg Roach    });
133caa53803SDavid Drury
134b7b71725SGreg Roach    const map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback)
135caa53803SDavid Drury      .addControl(geocoder)
136caa53803SDavid Drury      .addLayer(marker)
137728c8c27SGreg Roach      .fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]})
1389a9dfcf7SGreg Roach      .on('zoomend', function () {
139d3a6a36aSGreg Roach        if (!map.getBounds().contains(marker.getLatLng())) {
140d3a6a36aSGreg Roach          map.panTo(marker.getLatLng());
141d3a6a36aSGreg Roach        }
142caa53803SDavid Drury    });
143dd6b2bfcSGreg Roach
14404a72e8fSDavid Drury    document.querySelectorAll('.editable').forEach((element) => {
14504a72e8fSDavid Drury      element.addEventListener('change', () => {
14604a72e8fSDavid Drury        let lat = new_place_lati.value;
14704a72e8fSDavid Drury        let lng = new_place_long.value;
14804a72e8fSDavid Drury        marker.setLatLng([lat, lng]);
14904a72e8fSDavid Drury        map.panTo([lat, lng]);
15004a72e8fSDavid Drury      });
15104a72e8fSDavid Drury    });
15204a72e8fSDavid Drury
15304a72e8fSDavid Drury    window.onload = function() {
15404a72e8fSDavid Drury      let icon = document.querySelector('.leaflet-control-geocoder-icon');
15504a72e8fSDavid Drury      icon.setAttribute('title', <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>);
15604a72e8fSDavid Drury    }
157dd6b2bfcSGreg Roach  })();
158dd6b2bfcSGreg Roach</script>
159dd6b2bfcSGreg Roach<?php View::endpush() ?>
160