((exports) => { const $ = exports.$; // eslint-disable-line const getCoordinateInputName = (coordinate, $input, options) => { const key = `${coordinate}Name`; if (options[key]) { return options[key]; } const inputName = $input.attr("name"); const subNameMatch = /\[[^\]]+\]$/; if (inputName.match(subNameMatch)) { return inputName.replace(subNameMatch, `[${coordinate}]`); } return coordinate; } /** * You can use this method to "attach" front-end geocoding to any forms in the * front-end which have address fields with geocoding autocompletion * functionality already applied to them. * * To learn more about the front-end geocoding autocompletion, please refer to * the maps documentation at: /docs/customization/maps.md. * * When the geocoding autocompletion finishes, most of the times, its results * will also contain the geocoordinate information for the selected address. * This method allows you to pass these coordinates (latitude and longitude) * to the same front-end form where the geocoding autocompletion address field * is located at (which is the $input you pass to this method). The latitude * and longitude coordinates will be added or "attached" to the form once the * user selects one of the suggested addresses. * * Therefore, if there was the following geocoding autocompletion field at * your form: * * * You would then "attach" the geocoding result coordinates to the same form * where this input is at as follows: * $(document).ready(function() { * window.Decidim.attachGeocoding($("#record_address")); * }); * * Now, after the user selects one of the suggested geocoding autocompletion * addresses and the geocoding autocompletion API provides the coordinates in * the results, you would have the following fields automatically generated * to your form: * * * * * If you would not do the attachment, these hidden longitude and latitude * fields would not be generated and the geocoding would have to happen at the * server-side when the form is submitted. The problem with that approach * would be that the server-side address geocoding could potentially result in * different coordinates than what the user actually selected in the front-end * because the autocompletion API can return different coordinates than the * geocoding API. Another reason is to avoid unnecessary calls to the * geocoding API as the front-end geocoding suggestion already returned the * coordinate values we need. * * @param {jQuery} $input The input jQuery element for the geocoded address * field. * @param {Object} options (optional) Extra options if you want to customize * the latitude and longitude element IDs or names from the default. * @returns {void} */ const attachGeocoding = ($input, options) => { const attachOptions = $.extend({}, options); const inputIdParts = $input.attr("id").split("_"); inputIdParts.pop(); const idPrefix = `${inputIdParts.join("_")}`; const config = $.extend({ latitudeId: `${idPrefix}_latitude`, longitudeId: `${idPrefix}_longitude`, latitudeName: getCoordinateInputName("latitude", $input, attachOptions), longitudeName: getCoordinateInputName("longitude", $input, attachOptions) }, options); $input.on("geocoder-suggest-coordinates.decidim", (_ev, coordinates) => { let $latitude = $(`#${config.latitudeId}`); let $longitude = $(`#${config.longitudeId}`); if ($latitude.length < 1) { $latitude = $(``); $input.after($latitude); } if ($longitude.length < 1) { $longitude = $(``); $input.after($longitude); } $latitude.val(coordinates[0]).attr("value", coordinates[0]); $longitude.val(coordinates[1]).attr("value", coordinates[1]); }); }; exports.Decidim = exports.Decidim || {}; exports.Decidim.attachGeocoding = attachGeocoding; })(window);