xref: /webtrees/resources/views/admin/location-edit.phtml (revision 81443e3cbe4eef5ccdcf8dae716a7e35f7417b60)
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)) ?>">
302a93faa6SGreg Roach    <input type="hidden" name="parent_id" value="<?= e($parent->id()) ?>">
312a93faa6SGreg Roach    <input type="hidden" name="place_id" value="<?= e($location->id()) ?>">
32dd6b2bfcSGreg Roach
339e3c2cf9SGreg Roach    <div class="row mb-3">
34dd6b2bfcSGreg Roach        <label class="col-form-label col-sm-1" for="new_place_name">
35dd6b2bfcSGreg Roach            <?= I18N::translate('Place') ?>
36dd6b2bfcSGreg Roach        </label>
37e340fe65SGreg Roach        <div class="col-sm-3">
387dca5265SGreg 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">
39dd6b2bfcSGreg Roach        </div>
40dd6b2bfcSGreg Roach    </div>
41dd6b2bfcSGreg Roach
429e3c2cf9SGreg Roach    <div class="row mb-3">
4356a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_lati">
44dd6b2bfcSGreg Roach            <?= I18N::translate('Latitude') ?>
45dd6b2bfcSGreg Roach        </label>
46dd6b2bfcSGreg Roach        <div class="col-sm-3">
47dd6b2bfcSGreg Roach            <div class="input-group">
4890949315SGreg 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) ?>">
49dd6b2bfcSGreg Roach            </div>
50dd6b2bfcSGreg Roach        </div>
51e340fe65SGreg Roach    </div>
52dd6b2bfcSGreg Roach
539e3c2cf9SGreg Roach    <div class="row mb-3">
5456a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_long">
55dd6b2bfcSGreg Roach            <?= I18N::translate('Longitude') ?>
56dd6b2bfcSGreg Roach        </label>
57dd6b2bfcSGreg Roach        <div class="col-sm-3">
58dd6b2bfcSGreg Roach            <div class="input-group">
5990949315SGreg 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) ?>">
60dd6b2bfcSGreg Roach            </div>
61dd6b2bfcSGreg Roach        </div>
62dd6b2bfcSGreg Roach    </div>
63dd6b2bfcSGreg Roach
649e3c2cf9SGreg Roach    <div class="row mb-3">
65dd6b2bfcSGreg Roach        <div class="col-sm-10 offset-sm-1">
66dd6b2bfcSGreg Roach            <button class="btn btn-primary" type="submit">
67dd6b2bfcSGreg Roach                <?= /* I18N: A button label. */
68dd6b2bfcSGreg Roach                I18N::translate('save')
69dd6b2bfcSGreg Roach                ?>
70dd6b2bfcSGreg Roach            </button>
7194e35917SGreg Roach            <a class="btn btn-secondary" href="<?= e(route(MapDataList::class, ['parent_id' => $parent->id()])) ?>">
72dd6b2bfcSGreg Roach                <?= I18N::translate('cancel') ?>
73dd6b2bfcSGreg Roach            </a>
74dd6b2bfcSGreg Roach        </div>
75dd6b2bfcSGreg Roach    </div>
76*81443e3cSGreg Roach
77*81443e3cSGreg Roach    <?= csrf_field() ?>
78dd6b2bfcSGreg Roach</form>
79dd6b2bfcSGreg Roach
80dd6b2bfcSGreg Roach<?php View::push('javascript') ?>
8174b9ba3fSGreg Roach<script>
82caa53803SDavid Drury  'use strict';
83dd6b2bfcSGreg Roach
8404a72e8fSDavid Drury  (function () {
85728c8c27SGreg Roach    const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
86728c8c27SGreg Roach    const add_place = <?= json_encode($location->id() === null, JSON_THROW_ON_ERROR) ?>;
872cbb0620SDavid Drury
8804a72e8fSDavid Drury    let new_place_lati = document.getElementById('new_place_lati');
8904a72e8fSDavid Drury    let new_place_long = document.getElementById('new_place_long');
9004a72e8fSDavid Drury
9175e7614aSGreg Roach    // postcss_image_inliner breaks the autodetection of image paths.
92728c8c27SGreg Roach    L.Icon.Default.imagePath = <?= json_encode(asset('css/images/'), JSON_THROW_ON_ERROR) ?>;
9375e7614aSGreg Roach
94caa53803SDavid Drury    // draggable marker
95728c8c27SGreg Roach    let marker = L.marker(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>, {
96caa53803SDavid Drury      draggable: true,
97caa53803SDavid Drury    })
989a9dfcf7SGreg Roach    .on('dragend', function () {
99dd6b2bfcSGreg Roach      let coords = marker.getLatLng();
100dd6b2bfcSGreg Roach      map.panTo(coords);
10104a72e8fSDavid Drury      new_place_lati.value = Number(coords.lat).toFixed(5);
10204a72e8fSDavid Drury      new_place_long.value = Number(coords.lng).toFixed(5);
103dd6b2bfcSGreg Roach    });
104dd6b2bfcSGreg Roach
105f352d954SDavid Drury    /**
106f352d954SDavid Drury     * Passed to resetControl to
107f352d954SDavid Drury     * perform necessary reset actions on map
108f352d954SDavid Drury     */
109b7b71725SGreg Roach     let resetCallback = function () {
110728c8c27SGreg Roach      map.fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]});
11160f8717eSDavid Drury      marker.setLatLng(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>);
11204a72e8fSDavid Drury      document.querySelector('form').reset();
113caa53803SDavid Drury    }
114dd6b2bfcSGreg Roach
115caa53803SDavid Drury    // Geocoder (place lookup)
116caa53803SDavid Drury    let geocoder = new L.Control.geocoder({
117c9c6f2ecSGreg Roach      position: 'bottomleft',
118caa53803SDavid Drury      defaultMarkGeocode: false,
11922b076ddSGreg Roach      expand: 'click',
120caa53803SDavid Drury      showResultIcons: true,
121728c8c27SGreg Roach      query: <?= json_encode($location->locationName(), JSON_THROW_ON_ERROR) ?>,
122728c8c27SGreg Roach      placeholder: <?= json_encode(I18N::translate('Place'), JSON_THROW_ON_ERROR) ?>,
123728c8c27SGreg Roach      errorMessage: <?= json_encode(I18N::translate('Nothing found.'), JSON_THROW_ON_ERROR) ?>,
124728c8c27SGreg Roach      iconLabel: <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>
125caa53803SDavid Drury    })
126caa53803SDavid Drury    .on('markgeocode', function (result) {
127caa53803SDavid Drury      let coords = result.geocode.center;
128164ab4fbSDavid Drury      let place = result.geocode.name.split(',', 1).toString();
129caa53803SDavid Drury      marker.setLatLng(coords);
130caa53803SDavid Drury      map.panTo(coords);
13162be603fSGreg Roach      if (add_place) {
13204a72e8fSDavid Drury        document.getElementById('new_place_name').value = place
133caa53803SDavid Drury      }
13404a72e8fSDavid Drury      new_place_lati.value = Number(coords.lat).toFixed(5);
13504a72e8fSDavid Drury      new_place_long.value = Number(coords.lng).toFixed(5);
13662be603fSGreg Roach    });
137caa53803SDavid Drury
138b7b71725SGreg Roach    const map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback)
139caa53803SDavid Drury      .addControl(geocoder)
140caa53803SDavid Drury      .addLayer(marker)
141728c8c27SGreg Roach      .fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]})
1429a9dfcf7SGreg Roach      .on('zoomend', function () {
143d3a6a36aSGreg Roach        if (!map.getBounds().contains(marker.getLatLng())) {
144d3a6a36aSGreg Roach          map.panTo(marker.getLatLng());
145d3a6a36aSGreg Roach        }
146caa53803SDavid Drury    });
147dd6b2bfcSGreg Roach
14804a72e8fSDavid Drury    document.querySelectorAll('.editable').forEach((element) => {
14904a72e8fSDavid Drury      element.addEventListener('change', () => {
15004a72e8fSDavid Drury        let lat = new_place_lati.value;
15104a72e8fSDavid Drury        let lng = new_place_long.value;
15204a72e8fSDavid Drury        marker.setLatLng([lat, lng]);
15304a72e8fSDavid Drury        map.panTo([lat, lng]);
15404a72e8fSDavid Drury      });
15504a72e8fSDavid Drury    });
15604a72e8fSDavid Drury
15704a72e8fSDavid Drury    window.onload = function() {
15804a72e8fSDavid Drury      let icon = document.querySelector('.leaflet-control-geocoder-icon');
15904a72e8fSDavid Drury      icon.setAttribute('title', <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>);
16004a72e8fSDavid Drury    }
161dd6b2bfcSGreg Roach  })();
162dd6b2bfcSGreg Roach</script>
163dd6b2bfcSGreg Roach<?php View::endpush() ?>
164