• >/* once-wcag-accesibilidad-js */ /* ============================================================ once-form-accesibilidad.js Correcciones WCAG 2.1 Nivel AA para el formulario ONCE Inyectar en: JotForm → Settings → Custom Code → JavaScript ============================================================ */ (function () { 'use strict'; /* ── Helpers ──────────────────────────────────────────── */ /* Añade un ID a aria-describedby sin borrar los existentes */ function appendAriaDescribedBy(el, id) { if (!el || !id) return; var current = (el.getAttribute('aria-describedby') || '').split(' ').filter(Boolean); if (current.indexOf(id) === -1) { current.push(id); el.setAttribute('aria-describedby', current.join(' ')); } } /* Copia atributos seleccionados de un elemento a otro */ function copyAttributes(src, tgt, attrs) { attrs.forEach(function (attr) { if (src.hasAttribute(attr)) { tgt.setAttribute(attr, src.getAttribute(attr)); } }); } /* ── Fix 1: Enlace "Saltar al contenido" (WCAG 2.4.1) ── */ function injectSkipLink() { if (document.querySelector('.wcag-skip-link')) return; var skip = document.createElement('a'); skip.href = '#main-content'; skip.className = 'wcag-skip-link'; skip.textContent = 'Saltar al contenido principal'; document.body.insertBefore(skip, document.body.firstChild); /* Asignar el id de ancla al contenedor del formulario */ var formAll = document.querySelector('.form-all, form[id]'); if (formAll && !document.getElementById('main-content')) { formAll.id = 'main-content'; } } /* ── Fix 2: Jerarquía de encabezados (WCAG 1.3.1) ──── */ function fixHeadings() { var h1s = Array.from(document.querySelectorAll('h1')); var h2s = Array.from(document.querySelectorAll('h2')); /* Si un H2 aparece ANTES del primer H1 en el DOM, convertirlo en

    */ if (h1s.length > 0) { var firstH1 = h1s[0]; h2s.forEach(function (h2) { /* compareDocumentPosition: bit 2 = el nodo comparado está ANTES */ if (firstH1.compareDocumentPosition(h2) & Node.DOCUMENT_POSITION_PRECEDING) { var p = document.createElement('p'); p.className = 'form-intro-text'; p.innerHTML = h2.innerHTML; copyAttributes(h2, p, ['id', 'style', 'aria-label']); h2.parentNode.replaceChild(p, h2); } }); } /* Si hay más de un H1, convertir los adicionales en H2 */ var h1sActualizados = Array.from(document.querySelectorAll('h1')); if (h1sActualizados.length > 1) { h1sActualizados.slice(1).forEach(function (h1) { var h2 = document.createElement('h2'); h2.innerHTML = h1.innerHTML; copyAttributes(h1, h2, ['id', 'class', 'style', 'aria-label']); h1.parentNode.replaceChild(h2, h1); }); } } /* ── Fix 3a: Nota explicativa de campos obligatorios (WCAG 1.3.1) ── */ function injectRequiredNotice() { if (document.querySelector('.wcag-required-notice')) return; var formAll = document.querySelector('.form-all, form[id]'); if (!formAll) return; var p = document.createElement('p'); p.className = 'wcag-required-notice'; /* aria-hidden en el asterisco visual para que el lector no lo lea */ p.innerHTML = 'Los campos marcados con * son obligatorios.'; formAll.insertBefore(p, formAll.firstChild); } /* ── Fix 3b: aria-hidden en asteriscos + aria-required en inputs (WCAG 1.3.1) */ function fixRequiredFields() { /* Ocultar asteriscos a lectores de pantalla */ document.querySelectorAll('.form-required').forEach(function (span) { span.setAttribute('aria-hidden', 'true'); }); /* Marcar los inputs/select/textarea del mismo campo como obligatorios */ document.querySelectorAll('.form-required').forEach(function (span) { var line = span.closest('li[id^="id_"], .form-line, .jf-form-group, fieldset'); if (!line) return; var field = line.querySelector( 'input:not([type="hidden"]):not([type="submit"]), select, textarea' ); if (field && !field.hasAttribute('aria-required')) { field.setAttribute('aria-required', 'true'); } }); } /* ── Fix 4: Atributos autocomplete (WCAG 1.3.5) ──── */ function fixAutocomplete() { var mapa = [ { id: 'input_10', value: 'given-name' }, /* Nombre */ { id: 'input_12', value: 'family-name' }, /* Apellido */ { id: 'q39_numeroDe', value: 'off' }, /* DNI — desactivar por seguridad */ { id: 'input_37_area', value: 'tel-national' }, /* Prefijo telefónico */ ]; mapa.forEach(function (entry) { var el = document.getElementById(entry.id); if (el) el.setAttribute('autocomplete', entry.value); }); /* Campo número de teléfono: buscar el input hermano del sublabel_37_area */ var sublabelArea = document.getElementById('sublabel_37_area'); if (sublabelArea) { var contenedor = sublabelArea.closest('li[id^="id_"], .form-line, fieldset'); if (contenedor) { var tel = contenedor.querySelector('input:not(#input_37_area):not([type="hidden"])'); if (tel && !tel.getAttribute('autocomplete')) { tel.setAttribute('autocomplete', 'tel'); } } } } /* ── Fix 5: Vincular sublabels a sus inputs (WCAG 1.3.1) ── */ function fixSublabels() { var pares = [ { input: 'input_37_area', sublabel: 'sublabel_37_area' }, /* Prefijo tel. */ { input: 'day_41', sublabel: 'sublabel_41_day' }, /* Día */ { input: 'month_41', sublabel: 'sublabel_41_month' }, /* Mes */ { input: 'year_41', sublabel: 'sublabel_41_year' }, /* Año */ ]; pares.forEach(function (par) { var input = document.getElementById(par.input); var sublabel = document.getElementById(par.sublabel); if (!input || !sublabel) return; /* Garantizar que el sublabel tiene ID */ if (!sublabel.id) sublabel.id = par.sublabel; appendAriaDescribedBy(input, par.sublabel); }); } /* ── Fix 6: SVGs decorativos sin accesibilidad (WCAG 1.1.1) ── */ function fixSVGs() { document.querySelectorAll('svg').forEach(function (svg) { /* Saltamos los que ya están correctamente marcados */ if (svg.getAttribute('aria-hidden') === 'true') return; if (svg.getAttribute('role') === 'img') return; if (svg.getAttribute('aria-label') || svg.getAttribute('aria-labelledby')) return; if (svg.querySelector('title')) return; /* Sin título ni etiqueta → es decorativo */ svg.setAttribute('aria-hidden', 'true'); svg.setAttribute('focusable', 'false'); }); } /* ── Fix 7: Vincular hints de textareas (WCAG 1.3.1) ── */ function fixTextareaHints() { document.querySelectorAll('textarea').forEach(function (textarea) { if (!textarea.id) return; var contenedor = textarea.closest('li[id^="id_"], .form-line, fieldset'); if (!contenedor) return; var hint = contenedor.querySelector('.form-hint, .form-description, [class*="hint"]'); if (!hint) return; if (!hint.id) hint.id = 'hint_' + textarea.id; appendAriaDescribedBy(textarea, hint.id); }); } /* ── Fix 8: Iframes sin title (WCAG 4.1.2) ─────────────────── */ function fixIframes() { document.querySelectorAll('iframe').forEach(function (iframe) { if (iframe.getAttribute('title') || iframe.getAttribute('aria-label')) return; var src = iframe.src || iframe.getAttribute('src') || ''; var title = src.includes('terms') || src.includes('Terms') || src.includes('termsConditions') ? 'Términos y Condiciones' : 'Contenido embebido'; iframe.setAttribute('title', title); }); } /* ── Fix 9: Barra de progreso multipágina (buena práctica AA) ── */ function injectProgressBar() { if (document.getElementById('wcag-progress-bar')) return; /* Contar páginas por separadores de JotForm */ var pagebreaks = document.querySelectorAll('.form-pagebreak, [class*="pagebreak"]'); var totalPages = pagebreaks.length > 0 ? pagebreaks.length + 1 : 1; if (totalPages <= 1) return; /* Sin barra si es formulario de una sola página */ var bar = document.createElement('div'); bar.id = 'wcag-progress-bar'; bar.className = 'wcag-progress-bar'; bar.setAttribute('role', 'progressbar'); bar.setAttribute('aria-valuenow', '1'); bar.setAttribute('aria-valuemin', '1'); bar.setAttribute('aria-valuemax', String(totalPages)); bar.setAttribute('aria-label', 'Página 1 de ' + totalPages); bar.textContent = 'Paso 1 de ' + totalPages; var formAll = document.querySelector('.form-all, form[id]'); if (formAll) { formAll.insertBefore(bar, formAll.firstChild); } } /* ── Fix 10: Gestión de foco en campos condicionales (WCAG 2.4.3) ── */ function observeConditionalFields() { var formAll = document.querySelector('.form-all, form[id]'); if (!formAll) return; var observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { /* Caso A: nodo nuevo añadido al DOM (campo revelado como nuevo elemento) */ mutation.addedNodes.forEach(function (node) { if (node.nodeType !== 1) return; if (!node.matches('li[id^="id_"], .form-line, fieldset')) return; var primero = node.querySelector( 'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled])' ); if (primero) setTimeout(function () { primero.focus(); }, 80); }); /* Caso B: estilo cambiado de display:none a visible */ if (mutation.type === 'attributes' && mutation.attributeName === 'style') { var target = mutation.target; var antes = mutation.oldValue || ''; var ocultaAntes = antes.indexOf('display: none') !== -1 || antes.indexOf('display:none') !== -1; var visibleAhora = target.style.display !== 'none' && target.style.display !== ''; if (ocultaAntes && visibleAhora) { var primero = target.querySelector( 'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled])' ); if (primero) setTimeout(function () { primero.focus(); }, 80); } } }); }); observer.observe(formAll, { childList: true, subtree: true, attributes: true, attributeOldValue: true, attributeFilter: ['style'] }); } /* ── Fix 8 live: Actualizar barra de progreso al cambiar de página ── */ function observePageChanges() { var formAll = document.querySelector('.form-all, form[id]'); if (!formAll) return; var paginaActual = 1; /* Guard para evitar bucle por las propias mutaciones que hacemos */ var enEjecucion = false; var observer = new MutationObserver(function (mutations) { if (enEjecucion) return; /* Detectar indicador de número de página que JotForm inyecta */ var indicador = document.querySelector( '[class*="form-page-number"], .form-pagebreak-title, [class*="jf-page-number"]' ); if (!indicador) return; var match = indicador.textContent.match(/(d+)/); if (!match) return; var nueva = parseInt(match[1], 10); if (nueva === paginaActual) return; paginaActual = nueva; enEjecucion = true; var bar = document.getElementById('wcag-progress-bar'); if (bar) { var total = bar.getAttribute('aria-valuemax') || '2'; bar.setAttribute('aria-valuenow', String(nueva)); bar.setAttribute('aria-label', 'Página ' + nueva + ' de ' + total); bar.textContent = 'Paso ' + nueva + ' de ' + total; } setTimeout(function () { enEjecucion = false; }, 300); }); observer.observe(formAll, { childList: true, subtree: true }); } /* ── Orquestador principal ─────────────────────────────── */ function runAllFixes() { injectSkipLink(); /* Fix 1 — skip link (primero: estructura de página) */ fixHeadings(); /* Fix 2 — jerarquía H1/H2 */ injectRequiredNotice(); /* Fix 3a — nota "campos obligatorios" */ fixRequiredFields(); /* Fix 3b — aria-hidden asteriscos + aria-required */ fixAutocomplete(); /* Fix 4 — atributos autocomplete */ fixSublabels(); /* Fix 5 — aria-describedby en campos compuestos */ fixSVGs(); /* Fix 6 — SVGs decorativos */ fixTextareaHints(); /* Fix 7 — hints de textareas */ fixIframes(); /* Fix 8 — iframes sin title */ injectProgressBar(); /* Fix 9 — barra de progreso (si multipágina) */ observeConditionalFields(); /* Fix 10 — foco en campos condicionales */ observePageChanges(); /* Fix 9 live — actualizar barra al cambiar página */ } /* Ejecutar después de que JotForm inicialice su propio JS (~300 ms) */ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function () { setTimeout(runAllFixes, 300); }); } else { setTimeout(runAllFixes, 300); } })();

  • Imagen promocional del programa ONCE Emprendedores, diseñado para personas con discapacidad

    ¿Sabías que este programa está diseñado para personas con discapacidad?

    Un pequeño paso para un gran cambio. Sabemos que cada proceso de aprendizaje es diferente, y que no siempre es fácil enfrentarse a formularios largos o con lenguaje técnico. Por eso queremos acompañarte desde el primer momento. Este formulario nos ayuda a entenderte mejor, conocer tus tiempos y lo que realmente necesitas para emprender y poder ofrecerte un apoyo que se adapte a ti, al fin. Puedes completarlo con calma, a tu ritmo. Te llevará aproximadamente 20 minutos, y toda la información es confidencial. No se trata de hacerlo perfecto, sino de dar ese primer paso con seguridad hacia una nueva etapa, pensada contigo y para ti.
  • Banner del formulario de pre-inscripción ONCE Emprendedores

    Formulario de pre-inscripción

    Para el programa 100% online pensado para que puedas crear un medio de vida. Recuerda que necesitamos que cuentes con el certificado de discapacidad del 33% o más y que puedes acceder a las clases desde cualquier dispositivo.
  • Logos de entidades colaboradoras: Unión Europea, Fundación ONCE y otros organismos del programa
  • Somos 49% emprendimiento 51% amor.

    Es un programa práctico donde realmente intentarás construirte un medio de vida que te genere ingresos. Tendrás asignados 2 mentores y participarás en sesiones grupales de mentoría y coaching.

    ➡️ Sabemos que cada persona tiene su propio camino de aprendizaje, y en este programa hemos diseñado un espacio inclusivo que entiende y respeta las distintas experiencias de quienes tienen alguna discapacidad. Aquí, todos los emprendedores son bienvenidos y acompañados en su proceso.

    ➡️ Este programa tiene una duración de 3 meses y se estructura de la siguiente manera:

    👉 Sesiones grupales de 3 horas por semana: Aprenderás de manera dinámica, con recursos accesibles que faciliten tu comprensión y participación.

    👉 Sesiones de equipo de 2 horas por semana: Un mentor te guiará personalmente, para que puedas avanzar con el modelo de tu negocio y resolver cualquier duda que surja.

    👉 3 horas semanales de validación práctica: Pondrás en práctica las ideas de tu emprendimiento, validando tus hipótesis en el mundo real.

    Participarás junto a cientos de emprendedores en un espacio de apoyo mutuo donde compartirás experiencias y aprenderás de otros emprendedores con proyectos similares a los tuyos.

    El programa está diseñado para que puedas dedicar unas 8 horas a la semana (3 horas de formación, 2 horas de mentoría, y 3 horas de validación práctica).

    💛Sabemos que emprender no es fácil, pero con esfuerzo y trabajo, puedes lograrlo. 

    ¡Es tu momento! Tienes todo lo necesario para construir el futuro que deseas, sin barreras ni límites. Estamos aquí para apoyarte, para que logremos superar cualquier obstáculo y diseñes el futuro de tus sueños.

    ¡Apresúrate, empezamos en pacos días!

    Equipo Programas 

    INCUBADORA CON VALORES

     

     

  • Selecciona la modalidad que más te interesa*
  • Edad*
  • Tienes un grado de discapacidad del 33% o superior?*
  • Si tu respuesta anterior fue Si ¿de qué tipo?
  •  -
  • Fecha de nacimiento*
     - -
  • Sexo*
  • Coméntame, ¿tienes estudios? ¿De qué tipo?*
  • ¿Tienes alguna idea de negocio en mente? Si no tienes una idea concreta, juntos te ayudaremos a definir una basada en tu experiencia 💡
  • ¿Alguna vez has emprendido?
  • ¿Tu emprendimiento ya está en marcha? Dinos como va
  • ¿Por qué quieres emprender?*
  • ¿Cuál es tu nivel aproximado de ingresos mensuales?*
  • ¿Dirías que estás en una situación económica vulnerable?*
  • ¿Tienes personas que dependan de ti económicamente?*
  • Si depende de ti una o varias personas, dinos que relación tienes con ellas*
  • ¿Tienes alguna actividad económica?*
  • ¿Cuál es tu nivel de habilidades tecnológicas?*
  • ¿Tienes un buen acceso a internet?*
  • ¿Has recibido alguna formación sobre emprendimiento?
  • ¿Qué esperas de Incubadora CON VALORES?
  • ¿Cuántas horas puedes dedicarle al programa de incubación durante las 12 semanas que dura?*
  • Una vez que hagas clic en enviar y completes tu inscripción, serás candidato/a para la próxima edición. Sin embargo, TE PEDIMOS PACIENCIA, porque NO TE CONTACTAREMOS HASTA UN MES ANTES DEL INICIO DE LA PRÓXIMA EDICIÓN. Seguidnos en la web (www.cvalores.org) y en redes sociales para estar al tanto de cuándo comenzamos. Y una última pregunta… ¿te gustaría ser una de las personas elegidas???? Si llegaste hasta acá, ya nos imaginamos la respuesta… 🚀🚀🚀🚀*
  • Should be Empty: