xref: /webtrees/resources/views/admin/location-edit.phtml (revision 9e3c2cf9009c4c2140f50ddfc80b91f2f82cdce5)
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
2784df6051SGreg Roach<div id="wt-map" class="wt-ajax-load mb-3 border wt-location-edit-map" dir="ltr"></div>
28dd6b2bfcSGreg Roach
292a93faa6SGreg Roach<form method="post" action="<?= e(route(MapDataSave::class)) ?>">
30dd6b2bfcSGreg Roach    <?= csrf_field() ?>
312a93faa6SGreg Roach    <input type="hidden" name="parent_id" value="<?= e($parent->id()) ?>">
322a93faa6SGreg Roach    <input type="hidden" name="place_id" value="<?= e($location->id()) ?>">
33dd6b2bfcSGreg Roach
34*9e3c2cf9SGreg Roach    <div class="row mb-3">
35dd6b2bfcSGreg Roach        <label class="col-form-label col-sm-1" for="new_place_name">
36dd6b2bfcSGreg Roach            <?= I18N::translate('Place') ?>
37dd6b2bfcSGreg Roach        </label>
38e340fe65SGreg Roach        <div class="col-sm-3">
397dca5265SGreg 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">
40dd6b2bfcSGreg Roach        </div>
41dd6b2bfcSGreg Roach    </div>
42dd6b2bfcSGreg Roach
43*9e3c2cf9SGreg Roach    <div class="row mb-3">
4456a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_lati">
45dd6b2bfcSGreg Roach            <?= I18N::translate('Latitude') ?>
46dd6b2bfcSGreg Roach        </label>
47dd6b2bfcSGreg Roach        <div class="col-sm-3">
48dd6b2bfcSGreg Roach            <div class="input-group">
4990949315SGreg 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) ?>">
50dd6b2bfcSGreg Roach            </div>
51dd6b2bfcSGreg Roach        </div>
52e340fe65SGreg Roach    </div>
53dd6b2bfcSGreg Roach
54*9e3c2cf9SGreg Roach    <div class="row mb-3">
5556a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_long">
56dd6b2bfcSGreg Roach            <?= I18N::translate('Longitude') ?>
57dd6b2bfcSGreg Roach        </label>
58dd6b2bfcSGreg Roach        <div class="col-sm-3">
59dd6b2bfcSGreg Roach            <div class="input-group">
6090949315SGreg 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) ?>">
61dd6b2bfcSGreg Roach            </div>
62dd6b2bfcSGreg Roach        </div>
63dd6b2bfcSGreg Roach    </div>
64dd6b2bfcSGreg Roach
65*9e3c2cf9SGreg Roach    <div class="row mb-3">
66dd6b2bfcSGreg Roach        <div class="col-sm-10 offset-sm-1">
67dd6b2bfcSGreg Roach            <button class="btn btn-primary" type="submit">
68dd6b2bfcSGreg Roach                <?= /* I18N: A button label. */
69dd6b2bfcSGreg Roach                I18N::translate('save')
70dd6b2bfcSGreg Roach                ?>
71dd6b2bfcSGreg Roach            </button>
7294e35917SGreg Roach            <a class="btn btn-secondary" href="<?= e(route(MapDataList::class, ['parent_id' => $parent->id()])) ?>">
73dd6b2bfcSGreg Roach                <?= I18N::translate('cancel') ?>
74dd6b2bfcSGreg Roach            </a>
75dd6b2bfcSGreg Roach        </div>
76dd6b2bfcSGreg Roach    </div>
77dd6b2bfcSGreg Roach</form>
78dd6b2bfcSGreg Roach
79dd6b2bfcSGreg Roach<?php View::push('javascript') ?>
8074b9ba3fSGreg Roach<script>
81caa53803SDavid Drury  'use strict';
82dd6b2bfcSGreg Roach
8304a72e8fSDavid Drury  (function () {
84728c8c27SGreg Roach    const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
85728c8c27SGreg Roach    const add_place = <?= json_encode($location->id() === null, JSON_THROW_ON_ERROR) ?>;
862cbb0620SDavid Drury
8704a72e8fSDavid Drury    let new_place_lati = document.getElementById('new_place_lati');
8804a72e8fSDavid Drury    let new_place_long = document.getElementById('new_place_long');
8904a72e8fSDavid Drury
9075e7614aSGreg Roach    // postcss_image_inliner breaks the autodetection of image paths.
91728c8c27SGreg Roach    L.Icon.Default.imagePath = <?= json_encode(asset('css/images/'), JSON_THROW_ON_ERROR) ?>;
9275e7614aSGreg Roach
93caa53803SDavid Drury    // draggable marker
94728c8c27SGreg Roach    let marker = L.marker(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>, {
95caa53803SDavid Drury      draggable: true,
96caa53803SDavid Drury    })
979a9dfcf7SGreg Roach    .on('dragend', function () {
98dd6b2bfcSGreg Roach      let coords = marker.getLatLng();
99dd6b2bfcSGreg Roach      map.panTo(coords);
10004a72e8fSDavid Drury      new_place_lati.value = Number(coords.lat).toFixed(5);
10104a72e8fSDavid Drury      new_place_long.value = Number(coords.lng).toFixed(5);
102dd6b2bfcSGreg Roach    });
103dd6b2bfcSGreg Roach
104f352d954SDavid Drury    /**
105f352d954SDavid Drury     * Passed to resetControl to
106f352d954SDavid Drury     * perform necessary reset actions on map
107f352d954SDavid Drury     */
108b7b71725SGreg Roach     let resetCallback = function () {
109728c8c27SGreg Roach      map.fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]});
11060f8717eSDavid Drury      marker.setLatLng(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>);
11104a72e8fSDavid Drury      document.querySelector('form').reset();
112caa53803SDavid Drury    }
113dd6b2bfcSGreg Roach
114caa53803SDavid Drury    // Geocoder (place lookup)
115caa53803SDavid Drury    let geocoder = new L.Control.geocoder({
116c9c6f2ecSGreg Roach      position: 'bottomleft',
117caa53803SDavid Drury      defaultMarkGeocode: false,
11822b076ddSGreg Roach      expand: 'click',
119caa53803SDavid Drury      showResultIcons: true,
120728c8c27SGreg Roach      query: <?= json_encode($location->locationName(), JSON_THROW_ON_ERROR) ?>,
121728c8c27SGreg Roach      placeholder: <?= json_encode(I18N::translate('Place'), JSON_THROW_ON_ERROR) ?>,
122728c8c27SGreg Roach      errorMessage: <?= json_encode(I18N::translate('Nothing found.'), JSON_THROW_ON_ERROR) ?>,
123728c8c27SGreg Roach      iconLabel: <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>
124caa53803SDavid Drury    })
125caa53803SDavid Drury    .on('markgeocode', function (result) {
126caa53803SDavid Drury      let coords = result.geocode.center;
127164ab4fbSDavid Drury      let place = result.geocode.name.split(',', 1).toString();
128caa53803SDavid Drury      marker.setLatLng(coords);
129caa53803SDavid Drury      map.panTo(coords);
13062be603fSGreg Roach      if (add_place) {
13104a72e8fSDavid Drury        document.getElementById('new_place_name').value = place
132caa53803SDavid Drury      }
13304a72e8fSDavid Drury      new_place_lati.value = Number(coords.lat).toFixed(5);
13404a72e8fSDavid Drury      new_place_long.value = Number(coords.lng).toFixed(5);
13562be603fSGreg Roach    });
136caa53803SDavid Drury
137b7b71725SGreg Roach    const map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback)
138caa53803SDavid Drury      .addControl(geocoder)
139caa53803SDavid Drury      .addLayer(marker)
140728c8c27SGreg Roach      .fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]})
1419a9dfcf7SGreg Roach      .on('zoomend', function () {
142d3a6a36aSGreg Roach        if (!map.getBounds().contains(marker.getLatLng())) {
143d3a6a36aSGreg Roach          map.panTo(marker.getLatLng());
144d3a6a36aSGreg Roach        }
145caa53803SDavid Drury    });
146dd6b2bfcSGreg Roach
14704a72e8fSDavid Drury    document.querySelectorAll('.editable').forEach((element) => {
14804a72e8fSDavid Drury      element.addEventListener('change', () => {
14904a72e8fSDavid Drury        let lat = new_place_lati.value;
15004a72e8fSDavid Drury        let lng = new_place_long.value;
15104a72e8fSDavid Drury        marker.setLatLng([lat, lng]);
15204a72e8fSDavid Drury        map.panTo([lat, lng]);
15304a72e8fSDavid Drury      });
15404a72e8fSDavid Drury    });
15504a72e8fSDavid Drury
15604a72e8fSDavid Drury    window.onload = function() {
15704a72e8fSDavid Drury      let icon = document.querySelector('.leaflet-control-geocoder-icon');
15804a72e8fSDavid Drury      icon.setAttribute('title', <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>);
15904a72e8fSDavid Drury    }
160dd6b2bfcSGreg Roach  })();
161dd6b2bfcSGreg Roach</script>
162dd6b2bfcSGreg Roach<?php View::endpush() ?>
163