From 01e9a8e40351a87f6548a4f55de842d6f6918ad0 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 15 Sep 2026 02:44:28 +0000
Subject: [PATCH] =Found little glitch with auto-adding rewrite rules to taxonomy Registrar instances where we have the post type as the base in the url rewrite
---
assets/js/concise/FormController.js | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 154 insertions(+), 10 deletions(-)
diff --git a/assets/js/concise/FormController.js b/assets/js/concise/FormController.js
index e5f3868..bd245ce 100644
--- a/assets/js/concise/FormController.js
+++ b/assets/js/concise/FormController.js
@@ -10,6 +10,7 @@
this.inputs = new Map();
this.repeaters = new Map();
this.tagLists = new Map();
+ this.locations = new Map();
this.charLimits = new Map();
this.quantityFields = new Map();
this.quillInstances = new Map(); // formId -> Set of quill instances
@@ -23,6 +24,7 @@
this.summaryTemplate = false;
this.init();
+
}
init() {
this.templates = window.jvbTemplates;
@@ -104,6 +106,14 @@
inputs: this.inputSelectors, //querySelectorAll
value: 'input[type="hidden"]' //querySelectorAll
},
+ location: {
+ location: '[data-field-type="location"]', //querySelectorAll
+ search: '[data-location-search]',
+ results: '.search-results',
+ message: '.message',
+ preview: '.location-preview',
+ fields: 'fieldset.location input',
+ },
tag: {
label: '.tag-label'
},
@@ -418,6 +428,7 @@
}
let form = this.getForm(e.target);
+ console.log(this.getFieldValue(e.target), 'value');
this.updateItem(field.dataset.field, this.getFieldValue(e.target), form);
}
@@ -506,6 +517,9 @@
* @param form
*/
updateItem(name, value, form) {
+ console.log('Updating field');
+ console.log(name,'name');
+ console.log(value,'value');
if (value === undefined) return;
if (!this.changes.has(form.id)) {
this.changes.set(form.id, {
@@ -853,7 +867,8 @@
repeater: this.repeaters,
tagList: this.tagLists,
charLimit: this.charLimits,
- quantity: this.quantityFields
+ quantity: this.quantityFields,
+ location: this.locations
};
for (let [type, check] of Object.entries(checks)) {
if (check.size === 0) continue;
@@ -873,6 +888,9 @@
case 'quantity':
this.removeQuantityListeners(item.element);
break;
+ case 'location':
+ this.removeLocationListeners(item.element);
+ break;
}
if (check.has(item.id)) {
@@ -963,6 +981,7 @@
initializeFields(container, config = null) {
const fieldHandlers = {
'[data-editor]': () => this.checkForQuill(container,config),
+ '[data-field-type="location"]': () => this.checkForLocationFields(container, config),
'div.quantity': () => this.checkForQuantity(container),
'.repeater': () => this.checkForRepeaters(container, config),
'.field.tag-list': () => this.checkForTagLists(container),
@@ -1336,6 +1355,127 @@
}
+ checkForLocationFields(form, config) {
+ form.querySelectorAll(this.selectors.location.location).forEach(field => {
+ let ui = window.uiFromSelectors(this.selectors.location, field);
+ if (!ui.search) return;
+
+ ui.fields = {};
+ field.querySelectorAll(this.selectors.location.fields).forEach(f => {
+ ui.fields[f.dataset.fieldName] = f;
+ });
+
+ let id = window.generateID('location');
+ field.dataset.locationId = id;
+
+ this.locations.set(id, {
+ id: id,
+ form: config?.id,
+ element: field,
+ ui: ui,
+ results: []
+ });
+
+ this.addLocationListeners(field);
+ });
+ }
+ addLocationListeners(el) {
+ el.addEventListener('input', this.locationInputHandler ??= this.handleLocationInput.bind(this));
+ el.addEventListener('click', this.locationClickHandler ??= this.handleLocationClick.bind(this));
+ }
+ removeLocationListeners(el) {
+ el.removeEventListener('input', this.locationInputHandler);
+ el.removeEventListener('click', this.locationClickHandler);
+ }
+ handleLocationInput(e) {
+ if (!e.target.matches(this.selectors.location.search)) return;
+ let field = e.target.closest('[data-location-id]');
+ if (!field) return;
+ let conf = this.locations.get(field.dataset.locationId);
+ if (!conf) return;
+
+ let query = e.target.value.trim();
+ if (query.length < 3) {
+ conf.ui.results.replaceChildren();
+ return;
+ }
+
+ window.debouncer.schedule(
+ `location:${conf.id}`,
+ () => this.searchLocation(conf, query),
+ 400
+ );
+ }
+ async searchLocation(conf, query) {
+ conf.ui.message.hidden = false;
+ try {
+ let response = await window.auth.fetch(
+ `${jvbSettings.api}geocode?q=${encodeURIComponent(query)}`,
+ { method: 'GET' }
+ );
+
+ conf.results = response.ok ? await response.json() : [];
+ } catch (err) {
+ console.error('Geocode error:', err);
+ conf.results = [];
+ }
+ conf.ui.message.hidden = true;
+ this.renderLocationResults(conf);
+ }
+ renderLocationResults(conf) {
+ conf.ui.results.replaceChildren();
+ if (conf.results.length === 0) {
+ conf.ui.results.innerHTML = '<li>No results found</li>';
+ return;
+ }
+ conf.results.forEach((result, index) => {
+ let li = document.createElement('li');
+ li.className = 'autocomplete item btn';
+ li.dataset.resultIndex = index;
+ li.textContent = result.display_name;
+ conf.ui.results.append(li);
+ });
+ }
+ handleLocationClick(e) {
+ let item = e.target.closest('[data-result-index]');
+ if (!item) return;
+ let field = e.target.closest('[data-location-id]');
+ if (!field) return;
+ let conf = this.locations.get(field.dataset.locationId);
+ if (!conf) return;
+
+ let result = conf.results[item.dataset.resultIndex];
+ if (!result) return;
+
+ this.populateLocationFromResult(conf, result);
+ conf.ui.results.replaceChildren();
+ conf.ui.search.value = result.display_name;
+
+ let form = this.getForm(field);
+ if (form) this.updateItem(field.dataset.field, this.getLocationValue(field), form);
+ }
+ populateLocationFromResult(conf, result) {
+ const addr = result.address ?? {};
+ const map = {
+ address: addr.house_number || '',
+ lat: result.lat,
+ lng: result.lon,
+ street: addr.road || '',
+ city: addr.city || addr.town || addr.village || '',
+ province: addr.state || '',
+ postal_code: addr.postcode || '',
+ country: addr.country || '',
+ };
+ for (let [field, input] of Object.entries(conf.ui.fields)) {
+ input.value = map[field]??'';
+ }
+
+ if (conf.ui.preview) {
+ conf.ui.preview.dataset.lat = map.lat;
+ conf.ui.preview.dataset.lng = map.lng;
+ }
+ }
+
checkForConditionalFields(form) {
form.querySelectorAll(this.selectors.dependsOn).forEach( field => {
const dependsOn = field.dataset.dependsOn;
@@ -1892,6 +2032,7 @@
let conf = this.getItem(element);
let fieldName = conf.field?.dataset.field??false;
+
if (!fieldName) return false;
switch (type) {
@@ -1906,7 +2047,7 @@
//Do we actually need anything here? I think each subfield just
case 'location':
- return this.getLocationValue(element, conf);
+ return this.getLocationValue(element);
case 'selector':
case 'upload':
@@ -2015,15 +2156,15 @@
});
return value;
}
- getLocationValue(element, conf) {
- if(!conf.values){
- conf.values = Array.from(conf.field?.querySelectorAll('[data-location-field]'));
- this.saveItem(conf);
- }
+ getLocationValue(element) {
+ let field = this.getField(element);
+ let conf = this.locations.get(field.dataset.locationId);
+ if (!conf) return;
+
let value = {};
- conf.values.forEach(input => {
- value[input.dataset.locationField] = input.value;
- });
+ for (let [field, input] of Object.entries(conf.ui.fields)) {
+ value[field] = input.value;
+ }
return value;
}
getHiddenInputValue(element, conf, fieldName) {
@@ -2356,10 +2497,13 @@
}
}
+
+
document.addEventListener('DOMContentLoaded', async function () {
window.auth.subscribe(event => {
if (event === 'auth-loaded') {
window.jvbForm = new FormController();
+ document.dispatchEvent(new CustomEvent('jvbFormLoaded'));
document.querySelectorAll('form[data-auto]').forEach(form => {
window.jvbForm.registerForm(form, {});
});
--
Gitblit v1.10.0