1"use strict" 2const getDateToday = () => { 3 let today = new Date(); 4 let dd = String(today.getDate()).padStart(2, '0'); 5 let mm = String(today.getMonth() + 1).padStart(2, '0'); 6 let yyyy = today.getFullYear(); 7 8 return yyyy + '-' + mm + '-' + dd; 9} 10 11const getLabelDateValue = (date) => { 12 // Obtener la fecha de hoy 13 let today = new Date(); 14 let todayString = getDateToday(); 15 16 // Obtener la fecha de mañana 17 let tomorrow = new Date(today); 18 tomorrow.setDate(today.getDate() + 1); 19 let ddTom = String(tomorrow.getDate()).padStart(2, '0'); 20 let mmTom = String(tomorrow.getMonth() + 1).padStart(2, '0'); // Enero es 0 21 let yyyyTom = tomorrow.getFullYear(); 22 23 var tomorrowString = yyyyTom + '-' + mmTom + '-' + ddTom; 24 25 // Valores nombres 26 const monthNames = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Sep.', 'Octubre', 'Nov.', 'Dic.']; 27 const dayNames = ['Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab', 'Dom']; 28 29 // Determinamos nombres 30 const fechaSelected = new Date(date); 31 const dayName = dayNames[fechaSelected.getDay()]; 32 const monthName = monthNames[date.split('-')[1] - 1]; 33 34 if(date == todayString){ 35 return `Hoy, ${date.split('-')[2]} ${monthName}`; 36 } 37 else if(date == tomorrowString) { 38 return `Mañ, ${date.split('-')[2]} ${monthName}`; 39 } 40 else { 41 return `${dayName}, ${date.split('-')[2]} ${monthName}`; 42 } 43} 44 45const inputSelectedDateIdaToSearch = document.getElementById('shopInputDateIda'); 46const labelSelectedDateIdaToSearch = document.getElementById('shopLabelDateIda'); 47 48inputSelectedDateIdaToSearch.value = getDateToday(); 49const labelStringIda = getLabelDateValue(inputSelectedDateIdaToSearch.value); 50labelSelectedDateIdaToSearch.innerHTML = labelStringIda; 51 52inputSelectedDateIdaToSearch.addEventListener('change', () => { 53 const labelString = getLabelDateValue(inputSelectedDateIdaToSearch.value); 54 labelSelectedDateIdaToSearch.innerHTML = labelString; 55}); 56 57const inputSelectedDateVueltaToSearch = document.getElementById('shopInputDateVuelta'); 58const labelSelectedDateVueltaToSearch = document.getElementById('shopLabelDateVuelta'); 59 60inputSelectedDateVueltaToSearch.value = getDateToday(); 61const labelStringVuelta = getLabelDateValue(inputSelectedDateVueltaToSearch.value); 62labelSelectedDateVueltaToSearch.innerHTML = labelStringVuelta; 63 64inputSelectedDateVueltaToSearch.addEventListener('change', () => { 65 const labelString = getLabelDateValue(inputSelectedDateVueltaToSearch.value); 66 labelSelectedDateVueltaToSearch.innerHTML = labelString; 67}); 68 69// Función para formatear una fecha en formato YYYY-MM-DD 70function formatearFecha(fecha) { 71 let dd = String(fecha.getDate()).padStart(2, '0'); 72 let mm = String(fecha.getMonth() + 1).padStart(2, '0'); // Enero es 0 73 let yyyy = fecha.getFullYear(); 74 return yyyy + '-' + mm + '-' + dd; 75} 76 77// Función para obtener la fecha del día anterior 78function getDateBeforeOne(fechaString) { 79 let fecha = new Date(fechaString); 80 let hoy = new Date(); 81 hoy.setHours(0, 0, 0, 0); 82 if (fecha >= hoy) { 83 return formatearFecha(fecha); 84 } else { 85 return formatearFecha(hoy); 86 } 87} 88 89// Función para obtener la fecha del día siguiente 90function getDateAfterOne(fechaString) { 91 let fecha = new Date(fechaString); 92 fecha.setDate(fecha.getDate() + 2); 93 return formatearFecha(fecha); 94} 95 96const getDateByBtnIda = (type) => { 97 const dateSend = inputSelectedDateIdaToSearch.value; 98 99 if(type){ 100 const date = getDateAfterOne(dateSend); 101 inputSelectedDateIdaToSearch.value = date; 102 const labelString = getLabelDateValue(date); 103 labelSelectedDateIdaToSearch.innerHTML = labelString; 104 } 105 else { 106 const date = getDateBeforeOne(dateSend); 107 inputSelectedDateIdaToSearch.value = date; 108 const labelString = getLabelDateValue(date); 109 labelSelectedDateIdaToSearch.innerHTML = labelString; 110 } 111} 112 113const getDateByBtnVuelta = (type) => { 114 const dateSend = inputSelectedDateVueltaToSearch.value; 115 116 if(type){ 117 const date = getDateAfterOne(dateSend); 118 inputSelectedDateVueltaToSearch.value = date; 119 const labelString = getLabelDateValue(date); 120 labelSelectedDateVueltaToSearch.innerHTML = labelString; 121 } 122 else { 123 const date = getDateBeforeOne(dateSend); 124 inputSelectedDateVueltaToSearch.value = date; 125 const labelString = getLabelDateValue(date); 126 labelSelectedDateVueltaToSearch.innerHTML = labelString; 127 } 128} 129 130// __________________________________________________________ 131// Data selected Ida and Vuelta 132const shopRadioIda = document.getElementById('shopRadioIda'); 133const shopRadioVuelta = document.getElementById('shopRadioIdaVuelta'); 134const shopInputDateVueltaContainer = document.getElementById('shopInputDateVueltaContainer'); 135
136shopRadioIda.addEventListener('change', () => { 137 if(shopRadioIda.checked){ 138 shopInputDateVueltaContainer.style.display = 'none'; 139 } 140}); 141 142shopRadioVuelta.addEventListener('change', () => { 143 if(shopRadioVuelta.checked){ 144 shopInputDateVueltaContainer.style.display = 'flex'; 145 } 146}); 147 148// __________________________________________________________ 149// Data input place from 150 151const shopInputToSearchFrom = document.getElementById('shopInputToSearchFrom'); 152const shopOptionsToPlaceFrom = document.getElementById('shopOptionsToPlaceFrom'); 153 154shopInputToSearchFrom.addEventListener('click', () => { 155 // Solo buscar si hay texto en el input 156 if (shopInputToSearchFrom.value.trim().length > 0) { 157 searchPlacesToData({valor:shopInputToSearchFrom, type:0}); 158 } 159}); 160 161const shopInputToSearchTo = document.getElementById('shopInputToSearchTo'); 162const shopOptionsToPlaceTo = document.getElementById('shopOptionsToPlaceTo'); 163 164shopInputToSearchTo.addEventListener('click', () => { 165 // Solo buscar si hay texto en el input 166 if (shopInputToSearchTo.value.trim().length > 0) { 167 searchPlacesToData({valor:shopInputToSearchTo, type:1}); 168 } 169}); 170 171 172async function obtenerDatos(text) { 173 try { 174 const respuesta = await fetch("/search/" + text, { 175 method: 'GET', 176 headers: { 177 'Accept': 'application/json, text/javascript, */*; q=0.01', 178 } 179 }); 180 181 if (!respuesta.ok) { 182 throw new Error('Error en la solicitud'); 183 } 184 185 const datos = await respuesta.json(); 186 if(!datos.status || !datos.results) return [] 187 return datos.results; 188 } catch (error) { 189 console.error('Error al obtener los datos:', error); 190 return null; 191 } 192} 193 194 195const searchPlacesToData = async ({valor, type}) => { 196 let useElement = type ? shopOptionsToPlaceTo : shopOptionsToPlaceFrom; 197 let ocultElement = type ? shopOptionsToPlaceFrom : shopOptionsToPlaceTo; 198 let useFunction = type ? 'shopSelectedItemSearchTo' : 'shopSelectedItemSearchFrom'; 199 200 const search = valor.value.toLowerCase().trim(); 201 202 useElement.innerHTML = ''; 203 useElement.style.display = 'flex'; 204 ocultElement.style.display = 'none'; 205 let itemsContador = 0; 206 207 // No hacer petición si la búsqueda está vacía o es muy corta 208 if (search === '' || search.length < 2) { 209 useElement.style.display = 'none'; 210 return; 211 } 212 213 let itemsFilter = await obtenerDatos(search); 214 215 // Verificar si obtuvimos datos válidos 216 if (itemsFilter && Array.isArray(itemsFilter)) { 217 itemsFilter.forEach(item => { 218 itemsContador += 1; 219 220 const spanContent = document.createElement('span'); 221 spanContent.classList.add('shop__place-items'); 222 spanContent.innerHTML = `<a class="shop__place-option" onclick="${useFunction}(${item.Id}, '${item.Name}')">${item.Name}</a>`; 223 useElement.append(spanContent); 224 }); 225 } else { 226 // Si no hay datos válidos, mostrar mensaje de error 227 console.warn('No se pudieron obtener los datos de búsqueda'); 228 itemsFilter = []; // Asignar array vacío para evitar errores 229 } 230 231 if(search == '' || search == ' '){ 232 useElement.style.display = 'none'; 233 } 234 else if(itemsContador == 0){ 235 const spanContent = document.createElement('span'); 236 spanContent.classList.add('shop__place-items'); 237 spanContent.innerHTML = `<p class="shop__place-option">No hay coincidencias ...</a>`; 238 useElement.append(spanContent); 239 } 240 else { 241 useElement.style.display = 'flex'; 242 } 243 244 if(valor.keyCode == 27){ 245 useElement.style.display = 'none'; 246 valor.target.value = ''; 247 } 248} 249 250function debounce(func, delay = 300) { 251 let timeout; 252 return (...args) => { 253 clearTimeout(timeout); 254 timeout = setTimeout(() => func(...args), delay); 255 }; 256} 257 258const debouncedBuscar = debounce(searchPlacesToData, 400); 259 260// Busqueda mediante input text 261document.addEventListener('keyup', async e => { 262 if(e.target.matches('#shopInputToSearchFrom')){ 263 // Solo buscar si hay al menos 2 caracteres 264 if (e.target.value.trim().length >= 2) { 265 await debouncedBuscar({valor: e.target, type: 0}); 266 } else { 267 // Ocultar las opciones si hay menos de 2 caracteres 268 shopOptionsToPlaceFrom.style.display = 'none'; 269 } 270 } 271 272 if(e.target.matches('#shopInputToSearchTo')){ 273 // Solo buscar si hay al menos 2 caracteres 274 if (e.target.value.trim().length >= 2) { 275 await debouncedBuscar({valor: e.target, type: 1}); 276 } else { 277 // Ocultar las opciones si hay menos de 2 caracteres 278 shopOptionsToPlaceTo.style.display = 'none'; 279 } 280 } 281}); 282 283// Selected item place Ida 284const shopSelectedItemSearchFrom = (id, name) => { 285 shopInputToSearchFrom.value = `${name}`; 286 shopInputToSearchFromSend.value = id; 287 shopOptionsToPlaceFrom.innerHTML = ''; 288 shopOptionsToPlaceFrom.style.display = 'none'; 289} 290 291// Selected item place Vuelta 292const shopSelectedItemSearchTo = (id, name) => { 293 shopInputToSearchTo.value = `${name}`; 294 shopInputToSearchToSend.value = id; 295 shopOptionsToPlaceTo.innerHTML = ''; 296 shopOptionsToPlaceTo.style.display = 'none'; 297} 298 299// __________________________________________________________ 300// Data input peoples quantity 301const shopOptionsToPeopleQuantity = document.getElementById('shopOptionsToPeopleQuantity'); 302const shopInputPeopleQuantity = document.getElementById('shopInputPeopleQuantity'); 303 304shopInputPeopleQuantity.addEventListener('click', () => { 305 if(shopOptionsToPeopleQuantity.style.display == 'block'){ 306 shopOptionsToPeopleQuantity.style.display = 'none'; 307 } 308 else { 309 shopOptionsToPeopleQuantity.style.display = 'block'; 310 } 311}); 312 313const arrItemQtyPeoles = document.querySelectorAll('.shop__people-qty'); 314const shopLabelPeopleQuantity = document.getElementById('shopLabelPeopleQuantity'); 315 316const shopEditQuantityPeople = (type, item) => { 317 const editText = arrItemQtyPeoles[item]; 318 319 if(Number(editText.textContent) <= 0 && !type) { 320 editText.textContent = 0; 321 } 322 else { 323 if(type){ 324 if(Number(editText.textContent) < 8) editText.textContent = Number(editText.textContent) + 1; 325 } 326 else { 327 editText.textContent = Number(editText.textContent) - 1; 328 } 329 } 330 331 let total = 0;
332 arrItemQtyPeoles.forEach((item) => { 333 total += Number(item.textContent) ? Number(item.textContent) : 0; 334 }); 335 336 shopLabelPeopleQuantity.textContent = total == 1 || total == 0 ? `1 pasajero` : `${total} pasajeros`; 337 shopInputPeopleQuantitySend.value = total || 1; 338 arrItemQtyPeoles[0].textContent = total == 0 ? 1 : arrItemQtyPeoles[0].textContent; 339} 340 341//url de busqueda 342const base_url_search = ({ 343 OrigenId, 344 destinoId, 345 idaVuelta, 346 fechaIda, 347 fechaVuelta, 348 CantidadPasajeros 349}) => { 350 return `https://reservadirecta.sittnet.net/Commerce/elpulqui/ServicioButacaOmnibus/ServiciosButacasOmnibusBusquedaExterna?OrigenId=${OrigenId}&destinoId=${destinoId}&idaVuelta=${idaVuelta}&fechaIda=${fechaIda}&fechaVuelta=${fechaVuelta}&CantidadPasajeros=${CantidadPasajeros}` 351} 352 353// Send Data 354const sendDataSearch = () => { 355 const idaActive = shopRadioIda.checked; 356 const idaVueltaActive = shopRadioIdaVuelta.checked; 357 const from = shopInputToSearchFromSend.value; 358 const to = shopInputToSearchToSend.value; 359 const ida = shopInputDateIda.value; 360 const vuelta = shopInputDateVuelta.value; 361 const qty = shopInputPeopleQuantitySend.value; 362 363 let adv = document.getElementById('home-card-adv'); 364 365 if(window.innerWidth <= 650 || screen.width <= 650){ 366 adv = document.getElementById('home-card-adv-respo'); 367 } 368 369 if(!idaActive && !idaVueltaActive){ 370 adv.innerHTML = '* Error, seleccione si es ida o ida y vuelta'; 371 adv.style.display = 'block'; 372 return; 373 } 374 375 if(!Number(from)){ 376 adv.innerHTML = '* Error, seleccione el punto de salida'; 377 adv.style.display = 'block'; 378 return; 379 } 380 381 if(!Number(to)){ 382 adv.innerHTML = '* Error, seleccione el punto de destino'; 383 adv.style.display = 'block'; 384 return; 385 } 386 387 const hoy = new Date(); 388 const dia = String(hoy.getDate()).padStart(2, '0'); 389 const mes = String(hoy.getMonth() + 1).padStart(2, '0'); // Los meses empiezan desde 0 390 const anio = hoy.getFullYear(); 391 392 const fechaActual = `${anio}-${mes}-${dia}`; 393 394 if(ida == '' || ida < fechaActual){ 395 adv.innerHTML = '* Error, seleccione una fecha de ida'; 396 adv.style.display = 'block'; 397 return; 398 } 399 400 if(idaVueltaActive && (vuelta == '' || vuelta < ida)){ 401 adv.innerHTML = '* Error, la fecha de vuelta debe ser mayor a la fecha de ida'; 402 adv.style.display = 'block'; 403 return; 404 } 405 406 if(Number(qty) < 1){ 407 adv.innerHTML = '* Error, selecciones la cantidad de pasajeros'; 408 adv.style.display = 'block'; 409 return; 410 } 411 412 const type = idaVueltaActive ? 'ida_vuelta' : 'ida'; 413 414 function convertirFecha(fecha) { 415 const [year, month, day] = fecha.split("-"); // Dividir la fecha por "-" 416 return `${day}/${month}/${year}`; // Reorganizar en formato dd/mm/aaaa 417 } 418 419 const valores_search = { 420 OrigenId: from, 421 destinoId: to, 422 idaVuelta: idaVueltaActive, 423 fechaIda: convertirFecha(ida), 424 fechaVuelta: convertirFecha(vuelta), 425 CantidadPasajeros: qty 426 } 427 const url = base_url_search(valores_search); 428 window.open(url, '_blank'); 429}
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.