Skip to content

Commit 00f81fd

Browse files
committed
FormBuilder form field for selecting a map location using Google Maps
Closes #6309
1 parent 38076b3 commit 00f81fd

File tree

4 files changed

+163
-0
lines changed

4 files changed

+163
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{capture assign='googleMapsElementID'}{$field->getPrefixedId()}_map{/capture}
2+
{include file='shared_googleMapsElement' accessUserLocation=true googleMapsLat=$field->getLatitude() googleMapsLng=$field->getLongitude()}
3+
4+
<input
5+
type="text"
6+
id="{$field->getPrefixedId()}"
7+
name="{$field->getPrefixedId()}"
8+
{if !$field->getFieldClasses()|empty} class="{implode from=$field->getFieldClasses() item='class' glue=' '}{$class}{/implode}"{/if}
9+
value="{$field->getValue()}"
10+
{if $field->isAutofocused()} autofocus{/if}
11+
{if $field->isRequired()} required{/if}
12+
{if $field->isImmutable()} disabled{/if}
13+
{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}
14+
{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}
15+
{foreach from=$field->getFieldAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}
16+
data-google-maps-geocoding="{$googleMapsElementID}"
17+
data-google-maps-geocoding-store="{$field->getPrefixedId()}_"
18+
data-google-maps-marker
19+
>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Data handler for a Google Maps form builder field in an Ajax form.
3+
*
4+
* @author Marcel Werk
5+
* @copyright 2001-2025 WoltLab GmbH
6+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
7+
* @since 6.2
8+
*/
9+
import { FormBuilderData } from "../Data";
10+
import Value from "./Value";
11+
import type WoltlabCoreGoogleMapsElement from "WoltLabSuite/Core/Component/GoogleMaps/woltlab-core-google-maps";
12+
13+
class GoogleMaps extends Value {
14+
protected _getData(): FormBuilderData {
15+
const map = document.getElementById(this._fieldId + "_map") as WoltlabCoreGoogleMapsElement;
16+
17+
return {
18+
[this._fieldId]: (this._field as HTMLInputElement).value,
19+
[this._fieldId + "_coordinates"]: `${map.lat},${map.lng}`,
20+
};
21+
}
22+
}
23+
24+
export = GoogleMaps;

wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/GoogleMaps.js

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\field;
4+
5+
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
6+
use wcf\system\form\builder\IFormDocument;
7+
8+
/**
9+
* Implementation of a form field for selecting map coordinates.
10+
*
11+
* @author Marcel Werk
12+
* @copyright 2001-2025 WoltLab GmbH
13+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14+
* @since 6.2
15+
*/
16+
final class GoogleMapsFormField extends AbstractFormField implements
17+
IAttributeFormField,
18+
IAutoFocusFormField,
19+
ICssClassFormField,
20+
IImmutableFormField,
21+
IPlaceholderFormField
22+
{
23+
use TAttributeFormField;
24+
use TAutoFocusFormField;
25+
use TCssClassFormField;
26+
use TImmutableFormField;
27+
use TPlaceholderFormField;
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
protected $javaScriptDataHandlerModule = 'WoltLabSuite/Core/Form/Builder/Field/GoogleMaps';
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
protected $templateName = 'shared_googleMapsFormField';
38+
39+
private float $latitude = 0;
40+
private float $longitude = 0;
41+
42+
public function __construct()
43+
{
44+
$this->addFieldClass('long');
45+
}
46+
47+
#[\Override]
48+
public function readValue()
49+
{
50+
if ($this->getDocument()->hasRequestData($this->getPrefixedId())) {
51+
$this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
52+
}
53+
54+
if ($this->getDocument()->hasRequestData($this->getPrefixedId() . '_coordinates')) {
55+
$coordinates = explode(',', $this->getDocument()->getRequestData(
56+
$this->getPrefixedId() . '_coordinates'
57+
));
58+
if (\count($coordinates) === 2) {
59+
$this->latitude = \floatval($coordinates[0]);
60+
$this->longitude = \floatval($coordinates[1]);
61+
}
62+
}
63+
64+
return $this;
65+
}
66+
67+
#[\Override]
68+
public function populate()
69+
{
70+
parent::populate();
71+
72+
$this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor(
73+
'coordinates',
74+
function (IFormDocument $document, array $parameters) {
75+
if ($this->getValue()) {
76+
$parameters[$this->getPrefixedId() . '_coordinates'] = [
77+
'latitude' => $this->getLatitude(),
78+
'longitude' => $this->getLongitude(),
79+
];
80+
}
81+
82+
return $parameters;
83+
}
84+
));
85+
86+
return $this;
87+
}
88+
89+
public function getLatitude(): float
90+
{
91+
return $this->latitude;
92+
}
93+
94+
public function getLongitude(): float
95+
{
96+
return $this->longitude;
97+
}
98+
99+
public function coordinates(float $latitude, float $longitude): static
100+
{
101+
$this->latitude = $latitude;
102+
$this->longitude = $longitude;
103+
104+
return $this;
105+
}
106+
}

0 commit comments

Comments
 (0)