validar cuestionario de responsable

This commit is contained in:
Tu Nombre
2025-01-30 09:54:08 -06:00
parent 99f409c7c4
commit 5eb9ca0d74
3 changed files with 237 additions and 35 deletions
+3
View File
@@ -1,3 +1,6 @@
.devcontainer
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
@@ -3,21 +3,27 @@
<h1 class="text-center mb-4">{{ formulario.titulo }}</h1>
<p class="text-center">{{ formulario.descripcion }}</p>
<form @submit.prevent="submitForm">
<div v-for="(item, index) in sortedItems" :key="item.id || item.idTabla" class="mb-4">
<div v-if="item.tipo">
<div v-for="(item, index) in sortedItems" :key="item.id || item.idTabla" class="mb-4 mt-6">
<div v-if="item.tipo" class="mt-6">
<label :for="item.id" class="form-label">{{ item.numeroPregunta }}. {{ item.texto }}</label>
<div v-if="item.tipo === 'seleccionUnica'">
<div v-if="item.tipo === 'seleccionUnica'" :key="item.id">
<div v-for="opcion in item.opciones" :key="opcion" class="SINO">
<!-- :id="item.id" -->
<b-radio
v-model="respuestas[item.id]"
:id="item.id"
:key="item.id + '-' + opcion"
:native-value="opcion"
type="is-info"
@change="updateRespuestas(item.id, opcion)"
>
{{ opcion }}
</b-radio>
</div>
</div>
<div v-if="item.tipo === 'seleccionMultiple'">
<div v-for="opcion in item.opciones" :key="opcion" class="SINO">
<input
@@ -29,6 +35,8 @@
{{ opcion }}
</div>
</div>
<div v-if="item.tipo === 'texto'">
<b-input
:id="item.id"
@@ -84,6 +92,7 @@
class="button is-success is-medium"
@click="submitForm()"
:disabled="!isFormComplete"
>
Enviar
</button>
@@ -719,33 +728,44 @@ Los datos están sujetos al aviso de privacidad integral que se puede consultar
},
created() {
// Inicializa las respuestas vacías para cada pregunta
this.formulario.preguntas.forEach((pregunta) => {
if (pregunta.tipo === 'evaluacion') {
this.respuestas[pregunta.id] = {}
pregunta.categorias.forEach((categoria) => {
categoria.items.forEach((item) => {
this.respuestas[pregunta.id][item] = ''
})
})
} else if (
pregunta.tipo === 'checkbox' ||
pregunta.tipo === 'seleccionMultiple'
) {
this.respuestas[pregunta.id] = []
} else {
this.respuestas[pregunta.id] = ''
}
})
this.respuestas = this.respuestas || {};
// Inicializa respuestas para cada tabla
this.formulario.tablas.forEach((tabla) => {
this.$set(this.respuestas, tabla.idTabla, {}); // Asegura que exista respuestas[tabla.idTabla]
tabla.renglones.forEach((renglon) => {
this.$set(this.respuestas[tabla.idTabla], renglon.idRenglon, null); // Asegura que exista respuestas[tabla.idTabla][renglon.idRenglon]
});
this.formulario.preguntas.forEach((pregunta) => {
if (!(pregunta.id in this.respuestas)) { // Solo inicializa si no existe
if (pregunta.tipo === 'seleccionMultiple') {
this.$set(this.respuestas, pregunta.id, []);
} else {
this.$set(this.respuestas, pregunta.id, null); // Usa null en lugar de ''
}
}
});
this.formulario.tablas.forEach((tabla) => {
if (!(tabla.idTabla in this.respuestas)) {
this.$set(this.respuestas, tabla.idTabla, {});
}
tabla.renglones.forEach((renglon) => {
if (!(renglon.idRenglon in this.respuestas[tabla.idTabla])) {
this.$set(this.respuestas[tabla.idTabla], renglon.idRenglon, null);
}
});
},
});
},
watch: {
respuestas: {
handler(newVal) {
console.log("Estado actualizado de respuestas:", newVal);
},
deep: true
}
},
computed: {
sortedItems() {
const items = [...this.formulario.preguntas, ...this.formulario.tablas]
@@ -756,10 +776,104 @@ Los datos están sujetos al aviso de privacidad integral que se puede consultar
return a.numeroPregunta - b.numeroPregunta
})
},
isFormComplete() {
// Verifica todas las preguntas individuales
const allQuestionsAnswered = this.formulario.preguntas.every((pregunta) => {
const respuesta = this.respuestas[pregunta.id];
if (pregunta.tipo === "seleccionMultiple") {
return respuesta && respuesta.length > 0; // Debe tener al menos una opción seleccionada
}
return respuesta !== null && respuesta !== ""; // No debe ser null ni vacío
});
// Verifica todas las respuestas de la tabla
const allTablesAnswered = this.formulario.tablas.every((tabla) => {
return tabla.renglones.every((renglon) => {
return this.respuestas[tabla.idTabla] && this.respuestas[tabla.idTabla][renglon.idRenglon] !== null;
});
});
return allQuestionsAnswered && allTablesAnswered;
}
},
methods: {
updateRespuestas(id, valor) {
this.$set(this.respuestas, id, valor);
console.log("Radio seleccionado:", id, valor);
},
validateResponses() {
for (const pregunta of this.formulario.preguntas) {
const respuesta = this.respuestas[pregunta.id];
// Verifica que no haya respuestas vacías
if (respuesta === null || respuesta === "") {
this.$buefy.dialog.alert({
title: "Error",
message: `Por favor, responde la pregunta: "${pregunta.texto}"`,
type: "is-danger",
});
return false;
}
// Para selección múltiple, al menos un elemento debe estar seleccionado
if (pregunta.tipo === "seleccionMultiple" && (!respuesta || respuesta.length === 0)) {
this.$buefy.dialog.alert({
title: "Error",
message: `Por favor, selecciona al menos una opción en: "${pregunta.texto}"`,
type: "is-danger",
});
return false;
}
// Validación adicional si la pregunta es de texto (evitar respuestas peligrosas)
if (pregunta.tipo === "texto" && respuesta.length > 500) {
this.$buefy.dialog.alert({
title: "Error",
message: `La respuesta de la pregunta "${pregunta.texto}" es demasiado larga.`,
type: "is-danger",
});
return false;
}
}
// Verifica que todas las respuestas en las tablas estén completas
for (const tabla of this.formulario.tablas) {
for (const renglon of tabla.renglones) {
const respuesta = this.respuestas[tabla.idTabla]?.[renglon.idRenglon];
if (respuesta === null) {
this.$buefy.dialog.alert({
title: "Error",
message: `Por favor, responde la pregunta en la tabla: "${tabla.preguntaTabla}" en la fila "${renglon.textoRenglon}"`,
type: "is-danger",
});
return false;
}
}
}
return true;
},
submitForm() {
console.log('Respuestas enviadas:', this.respuestas)
if (!this.validateResponses()) {
return; // Detiene el envío si la validación falla
}
console.log('Respuestas a enviar:', this.respuestas)
//alert('Formulario enviado. Gracias por tu participación.')
@@ -773,7 +887,7 @@ Los datos están sujetos al aviso de privacidad integral que se puede consultar
let data = { ...respuestaFormateada,
idServicio: localStorage.getItem('idCuestionarioAlumno'), // 4,
idServicio: localStorage.getItem('idServicio'), // 4,
p1: 'respuesta1 - trabajando para que sea una string',
}
@@ -805,7 +919,6 @@ Los datos están sujetos al aviso de privacidad integral que se puede consultar
},
formatearRespuestas(respuestas) {
// Objeto final a devolver
const resultado = {}
@@ -872,9 +985,6 @@ Los datos están sujetos al aviso de privacidad integral que se puede consultar
return resultado
},
},
}
</script>
@@ -84,6 +84,7 @@
class="button is-success is-medium"
@click="submitForm()"
:disabled="!isFormComplete"
>
Enviar
</button>
@@ -756,6 +757,32 @@
return a.numeroPregunta - b.numeroPregunta
})
},
isFormComplete() {
// Verifica todas las preguntas individuales
const allQuestionsAnswered = this.formulario.preguntas.every((pregunta) => {
const respuesta = this.respuestas[pregunta.id];
if (pregunta.tipo === "seleccionMultiple") {
return respuesta && respuesta.length > 0; // Debe tener al menos una opción seleccionada
}
return respuesta !== null && respuesta !== ""; // No debe ser null ni vacío
});
// Verifica todas las respuestas de la tabla
const allTablesAnswered = this.formulario.tablas.every((tabla) => {
return tabla.renglones.every((renglon) => {
return this.respuestas[tabla.idTabla] && this.respuestas[tabla.idTabla][renglon.idRenglon] !== null;
});
});
return allQuestionsAnswered && allTablesAnswered;
}
},
methods: {
submitForm() {
@@ -871,8 +898,70 @@
return resultado
},
validateResponses() {
for (const pregunta of this.formulario.preguntas) {
const respuesta = this.respuestas[pregunta.id];
// Verifica que no haya respuestas vacías
if (respuesta === null || respuesta === "") {
this.$buefy.dialog.alert({
title: "Error",
message: `Por favor, responde la pregunta: "${pregunta.texto}"`,
type: "is-danger",
});
return false;
}
// Para selección múltiple, al menos un elemento debe estar seleccionado
if (pregunta.tipo === "seleccionMultiple" && (!respuesta || respuesta.length === 0)) {
this.$buefy.dialog.alert({
title: "Error",
message: `Por favor, selecciona al menos una opción en: "${pregunta.texto}"`,
type: "is-danger",
});
return false;
}
// Validación adicional si la pregunta es de texto (evitar respuestas peligrosas)
if (pregunta.tipo === "texto" && respuesta.length > 500) {
this.$buefy.dialog.alert({
title: "Error",
message: `La respuesta de la pregunta "${pregunta.texto}" es demasiado larga.`,
type: "is-danger",
});
return false;
}
}
// Verifica que todas las respuestas en las tablas estén completas
for (const tabla of this.formulario.tablas) {
for (const renglon of tabla.renglones) {
const respuesta = this.respuestas[tabla.idTabla]?.[renglon.idRenglon];
if (respuesta === null) {
this.$buefy.dialog.alert({
title: "Error",
message: `Por favor, responde la pregunta en la tabla: "${tabla.preguntaTabla}" en la fila "${renglon.textoRenglon}"`,
type: "is-danger",
});
return false;
}
}
}
return true;
},
updateRespuestas(id, valor) {
this.$set(this.respuestas, id, valor);
console.log("Radio seleccionado:", id, valor);
},
},