PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 2.1.8
JetFormBuilder — Dynamic Blocks Form Builder v2.1.8
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / assets / js / map-field.js
jetformbuilder / assets / js Last commit date
admin 3 years ago action-localize-helper.js 3 years ago admin-package.js 3 years ago admin-vuex-package.js 3 years ago editor.js 3 years ago file-upload.js 3 years ago form-block.js 3 years ago frontend-forms.js 3 years ago import-form.js 3 years ago map-field.js 3 years ago package.js 3 years ago re-captcha-v3.js 3 years ago
map-field.js
353 lines
1 (
2 function ( $, JetMapFieldsSettings ) {
3
4 'use strict';
5
6 let provider = false;
7
8 function textToNode( text ) {
9 const template = document.createElement( 'template' );
10 template.innerHTML = text.trim();
11
12 return template.content;
13 }
14
15 function getConvertedName( name, prefix ) {
16 const regExp = /^(\w+\[\d+\])\[([\w\-]+)\]$/;
17
18 // fields inside repeater (rep_name[1][content_field])
19 if ( ! regExp.test( name )) {
20 return name + prefix;
21 }
22 const matches = name.match( regExp );
23
24 return matches[ 1 ] + `[${ matches[2] + prefix }]`;
25 }
26
27
28 const initMapField = currentField => {
29 const observer = new IntersectionObserver( ( entries, observer ) => {
30
31 entries.forEach( function ( entry ) {
32 if ( ! entry.isIntersecting ) {
33 return;
34 }
35
36 new MapField( currentField );
37
38 // Detach observer after the first render the map
39 observer.unobserve( entry.target );
40 } );
41 } );
42
43 observer.observe( currentField );
44 };
45
46
47 function MapFieldsManager( event, scope ) {
48 const [ form ] = scope;
49
50 if ( false === provider ) {
51 provider = new window.JetEngineMapsProvider();
52 }
53
54 for ( const mapField of form.querySelectorAll( '.jet-fb-map-field' ) ) {
55 initMapField( mapField );
56 }
57 }
58
59 class MapField {
60
61 constructor( nodeMap ) {
62
63 this.setup( nodeMap );
64
65 this.render();
66 this.events();
67 }
68
69 setup( selector ) {
70 this.$container = selector;
71 this.$input = selector.querySelector( 'input[name]' );
72 this.repeaterRow = this.$input.closest( '.jet-form-builder-repeater__row' );
73
74 this.fieldSettings = {
75 height: '300',
76 format: 'location_string',
77 field_prefix: false,
78 ...JSON.parse( this.$input.dataset.settings ),
79 };
80
81 this.$inputHash = this.$container.querySelector( this.getConvertedName( '_hash' ) );
82 this.$inputLat = this.$container.querySelector( this.getConvertedName( '_lat' ) );
83 this.$inputLng = this.$container.querySelector( this.getConvertedName( '_lng' ) );
84
85 // Map props.
86 this.map = null;
87 this.mapDefaults = {
88 center: { lat: 41, lng: 71 },
89 zoom: 1,
90 };
91 this.marker = null;
92 this.markerDefaults = {
93 content: '<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24"><path d="M12 0c-4.198 0-8 3.403-8 7.602 0 4.198 3.469 9.21 8 16.398 4.531-7.188 8-12.2 8-16.398 0-4.199-3.801-7.602-8-7.602zm0 11c-1.657 0-3-1.343-3-3s1.343-3 3-3 3 1.343 3 3-1.343 3-3 3z" fill="#C92C2C"/></svg>',
94 shadow: false,
95 };
96 }
97
98 render() {
99 let template = '<div class="jet-engine-map-field__preview" style="display: none; justify-content: space-between; padding: 0 0 5px; align-items: center;">' +
100 '<address class="jet-engine-map-field__position"></address>' +
101 '<div class="jet-engine-map-field__reset" role="button" style="cursor: pointer; color: #c92c2c; font-weight: 500; flex-shrink: 0;">× ' + JetMapFieldsSettings.i18n.resetBtn + '</div>' +
102 '</div>' +
103 '<div class="jet-engine-map-field__frame" style="height: ' + this.fieldSettings.height + 'px; width: 100%;"></div>';
104
105 if ( this.repeaterRow ) {
106 template += '<div class="jet-engine-map-field__description">' +
107 '<p style="margin-bottom: 0;"><strong>' + JetMapFieldsSettings.i18n.descTitle + ':</strong> <i>' + this.fieldSettings.field_prefix + '_lat, ' + this.fieldSettings.field_prefix + '_lng</i></p>' +
108 '</div>';
109 }
110
111 this.$container.append( textToNode( template ) );
112
113 this.$preview = this.$container.querySelector( '.jet-engine-map-field__preview' );
114 this.$position = this.$container.querySelector( '.jet-engine-map-field__position' );
115 this.$mapFrame = this.$container.querySelector( '.jet-engine-map-field__frame' );
116
117 let defaultPos,
118 valueFormat = false;
119
120 if ( this.$input.value ) {
121 // Set preview from input value.
122 try {
123 // `location_array` value format
124 const jsonValue = JSON.parse( this.$input.value );
125
126 defaultPos = jsonValue;
127 this.setPreview( jsonValue );
128
129 valueFormat = 'location_array';
130
131 } catch ( e ) {
132
133 const valueParts = this.$input.value.split( ',' );
134
135 if ( 2 === valueParts.length && Number( valueParts[ 0 ] ) && Number( valueParts[ 1 ] ) ) {
136 // `location_string` value format
137 defaultPos = { lat: Number( valueParts[ 0 ] ), lng: Number( valueParts[ 1 ] ) };
138 this.setPreview( defaultPos );
139
140 valueFormat = 'location_string';
141
142 } else {
143 // `location_address` value format
144 defaultPos = this.getPositionFromHashFields();
145 this.setPreview( this.$input.value );
146
147 valueFormat = 'location_address';
148 }
149 }
150
151 // Convert value format
152 if ( valueFormat !== this.fieldSettings.format ) {
153 this.setValue( defaultPos );
154 }
155 }
156
157 if ( defaultPos ) {
158 this.mapDefaults.center = defaultPos;
159 this.mapDefaults.zoom = 14;
160 }
161
162 this.map = provider.initMap( this.$mapFrame, this.mapDefaults );
163
164 if ( defaultPos ) {
165 this.marker = provider.addMarker( {
166 ...this.markerDefaults,
167 position: defaultPos,
168 map: this.map,
169 } );
170 }
171
172 provider.markerOnClick( this.map, this.markerDefaults, ( marker ) => {
173
174 if ( this.marker ) {
175 provider.removeMarker( this.marker );
176 }
177
178 this.marker = marker;
179
180 let position = provider.getMarkerPosition( marker, true );
181
182 this.setValue( position );
183 } );
184 }
185
186 setValue( position ) {
187
188 let self = this,
189 location = '';
190
191 this.setPreview( JetMapFieldsSettings.i18n.loading );
192
193 switch ( this.fieldSettings.format ) {
194 case 'location_string':
195
196 location = position.lat + ',' + position.lng;
197
198 this.updateHashFieldPromise( location ).then( function () {
199 self.$input.value = location;
200 self.setPreview( position );
201 $( self.$input ).trigger( 'change.JetFormBuilderMain' );
202 } );
203
204 break;
205
206 case 'location_array':
207
208 location = JSON.stringify( position );
209
210 this.updateHashFieldPromise( location ).then( function () {
211 self.$input.value = location;
212 self.setPreview( position );
213 $( self.$input ).trigger( 'change.JetFormBuilderMain' );
214 } );
215
216 break;
217
218 case 'location_address':
219
220 wp.apiFetch( {
221 method: 'get',
222 path: JetMapFieldsSettings.api + '?lat=' + position.lat + '&lng=' + position.lng,
223 headers: {
224 'nonce': JetMapFieldsSettings.nonce,
225 },
226 } ).then( function ( response ) {
227
228 if ( response.success ) {
229
230 if ( response.data ) {
231
232 self.updateHashFieldPromise( response.data ).then( function () {
233 self.$input.value = response.data;
234 self.setPreview( response.data );
235 } );
236
237 } else {
238 self.$input.value = null;
239 self.setPreview( JetMapFieldsSettings.i18n.notFound );
240 }
241
242 } else {
243 self.$input.value = null;
244 self.setPreview( response.html );
245 }
246
247 $( self.$input ).trigger( 'change.JetFormBuilderMain' );
248
249 } ).catch( function ( e ) {
250 console.log( e );
251 } );
252
253 break;
254 }
255
256 if ( this.$inputLat && this.$inputLng ) {
257 this.$inputLat.value = position.lat;
258 this.$inputLng.value = position.lng;
259 }
260 }
261
262 setPreview( position ) {
263 let positionText;
264
265 if ( position && position.lat && position.lng ) {
266 positionText = '<span title="Lat">' + position.lat + '</span>, <span title="Lng">' + position.lng + '</span>';
267 } else {
268 positionText = position;
269 }
270
271 this.$position.innerHTML = positionText;
272 this.$preview.style.display = position ? 'flex' : 'none';
273 }
274
275 events() {
276 const resetBtn = this.$container.querySelector( '.jet-engine-map-field__reset' );
277
278 resetBtn.addEventListener( 'click', this.resetLocation.bind( this ) );
279 }
280
281 resetLocation() {
282 provider.removeMarker( this.marker );
283 this.setPreview( null );
284 this.$input.value = null;
285
286 if ( this.$inputLat && this.$inputLng ) {
287 this.$inputLat.value = null;
288 this.$inputLng.value = null;
289 }
290
291 $( this.$input ).trigger( 'change.JetFormBuilderMain' );
292 }
293
294 updateHashFieldPromise( location ) {
295 if ( ! this.$inputHash ) {
296 return new Promise( function ( resolve ) {
297 resolve();
298 } );
299 }
300
301 return wp.apiFetch( {
302 method: 'get',
303 path: JetMapFieldsSettings.apiHash + '?loc=' + location,
304 headers: {
305 'nonce': JetMapFieldsSettings.nonce,
306 },
307 } ).then( response => {
308
309 if ( response.success ) {
310 this.$inputHash.value = response.data;
311 }
312
313 } ).catch( function ( e ) {
314 console.log( e );
315 } );
316 }
317
318 getPositionFromHashFields() {
319
320 if ( ! this.$inputLat || ! this.$inputLng ) {
321 return false;
322 }
323
324 const lat = this.$inputLat.value,
325 lng = this.$inputLng.value;
326
327 if ( ! lat || ! lng ) {
328 return false;
329 }
330
331 return { lat: Number( lat ), lng: Number( lng ) };
332 }
333
334 getConvertedName( prefix ) {
335 return `[name="${ getConvertedName( this.$input.name, prefix ) }"]`
336 }
337
338 }
339
340 // Run on each form ready.
341 $( document ).on( 'jet-form-builder/init', MapFieldsManager );
342 $( document ).on(
343 'jet-form-builder/repeater-add-new',
344 '.jet-form-builder-repeater__new',
345 ( { target } ) => {
346 const repeater = target.closest( '.jet-form-builder-repeater' ),
347 rows = repeater.querySelector( '.jet-form-builder-repeater__items' );
348
349 MapFieldsManager( null, [ rows.lastElementChild ] );
350 },
351 );
352 }
353 )( jQuery, window.JetMapFieldsSettings );