Skip to content

Commit

Permalink
feat: editable form support and replace jQuery dependancy
Browse files Browse the repository at this point in the history
  • Loading branch information
wilr committed Nov 14, 2024
1 parent aca2c32 commit 550d875
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 69 deletions.
165 changes: 97 additions & 68 deletions client/javascript/addressfinder.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,110 @@
(function ($) {
$(document).ready(function () {
/**
*
* @param {DOMElement} elem
*/
var setupAddressFinderField = function (elem) {
var widget,
key = $(elem).data("api-key"),
address = $(elem).find(".address_finder_address"),
input = $(elem).find("input").first(),
manual = $(elem).find(".manual_address"),
toggle = $(elem).find(".toggle_manual_address");

var useManual = manual.find("input[name*=ManualAddress]"),
field = address.find("input").get(0);

/* update ui with javascript */
toggle.show();
address.show();

if (!useManual.val()) {
manual.hide();
}
document.addEventListener("DOMContentLoaded", function () {
/**
* Sets up the Address Finder field.
* @param {HTMLElement} elem
*/
var setupAddressFinderField = function (elem) {
var widget,
key = elem.getAttribute("data-api-key"),
address = elem.querySelector(".address_finder_address"),
input = elem.querySelector("input"),
manual = elem.querySelector(".manual_address"),
toggle = elem.querySelector(".toggle_manual_address");

if (!$(elem).find(".addressfinder__holder input").length) {
return;
}
/* create widget */
widget = new AddressFinder.Widget(field, key, "NZ", {
container: $(elem).find(".addressfinder__holder").get(0),
});

/* updates manual fields and hidden metadata */
widget.on("result:select", function (value, item) {
/* populate postal line fields */
for (var i = 1; i <= 6; i++) {
manual
.find("input[name*=PostalLine" + i + "]")
.val(item["postal_line_" + i] || "");
}
var useManual = null;
var field = null;

if (manual) {
useManual = manual.querySelector("input[name*=ManualAddress]");
}

if (address) {
field = address.querySelector("input");
}

manual.find("input[name*=Suburb]").val(item.suburb || "");
manual.find("input[name*=Region]").val(item.region || "");
manual.find("input[name*=City]").val(item.city || "");
manual.find("input[name*=Postcode]").val(item.postcode || "");
manual.find("input[name*=Longitude]").val(item.x || "");
manual.find("input[name*=Latitude]").val(item.y || "");
if (!field) {
console.error(
"AddressFinder: Could not find address field in element",
elem
);

$("body").trigger(jQuery.Event("addressselected"));
});
return;
}

/* click handler to toggle manual div */
toggle.on("click", function (e) {
e.preventDefault();
// Update UI
if (toggle) {
toggle.style.display = "block";
}

manual.toggle("slow");
address.style.display = "block";

// if the manual address is visible then add a hidden flag so
if (manual.is(":visible")) {
useManual.val("1");
} else {
useManual.val("0");
if (useManual && useManual.value !== "1") {
manual.style.display = "none";
}

// Create widget
widget = new AddressFinder.Widget(field, key, "NZ", {
container: elem.querySelector(".addressfinder__holder"),
});

// Update manual fields and hidden metadata
widget.on("result:select", function (value, item) {
for (var i = 1; i <= 6; i++) {
var postalInput = manual.querySelector(
"input[name*=PostalLine" + i + "]"
);
if (postalInput) {
postalInput.value = item["postal_line_" + i] || "";
}
}

return false;
});
if (manual) {
manual.querySelector("input[name*=Suburb]").value =
item.suburb || "";
manual.querySelector("input[name*=Region]").value =
item.region || "";
manual.querySelector("input[name*=City]").value =
item.city || "";
manual.querySelector("input[name*=Postcode]").value =
item.postcode || "";
manual.querySelector("input[name*=Longitude]").value =
item.x || "";
manual.querySelector("input[name*=Latitude]").value =
item.y || "";
}

var event = new Event("addressselected", { bubbles: true });
document.body.dispatchEvent(event);
});

// Click handler to toggle manual div
toggle?.addEventListener("click", function (e) {
e.preventDefault();

/* focusing back on the address dropdown should hide the manual */
input.on("focus", function (e) {
manual.slideUp();
});
};
if (
manual.style.display === "none" ||
manual.style.display === ""
) {
manual.style.display = "block";
useManual.value = "1";
} else {
manual.style.display = "none";
useManual.value = "0";
}

return false;
});

$(".address_finder").each(function (i, elem) {
setupAddressFinderField(elem);
// Focus event to hide manual
input?.addEventListener("focus", function () {
manual.style.display = "none";
});
};

window.setupAddressFinderField = setupAddressFinderField;
var addressFinderElements = document.querySelectorAll(".address_finder");
addressFinderElements.forEach(function (elem) {
setupAddressFinderField(elem);
});
})(jQuery);

window.setupAddressFinderField = setupAddressFinderField;
});
10 changes: 9 additions & 1 deletion src/AddressFinderField.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\View\Requirements;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Environment;

/**
* A wrapper for the AddressFinder API.
Expand Down Expand Up @@ -281,7 +282,14 @@ public function FieldHolder($properties = array())
*/
public function getApiKey()
{
return Config::inst()->get(AddressFinderField::class, 'api_key');
$key = $this->config()->get('api_key');

// if the key is inside backticks then it's a constant and we need to load via Environment
if (preg_match('/`(.*)`/', $key, $matches)) {
$key = Environment::getEnv($matches[1]);
}

return $key;
}

/**
Expand Down
61 changes: 61 additions & 0 deletions src/EditableAddressFinderField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace FullscreenInteractive\SilverStripe;

use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\FieldList;
use SilverStripe\UserForms\Model\EditableFormField;


if (class_exists(EditableFormField::class)) {
return;
}

class EditableAddressFinderField extends EditableFormField
{
private static $singular_name = 'AddressFinder Field';

private static $plural_name = 'AddressFinder Fields';

private static $table_name = 'EditableAddressFinderField';

private static $db = [
'ShowManualFields' => 'Boolean',
];

/**
* @return FieldList
*/
public function getCMSFields()
{
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->addFieldToTab(
'Root.Main',
CheckboxField::create(
'ShowManualFields',
_t('SilverStripe\\UserForms\\Model\\EditableFormField.SHOWMANUALFIELDS', 'Show manual fields?')
)
);
});

return parent::getCMSFields();
}


public function getFormField()
{
$field = AddressFinderField::create($this->Name, $this->Title ?: false)
->setFieldHolderTemplate('EditableAddressFinderField_holder')
->setTemplate(EditableFormField::class);

if ($this->ShowManualFields) {
$field->setShowManualFields(true);
} else {
$field->setShowManualFields(false);
}

$this->doUpdateFormField($field);

return $field;
}
}
39 changes: 39 additions & 0 deletions templates/EditableAddressFinderField_holder.ss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<div id="$Name" class="field form-group mb-3<% if $extraClass %> $extraClass<% end_if %><% if $Message %> is-invalid<% end_if %>">
<div class="address_finder" data-api-key="$ApiKey">
<div id="$Name" class="address_finder_address form-group field text<% if $extraClass %> $extraClass<% end_if %>" style="display: none;">
<% if $Title %><label class="form__field-label" for="$ID">$Title</label><% end_if %>

<div class="form__field-holder">
<div class="addressfinder__holder" style="position: relative">
$AddressField
</div>

<% if $Message %><span class="message $MessageType">$Message</span><% end_if %>
<% if $Description %><p class="form__field-description">$Description</p><% end_if %>

<div class='address_finder_attribution'>
<p><a href='http://addressfinder.co.nz'>AddressFinder</a> provided by <a href='http://www.abletech.co.nz/'>Able Technology</a></p>
</div>

<% if ShowManualFields %>
<div class="toggle_manual_address" style="display: none">
<p><a href="#"><% _t('AddressFinderField.ENTERMANUAL', 'Or, enter your address manually') %></a></p>
</div>
<% end_if %>
</div>

<% if $RightTitle %><p class="form__field-extra-label" id="extra-label-$ID">$RightTitle</p><% end_if %>
</div>

<% if ShowManualFields %>

<div class="manual_address">
$ManualToggleField

<% loop ManualAddressFields %>
$FieldHolder
<% end_loop %>
</div>
<% end_if %>
</div>
</div>

0 comments on commit 550d875

Please sign in to comment.