{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "html-forms-basic", "title": "Formularios HTML", "description": "Aprende a crear formularios con varios tipos de campos", "mode": "html", "difficulty": "beginner", "lessons": [ { "id": "form-structure", "title": "Estructura del formulario", "description": "Todo formulario necesita un contenedor <form>. Dentro, usa <label> para describir campos y <input> para la entrada de datos.

El atributo for en los labels debe coincidir con el id de los inputs para accesibilidad.", "task": "Crea un formulario con:
1. Un <label> con el texto Nombre: y el atributo for=\"name\"
2. Un <input> de texto con los atributos id=\"name\" y name=\"name\"", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-bottom: 5px; font-weight: 500; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }", "sandboxCSS": "", "initialCode": "", "solution": "
\n \n \n
", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "form", "message": "Envuelve todo en un elemento <form>" }, { "type": "element_exists", "value": "label", "message": "Añade un <label> para tu campo" }, { "type": "element_exists", "value": "input", "message": "Añade un elemento <input>" }, { "type": "attribute_value", "value": { "selector": "label", "attr": "for", "value": null }, "message": "Añade un atributo for a tu label" }, { "type": "attribute_value", "value": { "selector": "input", "attr": "id", "value": null }, "message": "Añade un atributo id a tu campo" } ] }, { "id": "input-types", "title": "Tipos de campos", "description": "Diferentes tipos de campos proporcionan teclados apropiados y validación:

type=\"text\" - Texto general
type=\"email\" - Email con validación @
type=\"password\" - Caracteres ocultos
type=\"number\" - Teclado numérico
type=\"tel\" - Teclado telefónico", "task": "Crea un formulario de inicio de sesión con dos campos:
1. Campo de email: <label for=\"email\">Email:</label> y <input type=\"email\" id=\"email\">
2. Campo de contraseña: <label for=\"password\">Contraseña:</label> y <input type=\"password\" id=\"password\">", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }", "sandboxCSS": "", "initialCode": "
\n \n
", "solution": "
\n \n \n \n \n \n
", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "input[type='email']", "message": "Añade un campo con type=\"email\"" }, { "type": "element_exists", "value": "input[type='password']", "message": "Añade un campo con type=\"password\"" }, { "type": "element_count", "value": { "selector": "label", "min": 2 }, "message": "Añade labels para ambos campos" } ] }, { "id": "submit-button", "title": "Botón de envío", "description": "Los formularios necesitan una forma de enviar datos. Usa:

<button type=\"submit\"> - Preferido, contenido flexible
<input type=\"submit\"> - Botón de solo texto

El texto del botón debe estar orientado a la acción (ej. Iniciar Sesión, 'Registrar', 'Enviar').", "task": "Añade un botón de envío al formulario con el texto Iniciar Sesión.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } button { width: 100%; margin-top: 20px; padding: 10px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background: #1565c0; }", "sandboxCSS": "", "initialCode": "
\n \n \n \n \n \n \n
", "solution": "
\n \n \n \n \n \n \n \n
", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "button[type='submit'], input[type='submit']", "message": "Añade un botón de envío a tu formulario" }, { "type": "element_text", "value": { "selector": "button", "text": "Iniciar Sesión" }, "message": "El botón debe decir Iniciar Sesión" } ] } ] }