oscarviedma

Código JavaScript Funcionalidad Formulario Registro

Apr 3rd, 2026 (edited)
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 13.17 KB | None | 0 0
  1. <script>
  2. (function () {
  3.  
  4.   // ─── ÚNICA LÍNEA QUE HAY QUE EDITAR ──────────
  5.   var OV_RE_URL = 'TU_URL_DE_APPS_SCRIPT_AQUI';
  6.   // ─────────────────────────────────────────────
  7.  
  8.   var ovReCampos = [];
  9.  
  10.   // ═══════════════════════════════════════════
  11.   //  PRECARGADOR
  12.   // ═══════════════════════════════════════════
  13.   function ovReMostrarFormulario() {
  14.     var preloader = document.getElementById('ov-re-preloader');
  15.     var formWrap  = document.getElementById('ov-re-form-wrap');
  16.     if (preloader) preloader.classList.add('ov-re-oculto');
  17.     if (formWrap)  formWrap.style.display = 'block';
  18.   }
  19.  
  20.   function ovReMostrarErrorCarga() {
  21.     var preloader = document.getElementById('ov-re-preloader');
  22.     if (preloader) {
  23.       preloader.innerHTML = '<span style="color:#c0392b;">⚠️ No se pudo cargar el formulario. Recarga la página.</span>';
  24.     }
  25.   }
  26.  
  27.   // ═══════════════════════════════════════════
  28.   //  INIT — carga campos y cupos en paralelo
  29.   // ═══════════════════════════════════════════
  30.   function ovReInit() {
  31.     Promise.all([
  32.       fetch(OV_RE_URL + '?action=campos').then(function (r) { return r.json(); }),
  33.       fetch(OV_RE_URL + '?action=cupos').then(function (r) { return r.json(); }),
  34.     ])
  35.     .then(function (resultados) {
  36.       ovReCampos = resultados[0].campos || [];
  37.       var cupos  = resultados[1];
  38.  
  39.       ovReGenerarCampos(ovReCampos);
  40.       ovReActualizarCupos(cupos);
  41.       ovReBindInputs();
  42.       ovReBindForm();
  43.       ovReMostrarFormulario();
  44.     })
  45.     .catch(function () {
  46.       console.error('OV-RE: No se pudo conectar con el servidor.');
  47.       ovReMostrarErrorCarga();
  48.     });
  49.   }
  50.  
  51.   // ═══════════════════════════════════════════
  52.   //  BARRA DE CUPOS
  53.   // ═══════════════════════════════════════════
  54.   function ovReActualizarCupos(cupos) {
  55.     var elCount = document.getElementById('ov-re-spots-count');
  56.     var elBar   = document.getElementById('ov-re-bar-fill');
  57.     var elWrap  = document.getElementById('ov-re-spots-wrap');
  58.  
  59.     if (cupos.ilimitado) {
  60.       if (elWrap) elWrap.style.display = 'none';
  61.       return;
  62.     }
  63.  
  64.     var restantes = Math.max(0, cupos.maximo - cupos.registrados);
  65.     var pct       = Math.min(100, (cupos.registrados / cupos.maximo) * 100);
  66.  
  67.     if (elCount) elCount.textContent = restantes;
  68.     if (elBar) {
  69.       setTimeout(function () {
  70.         elBar.style.width = pct + '%';
  71.       }, 500);
  72.     }
  73.   }
  74.  
  75.   // ═══════════════════════════════════════════
  76.   //  GENERAR CAMPOS DINÁMICAMENTE
  77.   // ═══════════════════════════════════════════
  78.   function ovReGenerarCampos(campos) {
  79.     var contenedor = document.getElementById('ov-re-campos-dinamicos');
  80.     if (!contenedor) return;
  81.  
  82.     contenedor.innerHTML = '';
  83.  
  84.     campos.forEach(function (campo) {
  85.       var fieldDiv = document.createElement('div');
  86.       fieldDiv.className = 'ov-re-field';
  87.  
  88.       // Label
  89.       var label = document.createElement('label');
  90.       label.setAttribute('for', 'ov-re-field-' + campo.nombre);
  91.       label.textContent = campo.etiqueta + (campo.requerido ? '' : ' (opcional)');
  92.       fieldDiv.appendChild(label);
  93.  
  94.       if (campo.tipo === 'select') {
  95.         var input = document.createElement('select');
  96.         input.id   = 'ov-re-field-' + campo.nombre;
  97.         input.name = campo.nombre;
  98.         if (campo.requerido) input.dataset.requerido = 'true';
  99.  
  100.         var optDefault = document.createElement('option');
  101.         optDefault.value = '';
  102.         optDefault.textContent = '— Selecciona una opción —';
  103.         input.appendChild(optDefault);
  104.  
  105.         campo.opciones.forEach(function (opcion) {
  106.           var opt = document.createElement('option');
  107.           opt.value = opcion;
  108.           opt.textContent = opcion;
  109.           input.appendChild(opt);
  110.         });
  111.  
  112.         // Wrapper para el ícono ::after de ETmodules
  113.         var selectWrap = document.createElement('div');
  114.         selectWrap.className = 'ov-re-field-select-wrap';
  115.         selectWrap.appendChild(input);
  116.         fieldDiv.appendChild(selectWrap);
  117.  
  118.       } else if (campo.tipo === 'textarea') {
  119.         var input = document.createElement('textarea');
  120.         input.id   = 'ov-re-field-' + campo.nombre;
  121.         input.name = campo.nombre;
  122.         input.rows = 4;
  123.         if (campo.placeholder) input.placeholder = campo.placeholder;
  124.         if (campo.requerido) input.dataset.requerido = 'true';
  125.         fieldDiv.appendChild(input);
  126.  
  127.       } else {
  128.         var input = document.createElement('input');
  129.         input.id   = 'ov-re-field-' + campo.nombre;
  130.         input.name = campo.nombre;
  131.         input.type = campo.tipo || 'text';
  132.         if (campo.placeholder) input.placeholder = campo.placeholder;
  133.         if (campo.requerido) input.dataset.requerido = 'true';
  134.         fieldDiv.appendChild(input);
  135.       }
  136.  
  137.       // Mensaje de error
  138.       var errSpan = document.createElement('span');
  139.       errSpan.className   = 'ov-re-field-error';
  140.       errSpan.id          = 'ov-re-err-' + campo.nombre;
  141.       errSpan.textContent = campo.etiqueta + ' es requerido';
  142.       fieldDiv.appendChild(errSpan);
  143.  
  144.       contenedor.appendChild(fieldDiv);
  145.     });
  146.   }
  147.  
  148.   // ═══════════════════════════════════════════
  149.   //  VALIDACIÓN DINÁMICA
  150.   // ═══════════════════════════════════════════
  151.   function ovReValidar() {
  152.     var ok = true;
  153.  
  154.     ovReCampos.forEach(function (campo) {
  155.       if (!campo.requerido) return;
  156.  
  157.       var el    = document.getElementById('ov-re-field-' + campo.nombre);
  158.       var errEl = document.getElementById('ov-re-err-' + campo.nombre);
  159.       if (!el || !errEl) return;
  160.  
  161.       var valido;
  162.       if (campo.tipo === 'email') {
  163.         valido = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(el.value);
  164.         errEl.textContent = 'Ingresa un correo válido';
  165.       } else {
  166.         valido = el.value.trim() !== '';
  167.         errEl.textContent = campo.etiqueta + ' es requerido';
  168.       }
  169.  
  170.       if (!valido) {
  171.         el.classList.add('ov-re-error');
  172.         errEl.classList.add('ov-re-show');
  173.         ok = false;
  174.       } else {
  175.         el.classList.remove('ov-re-error');
  176.         errEl.classList.remove('ov-re-show');
  177.       }
  178.     });
  179.  
  180.     var terminos    = document.getElementById('ov-re-terminos');
  181.     var errTerminos = document.getElementById('ov-re-err-terminos');
  182.     if (terminos && errTerminos) {
  183.      if (!terminos.checked) {
  184.        errTerminos.classList.add('ov-re-show');
  185.         ok = false;
  186.       } else {
  187.         errTerminos.classList.remove('ov-re-show');
  188.       }
  189.     }
  190.  
  191.     return ok;
  192.   }
  193.  
  194.   // ═══════════════════════════════════════════
  195.   //  LIMPIAR ERRORES AL ESCRIBIR
  196.   // ═══════════════════════════════════════════
  197.   function ovReBindInputs() {
  198.     ovReCampos.forEach(function (campo) {
  199.       var el = document.getElementById('ov-re-field-' + campo.nombre);
  200.       if (!el) return;
  201.       el.addEventListener('input', function () {
  202.         el.classList.remove('ov-re-error');
  203.         var errEl = document.getElementById('ov-re-err-' + campo.nombre);
  204.         if (errEl) errEl.classList.remove('ov-re-show');
  205.       });
  206.     });
  207.   }
  208.  
  209.   // ═══════════════════════════════════════════
  210.   //  MOSTRAR / OCULTAR ESTADOS
  211.   // ═══════════════════════════════════════════
  212.   function ovReMostrar(id) {
  213.     var wrap = document.getElementById('ov-re-form-wrap');
  214.     if (wrap) wrap.style.display = 'none';
  215.     var el = document.getElementById(id);
  216.     if (el) el.classList.add('ov-re-visible');
  217.   }
  218.  
  219.   function ovReOcultarEstados() {
  220.     ['ov-re-estado-success', 'ov-re-estado-espera', 'ov-re-estado-error'].forEach(function (id) {
  221.       var el = document.getElementById(id);
  222.       if (el) el.classList.remove('ov-re-visible');
  223.     });
  224.     var wrap = document.getElementById('ov-re-form-wrap');
  225.     if (wrap) wrap.style.display = 'block';
  226.   }
  227.  
  228.   function ovReResetForm() {
  229.     var form = document.getElementById('ov-re-form');
  230.     if (form) form.reset();
  231.     ovReOcultarEstados();
  232.     fetch(OV_RE_URL + '?action=cupos')
  233.       .then(function (r) { return r.json(); })
  234.       .then(ovReActualizarCupos);
  235.   }
  236.  
  237.   window.ovReOcultarEstados = ovReOcultarEstados;
  238.   window.ovReResetForm      = ovReResetForm;
  239.  
  240.   // ═══════════════════════════════════════════
  241.   //  ARMAR RESUMEN DE CONFIRMACIÓN
  242.   // ═══════════════════════════════════════════
  243.   function ovReArmarResumen(valores) {
  244.     var lineas = '';
  245.     ovReCampos.forEach(function (campo) {
  246.       var val = valores[campo.nombre];
  247.       if (val && val !== '—') {
  248.        lineas += '<strong>' + campo.etiqueta + ':</strong> ' + val + '<br/>';
  249.       }
  250.     });
  251.     return lineas;
  252.   }
  253.  
  254.   // ═══════════════════════════════════════════
  255.   //  SUBMIT
  256.   // ═══════════════════════════════════════════
  257.   function ovReBindForm() {
  258.     var form = document.getElementById('ov-re-form');
  259.     if (!form) return;
  260.  
  261.     form.addEventListener('submit', function (e) {
  262.       e.preventDefault();
  263.       if (!ovReValidar()) return;
  264.  
  265.       var btn = document.getElementById('ov-re-btn-submit');
  266.       var txt = document.getElementById('ov-re-btn-text');
  267.       var spn = document.getElementById('ov-re-spinner');
  268.       var arr = document.getElementById('ov-re-btn-arrow');
  269.  
  270.       if (btn) btn.disabled = true;
  271.       if (txt) txt.textContent = 'Enviando...';
  272.       if (spn) spn.style.display = 'block';
  273.       if (arr) arr.style.display = 'none';
  274.  
  275.       var valores = {};
  276.       ovReCampos.forEach(function (campo) {
  277.         var el = document.getElementById('ov-re-field-' + campo.nombre);
  278.         if (el) valores[campo.nombre] = el.value.trim();
  279.       });
  280.  
  281.       var params = new URLSearchParams({ action: 'registrar' });
  282.       Object.keys(valores).forEach(function (key) {
  283.         params.append(key, valores[key]);
  284.       });
  285.  
  286.       fetch(OV_RE_URL + '?' + params.toString())
  287.         .then(function (res) { return res.json(); })
  288.         .then(function (data) {
  289.           ovReOcultarEstados();
  290.  
  291.           if (data.status === 'ok') {
  292.             var resumen = document.getElementById('ov-re-resumen-registro');
  293.             if (resumen) resumen.innerHTML = ovReArmarResumen(valores);
  294.             ovReMostrar('ov-re-estado-success');
  295.             fetch(OV_RE_URL + '?action=cupos')
  296.               .then(function (r) { return r.json(); })
  297.               .then(ovReActualizarCupos);
  298.  
  299.           } else if (data.status === 'espera') {
  300.             var resumenE = document.getElementById('ov-re-resumen-espera');
  301.             if (resumenE) {
  302.               resumenE.innerHTML = ovReArmarResumen(valores) +
  303.                 '<strong>Lista de espera:</strong> #' + data.posicion;
  304.             }
  305.             ovReMostrar('ov-re-estado-espera');
  306.  
  307.           } else {
  308.             var errMsg = document.getElementById('ov-re-error-msg');
  309.             if (errMsg) errMsg.textContent = data.mensaje || 'Error desconocido.';
  310.             ovReMostrar('ov-re-estado-error');
  311.           }
  312.         })
  313.         .catch(function () {
  314.           var errMsg = document.getElementById('ov-re-error-msg');
  315.           if (errMsg) errMsg.textContent = 'No se pudo conectar. Revisa tu conexión e intenta de nuevo.';
  316.           ovReMostrar('ov-re-estado-error');
  317.         })
  318.         .finally(function () {
  319.           if (btn) btn.disabled = false;
  320.           if (txt) txt.textContent = 'Confirmar registro';
  321.           if (spn) spn.style.display = 'none';
  322.           if (arr) arr.style.display = 'flex';
  323.         });
  324.     });
  325.   }
  326.  
  327.   // ─── ARRANCAR ─────────────────────────────
  328.   if (document.readyState === 'loading') {
  329.     document.addEventListener('DOMContentLoaded', ovReInit);
  330.   } else {
  331.     ovReInit();
  332.   }
  333.  
  334. })();
  335. </script>
Advertisement
Add Comment
Please, Sign In to add comment