balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

osm.js (7563B)


      1 ( function( $, L, rwmb, i18n ) {
      2 	'use strict';
      3 
      4 	// Use function construction to store map & DOM elements separately for each instance
      5 	var OsmField = function ( $container ) {
      6 		this.$container = $container;
      7 	};
      8 
      9 	// Use prototype for better performance
     10 	OsmField.prototype = {
     11 		// Initialize everything
     12 		init: function () {
     13 			this.initDomElements();
     14 			this.initMapElements();
     15 
     16 			this.initMarkerPosition();
     17 			this.addListeners();
     18 			this.autocomplete();
     19 
     20 			// Make sure the map is displayed fully.
     21 			var map = this.map;
     22 			setTimeout( function() {
     23 				map.invalidateSize();
     24 			}, 0 );
     25 		},
     26 
     27 		// Initialize DOM elements
     28 		initDomElements: function () {
     29 			this.$canvas = this.$container.find( '.rwmb-osm-canvas' );
     30 			this.canvas = this.$canvas[0];
     31 			this.$coordinate = this.$container.find( '.rwmb-osm' );
     32 			this.addressField = this.$container.data( 'address-field' );
     33 		},
     34 
     35 		// Initialize map elements
     36 		initMapElements: function () {
     37 			var defaultLoc = this.$canvas.data( 'default-loc' ),
     38 				latLng;
     39 
     40 			defaultLoc = defaultLoc ? defaultLoc.split( ',' ) : [53.346881, -6.258860];
     41 			latLng = L.latLng( defaultLoc[0], defaultLoc[1] ); // Initial position for map.
     42 
     43 			this.map = L.map( this.canvas, {
     44 				center: latLng,
     45 				zoom: 14
     46 			} );
     47 
     48 			L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
     49 				attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
     50 			} ).addTo( this.map );
     51 			this.marker = L.marker( latLng, {
     52 				draggable: true
     53 			} ).addTo( this.map );
     54 		},
     55 
     56 		// Initialize marker position
     57 		initMarkerPosition: function () {
     58 			var coordinate = this.$coordinate.val(),
     59 				location,
     60 				zoom;
     61 
     62 			if ( coordinate ) {
     63 				location = coordinate.split( ',' );
     64 				var latLng = L.latLng( location[0], location[1] );
     65 				this.marker.setLatLng( latLng );
     66 
     67 				zoom = location.length > 2 ? parseInt( location[2], 10 ) : 14;
     68 
     69 				this.map.panTo( latLng );
     70 				this.map.setZoom( zoom );
     71 			} else if ( this.addressField ) {
     72 				this.geocodeAddress( false );
     73 			}
     74 		},
     75 
     76 		// Add event listeners for 'click' & 'drag'
     77 		addListeners: function () {
     78 			var that = this;
     79 
     80 			/*
     81 			 * Auto change the map when there's change in address fields.
     82 			 * Works only for multiple address fields as single address field has autocomplete functionality.
     83 			 */
     84 			if ( this.addressField.split( ',' ).length > 1 ) {
     85 				var geocodeAddress = that.geocodeAddress.bind( that );
     86 				var addressFields = this.addressField.split( ',' ).forEach( function( part ) {
     87 					var $field = that.findAddressField( part );
     88 					if ( null !== $field ) {
     89 						$field.on( 'change', geocodeAddress );
     90 					}
     91 				} );
     92 			}
     93 
     94 			this.map.on( 'click', function ( event ) {
     95 				that.marker.setLatLng( event.latlng );
     96 				that.updateCoordinate( event.latlng );
     97 			} );
     98 
     99 			this.map.on( 'zoom', function () {
    100 				that.updateCoordinate( that.marker.getLatLng() );
    101 			} );
    102 
    103 			this.marker.on( 'drag', function () {
    104 				that.updateCoordinate( that.marker.getLatLng() );
    105 			} );
    106 
    107 			// Custom event to refresh maps when in hidden divs.
    108 			var refresh = that.refresh.bind( this );
    109 			$( window ).on( 'rwmb_map_refresh', refresh );
    110 
    111 			// Refresh on meta box hide and show
    112 			rwmb.$document.on( 'postbox-toggled', refresh );
    113 			// Refresh on sorting meta boxes
    114 			$( '.meta-box-sortables' ).on( 'sortstop', refresh );
    115 		},
    116 
    117 		refresh: function () {
    118 			if ( ! this.map ) {
    119 				return;
    120 			}
    121 			this.map.invalidateSize();
    122 			this.map.panTo( this.map.getCenter() );
    123 		},
    124 
    125 		// Autocomplete address
    126 		autocomplete: function () {
    127 			var that = this,
    128 				$address = this.getAddressField();
    129 
    130 			if ( null === $address ) {
    131 				return;
    132 			}
    133 
    134 			$address.autocomplete( {
    135 				source: function ( request, response ) {
    136 					$.get( 'https://nominatim.openstreetmap.org/search', {
    137 						format: 'json',
    138 						q: request.term,
    139 						countrycodes: that.$canvas.data( 'region' ),
    140 						"accept-language": that.$canvas.data( 'language' ),
    141 						addressdetails: 1
    142 					}, function( results ) {
    143 						if ( ! results.length ) {
    144 							response( [ {
    145 								value: '',
    146 								label: i18n.no_results_string
    147 							} ] );
    148 							return;
    149 						}
    150 						response( results.map( function ( item ) {
    151 							return {
    152 								address: item.address,
    153 								label: item.display_name,
    154 								value: item.display_name,
    155 								latitude: item.lat,
    156 								longitude: item.lon
    157 							};
    158 						} ) );
    159 					}, 'json' );
    160 				},
    161 				select: function ( event, ui ) {
    162 					var latLng = L.latLng( ui.item.latitude, ui.item.longitude );
    163 
    164 					that.map.panTo( latLng );
    165 					that.marker.setLatLng( latLng );
    166 					that.updateCoordinate( latLng );
    167 
    168 					$address.trigger( 'selected_address', [ui.item] );
    169 				}
    170 			} );
    171 		},
    172 
    173 		// Update coordinate to input field
    174 		updateCoordinate: function ( latLng ) {
    175 			var zoom = this.map.getZoom();
    176 			this.$coordinate.val( latLng.lat + ',' + latLng.lng + ',' + zoom ).trigger( 'change' );
    177 		},
    178 
    179 		// Find coordinates by address
    180 		geocodeAddress: function ( notify ) {
    181 			var address = this.getAddress(),
    182 				that = this;
    183 			if ( ! address ) {
    184 				return;
    185 			}
    186 
    187 			if ( false !== notify ) {
    188 				notify = true;
    189 			}
    190 			$.get( 'https://nominatim.openstreetmap.org/search', {
    191 				format: 'json',
    192 				q: address,
    193 				limit: 1,
    194 				countrycodes: that.$canvas.data( 'region' ),
    195 				"accept-language": that.$canvas.data( 'language' )
    196 			}, function( result ) {
    197 				if ( result.length !== 1 ) {
    198 					if ( notify ) {
    199 						alert( i18n.no_results_string );
    200 					}
    201 					return;
    202 				}
    203 				var latLng = L.latLng( result[0].lat, result[0].lon );
    204 				that.map.panTo( latLng );
    205 				that.marker.setLatLng( latLng );
    206 				that.updateCoordinate( latLng );
    207 			}, 'json' );
    208 		},
    209 
    210 		// Get the address field.
    211 		getAddressField: function() {
    212 			// No address field or more than 1 address fields, ignore
    213 			if ( ! this.addressField || this.addressField.split( ',' ).length > 1 ) {
    214 				return null;
    215 			}
    216 			return this.findAddressField( this.addressField );
    217 		},
    218 
    219 		// Get the address value for geocoding.
    220 		getAddress: function() {
    221 			var that = this;
    222 
    223 			return this.addressField.split( ',' )
    224 				.map( function( part ) {
    225 					part = that.findAddressField( part );
    226 					return null === part ? '' : part.val();
    227 				} )
    228 				.join( ',' ).replace( /\n/g, ',' ).replace( /,,/g, ',' );
    229 		},
    230 
    231 		// Find address field based on its name attribute. Auto search inside groups when needed.
    232 		findAddressField: function( fieldName ) {
    233 			// Not in a group.
    234 			var $address = $( 'input[name="' + fieldName + '"]');
    235 			if ( $address.length ) {
    236 				return $address;
    237 			}
    238 
    239 			// If map and address is inside a cloneable group.
    240 			$address = this.$container.closest( '.rwmb-group-clone' ).find( 'input[name*="[' + fieldName + ']"]' );
    241 			if ( $address.length ) {
    242 				return $address;
    243 			}
    244 
    245 			// If map and address is inside a non-cloneable group.
    246 			$address = this.$container.closest( '.rwmb-group-wrapper' ).find( 'input[name*="[' + fieldName + ']"]' );
    247 			if ( $address.length ) {
    248 				return $address;
    249 			}
    250 
    251 			return null;
    252 		}
    253 	};
    254 
    255 	function createController() {
    256 		var $this = $( this ),
    257 			controller = $this.data( 'osmController' );
    258 		if ( controller ) {
    259 			return;
    260 		}
    261 
    262 		controller = new OsmField( $this );
    263 		controller.init();
    264 		$this.data( 'osmController', controller );
    265 	}
    266 
    267 	function init( e ) {
    268 		$( e.target ).find( '.rwmb-osm-field' ).each( createController );
    269 	}
    270 
    271 	function restart() {
    272 		$( '.rwmb-osm-field' ).each( createController );
    273 	}
    274 
    275 	rwmb.$document
    276 		.on( 'mb_ready', init )
    277 		.on( 'clone', '.rwmb-input', restart );
    278 } )( jQuery, L, rwmb, RWMB_Osm );