1window.SelectAddressBlock = (function() { 2 const handlers = { 3 submit: function() { submit() }, 4 change: function() { removeSuccess() } 5 }; 6 // 0 - dataset.elem, 1 - òåêñòîâîå îáîçíà÷åíèå (åñëè íåò - â òåêñò íå äîáàâèòñÿ), òåêñò ñîñòàâèòñÿ ïî ïîðÿäêó ìàññèâà 7 const flatFieldsHelper = [ 8 ['flat', 'êâ.'], 9 ['pod', 'ïîäúåçä'], 10 ['floor', 'ýòàæ'], 11 ['domophone', 'äîìîôîí'], 12 ['comment'] 13 ]; 14 15 let block, elements, map, suggestView, 16 fields, flatFields, coords, 17 isSubmit, isSuccess; 18 19 function init() { 20 block = document.getElementById('selectAddressBlock'); 21 if (!block) return; 22 elements = {}; 23 [...block.querySelectorAll('[data-elem]')].forEach(el => elements[el.dataset.elem] = el); 24 25 $(block).on('click', '[data-action]', function(e) { 26 if (isSubmit) return; 27 const action = this.dataset.action; 28 action in handlers && handlers[action].call(this, e); 29 }); 30 31 map = suggestView = null; 32 coords = elements.coords && elements.coords.value.split(' '); 33 isSuccess = block.classList.contains('is-success'); 34 !isSuccess && initMapAndInput(); 35 } 36 37 function initMapAndInput(query) { 38 query = query || coords || elements.addressString.textContent || $.cookie('city_name'); 39 40 if (query) { 41 ymaps.geocode(query, {results: 1}).then(res => { 42 const geoObject = res.geoObjects.get(0); 43 if (!geoObject) { 44 initMap() && initInput(); 45 return; 46 } 47 handleGeoObject(geoObject); 48 initMap(coords, fields.house ? 16 : 11); 49 initInput(); 50 addPlacemark(geoObject); 51 elements.input.value = fields.text; 52 }).catch(err => alert(err.message)); 53 } else { 54 initMap(); 55 initInput(); 56 } 57 } 58 59 function initMap(center = [55.755864, 37.617698], zoom = 11) { 60 if (!elements.map) return; 61 62 map = new ymaps.Map(elements.map, { 63 center, 64 zoom, 65 controls: ['geolocationControl', 'zoomControl'] 66 }, { 67 suppressMapOpenBlock: true 68 }); 69 70 map.events.add('click', function(e) { 71 ymaps.geocode(e.get('coords'), {kind: 'house', results: 1}).then(res => { 72 const geoObject = res.geoObjects.get(0); 73 if (!geoObject) return; 74 handleGeoObject(geoObject); 75 elements.input.value = fields.text; 76 return map.panTo(coords).then(() => map.getZoom() < 16 && map.setZoom(16)); 77 }).catch(err => alert(err)); 78 }); 79 80 map.cursors.push('arrow'); 81 return map; 82 } 83 84 function initInput() { 85 if (!elements.input) return; 86 elements.input.disabled = false; 87 suggestView = new ymaps.SuggestView(elements.input); 88 89 suggestView.events.add('select', function(e) { 90 ymaps.geocode(e.get('item').value, {results: 1}).then(res => { 91 const geoObject = res.geoObjects.get(0); 92 if (!geoObject) return; 93 handleGeoObject(geoObject); 94 // map.setCenter(coords, fields.house ? 16 : 11); 95 return map.setBounds(geoObject.properties.get('boundedBy')); 96 }).catch(err => alert(err)); 97 }); 98 } 99 100 function handleGeoObject(geoObject) { 101 coords = geoObject.geometry.getCoordinates(); 102 makeFields(geoObject); 103 updateElements(); 104 addPlacemark(geoObject); 105 } 106 107 function makeFields(geoObject) { 108 fields = { text: geoObject.properties.get('text') }; 109 geoObject.properties.get('metaDataProperty.GeocoderMetaData.Address.Components').forEach(({kind, name}) => { 110 fields[kind] = fields[kind] ? fields[kind]+', '+name : name 111 }); 112 } 113 114 function updateElements() { 115 elements.btn.disabled = !fields.house; 116 elements.flatFields.hidden = !fields.house; 117 map && clearFlatFields(); 118 } 119 120 function addPlacemark(geoObject) { 121 if (!map) { 122 return; 123 } 124 // geoObject.balloon.destroy(); 125 geoObject.properties.set('iconCaption', geoObject.properties.get('name')); 126 map.geoObjects.getLength() && map.geoObjects.removeAll(); 127 map.geoObjects.add(geoObject); 128 } 129 130 function makeFlatFields() { 131 flatFields = { text: '' }; 132 133 flatFieldsHelper.forEach(([name, type]) => { 134 const val = elements[name] && elements[name].value || ''; 135 flatFields[name] = val; 136 if (!type || !val) return; 137 flatFields.text = flatFields.text ? flatFields.text+', '+type+' '+val : type+' '+val; 138 });
139 } 140 141 function clearFlatFields() { 142 flatFields = null; 143 flatFieldsHelper.forEach(([name, type]) => elements[name] && (elements[name].value = '')); 144 } 145 146 function addSuccess() { 147 let text = fields.text; 148 if (flatFields && flatFields.text) text += ', '+flatFields.text; 149 elements.addressString.textContent = text; 150 destroyMapView(); 151 block.classList.add('is-success'); 152 isSuccess = true; 153 S2UBasket.prototype.updateDeliveryPayButtonDisabled(); 154 } 155 156 function removeSuccess() { 157 isSuccess = false; 158 block.classList.remove('is-success'); 159 initMapAndInput(); 160 S2UBasket.prototype.updateDeliveryPayButtonDisabled(); 161 } 162 163 function destroyMapView() { 164 map && map.destroy(); 165 map = null; 166 suggestView && suggestView.destroy(); 167 suggestView = null; 168 elements.input.disabled = true; 169 elements.btn.disabled = true; 170 } 171 172 function destroy() { 173 map && destroyMapView(); 174 $(block).off('click'); 175 } 176 177 function save(city_id) { 178 fields.city_id = city_id; 179 return new S2UAjax("S2U::Gorodtokyo::Frame::FO::BasketMapAddress", "set_address_from_map").addParams({ 180 'area_map': fields.area || '', 181 'city_map': fields.locality || '', 182 'street_map': fields.street || fields.district || '', 183 'dom_map': fields.house || '', 184 'city_id_map': fields.city_id || '', 185 'coords': coords ? coords[0]+' '+coords[1] : '', 186 'flat': flatFields.flat, 187 'pod': flatFields.pod, 188 'floor': flatFields.floor, 189 'domophone': flatFields.domophone, 190 'comment': flatFields.comment 191 }).send(); 192 } 193 194 function changeCity(id, name) { 195 destroy(); 196 S2UCity.prototype.setCookie(id, name); 197 S2UCity.prototype.setCity(); 198 S2UBasket.prototype.reloadDeliveryPay($()); 199 } 200 201 function truncateString(str) { 202 return str.length > 13 ? str.slice(0, 13) : str; 203 } 204 205 function getDadata(api, data) { 206 data.count = 1; 207 208 return $.ajax({ 209 method: 'POST', 210 url: 'https://suggestions.dadata.ru/suggestions/api/4_1/rs/'+api, 211 data: JSON.stringify(data), 212 headers: { 213 "Content-Type": "application/json", 214 "Accept": "application/json", 215 "Authorization": "Token " + "0206a6952c3be1d3e9df35f75d74a535fd0d16a0" 216 } 217 }).then(res => { 218 return res.suggestions.length ? res.suggestions[0].data : null; 219 }); 220 } 221 222 function submit() { 223 if (isSubmit || !fields.house || !coords) return; 224 isSubmit = true; 225 block.classList.add('is-submit'); 226 227 // ñíà÷àëà íóæíî ïîëó÷èòü êëàäð 228 getDadata('geolocate/address', { lat: coords[0], lon: coords[1] }) 229 230 // íàøëè - îê, íåò - ïðîáóåì ïîëó÷èòü ÷åðåç àïè ïîäñêàçîê ïî ñòðîêå 231 .then(res => { 232 if (res && res.city_kladr_id) { 233 return res.city_kladr_id; 234 } 235 236 // ïðîáóåì suggestions 237 return getDadata('suggest/address', { query: fields.text }) 238 .then(res => { 239 240 if (res) { 241 return truncateString( 242 res.city_kladr_id || 243 res.settlement_kladr_id || 244 res.kladr_id 245 ); 246 } 247 248 // åñëè suggestions íè÷åãî íå âåðíóë 249 // ïðîáóåì ñåðâåðíûé ìåòîä 250 return new S2UAjax( 251 "S2U::Gorodtokyo::Frame::FO::BasketMapAddress", 252 "get_info_dadata" 253 ) 254 .addParams({ 255 address_text: fields.text || '' 256 }) 257 .send() 258 .then(res => { 259 260 if (!res) return null; 261 262 const kladr = 263 res.city_kladr_id || 264 res.settlement_kladr_id || 265 res.kladr_id; 266 267 if (!kladr) return null; 268 269 return truncateString(kladr); 270 }); 271 }); 272 }) 273 274 // ïîòîì ïðîâåðèòü êëàäð 275 .then(res => { 276 if (!res) { 277 return { success: 0, msg: 'Êóðüåðñêàÿ äîñòàâêà íà ýòîò àäðåñ íå îñóùåñòâëÿåòñÿ. Âûáåðèòå áëèæàéøèé íàñåëåííûé ïóíêò.' }; 278 } 279 280 return new S2UAjax('S2U::Frame::FO::RussianPost::PostalCode', 'get_city_info_by_kladr_id').addParams({ 281 kladr_id: res 282 }).send(); 283 }) 284 285 // åñëè íå íàéäåí - âûõîäèì, åñëè íàéäåí - ñîõðàíÿåì, ïîòîì ôèêñèðóåì àäðåñ è ìåíÿåì ãîðîä 286 .then(res => { 287 if (res.success != 1) { 288 alert(res.msg || 'Êóðüåðñêàÿ äîñòàâêà íà ýòîò àäðåñ íå îñóùåñòâëÿåòñÿ.\nÂûáåðèòå áëèæàéøèé íàñåëåííûé ïóíêò.'); 289 return; 290 } 291 292 makeFlatFields(); 293 294 return save(res.city_id).done(() => { 295 addSuccess(); 296 ($.cookie('city_id') != res.city_id) 297 ? changeCity(res.city_id, res.city_name) 298 : S2UBasket.prototype.getSaveDeliveryAdditionalBlockS2UAjax().send(); 299 }); 300 }) 301 302 // ñíèìàåì ñîñòîÿíèå îòïðàâêè 303 .always(() => { 304 block.classList.remove('is-submit'); 305 isSubmit = false; 306 }) 307 308 .fail(function() { 309 console.log('Submit fail', arguments); 310 });
311 } 312 313 return { init, destroy, isSuccess: () => isSuccess } 314})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.