1gsap.registerPlugin(ScrollTrigger); 2let _sliders=[]; 3let carreras = []; 4let modalidads = []; 5let horarios = []; 6let especializacions = []; 7let cantones = []; 8let loadContent = !0; 9let sliderLoad= false; 10const formValidators = new Map(); 11const animacion = "animate__pulse"; 12const mediaElements = document.querySelectorAll("#listaItemsFlecha .itemflecha"); 13const exampleModal = document.getElementById("formInscripcionModal"); 14const forms = document.querySelectorAll(".needs-validation"); 15let splitTextInstances = [],swiperInstance = null; 16const homeCarousel = document.getElementById("homeCarousel"); 17let videoBg = document.getElementById("bgvideo"); 18let audioBg = null; 19let hideVideo = getCookie("hideVideo") || !1; 20window.addEventListener("load", function () { 21 if (window.innerWidth < 768) { hideVideo = !0;} 22 if (!hideVideo) { LoadVideo();} 23 InitMask(); 24}); 25window.addEventListener("scroll", (e) => { 26 if (window.scrollY > 200 && loadContent) { 27 loadContent = !1; 28 InitSwipper(); 29 StartAnimScroll(); 30 LoadBgIamges(); 31 LazyLoadIframes(); 32 } 33}); 34window.onbeforeunload = function (){if(prelodmask == 1){window.scrollTo(0,0);}}; 35function InitMask(){ 36 const overlay = document.getElementById("overlay"); 37 const preloader = document.getElementById("preloader"); 38 const body = document.getElementById("body"); 39 const tl = gsap.timeline({ ease: "power2.out" }); 40 if (hideVideo){ 41 tl.add(()=>{RenderCarrousel();},0.3); 42 } 43 if (prelodmask == 1 && hideVideo) { 44 tl.add(() => { 45 if (preloader) preloader.style.display = "none"; 46 }, 0.3).add(() => { 47 if (overlay) { 48 overlay.style.display = "none"; 49 body.style.overflow = "auto"; 50 } 51 }, 3); 52 } else if (prelodmask == 1 && !hideVideo) { 53 tl.add(() => { 54 if (overlay) { 55 overlay.style.display = "none"; 56 body.style.overflow = "auto"; 57 } 58 }, 3); 59 } 60} 61function LoadVideo() { 62 if (!videoBg) return; 63 document.getElementById("preloader-bg").classList.remove("d-none"); 64 const sourceMp4 = document.createElement("source"); 65 sourceMp4.src = _root + "/statics/video/bgvideo.mp4"; 66 sourceMp4.type = "video/mp4"; 67 const sourceWebm = document.createElement("source"); 68 sourceWebm.src = _root + "/statics/video/bgvideo.mp4"; 69 sourceWebm.type = "video/webm"; 70 videoBg.appendChild(sourceMp4); 71 videoBg.appendChild(sourceWebm); 72 videoBg.load(); 73 74 // Configurar y reproducir audio de fondo 75 if (!audioBg) { 76 audioBg = new Audio(_root + "/statics/video/cancion.mp3"); 77 audioBg.volume = 0.5; // Volumen al 50% 78 audioBg.loop = false; 79 } 80 81 // Intentar reproducir ambos 82 videoBg.play().catch((error) => { 83 EndVideo(); 84 }); 85 86 audioBg.play().catch((error) => { 87 // console.log("Autoplay de audio bloqueado por el navegador:", error); 88 // No detenemos el video si solo falla el audio 89 }); 90 91 StartVideo(); 92} 93function StartVideo() { 94 if (videoBg) { 95 videoBg.addEventListener("ended", function () { 96 EndVideo(); 97 }); 98 } 99} 100function EndVideo() { 101 if (audioBg) { 102 audioBg.pause(); 103 audioBg.currentTime = 0; 104 audioBg = null; 105 } 106 107 if (videoBg) { 108 videoBg.pause(); 109 videoBg.removeAttribute("src"); 110 videoBg.load(); 111 document.getElementById("body").style.overflow = "auto"; 112 if (videoBg.parentNode) { 113 videoBg.parentNode.removeChild(videoBg); 114 } 115 document.getElementById("preloader-bg").classList.add("d-none"); 116 } 117 EndLoadEffect(); 118} 119 120function ToggleAudio() { 121 const btn = document.getElementById("btnToggleAudio"); 122 if (!audioBg) return; 123 124 if (audioBg.paused) { 125 // Sincronizar audio con el video actual 126 if (videoBg) { 127 audioBg.currentTime = videoBg.currentTime; 128 } 129 audioBg.play().then(() => { 130 if (btn) btn.innerText = "Silenciar"; 131 }).catch(err => console.log(err)); 132 } else { 133 audioBg.pause(); 134 if (btn) btn.innerText = "Activar Sonido"; 135 } 136} 137 138// Intentar activar audio con el primer clic en el documento si no se ha activado aun 139document.addEventListener('click', function EnableAudioOnInteraction() { 140 if (audioBg && audioBg.paused) { 141 const btn = document.getElementById("btnToggleAudio"); 142 audioBg.play().then(() => { 143 if (btn) btn.innerText = "Silenciar"; 144 }).catch(() => {}); 145 } 146 document.removeEventListener('click', EnableAudioOnInteraction); 147}, { once: true }); 148
149function SkipVideo() { 150 setCookie("hideVideo", !0, 2); 151 EndVideo(); 152} 153function CloseVideo() { EndVideo();} 154function RenderCarrousel() { 155 if (homeCarousel.classList.contains("swiper-initialized")) return; 156 const limitCarga = 1; 157 document.fonts.ready.then(() => { 158 const homeCarouselElement = document.getElementById("homeCarousel"); 159 if (homeCarouselElement) { homeCarouselElement.classList.add("animate__animated","animate__fadeInUp"); } 160 document.body.style.overflow = "auto"; 161 if (homeCarousel) homeCarousel.classList.remove("d-none"); 162 const swEffect1 = {prev:{shadow:true,translate:[0,0,-400]},next:{translate:["100%",0,0]}}; 163 const swEffect2 = {prev:{shadow:true,translate:["-120%",0,-500]},next:{shadow:true,translate:["120%",0,-500]}}; 164 const swEffect3 = {prev:{shadow:true,translate:["-20%",0,-1]},next:{translate:["100%",0,0]}}; 165 const allEffects = [swEffect1,swEffect2,swEffect3]; 166 let nrndEffect =Math.floor(Math.random() * allEffects.length); 167 const randomEffect = allEffects[nrndEffect]; 168 const swiperHome = new Swiper(".home-swiper", 169 { grabCursor: true, 170 effect: "creative", 171 autoplay: { 172 delay: 5000,// 5 segundos entre slides 173 disableOnInteraction: false,// Continúa después de que el usuario interactúa 174 pauseOnMouseEnter: true,// Pausa al pasar el mouse (opcional) 175 }, 176 creativeEffect : randomEffect, 177 slidesPerView : 1, 178 loop: true, 179 lazy : true, 180 a11y: { 181 enabled: true, 182 prevSlideMessage: 'Slide anterior', 183 nextSlideMessage: 'Siguiente slide', 184 }, 185 } 186 ); 187 const slides = document.querySelectorAll(".swiper-slide"); 188 const outerWrappers = gsap.utils.toArray(".outer"); 189 const innerWrappers = gsap.utils.toArray(".inner"); 190 gsap.set([outerWrappers,innerWrappers],{yPercent:(i)=>i<outerWrappers.length?100:-100}); 191 let currentIndex = 0; 192 let shouldLoadMore = false; 193 AnimateSlide(currentIndex,1); 194 swiperHome.on("slideChangeTransitionStart",()=> {
195 const loadMore = homeCarouselElement.getAttribute("data-load-slider"); 196 const nextIndex = swiperHome.realIndex; 197 if (limitCarga === nextIndex && loadMore === 'true' && _sliders.length > 0) { 198 shouldLoadMore = true; 199 homeCarouselElement.setAttribute("data-load-slider", "false"); 200 } 201 const direction = nextIndex > currentIndex || (nextIndex === 0 && currentIndex === slides.length - 1) ? 1 : -1; 202 AnimateSlide(nextIndex, direction); 203 currentIndex = nextIndex; 204 }); 205 swiperHome.on("slideChangeTransitionEnd",()=>{ 206 if (shouldLoadMore) { 207 shouldLoadMore = false; 208 const wrapper = homeCarousel.querySelector('.swiper-wrapper'); 209 let slidesHtml = ''; 210 _sliders.forEach((slide,index) => { 211 if (index > 1 && slide.rutalg && slide.rutalg.length > 0){ 212 const desktopImage= slide.rutalg?`https://www.itb.edu.ec/${slide.rutalg}`:`${_root}statics/imagenes/plantilla/portada.jpg`; 213 const mobileImage= slide.ruta?`https://www.itb.edu.ec/${slide.ruta}`:`${_root}statics/imagenes/main/arte4.jpg`; 214 if(slide.btnlabel && slide.btnlabel.length > 0){ 215 console.log('URL',slide.url); 216 slidesHtml += `<div class="swiper-slide section"> 217 <img class="d-none d-sm-none d-md-block bg lazyload" data-src="${desktopImage}" alt="Imagen 1"> 218 <img class="d-block d-sm-block d-md-none bg lazyload" data-src="${mobileImage}" alt="Imagen 1, Mobile"> 219 <div class="caption"> 220 <div class="container"> 221 <div class="row"> 222 <div class="col-12 col-md-7 col-lg-6 pe-5 d-flex flex-column justify-content-center align-items-start"> 223 <div class="outer"><div class="inner"> 224 <h1 class="section-heading text-start p-0 heading-style"> <span class="text-naranja">${slide.titulo||'Imagen'}</span><br> </h1></div></div> 225 <div id="botton-container" class="botton-container mt-5"> 226 <div class="row"><div class="col-12 col-md-6"> 227 <a class="btn btn-naranja px-5 mx-1" target="_blank" href="${slide.url||'#'}">${slide.btnlabel||'clic aqui'}</a> 228 </div></div></div> 229 </div> 230 </div> 231 </div> 232 </div> 233 </div>`; 234 }else{ 235 slidesHtml += `<div class="swiper-slide only-image"> 236 <img class="d-none d-sm-none d-md-block bg lazyload" data-src="${desktopImage}" alt="Desktop ${slide.titulo||'Imagen'}"> 237 <img class="d-block d-sm-block d-md-none bg lazyload" data-src="${mobileImage}" alt="Mobil ${slide.titulo||'Imagen'}"></div>`; 238 } 239 } 240 }); 241 wrapper.insertAdjacentHTML('beforeend', slidesHtml); 242 swiperHome.update(); 243 } 244 }); 245 }); 246} 247function AnimateSlide(index, direction = 1) { 248 const prelodmask = index === 0; 249 const dFactor = direction === 1 ? 1 : -1; 250 const slide = document.querySelectorAll(".swiper-slide.section")[index]; 251 if (!slide) return; 252 const [outer,inner,heading,subtitle,btns,image] = [ 253 slide.querySelector(".outer"), 254 slide.querySelector(".inner"), 255 slide.querySelector(".section-heading"), 256 slide.querySelector(".hero-subtitle"), 257 slide.querySelector(".botton-container"), 258 slide.querySelector(".bg") 259 ]; 260 const elementsToAnimate = [outer,inner,heading,subtitle,btns,image].filter(
260Boolean); 261 gsap.killTweensOf(elementsToAnimate); 262 const tl = gsap.timeline({defaults:{duration:prelodmask?1:0.7,ease:"power1.inOut"}}); 263 gsap.set([outer,inner,heading,subtitle,btns,image],{ clearProps: "all" }); 264 if (image){ 265 tl.fromTo(image, 266 {scale:1.1,xPercent:20 * dFactor,filter:"blur(10px)",opacity:0}, 267 {scale:1,xPercent:0,filter:"blur(0px)",opacity:1,duration:prelodmask?1:0.5,ease:"power3.out" }); 268 } 269 if (outer && inner) { 270 tl.fromTo([outer, inner], { yPercent: (i) => (i ? -100*dFactor:100*dFactor)},{yPercent:0},">"); 271 } 272 if (heading) { 273 tl.fromTo(heading, {y:50,opacity:0},{y:0,opacity:1,duration:prelodmask?1.2:0.6,ease:"power2.out" },">"); 274 } 275 if (subtitle) { 276 tl.fromTo(subtitle, {y:50,opacity:0},{y:0,opacity:1,duration:prelodmask?1.2:0.6,ease:"power2.out" },">"); 277 } 278 if (btns) { 279 tl.fromTo(btns, {scale:0.8,opacity:0,y:60},{scale:1,opacity:1,y:0,duration:prelodmask?1.3:0.8,ease:"back.out(1.7)"},">"); 280 } 281} 282function EndLoadEffect() { 283 RenderCarrousel(); 284} 285function StartAnimScroll() { 286 document.querySelectorAll(".anim").forEach((el) => { 287 if (el.hasAttribute("data-animate")) { 288 const animClass = "animate__" + el.getAttribute("data-animate"); 289 ScrollTrigger.create({ trigger: el, start: "top 98%", onEnter: () => el.classList.add("animate__animated", animClass), onLeaveBack: () => el.classList.remove("animate__animated", animClass), once: !1 }); 290 } 291 }); 292} 293function LoadBgIamges() { 294 const lazyBackgrounds = document.querySelectorAll("[data-bg-image]"); 295 if ("IntersectionObserver" in window) { 296 let lazyObserver = new IntersectionObserver((entries,observer) => { 297 entries.forEach((entry) => { 298 if (entry.isIntersecting) { 299 const element = entry.target; 300 const imageUrl = element.getAttribute("data-bg-image"); 301 const claseImg = element.hasAttribute("data-repeat")?'lazy-background-loaded-repeat':'lazy-background-loaded'; 302 element.style.backgroundImage = `url(${imageUrl})`; 303 element.classList.add(claseImg); 304 observer.unobserve(element); 305 } 306 }); 307 }); 308 lazyBackgrounds.forEach((element) => { 309 lazyObserver.observe(element); 310 }); 311 } 312} 313function LazyLoadIframes() { 314 const iframeContainers = document.querySelectorAll(".lazy-iframe"); 315 iframeContainers.forEach(container => { 316 const dataSrc = container.getAttribute("data-src"); 317 // Skip if no data-src attribute or if it's empty 318 if (!dataSrc || dataSrc.trim() === '') { return; } 319 if ("IntersectionObserver" in window) { 320 const observer = new IntersectionObserver((entries, obs) => { 321 entries.forEach((entry) => { 322 if (entry.isIntersecting) { 323 container.innerHTML = `<iframe 324 data-testid="embed-iframe" 325 style="border-radius:12px" 326 src="${dataSrc}" 327 width="100%" 328 height="300" 329 frameborder="0" 330 allowfullscreen 331 allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" 332 loading="lazy"></iframe>`; 333 container.removeAttribute("data-src"); 334 obs.unobserve(container); 335 } 336 }); 337 }); 338 observer.observe(container); 339 } else { 340 // Fallback for browsers without IntersectionObserver 341 container.innerHTML = `<iframe 342 data-testid="embed-iframe" 343 style="border-radius:12px" 344 src="${dataSrc}" 345 width="100%" 346 height="300" 347 frameborder="0" 348 allowfullscreen 349 allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" 350 loading="lazy"></iframe>`; 351 container.removeAttribute("data-src"); 352 } 353 }); 354} 355function InitSwipper() { 356 new Swiper("#ofertasGrupo", { slidesPerView: 1, spaceBetween: 30, pagination: { clickable: !0, hide: !0 }, breakpoints: { 357 1100:{slidesPerView: 5, spaceBetween: 30}, 358 768:{slidesPerView: 4, spaceBetween: 30} 359 } }); 360 new Swiper(".swiper-artec", { 361 effect: "cards", 362 grabCursor: !0, 363 on: { 364 slideChange: () => {
365 document.querySelectorAll(".card-img-overlay.active").forEach((o) => o.classList.remove("active")); 366 }, 367 }, 368 }); 369 new Swiper("#avalesContent",{ slidesPerView: 1, spaceBetween: 30, pagination: { clickable: !0, hide: !0 }, breakpoints: { 768: { slidesPerView: 4, spaceBetween: 30 } } }); 370 new Swiper(".swiper-artec",{ 371 effect: "cards", 372 grabCursor: !0, 373 on: { 374 slideChange: () => { 375 document.querySelectorAll(".card-img-overlay.active").forEach((o) => o.classList.remove("active")); 376 }, 377 }, 378 }); 379} 380if (exampleModal) { 381 exampleModal.addEventListener("show.bs.modal", () => { 382 document.querySelector(".caption .outer").classList.add("d-none"); 383 document.querySelector(".hero-subtitle").classList.add("d-none"); 384 document.getElementById("botton-container").classList.add("d-none"); 385 loadInscriptForm(); 386 ResetModalFrm(); 387 }); 388 exampleModal.addEventListener("hide.bs.modal", () => { 389 document.getElementById("botton-container").classList.remove("d-none"); 390 document.querySelector(".caption .outer").classList.remove("d-none"); 391 document.querySelector(".hero-subtitle").classList.remove("d-none"); 392 }); 393} 394 395function loadInscriptForm() { 396 if (carreras.length > 0) return; 397 $.ajax({ 398 type: "POST", 399 url: _root + "ajaxsapp/ajax", 400 headers: { "X-Requested-With": "XMLHttpRequest" }, 401 data: { action: "formdatainscrip" }, 402 success: function (data) { 403 // ESPECIALIDADES 404 especializacions = data.especializaciones || []; 405 let espeOpt = "<option value=''>Seleccione una especialidad</option>"; 406 $.each(especializacions, function(i, fila){ 407 espeOpt += `<option value="${fila.id}">${fila.descripcion}</option>`; 408 }); 409 $("#especialidad_id").html(espeOpt); 410 safeSelectpickerUpdate("#especialidad_id"); 411 412 // CARRERAS 413 carreras = data.carreras || []; 414 let carOpt = "<option value=''>Seleccione una carrera</option>"; 415 $.each(carreras, function(i, fila){ 416 carOpt += `<option value="${fila.id}">${fila.descripcion}</option>`; 417 }); 418 $("#carrera_id").html(carOpt); 419 safeSelectpickerUpdate("#carrera_id"); 420 421 // COLEGIOS 422 let colOpt = "<option value=''>Seleccione un colegio</option>"; 423 $.each(data.colegios || [], function(i, fila){ 424 const id = fila.id ?? fila.iD ?? fila.iD; 425 const label = fila.descripcion ?? fila.Name ?? fila.nombre ?? ""; 426 colOpt += `<option value="${id}">${label}</option>`; 427 }); 428 $("#colegio_id").html(colOpt); 429 safeSelectpickerUpdate("#colegio_id"); 430 431 // CANTONES / CIUDADES 432 let ciuOpt = "<option value=''>Seleccione una ciudad</option>"; 433 $.each(data.cantones || [], function(i, fila){ 434 ciuOpt += `<option value="${fila.id}">${fila.nombre} - ${fila.provincia}</option>`; 435 }); 436 $("#ciudad_id").html(ciuOpt); 437 safeSelectpickerUpdate("#ciudad_id"); 438 439 // Re-initialize parroquia_id but keep it empty initially 440 $("#parroquia_id").html("<option value=''>Seleccione una parroquia</option>"); 441 442 // ZONAS 443 let zonOpt = "<option value=''>Seleccione una zona</option>"; 444 $.each(data.zonas || [], function(i, fila){ 445 zonOpt += `<option value="${fila.id}">${fila.nombre}</option>`; 446 }); 447 $("#zona_id").html(zonOpt); 448 449 // ENCUESTA 450 const pregunta = (data.encuesta && data.encuesta.pregunta && data.encuesta.pregunta.length > 0) 451 ? data.encuesta.pregunta 452 : "¿Por qué medio llegaste a nuestro sitio web?"; 453 $("#lblPregunta").html(pregunta); 454 let selec = "<option value=''>Seleccione una respuesta</option>"; 455 $.each(data.opciones || [], function (i, op) { 456 selec += `<option value="${op.id}">${op.descripcion}</option>`; 457 }); 458 $("#opcion_id").html(selec); 459 safeSelectpickerUpdate("#opcion_id"); 460 }, 461 error: function (xhr, status, error) { 462 console.log(error); 463 }, 464 }); 465} 466 467function safeSelectpickerUpdate(selector) { 468 const $el = $(selector); 469 if (!$el.length) return; 470 if (typeof $el.selectpicker !== 'function') { 471 return; 472 } 473 try { 474 $el.selectpicker('destroy'); 475 } catch(e) { 476 477 } 478 $el.selectpicker(); 479 try { 480 $el.selectpicker('render'); 481 } catch (e) { 482 try { $el.selectpicker('refresh'); } catch(e2) {} 483 } 484} 485 486function loadModalidaCarrera(id){ 487 let opcion = "<option selected value=''>Seleccione una modalidad</option>"; 488 $.ajax({ 489 type: 'POST', 490 url: _root + 'ajaxsapp/ajax', 491 headers: {'X-Requested-With':'XMLHttpRequest'}, 492 data: { 493 action: 'modalidad_idcarrera', 494 carreraid: id 495 }, 496 success: function(data){ 497 modalidads = data.modalidads || []; 498 horarios = data.horarios || []; 499 if (modalidads.length > 0) { 500 $.each(modalidads, function(i, fila){ 501 opcion += `<option value="${fila.id}">${fila.descripcion}</option>`; 502 }); 503 } 504 $("#modalidad_id").html(opcion); 505 $("#horario_id").html("<option selected value=''>Seleccione un horario</option>"); 506 $("#infoHorario").addClass('d-none'); 507 $("#pendiente_horario").val(''); 508 } 509 }); 510} 511 512function loadHorarios(){ 513 const id = $("#modalidad_id").val(); 514 let opcion = "<option value=''>Seleccione un horario</option>"; 515 let hayHorarios = false;
516 $.each(horarios, function(i, fila){ 517 if (id == fila.modalidad_id) { 518 hayHorarios = true; 519 opcion += ` 520 <option 521 data-codigo="${fila.hcodigo}" 522 value="${fila.id}"> 523 ${fila.descripcion} 524 </option>`; 525 } 526 }); 527 if (!hayHorarios) { 528 opcion += ` 529 <option selected value=""> 530 No hay horarios para la carrera â continuar con la pre-inscripción 531 </option>`; 532 } 533 $("#horario_id").html(opcion); 534 $("#codigohora").val(''); 535 if (hayHorarios) { 536 $("#pendiente_horario").val('0'); 537 $("#horario_id").prop('required', true); 538 $("#infoHorario").addClass('d-none'); 539 $("#horario_id").val(''); 540 } else { 541 $("#pendiente_horario").val('1'); 542 $("#horario_id").prop('required', false); 543 $("#infoHorario").removeClass('d-none'); 544 } 545} 546 547document.getElementById('horario_id').addEventListener('change', function () { 548 const selectedOption = this.options[this.selectedIndex]; 549 const codigo = selectedOption.getAttribute('data-codigo'); 550 document.getElementById('codigohora').value = codigo || ''; 551}); 552 553function ResetModalFrm() { 554 const hace15Anios = new Date(new Date().getFullYear() - 15, new Date().getMonth(), new Date().getDate()).toISOString().split("T")[0]; 555 $("#fecha").val(hace15Anios); 556 $("#frmInscriptModal")[0].reset(); 557 setTimeout(function() { 558 $(".selectpicker").selectpicker("refresh"); 559 560 }, 100); 561 $("#litaAlertaErrores").html("<li class='list-group-item bg-transparent p-0 m-0'> ... </li>"); 562 $("#alertFormError").addClass("d-none"); 563 $("#contentBtns").removeClass("d-none"); 564 $("#bar-save-modal").addClass("d-none"); 565 $("#alertErrorDefault").addClass("d-none"); 566} 567function SaveForm() { 568 'use strict'; 569 const form = document.getElementById('frmInscriptModal'); 570 if (!form.checkValidity()) { 571 let firstInvalidElement = null; 572 for(const element of form.elements) { 573 if(element.willValidate && !element.checkValidity()){ 574 if (!firstInvalidElement) { 575 firstInvalidElement = element; 576 } 577 console.error(`Campo: ${element.name || element.id}, Error: ${element.validationMessage}`); 578 } 579 } 580 if(firstInvalidElement) { 581 const tabIndex = firstInvalidElement.getAttribute('data-tab'); 582 const tabs = document.querySelectorAll('#formInscripcionModal [role="tab"]'); 583 if (tabIndex) { 584 const tabButton = document.querySelector(`#inicio-inscripcion-tab button[data-bs-percent="${parseInt(tabIndex)+1}"]`); 585 if (tabButton){ 586 const tab = new bootstrap.Tab(tabButton); 587 tab.show(); 588 } 589 ShowFrmBtns(parseInt(tabIndex)+1,tabs.length); 590 } 591 } 592 }else{ 593 $("#bar-save-modal").removeClass("d-none"); 594 $("#contentBtns").addClass("d-none"); 595 let progressAnimation = animateProgressBar(); 596 const formData = new FormData(form); 597 formData.append('action','addIscipcion'); 598 $.ajax({ 599 url: _root + 'ajaxsapp/ajax', 600 type: 'POST', 601 data: formData, 602 processData : false, 603 contentType : false, 604 headers : {'X-Requested-With': 'XMLHttpRequest'} 605 }).done(function(response){ 606 // console.log('Respuesta AJAX:',response); 607 if(progressAnimation)progressAnimation.progress(1); 608 if(response.success){ 609 ShowAlertModal(response.message,'success','formInscripcionModal',6); 610 }else{ 611 ShowAlertModal(response.message,'error','formInscripcionModal',8); 612 } 613 }).fail(function(jqXHR, textStatus, errorThrown){ 614 if (progressAnimation) progressAnimation.kill(); 615 ShowAlertModal("Errror inesperado, intente más tarde",'error','frmInscriptModal',8); 616 console.error('Error en AJAX:',jqXHR); 617 console.error('Error en AJAX:', textStatus, errorThrown); 618 }); 619 console.log('Formulario válido, listo para enviar.'); 620 } 621 form.classList.add('was-validated'); 622} 623function animateProgressBar(onCompleteCallback) { 624 const progressBar = document.querySelector('#bar-save-modal .progress-bar'); 625 if (!progressBar) return null; 626 let progress = { percent: 0 }; 627 gsap.set(progressBar, { width: '0%' }); 628 progressBar.textContent = '0%'; 629 const tl = gsap.timeline({ 630 onComplete: () => { 631 if (typeof onCompleteCallback === 'function') { 632 onCompleteCallback(); 633 } 634 } 635 }); 636 tl.to(progress, { 637 percent: 100, 638 duration: 2.5, 639 ease: 'power1.inOut', 640 onUpdate: () => { 641 const roundedPercent = Math.round(progress.percent); 642 progressBar.style.width = `${roundedPercent}%`; 643 progressBar.textContent = `${roundedPercent}%`; 644 } 645 }); 646 return tl; 647} 648function ShowAlertModal(texto='',tipo='success',idmodal='',duracion=6){ 649 let alertBody = ''; 650 if(tipo === 'success'){ 651 alertBody = '<div class="alert alert-success" role="alert"><strong class="bi bi-exclamation-triangle-fill flex-shrink-0 me-2">'+ 652 '<i class="fa-regular fa-thumbs-up fa-beat-fade text-success"></i></strong>'+texto+'<div class="progress" id="bar-alert-msj" style="height:2px;">'+ 653 '<div class="progress-bar bg-success" role="progressbar" aria-label="Cerrar" style="width:0;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div></div></div>'; 654 }else{ 655 alertBody = '<div class="alert alert-danger" role="alert"><strong class="bi bi-exclamation-triangle-fill flex-shrink-0 me-2">'+ 656 '<i class="fa-solid fa-bug fa-shake text-danger"></i></strong>'+texto+'<div class="progress" id="bar-alert-msj" style="height:2px;">'+ 657 '<div class="progress-bar bg-naranja" role="progressbar" aria-label="Cerrar" style="width:0;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div></div></div>'; 658 } 659 $("#contentFooter").html(alertBody); 660 const progressMsjBar = document.querySelector('#bar-alert-msj .progress-bar'); 661 gsap.set(progressMsjBar,{width:'0%'}); 662 let progress = {percent:0}; 663 const tl = gsap.timeline({ 664 onComplete : () => { if (idmodal.length > 3) $('#'+idmodal).modal('hide'); } 665 }); 666 tl.to(progress,{ 667 percent:100, 668 duration:duracion, 669 ease: 'power1.inOut', 670 onUpdate: () => { 671 const roundedPercent = Math.round(progress.percent); 672 progressMsjBar.style.width = `${roundedPercent}%`; 673 } 674 }); 675} 676function nextTab(direction,tabsContainerId = 'formInscripcionModal'){ 677 const tabs = document.querySelectorAll(`#${tabsContainerId} [role="tab"]`); 678 const tabContent = document.querySelectorAll("#pills-tabContent .tab-pane"); 679 if (!tabs.length || !tabContent)return; 680 let activeIndex = -1;
681 tabs.forEach((tab, index) => { 682 if (tab.classList.contains('active')){ 683 activeIndex = index; 684 } 685 }); 686 if(activeIndex === -1)return; 687 let newIndex; 688 if(direction === '+'){ 689 newIndex = (activeIndex+1)%tabs.length; 690 }else if(direction === '-'){ 691 newIndex = (activeIndex-1+tabs.length)%tabs.length; 692 }else{ 693 return; 694 } 695 if(newIndex !== activeIndex){ 696 const tabInstance = bootstrap.Tab.getOrCreateInstance(tabs[newIndex]); 697 tabInstance.show(); 698 } 699 ShowFrmBtns(newIndex,tabs.length); 700 701} 702function ShowFrmBtns(newIndex,tabs){ 703 if(newIndex > 0){ 704 $("#btn-back").removeClass("d-none"); 705 } 706 if(newIndex == 0){ 707 $("#btn-back").addClass("d-none"); 708 } 709 $("#btn-next").removeClass("d-none"); 710 $("#btn-finish").addClass("d-none"); 711 if(newIndex == tabs-1){ 712 $("#btn-next").addClass("d-none"); 713 $("#btn-finish").removeClass("d-none"); 714 } 715 var barraWidth = (newIndex+1)*33; 716 barraWidth = barraWidth>66?100:barraWidth; 717 $("#bar-inscript").css("width",barraWidth+"%"); 718} 719$("#inpsrchome").on('keyup',function(){ 720 const length = $(this).val().length; 721 const searchBox = $(".searchofertas"); 722 if(length >= 40){ 723 searchBox.css('width','100%'); 724 }else if(length >= 27){ 725 searchBox.css('width','450px'); 726 }else if(length > 6) { 727 searchBox.css('width','300px'); 728 }else{ 729 searchBox.css('width','300px'); 730 } 731 if(length > 3){ 732 $("#contentSrcOfertas").addClass("animate__animated animate__flipInX"); 733 $("#contentSrcOfertas").removeClass("d-none"); 734 $("#ofertasGrupo").addClass("d-none"); 735 srcOferta($(this).val()); 736 }else if(length == 0){ 737 $("#contentSrcOfertas").addClass("d-none"); 738 $("#ofertasGrupo").addClass("animate__animated animate__bounceIn"); 739 $("#ofertasGrupo").removeClass("d-none"); 740 } 741}); 742function srcOferta(src){ 743 if (src.length>3){ 744 $.ajax({ 745 type: 'POST', 746 url: _root+'ajaxsapp/ajax', 747 headers: {'X-Requested-With':'XMLHttpRequest'}, 748 data: {action:'query_carrera',s:src }, 749 success: function(data){ 750 var array = eval(data); 751 // console.log(array) 752 var listado='<div class="alert alert-secondary" role="alert"><i class="fas fa-magnifying-glass-arrow-right"></i> No se ha encontrado nada aún, intente de nuevo...</div>'; 753 if(array[0]!=0){ 754 listado=''; 755 $.each(array, function (i, fila) { 756 listado += '<div class="col-md-3 m-1"><div class="card shadow" style="width:18rem;">' + 757 '<img src="https://itb.edu.ec/'+fila['img']+'" class="card-img-top img-orange-filter" alt="...">' + 758 '<div class="card-img-overlay h-50"></div> <div class="card-body">'+ 759 '<h3 class="card-title text-azul">'+fila['descripcion']+'</h3>'+ 760 '<a href="'+_root+fila['url']+'" class="btn btn-naranja card-button">Más Información</a>' + 761 '</div></div></div>'; 762 }); 763 } 764 $("#ofertalista").html(listado); 765 } 766 }); 767 } 768} 769function getCodigo(codigo) { 770 $("#lblCodigo").text($(codigo).val()); 771} 772 773// Reset form when pasaporte checkbox is toggled 774document.getElementById('pasaporte').addEventListener('change', function() { 775 const isChecked = this.checked; 776 ResetModalFrm(); 777 this.checked = isChecked; 778 const label = document.getElementById('lblPasaporte'); 779 const cedulaInput = document.getElementById('cedula'); 780 if (isChecked) { 781 label.textContent = 'Pasaporte'; 782 cedulaInput.placeholder = 'Pasaporte *'; 783 cedulaInput.setAttribute('maxlength', '40'); 784 cedulaInput.setAttribute('minlength', '3'); 785 } else { 786 label.textContent = 'Cédula'; 787 cedulaInput.placeholder = 'Cédula *'; 788 cedulaInput.setAttribute('maxlength', '10'); 789 cedulaInput.setAttribute('minlength', '9'); 790 } 791}); 792 793$("#fecha").on("change", function () { 794 const aniooSeleccionado = new Date($(this).val()).getFullYear(); 795 const anioActual = new Date().getFullYear(); 796 const $input = $(this);
797 const $feedback = $input.next(".invalid-feedback"); 798 if (aniooSeleccionado > anioActual - 15) { 799 $input.addClass("is-invalid"); 800 $feedback.text("¡Debes seleccionar la fecha actual!").show(); 801 } else { 802 $input.removeClass("is-invalid"); 803 $feedback.hide(); 804 } 805 if (aniooSeleccionado > anioActual - 15) { 806 // console.log("Error: Debes tener al menos 15 años."); 807 $(this).val(anioActual - 16 + "-01-01"); 808 } else { 809 // console.log("Fecha válida (solo validación por año)"); 810 } 811}); 812 813$("#cedula").on("blur", function () { 814 const $input = $(this); 815 const $feedback = $input.next(".invalid-feedback"); 816 if (!$("#pasaporte").is(":checked")) { 817 if (Cedula($(this).val()).length > 0) { 818 $input.addClass("is-invalid"); 819 $feedback.text("¡Debes seleccionar la fecha actual!").show(); 820 } else { 821 $input.removeClass("is-invalid"); 822 $feedback.hide(); 823 } 824 } 825});
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.