1 2 3 4 5 6 <!DOCTYPE html> 7 <html lang="es" class="html"> 8 <head> 9 <meta charset="utf-8"/> 10 <title> 11 Asociación de Usuarios de VehÃculos Eléctricos | 12 </title> 13 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 14 <meta content="width=device-width, initial-scale=1" name="viewport"/> 15 <meta content="Timtul" name="author"/> 16 17 18 <meta name="robots" content="noindex, nofollow, noarchive, nosnippet"> 19 <meta name="googlebot" content="noindex, nofollow, noarchive, nosnippet"> 20 21
21<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
21 22
22<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery-migrate/3.4.1/jquery-migrate.min.js" integrity="sha512-KgffulL3mxrOsDicgQWA11O6q6oKeWcV00VxgfJw4TcM8XRQT8Df9EsrYxDf7tpVpfl3qcYD96BpyPvA4d1FDQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
22 23 24 <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" type="text/css"/> 25 <link href="//cdnjs.cloudflare.com/ajax/libs/fotorama/4.6.4/fotorama.css" rel="stylesheet">
vendor: 119 bytes, lines 25-28
25 26 <script src="https://www.google.com/recaptcha/api.js?onload=tt_recaptcha&render=explicit" async defer></script> 27 28
28<link rel="stylesheet" href="/static/CACHE/css/abc33ae170c2.css" type="text/css" /> 29 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.11.2/css/bootstrap-select.min.css"> 30
30<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js"></script>
30 31
31<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.11.2/js/bootstrap-select.min.js"></script>
31 32 <link rel="shortcut icon" href="/favicon.ico"/> 33
33<script type="text/javascript" src="/static/admin/js/i18n-periodpicker.js"></script>
33 34 35 36 <!-- FAVICON --> 37<link rel="icon" type="image/png" href="https://media.timtul.com/media/web_auve/favicon-96x96_20241203163113.png" sizes="96x96" /> 38<link rel="icon" type="image/svg+xml" href="https://media.timtul.com/media/web_auve/favicon_20241203163110.svg" /> 39<link rel="shortcut icon" href="https://media.timtul.com/media/web_auve/favicon_20241203163110.ico" /> 40<link rel="apple-touch-icon" sizes="180x180" href="https://media.timtul.com/media/web_auve/apple-touch-icon_20241203163110.png" /> 41<meta name="apple-mobile-web-app-title" content="AUVE" /> 42<link rel="manifest" href="https://media.timtul.com/media/web_auve/site_20241203163207.webmanifest" /> 43 44<!-- FUENTES --> 45<link rel="preconnect" href="https://fonts.googleapis.com"> 46<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 47<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Quicksand:[email protected]&display=swap" rel="stylesheet"> 48 49<!-- Add the slick-theme.css if you want default styling --> 50<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/slick/slick.css"/> 51<!-- Add the slick-theme.css if you want default styling --> 52<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/slick/slick-theme.css"/>
53<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
53 54<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/> 55 56<!-- Google tag (gtag.js) -->
vendor: 65 bytes, lines 56-57
56 57<script async src="https://www.googletagmanager.com/gtag/js?id=
57G-N4DBWWNKRT
vendor: 13 bytes, line 57
57"></script>
58<script> 59
vendor: 138 bytes, lines 59-63
59window.dataLayer = window.dataLayer || []; 60 function gtag(){dataLayer.push(arguments);} 61 gtag('js', new Date()); 62 63 gtag('config', '
63G-N4DBWWNKRT
vendor: 5 bytes, line 63
63');
64</script>
64 65 66 67 </head> 68 69 <body style="margin-bottom:0px;padding-top:0px;" class="modal-base-body"> 70 <div class="login-container"> 71 72 73
74<script type="text/javascript"> 75 76 77var tt_recaptcha = function() { 78 $( ".g-recaptcha-modal" ).each(function( index ) { 79 var key = $(this).attr("data-sitekey"); 80 var lang = "es" 81 if( lang == "pr") { 82 lang = "pt"; 83 } 84 recaptcha = grecaptcha.render(this, { 85 'sitekey' : key, 86 'hl': lang 87 }); 88 }); 89}; 90 91 92$( document ).ready(function() { 93 94 95}); 96</script>
96 97 98 99<!-- 100 <div> 101 <ul> 102 103 <li><a href="/accounts/login/">Sign In</a></li> 104 <li><a href="/accounts/signup/">Sign Up</a></li> 105 106 </ul> 107 </div> 108 --> 109 110 111<h3>Inicia sesión</h3> 112 113 114 115 116<p>Si todavÃa no has creado una cuenta, entonces por favor 117<a href="/accounts/signup/?next=%2Fdocumentacion-para-socios%2F">regÃstrate</a> primero.</p> 118 119 120<form class="login" method="POST" action="/accounts/login/"> 121 <input type='hidden' name='csrfmiddlewaretoken' value='LKZrCog8GIMMvXau5NOA3IeT7SwVQ1nEGUwTtt6uFhv2f0UT89szOvRtYcBXFhR1' /> 122 <p><label for="id_login">Email:</label> <input autofocus="autofocus" id="id_login" name="login" placeholder="Dirección email" type="email" required /></p> 123<p><label for="id_password">Contraseña:</label> <input id="id_password" name="password" placeholder="Contraseña" type="password" required /></p> 124<p><label for="id_remember">Recordarme:</label> <input id="id_remember" name="remember" type="checkbox" /></p> 125 126 <input type="hidden" name="next" value="/documentacion-para-socios/" /> 127 128 <button type="button" class="btn btn-danger" data-dismiss="modal" aria-hidden="true" aria-labelledby="Cancelar">Cancelar</button> 129 <button class="primaryAction" type="submit" aria-labelledby="Inicia sesión">Inicia sesión</button> 130 <a class="button secondaryAction" href="/accounts/password/reset/" style="display:block" role="button" aria-labelledby="Recordar contraseña">Recordar contraseña</a> 131</form> 132 133 134 135 136 137 138 139 140 141 </div> 142 </body> 143</html> 144 145
146<script type="text/javascript"> 147 148 try { 149 function addWayetTooltipAndLeyendInRegisterForm(){ 150 const checkbox = document.getElementById('id_custom_WAYLET-PERMISO'); 151 152 if (!checkbox) { 153 return; 154 } 155 156 const field = checkbox.closest('.form-group'); 157 const label = field ? field.querySelector('label.control-label') : null; 158 const inputGroup = field ? field.querySelector('.input-group') : null; 159 160 if (!field || !label) { 161 return; 162 } 163 164 field.classList.add('waylet-permiso-field'); 165 166 label.insertBefore(checkbox, label.firstChild); 167 168 if (inputGroup && inputGroup.children.length === 0) { 169 inputGroup.remove(); 170 } 171 172 const tooltipId = 'waylet-permiso-tooltip'; 173 174 const infoIcon = document.createElement('span'); 175 infoIcon.className = 'waylet-info-icon'; 176 infoIcon.textContent = '?'; 177 infoIcon.setAttribute('tabindex', '0'); 178 infoIcon.setAttribute('role', 'button'); 179 infoIcon.setAttribute('aria-describedby', tooltipId); 180 181 const tooltip = document.createElement('span'); 182 tooltip.id = tooltipId; 183 tooltip.className = 'waylet-tooltip'; 184 tooltip.setAttribute('role', 'tooltip'); 185 tooltip.textContent = 'Al marcar esta casilla autorizas a AUVE a enviar tu NIF a Repsol para incorporarte al colectivo de socios de AUVE en Waylet y disfrutar de sus ventajas. Es el único dato que se comparte. Tu NIF debe coincidir con el de tu cuenta de Waylet. Puedes revocar la autorización en cualquier momento desmarcando la casilla.'; 186 187 label.appendChild(infoIcon); 188 label.appendChild(tooltip); 189} 190 191addWayetTooltipAndLeyendInRegisterForm(); 192 193/* ------------------ CUSTOM LOGIN WIDGET ------------------ */ 194 195const initLoginWidget = () => { 196 const widget = document.querySelector('.custom-profile__dropdown'); 197 if (!widget) { 198 console.warn('Custom login widget not found.'); 199 return; 200 } 201 202 203 const widgetLoginToggle = widget.querySelector('.custom-profile__dropdown-toggle'); 204 205 widgetLoginToggle.addEventListener('click', (event) => { 206 event.preventDefault(); 207 event.stopPropagation(); // Evita que el click llegue al document 208 widget.classList.toggle('open'); 209 }); 210 211 document.addEventListener('click', (event) => { 212 if (!widget.contains(event.target)) { 213 widget.classList.remove('open'); 214 } 215 }); 216} 217 218initLoginWidget(); 219 220 221 222 223////EDITS DEL FORMULARIO DE REGISTRO 224 225const labelPassword1 = document.querySelector('label[for="id_password1"]'); 226const placeHolderPassword = document.getElementById('id_password1'); 227 228 229if (labelPassword1) { 230 labelPassword1.textContent = "Contraseña: (mÃnimo de 6 caracteres)"; 231 placeHolderPassword.placeholder = "Contraseña: (mÃnimo 6 caracteres)"; 232} 233 234 235const requiresAsterisco = document.querySelectorAll(` 236 .form-group.custom-field:has(:is(input, select, textarea):required) > label.control-label, 237 p:has(:is(input, select, textarea):required) > label 238`); 239 240const labelLastName = document.querySelector('label[for="id_last_name"]'); 241if (labelLastName && !labelLastName.querySelector(".required-asterisk")) { 242 const asterisk = document.createElement("span"); 243 asterisk.textContent = " *"; 244 asterisk.className = "required-asterisk"; 245 asterisk.setAttribute("aria-hidden", "true"); 246 labelLastName.appendChild(asterisk); 247} 248 249 250requiresAsterisco.forEach(label => { 251 if (!label.querySelector(".required-asterisk")) { 252 const asterisk = document.createElement("span"); 253 asterisk.textContent = " *"; 254 asterisk.className = "required-asterisk"; 255 asterisk.setAttribute("aria-hidden", "true"); 256 label.appendChild(asterisk); 257 } 258}); 259 260 261const signup_form = document.getElementById("signup_form"); 262 263if (signup_form) { 264 signup_form.insertAdjacentHTML( 265 "beforebegin", 266 `<p style="font-size: 0.9em !important;">Los campos <span style="color: #58c0cc; font-weight: bold !important;">resaltados con asterisco*</span> son obligatorios</p>` 267 ); 268} 269 270(function () { 271 const NEW_TEXT = "Nada seleccionado"; 272 273 function fixNothingSelected(root = document) { 274 root.querySelectorAll(".filter-option").forEach(el => { 275 if (el.textContent.trim() === "Nothing selected") { 276 el.textContent = NEW_TEXT; 277 } 278 });
279 280 root.querySelectorAll('button[title="Nothing selected"]').forEach(btn => { 281 btn.title = NEW_TEXT; 282 }); 283 } 284 285 // 1) Intento inmediato 286 fixNothingSelected(); 287 288 // 2) Reaplicar cuando bootstrap-select refresca / cambia 289 $(document).on("loaded.bs.select refreshed.bs.select changed.bs.select", function () { 290 fixNothingSelected(); 291 }); 292 293 // 3) Por si lo pinta después (AJAX / render tardÃo) 294 const obs = new MutationObserver(() => fixNothingSelected()); 295 obs.observe(document.body, { subtree: true, childList: true, characterData: true }); 296 297 // 4) Reintentos cortos (por si el render va con delay) 298 setTimeout(fixNothingSelected, 50); 299 setTimeout(fixNothingSelected, 200); 300 setTimeout(fixNothingSelected, 800); 301})(); 302 303 304 305 306 307// --> --------------- 308// --> Fix Date Inputs 309 310function fixDateInputs() { 311 var $inputs = $('input.date-field, input.datetime-field, input[type="date"], input[type="datetime-local"]'); 312 313 $inputs.each(function(index, input_bucle){ 314 var $input = $(input_bucle), type = $input.attr('type'); 315 316 if (!(type === "date" || type === "datetime-local")) { 317 if ($input.hasClass('date-field')) { 318 $input.attr('type', 'date'); 319 } else { 320 $input.attr('type', 'datetime-local'); 321 } 322 } 323 }); 324 325 $(document).on('click', 'input.date-field, input.datetime-field, input[type="date"], input[type="datetime-local"]', function(){ 326 if($(this).parents('.widget').hasClass('widget-event-registration')) return; 327 328 $(this)[0].showPicker?.(); 329 $(this).focus(); 330 }); 331} 332 333$(window).on('load', fixDateInputs); 334 335$(window).on("load", function(){ 336 var year = new Date().getFullYear(); 337 var maxyear = year - 18; 338 var minyear = year - 110; 339 340 $("input[type='date']").attr("min", minyear + "-01-01"); 341 $("input[type='date']").attr("max", maxyear + "-12-31"); 342}); 343 344function validateDateProfile () { 345 const widgetProfile = document.querySelector('.widget-user-profile-edit'); 346 347 // OJO: Si por alguna razón tu widget no se llama exactamente asÃ, 348 // esta lÃnea está matando la función antes de que empiece. 349 if (!widgetProfile) { 350 console.warn('El widget profile no se encontró. La función se detuvo.'); 351 return; 352 } 353 354 const inputFecha = document.getElementById('id_custom_FECHA-NACIMIENTO-NUEVA'); 355 356 if (inputFecha) { 357 let valorOriginal = inputFecha.getAttribute('value'); 358 359 if (valorOriginal) { 360 let valorCorregido = ''; 361 362 if (valorOriginal.includes('/')) { 363 const partes = valorOriginal.split('/'); 364 if (partes.length === 3) { 365 const dia = partes[0].trim(); 366 const mes = partes[1].trim(); 367 const anio = partes[2].trim(); 368 valorCorregido = `${anio}-${mes}-${dia}`; 369 } 370 } else if (valorOriginal.includes('-')) { 371 const partes = valorOriginal.split('-'); 372 373 if (partes.length === 3) { 374 const parte1 = partes[0].trim(); 375 const parte2 = partes[1].trim(); 376 const parte3 = partes[2].trim(); 377 378 // Si fuera dd-mm-aaaa por error, esto lo ignora para evitar bugs. 379 if (parte1.length === 4) { 380 valorCorregido = `${parte1}-${parte2}-${parte3}`; 381 } 382 } 383 } 384 385 // Si logramos capturar y formatear la fecha correctamente, ejecutamos los cambios 386 if (valorCorregido !== '') { 387 inputFecha.removeAttribute('value'); 388 inputFecha.value = ''; 389 inputFecha.setAttribute('type', 'date'); 390 391 setTimeout(function() { 392 inputFecha.value = valorCorregido;
393 inputFecha.setAttribute('value', valorCorregido); 394 395 console.log('¡Ahora sÃ! Asignado después del redibujado: ', inputFecha.value); 396 }, 500); 397 } else { 398 console.warn('El formato de fecha no es válido ni como dd/mm/aaaa ni como aaaa-mm-dd'); 399 } 400 } 401 } 402} 403 404document.addEventListener('DOMContentLoaded', validateDateProfile); 405 406 407 408 409 410//////////////////////////////////////////////////////////////////////////////// 411//variables globales 412let prevScrollpos = window.pageYOffset; 413let currentScrollPos = window.pageYOffset; 414 415// funcion para calcular y ajustar el height del slider según su cabecera y demás elemmentos 416function slider_height(){ 417 418 //sizes 419 const $nav_height = $('.with-region-nav').height(); //nav 420 const $window_height = window.innerHeight; //window 421 let $header_height = 0; //se esconde en versión mobile 422 let $total_height = 0; // 423 424 //si header está visible, get su height 425 if($('header.region-header').is(":visible")) $header_height = $('header.region-header').height(); 426 427 //total height de la cabecera 428 $total_height = $header_height + $nav_height; 429 430 $(document).find('.box--slider').css('min-height', `${$window_height - $total_height}px`) 431} 432 433//cambiar titular de la página profile 434if($('.CoreApp.profile').length > 0){ 435 $('h1').html('Perfil').css('opacity',1) 436} 437 438//cambiar titular de la página de noticias 439if($('body[class*=" entry-"]').length > 0){ 440 $('.widget-single-article .details .title').appendTo($('.region-cabecera .widget-simple-title >.content')).animate({opacity:1, 'top':0},500).siblings().remove(); 441 $('.date').appendTo($('.picture')).animate({opacity:1},0); 442} else if($('body[class*=" tag-"][class*="NewsApp"]').length > 0) { 443 const url = new URL(window.location.href); 444 let tag = url.pathname.split('/').pop(); 445 $('.region-cabecera .widget-simple-title >.content *').html('Etiqueta: ' + tag).css({'opacity':1}); 446} 447 448/////////////////////////////////////////// 449// EVENTOS 450 451if($('body[class*=event-]').length > 0){ 452 //copiar titular en cabecera 453 $('[data-level="1"]').find('h1').html($('.title').text()).css({'opacity':1}) 454 $('.widget-social-share').appendTo('.share').css({'opacity':1}) 455} 456/////////////////////////////////////////////////////////////////////////////// 457// FETCH SECCIONES NOTICIA 458 459const urls = [ 460 'aparicion-en-medios', 461 'convenios', 462 'notas-de-prensa', 463 'noticias', 464 'participacion-en-eventos', 465 'reuniones' 466] 467 468async function getTotalSeccion(urls) { 469 470 const path = '/api/v1/news/search?stream=' 471 const totales = []; 472 473 for (const url of urls) { 474 try { 475 const response = await fetch(path + url); 476 const data = await response.json(); 477 const total = data.total; 478 totales.push(total); 479 } catch (error) { 480 console.error(`Error al obtener los datos de ${url}:`, error); 481 totals.push(null); 482 } 483 } 484 485 return totales; 486} 487 488getTotalSeccion(urls).then(totales => { 489 totales.forEach( (total, index) => { 490 $('.menu-secciones ul li:nth-child('+ (index + 1 ) +')').children().append('<span class="li-num-seccion">'+ total +'</span>'); 491 }); 492}) 493 494 495//////////////////////////////////////////////////////////////////////////////// 496 497$(document).on('click', 'button.navbar-toggle', function(){ 498 $('body').toggleClass('o-hidden') 499}) 500 501$(document).on('click', '.login-container button[aria-labelledby="Cancelar"]', function(){ 502 window.history.back(); 503 return false; 504}) 505 506//////////////////////////////////////////////////////////////////////////////// 507// SLICK NOTICIAS 508 509//añadir tag picture para poder hacer zoom a la imagen dentro de su espacio 510$('.widget-article-list .card:not(.empty), .widget-event-list .card:not(.empty)').each(function(){ 511 $(this).find('img').wrap('<picture></picture>'); 512}) 513 514$('.region-hero >.row').slick({ 515 infinite: true, // Desplazamiento infinito 516 slidesToShow: 1, // Número de slides visibles al mismo tiempo 517 slidesToScroll: 1, // Número de slides que se desplazan al mismo tiempo 518 autoplay: true, // Activar autoplay 519 autoplaySpeed: 5000, // Velocidad del autoplay en ms (0 para movimiento continuo) ES LA VELOCIDAD DE LA BARRA. BUSCAD EN EL CSS 'BARRA' 520 speed: 1000, // Velocidad de transición más lenta para suavizar el movimiento 521 cssEase: 'linear', // Transición lineal para un movimiento continuo
522 arrows: false, // Sin flechas de navegación 523 dots: true, // Sin puntos de navegación 524 pauseOnHover: true, 525 pauseOnFocus: false, // No pausar cuando el slider esté enfocado 526 fade: true, // fade 527// responsive: [ 528// { 529// breakpoint: 992.1, 530// settings: { 531// arrows: false, 532// centerMode: true, 533// centerPadding: '15vw', 534// slidesToShow: 1 535// } 536// } 537// ] 538}); 539 540////////////////////////////////////////////////////////////////////////////// 541// WIDGET SEARCH 542 543if($('.widget-search.eventos').length > 0){ 544 545 var search_custom_item_markup = ` 546 <article class="event"> 547 <div class="event-header"> 548 <figure> 549 <img class="event-img card-img-top" loading="lazy" decoding="async"/> 550 <div class="event-date"> 551 <span class="event-date-day"></span> 552 <span class="event-date-month"></span> 553 <span class="event-date-year"></span> 554 </div> 555 </figure> 556 </div> 557 <div class="event-body"> 558 <div class="event-info"> 559 <div class="event-horario"> 560 <i class="bi bi-clock"></i> 561 <div class="event-horario-info"> 562 <span class="event-horario-start"></span> 563 <span class="event-horario-end"></span> 564 </div> 565 </div> 566 <div class="event-city"> 567 <i class="bi bi-geo-alt"></i> 568 <span class="event-city-text"></span> 569 </div> 570 </div> 571 <a class="event-link"> 572 <h3 class="event-title"></h3> 573 </a> 574 </div> 575 </article> 576 `; 577 578 $(document).on('results', '.widget-search.eventos', function(event, res){ 579 const items = res.data.items 580 let card = $('.event'); 581 console.table(items); 582 583 card.each(function(index){ 584 585 //fecha esquina superior 586 let fecha = items[index].date.split(' ') 587 588 //fechas card body start 589 let horario_start = items[index].start_time.split(' '), 590 dia_start = horario_start[0].split('-').reverse().join('/'), 591 hora_start = horario_start[1].substring(0,5) 592 593 //fechas card body end 594 let horario_end = items[index].end_time.split(' '), 595 dia_end = horario_end[0].split('-').reverse().join('/'), 596 hora_end = horario_end[1].substring(0,5) 597 598 //insertar datos en CARD 599 $(this).find('.event-img').attr({ 600 'alt': items[index].title, 601 'title': items[index].title, 602 'src': items[index].image 603 }) 604 $(this).find('.event-date-day').html(fecha[0]) 605 $(this).find('.event-date-month').html(fecha[1].substring(0,3)) 606 $(this).find('.event-date-year').html(fecha[2]) 607 $(this).find('.event-city-text').html(items[index].city) 608 $(this).find('.event-title').html(items[index].title) 609 $(this).find('.event-horario-start').html(dia_start + ' h: ' + hora_start + ' -') 610 $(this).find('.event-horario-end').html(dia_end + ' h: ' + hora_end) 611 $(this).find('.event-link').attr({ 612 'href': items[index].url, 613 'target': '_self' 614 }) 615 }); 616 617 $(this).animate({opacity : 1}, 500) 618 619 }) 620} 621 622// Mini buscador de noticias del sidebar 623if ($('.widget-search.sidebar-search').length > 0) { 624 625 var search_custom_item_markup = ` 626 <li class="item-search"> 627 <a class="item-link"></a> 628 </li> 629 `; 630 631 $(document).on( 632 'results', 633 '.widget-search.sidebar-search', 634 function (event, response) { 635 const $widget = $(this); 636 const $results = $widget.find('.content-results'); 637 const items = response?.data?.items || []; 638 const $cards = $results.find('.item-search'); 639 640 $cards.each(function (index) { 641 const item = items[index]; 642 const $card = $(this); 643 644 if (!item) { 645 $card.remove(); 646 return; 647 } 648 649 $card 650 .find('.item-link') 651 .attr({ 652 href: item.url, 653 target: '_self' 654 }) 655 .text(item.title); 656 }); 657 658 if (items.length) { 659 $results 660 .stop(true, true) 661 .css({ 662 opacity: 1, 663 zIndex: 3, 664 pointerEvents: 'auto' 665 }); 666 } else { 667 $results 668 .stop(true, true) 669 .css({ 670 opacity: 0, 671 zIndex: 0, 672 pointerEvents: 'none' 673 }); 674 } 675 } 676 ); 677 678 $('.widget-search.sidebar-search').each(function () { 679 const $widget = $(this); 680 const $input = $widget.find('.sidebar-input'); 681 const $results = $widget.find('.content-results'); 682 683 $input 684 .off('.sidebarSearch') 685 .on('focusin.sidebarSearch', function () { 686 if ($results.children().length) { 687 $results 688 .stop(true, true) 689 .css({ 690 opacity: 1, 691 zIndex: 3, 692 pointerEvents: 'auto' 693 }); 694 } 695 }) 696 .on('focusout.sidebarSearch', function () { 697 setTimeout(function () { 698 $results 699 .stop(true, true) 700 .css({ 701 opacity: 0, 702 zIndex: 0, 703 pointerEvents: 'none' 704 }); 705 }, 200); 706 }); 707 });
708} 709 710function connectSidebarSearchToArticleList() { 711 try { 712 const $sidebarSearch = $('.widget-search.sidebar-search'); 713 const $articleList = $('.region-content .widget-article-list'); 714 715 if (!$sidebarSearch.length || !$articleList.length) { 716 return; 717 } 718 719 const $articleContent = $articleList.children('.content').first(); 720 721 if (!$articleContent.length) { 722 return; 723 } 724 725 /* 726 * Guardamos las noticias originales para recuperarlas 727 * cuando el buscador vuelva a estar vacÃo. 728 */ 729 const originalArticleHtml = $articleContent.html(); 730 731 function escapeHtml(value) { 732 return $('<div>') 733 .text(value == null ? '' : String(value)) 734 .html(); 735 } 736 737 function createArticleCard(item) { 738 const title = escapeHtml(item.title || ''); 739 const url = escapeHtml(item.url || '#'); 740 const date = escapeHtml(item.date || ''); 741 742 const image = 743 item.image || 744 item.thumbnail || 745 item.picture || 746 ''; 747 748 const abstract = escapeHtml( 749 item.abstract || 750 item.description || 751 '' 752 ); 753 754 const imageHtml = image 755 ? ` 756 <picture class="sidebar-search-picture"> 757 <img 758 class="card-img-top" 759 src="${escapeHtml(image)}" 760 alt="${title}" 761 loading="lazy" 762 decoding="async" 763 > 764 </picture> 765 ` 766 : ''; 767 return ` 768 <div class="card with-footer col_4"> 769 ${imageHtml} 770 771 <div class="card-block"> 772 <h4 773 class="card-title" 774 title="${title}" 775 > 776 <a href="${url}"> 777 ${title} 778 </a> 779 </h4> 780 781 ${ 782 date 783 ? ` 784 <p class="card-subtitle text-muted date"> 785 ${date} 786 </p> 787 <br> 788 ` 789 : '' 790 } 791 792 ${ 793 abstract 794 ? ` 795 <div class="card-text"> 796 <p>${abstract}</p> 797 </div> 798 ` 799 : '' 800 } 801 </div> 802 803 <div class="card-footer text-muted"> 804 <a 805 href="${url}" 806 class="readmore" 807 > 808 Leer más 809 </a> 810 </div> 811 </div> 812 `; 813 } 814 815 function renderArticles(items) { 816 if (!items.length) { 817 $articleContent.html(` 818 <div class="sidebar-search-no-results"> 819 No se han encontrado noticias. 820 </div> 821 `); 822 823 return; 824 } 825 826 let html = '<div class="card-deck-wrapper">'; 827 828 /* 829 * Las tarjetas originales están agrupadas de tres en tres. 830 */ 831 for (let index = 0; index < items.length; index += 3) { 832 const group = items.slice(index, index + 3); 833 834 html += '<div class="card-deck">'; 835 836 group.forEach(function (item) { 837 html += createArticleCard(item); 838 }); 839 840 /* 841 * Rellenamos el último grupo para conservar 842 * la estructura visual de tres columnas. 843 */ 844 while (group.length < 3) { 845 html += '<div class="card col_4 empty"></div>'; 846 group.push(null); 847 } 848 849 html += '</div>'; 850 } 851 852 html += '</div>'; 853 854 $articleContent.html(html); 855 } 856 857 $(document) 858 .off( 859 'results.sidebarArticleList', 860 '.widget-search.sidebar-search' 861 ) 862 .on( 863 'results.sidebarArticleList', 864 '.widget-search.sidebar-search', 865 function (event, response) { 866 const searchTerm = $(this) 867 .find('input[name="term"]') 868 .val() 869 .trim(); 870 871 /* 872 * Al borrar el buscador recuperamos el listado 873 * y la paginación originales. 874 */ 875 if (!searchTerm) { 876 $articleContent.html(originalArticleHtml); 877 return; 878 } 879 880 const items = 881 response && 882 response.data && 883 Array.isArray(response.data.items) 884 ? response.data.items 885 : []; 886 887 // console.table(items); 888 889 renderArticles(items); 890 } 891 ); 892 893 } catch (error) { 894 console.error( 895 'Error en connectSidebarSearchToArticleList:', 896 error 897 ); 898 } 899} 900 901$(window).on('load', function () { 902 connectSidebarSearchToArticleList(); 903}); 904 905 906// $(document).on('focus', '.sidebar-input', function(){ 907// $('.content-results').slideDown(); 908// }).on('focusout', function(){
909// $('.content-results').slideUp(); 910// }) 911 912 913//rellenar input datalist 914// if($('.widget-search.sidebar-search').length > 0){ 915// var search_custom_item_markup = ` 916// <option value=""> 917// `; 918// $(document).on('results', '.widget-search.sidebar-search', function(event, res){ 919// const items = res.data.items 920// let card = $('option') 921// // console.table(items) 922// card.each(function(index){ 923// $(this).val(items[index].title) 924// }); 925// $(this).animate({opacity : 1}, 500) 926// }) 927// } 928 929 930////////////////////////////////////////////////////////////////////////////// 931// MEDIATECAS 932 933//box tipo VER DOCUMENTO 934if($('.widget-media-library.recursos').length > 0){ 935 //plantilla 936 var media_custom_item_markup = ` 937 <!-- start --> 938 <article class="card files"> 939 <div class="content display-grid"> 940 <div class="card-background"></div> 941 <div class="card-data card-data-info"> 942 <p class="card-date">__date__</p> 943 <h3 clasS="card-title">__title__</h3> 944 <p class="card-descripcion"></p> 945 </div> 946 <div class="card-data card-data-download"> 947 <a class="" target="_blank" href="__download__url"> 948 <h4>VER DOCUMENTO</h4> 949 </a> 950 </div> 951 </div> 952 </article> 953 <!-- end --> 954 `; 955 956 //get datos 957 $(document).on('results','.widget-media-library.recursos', function(event, res){ 958 console.table(res.data.resources); 959 const notas = res.data.resources;//datos 960 961 $(this).find('.card').each(function(index){ 962 $(this).attr({ 963 'data-index': index, 964 'data-name': notas[index].title 965 }) 966 $(this).find('.card-date').html(notas[index].date) 967 $(this).find('.card-descripcion').html(notas[index].custom.DESCRIPCIÃN) 968 }) 969 }); 970} 971 972//box tipo card COCHE background 973if($('.widget-media-library.documentacion').length > 0){ 974 //plantilla 975 var media_custom_item_markup = ` 976 <!-- start --> 977 <article class="card files"> 978 <div class="content display-grid"> 979 <div class="card-background"></div> 980 <img src="https://media.timtul.com/media/web_auve/isotipo-auve-linear-gradient_20241227152746.svg" class="card-car"/> 981 <div class="card-data card-data-info"> 982 <h3 clasS="card-title">__title__</h3> 983 <a class="" target="_blank" href="__download__url"> 984 DESCARGAR 985 </a> 986 </div> 987 </div> 988 </article> 989 <!-- end --> 990 `; 991 992 //get datos 993 $(document).on('results','.widget-media-library.documentacion', function(event, res){ 994 console.table(res.data.resources); 995 const notas = res.data.resources;//datos 996 997 $(this).find('.card').each(function(index){ 998 $(this).attr({ 999 'data-index': index, 1000 'data-name': notas[index].title 1001 }) 1002 $(this).find('.card-date').html(notas[index].date) 1003 $(this).find('.card-descripcion').html(notas[index].custom.DESCRIPCIÃN) 1004 }) 1005 }); 1006} 1007 1008//box color SOLID 1009if($('.widget-media-library.legislacion').length > 0){ 1010 //plantilla 1011 var media_custom_item_markup = ` 1012 <!-- start --> 1013 <article class="card files"> 1014 <div class="content display-grid"> 1015 <div class="card-data card-data-info"> 1016 <a class="" target="_blank" href="__download__url"> 1017 <h3 clasS="card-title">__title__</h3> 1018 </a> 1019 <p class="card-descripcion"></p> 1020 </div> 1021 </div> 1022 </article> 1023 <!-- end --> 1024 `; 1025 1026 //get datos 1027 $(document).on('results','.widget-media-library.legislacion', function(event, res){ 1028 console.table(res.data.resources); 1029 const notas = res.data.resources;//datos 1030 1031 $(this).find('.card').each(function(index){ 1032 $(this).attr({ 1033 'data-index': index, 1034 'data-name': notas[index].title 1035 }) 1036 $(this).find('.card-date').html(notas[index].date) 1037 $(this).find('.card-descripcion').html(notas[index].custom.DESCRIPCIÃN) 1038 }) 1039 });
1040} 1041 1042 1043if ($('input#term').length > 0){ 1044 $('input#term').attr('placeholder', $('input#term').prev().text()) 1045 .focus(function(){ 1046 $('::placeholder', this).css({'opacity':'0'}) 1047 }) 1048} 1049 1050//cambiar input fecha a input data 1051function inputDateFunction () { 1052 const widgetProfile = document.querySelector('.widget-user-profile-edit'); 1053 if (widgetProfile) return; 1054 1055 if ($('input[type=date]').length > 0){ 1056 $('input[type=date]').each(function(){ 1057 $($(this)).attr({ 1058 'type': 'date', 1059 'placeholder' : $(this).prev().text() 1060 }) 1061 .focus(function(){$(this).attr('type', 'date')}) 1062 .blur(function(){$(this).attr('type', 'text')}) 1063 }) 1064 } 1065} 1066 1067inputDateFunction(); 1068 1069///////////////////////////////////////////////////////////////////////////////////////// 1070// 1071$(".widget-mini-calendar.crazy").on("results", function(evt, data) { 1072 var eventos = data.data; 1073 var days =$(".widget-mini-calendar .day") 1074 1075 eventos.forEach(function(event, index){ 1076 var date = new Date(Date.parse(event.day)); 1077 var categorias=""; 1078 event["tags"].forEach(function(tag, index){categorias+= tag + " ";}); 1079 days.each(function(){ 1080 var diaEvento = new Date($(this).attr('data-dt')); 1081 if(diaEvento.toString() === date.toString()){ 1082 var adins = `<div class="event-cal"><a href="${event.url}" class="${categorias}"> 1083 ${event.title} 1084 </a></div>`; 1085 $(this).append(adins); 1086 } 1087 }); 1088 }); 1089}); 1090 1091function buscarAuto() { 1092 $('.media-library-search input:not([role="textbox"])').on('keyup', function(){$('.media-library-search .btn-search-files').trigger('submit')}); 1093 $('.media-library-search select').on('change', function(){$('.media-library-search .btn-search-files').trigger('submit')}); 1094 $('.widget-search input:not([role="textbox"])').on('keyup', function(){$('.widget-search form').trigger('submit')}); 1095 $('.widget-search input[type="date"]').on('keyup', function(){$('.widget-search form').trigger('submit')}); 1096 $('.widget-search select').on('change', function(){$('.widget-search form').trigger('submit')}); 1097 $(document).on('change', '.widget-search input[type="date"]', function(){$('.widget-search form').trigger('submit')}); 1098 $('.widget-users-search input:not([role="textbox"])').on('keyup', function(){$('.widget-users-search .submit-form').click()}); 1099 $('.widget-users-search select').on('change', function(){$('.widget-users-search .submit-form').click()}); 1100} 1101 1102////////////////////////////////////////////////////////////////////////////// 1103// HEADERMENU 1104 1105function headerScroll(){ 1106 currentScrollPos = window.pageYOffset; 1107 if (currentScrollPos > 250) $(".with-region-nav").addClass('scroll'); else $(".with-region-nav").removeClass('scroll'); 1108} 1109 1110//onloads////////////////////////////////////////////////// 1111document.addEventListener("scroll", (event) => { 1112 headerScroll(); 1113}); 1114 1115//carga antes que los widgets 1116document.addEventListener("DOMContentLoaded", (event) => { 1117 // jarallaxs(); 1118 // owlcustom(); 1119 // drawNoticia(); 1120 // activarContador($('.region-contadores')); 1121 // $('body').append('
1121<script>AOS.init();<\/script>'); 1122}); 1123 1124//carga después de los widgets 1125window.addEventListener("load", (event) => { 1126 // if($('body.body.modal-open').length>0) $('#login-modal').addClass('in').css('display','inline'); 1127 // $('.jarallax').jarallax({speed: 0.4}); 1128 buscarAuto() 1129 slider_height() 1130 validSpanishDNIOnSignup() 1131 makeLastNameRequiredOnSignupForm(); 1132 cambiarTitleLogout() 1133}); 1134 1135 1136 1137 1138 1139 1140 1141// --> ----------------------------------------------------------------------------- 1142 1143$("#contact-form .modelo-vehiculo, #contact-form .tipo-de-vehiculo, #contact-form .marca-vehiculo, #contact-form .profesion").find("input").removeAttr("required"); 1144 1145 1146 1147 1148// --> ----------------------------------- 1149// --> Fix Register para que lleve al alta 1150 1151function waitForElement(selector, { root = document, timeout = 10000 } = {}) { 1152 return new Promise((resolve, reject) => { 1153 const found = root.querySelector(selector); 1154 1155 if (found) return resolve(found); 1156 1157 const obs = new MutationObserver(() => { 1158 const el = root.querySelector(selector); 1159 1160 if (el) { 1161 obs.disconnect(); 1162 resolve(el); 1163 } 1164 }); 1165 1166 obs.observe(root, { childList: true, subtree: true }); 1167 1168 if (timeout) { 1169 setTimeout(() => { 1170 obs.disconnect(); 1171 reject(new Error(`waitForElement timeout (${selector})`)); 1172 }, timeout); 1173 } 1174 }); 1175} 1176 1177function fixRegister(){ 1178 // var $popup = $('#login-modal'); 1179 1180 // $popup.on('shown.bs.modal', function(){ 1181 // var popup = this; 1182 1183 // waitForElement('a[href*="/accounts/signup"]', {root: popup}) 1184 // .then(a => {$(a).attr('href', $(a));}) 1185 // .catch(console.warn); 1186 // }); 1187 1188 // $(window).on('load', function(){ 1189 // $('a[href*="/accounts/signup"]').attr('href', '/alta-socios-auve'); 1190 1191 // }); 1192 1193 $(document).on('click', 'a[href*="/accounts/signup"], a[href*="/accounts/register"]', function(event){ 1194 event.preventDefault(); 1195 var href = $(this).attr('href'), 1196 $popup = $('#login-modal'); 1197 1198 $popup.removeClass('in'); 1199 1200 if (!href) return; 1201 1202 setTimeout(function(){window.location = href;}, 500); 1203 return false; 1204 }); 1205} 1206 1207 1208fixRegister(); 1209$(window).on('load', fixRegister); 1210 1211 1212 1213 1214// --> ------------------------- 1215// --> Arreglar los desplegables 1216 1217function destroySelect2(select2){ 1218 var $select2 = select2; 1219 1220 $select2.select2('destroy'); 1221} 1222
1223function renderSelectpicker(){ 1224 $('select', 'form.signup').each(function(){ 1225 var $select = $(this); 1226 1227 $select.selectpicker('destroy'); 1228 $select.selectpicker().addClass('tt-selectpicker'); 1229 }); 1230} 1231 1232function fixDropdowns(){ 1233 $('.tt-selectpicker, select', 'form.signup').each(function(){ 1234 $selectpicker = $(this); 1235 1236 if(!$selectpicker.hasClass('select2-hidden-accessible')) return; 1237 destroySelect2($selectpicker); 1238 }); 1239} 1240 1241 1242$(window).on('load', function(){fixDropdowns(); renderSelectpicker();}); 1243 1244 1245 1246 1247// --> ----------------------------------- 1248 1249function cambiarTituloRegister() { 1250 if (!window.location.pathname.includes('/register/') && !window.location.pathname.includes('/signup/')) return; 1251 1252 var $titulo = $('.modal-base-body > .login-container > h3'); 1253 $titulo.text('¡Hazte Socio!'); 1254} 1255 1256cambiarTituloRegister(); 1257$(window).on('load', cambiarTituloRegister); 1258 1259$(window).on('load', function(){ 1260 // var $titulo = $('.modal-base-body >.login-container >h3'); 1261 // $('<a href="/">Volver a la web de AUVE</a>').insertBefore($titulo); 1262 let htmlMessage = '<a href="/">Volver a la web de AUVE</a> <div class="js-box"><h4>No disponible temporalmente</h4> <p>Estamos realizando trabajos de mejora en la plataforma. Os notificaremos por email cuando volvamos a tener el accesso disponible. <br><br>¡Gracias por confiar en AUVE!</p></div>'; 1263 // $('.modal-base-body >.login-container:has(form[action="/accounts/login/"])').prepend(htmlMessage); 1264}); 1265 1266// Cuando se abre el modal 1267$('#login-modal').on('shown.bs.modal', function (e) { 1268 let htmlMessage = '<div class="js-box"><h4>No disponible temporalmente</h4> <p>Estamos realizando trabajos de mejora en la plataforma. Os notificaremos por email cuando volvamos a tener el accesso disponible. <br><br>¡Gracias por confiar en AUVE!</p></div>'; 1269 1270 // $('#login-modal .loginmodal-container').prepend(htmlMessage); 1271 // setTimeout(function(){$('#login-modal .loginmodal-container').prepend(htmlMessage);}, 300); 1272 // setTimeout(function(){$('#login-modal .loginmodal-container').prepend(htmlMessage);}, 600); 1273}); 1274 1275// --> ----------------------------------- 1276 1277// CALCULADORA CAE 1278 1279function initCaeCalculator() { 1280 1281 const form = document.getElementById('cae-form'); 1282 1283 if (!form) {return} 1284 // --- DATA FROM BOE --- 1285 const BOE_DATA = { 1286 annualMileage: { Turismo: 13073, Furgoneta: 15815, Camion: 53508, Autobus: 46607, Motocicleta: 2831, Ciclomotor: 1759 }, 1287 conversionFactor: { Gasolina: 9.19, Diesel: 10.0, GLP: 7.16, GasNatural: 13.33 }, 1288 defaultCVA: { 1289 Turismo: { 1290 Gasolina: 7.89, 1291 Diesel: 6.99, 1292 HibridoGasolina: 5.135, 1293 HibridoDiesel: 5.18, 1294 GLP: 6.45, 1295 GasNatural: 4.88 1296 }, 1297 Furgoneta: { Gasolina: 7.05, Diesel: 5.63, GasNatural: 8.28 }, 1298 Camion: { Diesel: 35 }, 1299 Autobus: { Diesel: 21 }, 1300 Motocicleta: { Gasolina: 2.9 }, 1301 Ciclomotor: { Gasolina: 2.9 } 1302 }, 1303 defaultCVN: { Turismo: 17.92, Furgoneta: 20.84, Camion: 118.53, Autobus: 86.70, Motocicleta: 4.84, Ciclomotor: 19.45 } 1304 }; 1305 1306 // --- FORM ELEMENTS --- 1307 1308 const vehicleTypeSelect = document.getElementById('vehicle-type'); 1309 const fuelTypeSelect = document.getElementById('fuel-type'); 1310 const cvaInput = document.getElementById('cva'); 1311 const cvaHelperText = document.getElementById('cva-helper-text'); 1312 const resultsContainer = document.getElementById('results-container'); 1313 const resultElement = document.getElementById('result'); 1314 const resultWarningElement = document.getElementById('result-warning'); 1315 const detailsList = document.querySelector('#calculation-details .details-list'); 1316 const auvePromo = document.getElementById('auve-promo'); 1317 1318 // --- DYNAMIC UX FUNCTIONS --- 1319 function handleVehicleAndFuelChange() { 1320 const selectedVehicle = vehicleTypeSelect.value; 1321 const selectedFuel = fuelTypeSelect.value; 1322 1323 if (selectedVehicle === 'Turismo' && (selectedFuel === 'Gasolina' || selectedFuel === 'Diesel')) { 1324 const fixedValue = BOE_DATA.defaultCVA.Turismo[selectedFuel]; 1325 cvaInput.value = fixedValue; 1326 // cvaInput.disabled = true; 1327 cvaHelperText.innerHTML = `Para Turismos de ${selectedFuel}, el BOE establece un consumo fijo de <strong>${fixedValue} l/100km</strong>.`; 1328 } else { 1329 cvaInput.disabled = false; 1330 cvaInput.value = ''; 1331 cvaHelperText.innerHTML = `Si no conoces el dato, déjalo en blanco. Puedes consultarlo en: <a href="https://coches.idae.es/base-datos/marca-y-modelo" target="_blank" class="text-blue-600 hover:underline">IDAE Actual</a> o <a href="https://coches.idae.es/historico-emisiones-consumos" target="_blank" class="text-blue-600 hover:underline">IDAE Histórico</a>.`; 1332 } 1333 updateCVAPlaceholder(); 1334 } 1335 1336 function updateFuelOptions() { 1337 const selectedVehicle = vehicleTypeSelect.value; 1338 const availableFuels = Object.keys(BOE_DATA.defaultCVA[selectedVehicle]); 1339 const currentFuel = fuelTypeSelect.value; 1340 fuelTypeSelect.innerHTML = '';
1341 availableFuels.forEach(fuel => { 1342 const option = document.createElement('option'); 1343 option.value = fuel; 1344 let fuelName; 1345 switch (fuel) { 1346 case 'GasNatural': fuelName = 'Gas Natural'; break; 1347 case 'HibridoGasolina': fuelName = 'HÃbrido Gasolina'; break; 1348 case 'HibridoDiesel': fuelName = 'HÃbrido Diésel'; break; 1349 default: fuelName = fuel; 1350 } 1351 option.textContent = fuelName; 1352 fuelTypeSelect.appendChild(option); 1353 }); 1354 1355 if (availableFuels.includes(currentFuel)) { 1356 fuelTypeSelect.value = currentFuel; 1357 } 1358 handleVehicleAndFuelChange(); 1359 } 1360 1361 function updateCVAPlaceholder() { 1362 if (cvaInput.disabled) return; 1363 const selectedFuel = fuelTypeSelect.value; 1364 const units = selectedFuel === 'GasNatural' ? 'kg/100km' : 'l/100km'; 1365 cvaInput.placeholder = `Ej: 6.5 (${units})`; 1366 } 1367 1368 // --- EVENT LISTENERS --- 1369 vehicleTypeSelect.addEventListener('change', updateFuelOptions); 1370 fuelTypeSelect.addEventListener('change', handleVehicleAndFuelChange); 1371 document.addEventListener('DOMContentLoaded', updateFuelOptions); 1372 1373 form.addEventListener('submit', function(event) { 1374 event.preventDefault(); 1375 detailsList.innerHTML = ''; 1376 resultWarningElement.textContent = ''; 1377 resultElement.textContent = ''; 1378 auvePromo.classList.add('hidden'); 1379 1380 const vehicleType = vehicleTypeSelect.value; 1381 const fuelType = fuelTypeSelect.value; 1382 const userInputCVA = cvaInput.value; 1383 const userInputCVN = document.getElementById('cvn').value; 1384 1385 const L = BOE_DATA.annualMileage[vehicleType]; 1386 1387 const conversionFactorKey = fuelType.includes('Gasolina') ? 'Gasolina' : (fuelType.includes('Diesel') ? 'Diesel' : fuelType); 1388 const f = BOE_DATA.conversionFactor[conversionFactorKey]; 1389 1390 let cvaSource; 1391 let CVA; 1392 1393 if (cvaInput.disabled) { 1394 CVA = parseFloat(cvaInput.value); 1395 cvaSource = 'Valor fijo (BOE)'; 1396 } else if (userInputCVA) { 1397 CVA = parseFloat(userInputCVA); 1398 cvaSource = 'Valor introducido'; 1399 } else { 1400 CVA = BOE_DATA.defaultCVA[vehicleType][fuelType]; 1401 cvaSource = 'Valor por defecto (BOE)'; 1402 } 1403 1404 if (CVA === undefined) { 1405 resultWarningElement.textContent = 'La combinación de vehÃculo y combustible seleccionada no es válida.'; 1406 resultsContainer.classList.remove('hidden'); 1407 return; 1408 } 1409 1410 let cvnSource = 'Valor por defecto (BOE)'; 1411 let CVN = BOE_DATA.defaultCVN[vehicleType]; 1412 if (userInputCVN) { CVN = parseFloat(userInputCVN); cvnSource = 'Valor introducido'; } 1413 1414 const energyConsumptionOld = CVA * f; 1415 const savingsPer100km = energyConsumptionOld - CVN; 1416 const totalSavingsKWh = (savingsPer100km / 100) * L; 1417 1418 if (totalSavingsKWh > 0) { 1419 const totalSavingsMWh = totalSavingsKWh / 1000; 1420 resultElement.textContent = `${totalSavingsMWh.toFixed(3).replace('.', ',')} MWh/año`; 1421 auvePromo.classList.remove('hidden'); 1422 } else { 1423 resultElement.textContent = '0 MWh/año'; 1424 resultWarningElement.textContent = 'Según los datos, no se genera un ahorro energético.'; 1425 } 1426 1427 const cvaUnits = fuelType === 'GasNatural' ? 'kg/100km' : 'l/100km'; 1428 const fuelTypeNameForDetails = fuelTypeSelect.options[fuelTypeSelect.selectedIndex].text; 1429 1430 detailsList.innerHTML = `<ul> 1431 <li><strong>Kilometraje anual (L):</strong> ${L.toLocaleString('es-ES')} km</li> 1432 <li><strong>Consumo vehÃculo antiguo (CVA):</strong> ${CVA} ${cvaUnits} <span>
1432(${cvaSource})</span></li> 1433 <li><strong>Consumo vehÃculo nuevo (CVN):</strong> ${CVN} kWh/100km <span>(${cvnSource})</span></li> 1434 <li><strong>Factor de conversión (f):</strong> ${f} <span>(para ${fuelTypeNameForDetails})</span></li></ul> 1435 `; 1436 1437 resultsContainer.classList.remove('hidden'); 1438 resultsContainer.scrollIntoView({ behavior: 'smooth' }); 1439 }); 1440 1441} 1442$(function () { 1443 initCaeCalculator(); 1444}); 1445 1446 1447 1448/** 1449 * Valida NIF (DNI) y NIE (España). NO valida CIF. 1450 * @param {string} value 1451 * @returns {boolean} 1452 */ 1453function validSpanishNifNie(value) { 1454 const dni = (value || "").toUpperCase().trim(); 1455 const letras = "TRWAGMYFPDXBNJZSQVHLCKE"; 1456 1457 // NIF: 8 dÃgitos + letra 1458 if (/^\d{8}[A-Z]$/.test(dni)) { 1459 const numero = parseInt(dni.slice(0, 8), 10); 1460 const letra = dni[8]; 1461 return letra === letras[numero % 23]; 1462 } 1463 1464 // NIE: X/Y/Z + 7 dÃgitos + letra 1465 if (/^[XYZ]\d{7}[A-Z]$/.test(dni)) { 1466 const reemplazo = { X: "0", Y: "1", Z: "2" }; 1467 const numero = reemplazo[dni[0]] + dni.slice(1, 8); 1468 const letra = dni[8]; 1469 return letra === letras[parseInt(numero, 10) % 23]; 1470 } 1471 1472 return false; 1473} 1474 1475function validSpanishDNIOnSignup() { 1476 try { 1477 const formBASE = document.querySelector( 1478 'body.modal-base-body > .login-container > form#signup_form[action="/accounts/signup/"]' 1479 ); 1480 if (!formBASE) return; 1481 1482 console.log("Estamos validando DNI"); 1483 1484 const form = document.getElementById("signup_form"); 1485 if (!form) return; 1486 const submitButton = form.querySelector("button[type='submit']"); 1487 submitButton?.classList.add("disabled"); 1488 1489 const nifInput = document.getElementById("id_custom_NIF"); 1490 const countrySelect = document.getElementById("id_custom_PAIS"); 1491 if (!nifInput) return; 1492 1493 const ensureNifErrorContainer = () => { 1494 let nifError = document.getElementById("id_custom_NIF-error"); 1495 if (nifError) return nifError; 1496 1497 const parent = nifInput.parentElement; 1498 if (!parent) return null; 1499 1500 nifError = document.createElement("div"); 1501 nifError.id = "id_custom_NIF-error"; 1502 parent.appendChild(nifError); 1503 return nifError; 1504 }; 1505 1506 const getNifError = () => ensureNifErrorContainer(); 1507 1508 const isSpainSelected = () => 1509 countrySelect && (countrySelect.value || "").trim().toLowerCase() === "españa"; 1510 1511 const setNifError = (message = "") => { 1512 const nifError = getNifError(); 1513 1514 if (nifError) { 1515 nifError.textContent = message; 1516 nifError.style.color = message ? "red" : ""; 1517 if (message) { 1518 nifError.setAttribute("role", "alert"); 1519 submitButton?.classList.add("disabled"); 1520 } 1521 else { 1522 nifError.removeAttribute("role"); 1523 submitButton?.classList.remove("disabled"); 1524 } 1525 } 1526 1527 nifInput.setCustomValidity(message); 1528 if (message) nifInput.setAttribute("aria-invalid", "true"); 1529 else nifInput.removeAttribute("aria-invalid"); 1530 }; 1531 1532 const validateNifIfNeeded = () => { 1533 setNifError(""); 1534 1535 if (!isSpainSelected()) { 1536 submitButton?.classList.remove("disabled"); 1537 return true; 1538 } 1539 const value = (nifInput.value || "").trim(); 1540 if (!value) { 1541 setNifError("Introduce un NIF o NIE."); 1542 return false; 1543 } 1544 1545 if (!validSpanishNifNie(value)) { 1546 setNifError("NIF/NIE no válido. Ej: 12345678Z o X1234567L."); 1547 return false; 1548 } 1549 1550 setNifError(""); 1551 return true; 1552 }; 1553 1554 form.addEventListener("submit", (e) => { 1555 if (!validateNifIfNeeded()) { 1556 e.preventDefault(); 1557 e.stopPropagation(); 1558 nifInput.reportValidity?.(); 1559 nifInput.focus?.(); 1560 } 1561 }); 1562 1563 nifInput.addEventListener("blur", validateNifIfNeeded); 1564 nifInput.addEventListener("keyup", () => { 1565 if (isSpainSelected()) validateNifIfNeeded(); 1566 else setNifError(""); 1567 }); 1568 1569 countrySelect?.addEventListener("change", () => { 1570 if (!isSpainSelected()) setNifError(""); 1571 else validateNifIfNeeded(); 1572 }); 1573 1574 validateNifIfNeeded(); 1575 } catch (error) { 1576 console.error( 1577 "Error en la función validSpanishDNIOnSignup:", 1578 error 1579 ); 1580 } 1581} 1582 1583 1584 1585 1586 1587function cambiarTitleLogout(){ 1588 1589 // console.log("entra"); 1590 1591 var $logout = $("form[action='/accounts/logout/']").parent(); 1592 1593 $logout.find("h3").text("¡Cerrar sesión!"); 1594 1595}; 1596 1597function makeLastNameRequiredOnSignupForm() { 1598 const form = document.getElementById("signup_form"); 1599 1600 if (!form) return; 1601 1602 const lastNameInput = form.querySelector("#id_last_name"); 1603 console.log("lastNameInput" + lastNameInput); 1604 1605 if (!lastNameInput) return; 1606 1607 lastNameInput.setAttribute("required", "required"); 1608}; 1609 1610 1611//////// AUTO SELECCIONAR OTROS EN PROVINCIA CUANDO NO SE ESCOJA ESPAÃA COMO PAÃS EN EL REGISTRATION / SIGNUP_FORM 1612function initSignupCountryProvinceControl() { 1613 try { 1614 var $signupForm = $('#signup_form'); 1615 1616 if (!$signupForm.length) { 1617 return; 1618 } 1619 1620 var countrySelector = '#signup_form #id_custom_PAIS'; 1621 var provinceSelector = '#signup_form #id_custom_PROVINCIA-REAL'; 1622 1623 function updateProvinceByCountry() { 1624 var $country = $(countrySelector); 1625 var $province = $(provinceSelector); 1626 1627 if (!$country.length || !$province.length) { 1628 return; 1629 } 1630 1631 var countryValue = $.trim($country.val() || ''); 1632 var isSpain = countryValue === 'España'; 1633 1634 // Contenedor visual creado por Bootstrap Select. 1635 var $provinceBootstrap = $province.closest('.bootstrap-select'); 1636 var $provinceButton = $provinceBootstrap.find( 1637 'button.dropdown-toggle' 1638 ); 1639 1640 if (!isSpain) { 1641 // El select real permanece habilitado para que se envÃe. 1642 $province.prop('disabled', false); 1643 1644 // Seleccionar "Otros". 1645 if (typeof $.fn.selectpicker === 'function') { 1646 $province.selectpicker('val', 'Otros'); 1647 $province.selectpicker('refresh'); 1648 } else { 1649 $province.val('Otros').trigger('change'); 1650 } 1651 1652 // Solo bloqueamos la interacción visual. 1653 $provinceBootstrap 1654 .addClass('province-visually-locked') 1655 .attr('aria-disabled', 'true'); 1656 1657 $provinceButton 1658 .attr('aria-disabled', 'true') 1659 .attr('tabindex', '-1'); 1660 1661 } else { 1662 // Provincia vuelve a ser editable. 1663 $province.prop('disabled', false); 1664 1665 if (typeof $.fn.selectpicker === 'function') { 1666 $province.selectpicker('refresh'); 1667 } 1668 1669 $provinceBootstrap 1670 .removeClass('province-visually-locked') 1671 .removeAttr('aria-disabled'); 1672 1673 $provinceButton 1674 .removeAttr('aria-disabled') 1675 .removeAttr('tabindex'); 1676 } 1677 } 1678 1679 /* 1680 * Evita abrir el desplegable de Provincia cuando esté 1681 * bloqueado visualmente. 1682 */ 1683 $(document) 1684 .off( 1685 'click.signupProvinceLock', 1686 '#signup_form .province-visually-locked button.dropdown-toggle' 1687 ) 1688 .on( 1689 'click.signupProvinceLock', 1690 '#signup_form .province-visually-locked button.dropdown-toggle', 1691 function (event) { 1692 event.preventDefault(); 1693 event.stopImmediatePropagation(); 1694 return false; 1695 } 1696 ); 1697 1698 /* 1699 * Detecta cambios en PaÃs, también los generados por 1700 * Bootstrap Select. 1701 */ 1702 $(document) 1703 .off( 1704 'change.signupCountryProvince ' + 1705 'changed.bs.select.signupCountryProvince', 1706 countrySelector 1707 ) 1708 .on( 1709 'change.signupCountryProvince ' + 1710 'changed.bs.select.signupCountryProvince', 1711 countrySelector, 1712 updateProvinceByCountry 1713 ); 1714 1715 /* 1716 * Refuerzo antes del envÃo. 1717 * No es necesario habilitar Provincia porque nunca se deshabilita. 1718 */ 1719 $signupForm 1720 .off('submit.signupCountryProvince') 1721 .on('submit.signupCountryProvince', function () { 1722 var $country = $(this).find('#id_custom_PAIS'); 1723 var $province = $(this).find( 1724 '#id_custom_PROVINCIA-REAL' 1725 ); 1726 1727 if ($.trim($country.val() || '') !== 'España') { 1728 $province.val('Otros'); 1729 } 1730 }); 1731 1732 updateProvinceByCountry(); 1733 1734 } catch (error) { 1735 console.error( 1736 'Error en initSignupCountryProvinceControl:', 1737 error 1738 ); 1739 } 1740} 1741 1742$(window).on('load', function () { 1743 setTimeout(initSignupCountryProvinceControl, 300); 1744}); 1745 } 1746 catch(err) { 1747 console.log("[ERROR Custom JS]", err.message); 1748 } 1749</script>
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.