1/** 2 * iiko Legacy Street Suggestions 3 * ÐодÑказки ÑÐ»Ð¸Ñ Ð´Ð»Ñ legacy Ñежима iiko 4 */ 5 6jQuery(document).ready(function ($) { 7 // ÐÑовеÑÑем налиÑие конÑигÑÑаÑии 8 if (typeof iikoLegacy === 'undefined') { 9 console.warn('iikoLegacy configuration not found'); 10 return; 11 } 12 13 // СбÑÐ¾Ñ Ð¿Ð¾Ð»Ñ ÑлиÑÑ Ð¿Ñи Ñмене гоÑода 14 $('[name="billing_city"]').on('change', function () { 15 $('[name="billing_street"]').val('').change(); 16 $('[name="billing_street_id"]').val('').change(); 17 }); 18 19 // ÐниÑиализаÑÐ¸Ñ Ð°Ð²ÑокомплиÑа Ð´Ð»Ñ ÑÐ»Ð¸Ñ 20 initStreetAutocomplete(); 21 22 function initStreetAutocomplete() { 23 let address = $('[name="billing_street"]'); 24 25 if (address.length === 0) { 26 console.log('billing_street field not found'); 27 return; 28 } 29 30 // УÑÑанавливаем наÑалÑнÑе знаÑÐµÐ½Ð¸Ñ Ð¸Ð· конÑигÑÑаÑии ÑолÑко еÑли Ð¿Ð¾Ð»Ñ Ð¿ÑÑÑÑе 31 let streetIdField = $('[name="billing_street_id"]'); 32 if (streetIdField.length > 0 && !streetIdField.val()) { 33 streetIdField.val(iikoLegacy.streetId || ''); 34 } 35 if (!address.val()) { 36 address.val(iikoLegacy.streetName || ''); 37 } 38 39 // ÐбоÑаÑиваем поле в wrapper Ð´Ð»Ñ Ð¿ÑавилÑного позиÑиониÑÐ¾Ð²Ð°Ð½Ð¸Ñ dropdown 40 if (!address.parent().hasClass('iiko-autocomplete-wrapper')) { 41 address.wrap('<div class="iiko-autocomplete-wrapper"></div>'); 42 } 43 44 let wrapper = address.closest('.iiko-autocomplete-wrapper'); 45 if (wrapper.length === 0) { 46 console.error('Failed to create wrapper for street autocomplete'); 47 return; 48 } 49 50 // УдалÑем ÑÑаÑÑй load_info еÑли ÑÑÑеÑÑвÑÐµÑ 51 wrapper.next('.load_info').remove(); 52 wrapper.after('<div class="load_info"></div>'); 53 let load_info = wrapper.next('.load_info'); 54 55 let arr_iiko = []; 56 let dropdown = null; 57 let selectedIndex = -1; 58 59 // СоздаÑм dropdown вÑÑÑнÑÑ Ð±ÐµÐ· jQuery UI 60 function createDropdown(items) { 61 // УдалÑем ÑÑаÑÑй dropdown еÑли еÑÑÑ 62 if (dropdown) { 63 dropdown.remove(); 64 } 65 66 if (items.length === 0) { 67 return null; 68 } 69 70 dropdown = $('<ul class="iiko-suggestions-dropdown"></ul>'); 71 72 items.forEach(function(item, index) { 73 let displayText = item.name || item; // ÐоддеÑжка Ð¾Ð±Ð¾Ð¸Ñ ÑоÑмаÑов 74 let itemId = item.id || index; 75 76 let li = $('<li class="suggestion-item"></li>') 77 .text(displayText) 78 .data('index', index) 79 .data('id', itemId) 80 .data('value', displayText) 81 .on('click', function() { 82 selectStreet(index, itemId, displayText); 83 }) 84 .on('mouseenter', function() { 85 dropdown.find('.suggestion-item').removeClass('active'); 86 $(this).addClass('active'); 87 selectedIndex = index; 88 }); 89 90 dropdown.append(li); 91 }); 92 93 wrapper.append(dropdown); 94 selectedIndex = -1; 95 return dropdown; 96 } 97 98 function selectStreet(index, streetId, streetName) { 99 if (arr_iiko[index]) { 100 console.log('Selected street:', {index: index, id: streetId, name: streetName}); 101 address.val(streetName); 102 103 // УÑÑановка ID ÑлиÑÑ 104 let streetIdField = $('[name="billing_street_id"]'); 105 if (streetIdField.length > 0) { 106 streetIdField.val(streetId).change(); 107 } 108 109 // УÑÑановка адÑеÑа 110 let addressField = $('[name="billing_address_1"]'); 111 if (addressField.length > 0) { 112 addressField.val(streetName).change(); 113 } 114 115 // ÐÑиÑÑка кооÑÐ´Ð¸Ð½Ð°Ñ 116 let coordField = $('[name="billing_coordinates"]'); 117 if (coordField.length > 0) { 118 coordField.val('').change(); 119 } 120 121 hideDropdown(); 122 123 // 1. СнаÑала ÑÑÑанавливаем billing_delivery_type = '0' (доÑÑавка) в DOM 124 // ÐÑо кÑиÑиÑно ÑÑÐ¾Ð±Ñ ÑеÑÐ²ÐµÑ Ð¿Ð¾Ð»ÑÑил пÑавилÑное знаÑение пÑи AJAX запÑоÑе 125 if (typeof window.iikoSetDeliveryTypeValue === 'function') { 126 window.iikoSetDeliveryTypeValue('0', false); 127 } else { 128 var $deliveryTypeField = $('[name="billing_delivery_type"], #delivery_type, [name="delivery_type"]'); 129 $deliveryTypeField.filter('select, input[type="hidden"]').val('0'); 130 $deliveryTypeField.filter('input[type="radio"][value="
1300"]').prop('checked', true); 131 } 132 console.log('iiko Suggestions: billing_delivery_type selected as delivery'); 133 134 // 2. ÐеÑеклÑÑаем WC-меÑод доÑÑавки на доÑÑавкÑ, ÑÑÐ¾Ð±Ñ WC не веÑнÑл local_pickup из ÑеÑÑии 135 if (typeof chooseWooShippingByDeliveryType === 'function') { 136 chooseWooShippingByDeliveryType('0'); // 0 = доÑÑавка 137 console.log('iiko Suggestions: chooseWooShippingByDeliveryType(0) called'); 138 } 139 140 // 3. ÐаÑм вÑÐµÐ¼Ñ Ð½Ð° обновление DOM и ÑеÑÑии, заÑем вÑзÑваем update_checkout 141 setTimeout(function() { 142 $(document.body).trigger('update_checkout'); 143 console.log('iiko Suggestions: update_checkout triggered'); 144 }, 50); 145 } else { 146 console.warn('Street not found in arr_iiko at index:', index); 147 } 148 } 149 150 function hideDropdown() { 151 if (dropdown) { 152 dropdown.hide(); 153 } 154 } 155 156 function showDropdown() { 157 if (dropdown) { 158 dropdown.show(); 159 } 160 } 161 162 // ÐбÑабоÑка ввода Ñ debounce 163 let searchTimeout; 164 address.on('input', function() { 165 let query = $(this).val().trim(); 166 167 // ÐÑли поле ÑодеÑÐ¶Ð¸Ñ Ð¿Ð¾Ð»Ð½Ñй адÑÐµÑ (Ñ Ð½Ð¾Ð¼ÐµÑом дома), и полÑзоваÑÐµÐ»Ñ Ð²Ð²Ð¾Ð´Ð¸Ñ ÐºÐ¾ÑоÑкий ÑекÑÑ (веÑоÑÑно новÑÑ ÑлиÑÑ), 168 // оÑиÑÑим поле Ð¾Ñ ÑÑаÑого полного адÑеÑа 169 if (query.length >= 2 && query.length < 10 && !/\d/.test(query) && /\s+(?:д|дом|д\.)\s+\d+/i.test(address.val())) { 170 address.val(query); 171 } 172 173 // ÐÑиÑаем пÑедÑдÑÑий ÑÐ°Ð¹Ð¼ÐµÑ 174 if (searchTimeout) { 175 clearTimeout(searchTimeout); 176 } 177 178 if (query.length < 2) { 179 hideDropdown(); 180 load_info.empty(); 181 return; 182 } 183 184 load_info.text(iikoLegacy.i18n.searching); 185 186 // ÐобавлÑем debounce Ð´Ð»Ñ Ð¾Ð¿ÑимизаÑии 187 searchTimeout = setTimeout(function() { 188 performSearch(query); 189 }, 300); 190 }); 191 192 function performSearch(query) { 193 // iiko Legacy не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ REST API геокодиÑÐ¾Ð²Ð°Ð½Ð¸Ñ 194 // ÐÑполÑзÑем ÑолÑко ÑÑаÑÑй AJAX обÑабоÑÑик 195 performLegacySearch(query); 196 } 197 198 function performLegacySearch(query) { 199 $.ajax({ 200 url: iikoLegacy.ajaxUrl, 201 method: 'post', 202 dataType: 'json', 203 data: { 204 action: 'kladr_street', 205 city: $('[name="billing_city"] option:selected').val(), 206 street: query, 207 nonce: iikoLegacy.nonce, 208 }, 209 cache: true, 210 timeout: 5000 211 }).done(function (data) { 212 // ÐÑеобÑазÑем в ÑоÑÐ¼Ð°Ñ REST API 213 let response = { 214 success: true, 215 data: { 216 suggestions: [] 217 } 218 }; 219 220 if (Array.isArray(data)) { 221 response.data.suggestions = data.map(function(item) { 222 return { 223 value: item.name || item, 224 data: { 225 id: item.id || '', 226 name: item.name || item 227 } 228 }; 229 }); 230 } else if (typeof data === 'object') { 231 // ÐбÑÐµÐºÑ Ð²Ð¸Ð´Ð° {id: name, id: name, ...} 232 for (let id in data) { 233 if (data.hasOwnProperty(id)) { 234 response.data.suggestions.push({ 235 value: data[id], 236 data: { 237 id: id, 238 name: data[id] 239 } 240 }); 241 } 242 } 243 } 244 245 handleSearchResponse(response); 246 }).fail(function(jqXHR, textStatus, errorThrown) { 247 console.error('Legacy AJAX search error:', textStatus, errorThrown); 248 showSearchError(); 249 }); 250 } 251 252 function handleSearchResponse(response) { 253 let items = []; 254 255 if (response.success && response.data && response.data.suggestions) { 256 items = response.data.suggestions.map(function(suggestion) { 257 return { 258 id: suggestion.data.id, 259 name: suggestion.value 260 }; 261 }); 262 } 263 264 arr_iiko = items; 265 console.log('Street search response:', response, 'Items:', items); 266 267 if (!items || items.length === 0) { 268 load_info.html( 269 '<span style="color:red;">
269' + iikoLegacy.i18n.notFound + '</span>' 270 ); 271 hideDropdown(); 272 } else { 273 load_info.empty().hide(); 274 createDropdown(items); 275 showDropdown(); 276 } 277 } 278 279 function showSearchError() { 280 load_info.html( 281 '<span style="color:red;">' + iikoLegacy.i18n.searchError + '</span>' 282 ); 283 hideDropdown(); 284 } 285 286 // ÐбÑабоÑка ÐºÐ»Ð°Ð²Ð¸Ñ 287 address.on('keydown', function(e) { 288 if (!dropdown || dropdown.is(':hidden')) { 289 return; 290 } 291 292 let items = dropdown.find('.suggestion-item'); 293 294 if (e.keyCode === 40) { // Arrow Down 295 e.preventDefault(); 296 selectedIndex = Math.min(selectedIndex + 1, items.length - 1); 297 items.removeClass('active').eq(selectedIndex).addClass('active'); 298 } else if (e.keyCode === 38) { // Arrow Up 299 e.preventDefault(); 300 selectedIndex = Math.max(selectedIndex - 1, -1); 301 if (selectedIndex >= 0) { 302 items.removeClass('active').eq(selectedIndex).addClass('active'); 303 } else { 304 items.removeClass('active'); 305 } 306 } else if (e.keyCode === 13) { // Enter 307 e.preventDefault(); 308 if (selectedIndex >= 0 && arr_iiko[selectedIndex]) { 309 let item = arr_iiko[selectedIndex]; 310 selectStreet(selectedIndex, item.id, item.name); 311 } 312 } else if (e.keyCode === 27) { // Escape 313 hideDropdown(); 314 } 315 }); 316 317 // ÐакÑÑÑие пÑи клике вне 318 $(document).on('click', function(e) { 319 if (!$(e.target).closest('.iiko-autocomplete-wrapper').length) { 320 hideDropdown(); 321 } 322 }); 323 } 324});
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.