diff --git a/estudio_socio_economico/templates/admin/config_estudioSE.html b/estudio_socio_economico/templates/admin/config_estudioSE.html index b0bc61113f5d17a1623ec84b71358794f609a65c..56035b15c42075157c80c9b5f590fb1f66f09368 100644 --- a/estudio_socio_economico/templates/admin/config_estudioSE.html +++ b/estudio_socio_economico/templates/admin/config_estudioSE.html @@ -28,16 +28,27 @@ // Ocultar el divPadre del formset divSeccion.style.display = "none"; + //marcar para eliminacion sus secciones dependientes + const elementos = divSeccion.getElementsByClassName('cont-elem'); + for (let i = 0; i < elementos.length; i++) { + eliminarElemento(elementos[i],true); + } + } } - function eliminarElemento(elimBtn) { + function eliminarElemento(elimBtn, force) { //error reorden done const divElement = elimBtn.closest('.cont-elem'); // Obtener el número de formularios presentes en el formset + let confirmacion; + if (force === undefined){ + confirmacion = window.confirm("¿Estás seguro de que deseas eliminar este elemento?"); + }else { + confirmacion = true; + } - const confirmacion = window.confirm("¿Estás seguro de que deseas eliminar este elemento?"); if (confirmacion) { // Crear el input para marcar el elemento para eliminar const idElemento = divElement.querySelector(`[id^="id_elemento_formset-"][id$="-id"]`); @@ -57,15 +68,24 @@ revisarFilasVacias(divParentDiv.id) updateRowColValues(divParentDiv.id) } + + const opciones = divElement.getElementsByClassName('cont-opcion'); + for (let i = 0; i < opciones.length; i++) { + eliminarOpcion(opciones[i],true); + } } - function eliminarOpcion(elimBtn) { + function eliminarOpcion(elimBtn, force) { //error reorden done const divOpcion = elimBtn.closest('.cont-opcion'); // Obtener el número de formularios presentes en el formset - - const confirmacion = window.confirm("¿Estás seguro de que deseas eliminar esta opción?"); + let confirmacion; + if (force === undefined){ + confirmacion = window.confirm("¿Estás seguro de que deseas eliminar esta opción?"); + }else { + confirmacion = true; + } if (confirmacion) { // Crear el input para marcar el elemento para eliminar const idOpcion = divOpcion.querySelector(`[id^="id_opcion_formset-"][id$="-id"]`); @@ -115,7 +135,7 @@ // Obtener el número de formularios presentes en el formset // Ocultar el divPadre del formset - //divSeccion.style.display = "none"; + divSeccion.style.display = "none"; } @@ -215,24 +235,29 @@ if (ultimoRow !== undefined){ ultimoId = ultimoRow.id.split('-').pop(); // Extraer el número después del último guion } else { - ultimoId = '1'; + ultimoId = '0'; } - - + // Crear un nuevo elemento row const nuevoId = parseInt(ultimoId) + 1; const nuevoRow = document.createElement('div'); + const nuevoRow2 = document.createElement('div'); const rowid = parentDiv.split('-').pop(); nuevoRow.id = `elementos-${rowid}-${nuevoId}`; + nuevoRow2.id = `elementos-${rowid}-${nuevoId+1}`; nuevoRow.classList.add('row', 'conte-sort', 'px-1', 'm-0', 'pagina-fondo', 'altura-min-100px'); + nuevoRow2.classList.add('row', 'conte-sort', 'px-1', 'm-0', 'pagina-fondo', 'altura-min-100px'); - // Insertar el nuevo script dentro del nuevoRow nuevoRow.appendChild(document.createElement('script')); + nuevoRow2.appendChild(document.createElement('script')); // Insertar el nuevo row dentro del divPadre - divPadre.insertBefore(nuevoRow, botonAElem); + divPadre.insertBefore(nuevoRow, botonAElem); + const newfilas = divPadre.getElementsByClassName('conte-sort'); + divPadre.insertBefore(nuevoRow2, newfilas[0]); initializeSortable(nuevoRow.id, rowid, '.handle2', 150, 'ghost'); + initializeSortable(nuevoRow2.id, rowid, '.handle2', 150, 'ghost'); } function revisarFilasVacias(parentDiv) { @@ -335,6 +360,7 @@ divPadre.insertBefore(nuevoFormulario, botonASeccion); revisarFilasVacias(nuevoFormulario.id); updateTooltips(); + updateSeccionOrden(); } @@ -581,7 +607,8 @@ {{ seccion.nombre.label }} {{ seccion.nombre }}
- {{ seccion.nombre.errors }} + {{ seccion.nombre.errors }} + {{ seccion.non_field_errors }}
@@ -640,6 +667,7 @@ {{ elemento.nombre }}
{{ elemento.nombre.errors }} + {{ elemento.non_field_errors }}
@@ -703,6 +731,7 @@ {{ opcion.nombre }}
{{ opcion.nombre.errors }} + {{ opcion.non_field_errors }}
diff --git a/estudio_socio_economico/viewsAdmin.py b/estudio_socio_economico/viewsAdmin.py index 5c39cad19fb7364644dcba61152ccb5304c6a735..33758764a688a8041d19523899eb30fce80b0e09 100644 --- a/estudio_socio_economico/viewsAdmin.py +++ b/estudio_socio_economico/viewsAdmin.py @@ -28,10 +28,51 @@ def configEstudio(request): newId = elemFormsetId[1] + '-' + elemFormsetId[2] dictOpcionForm[elementoform.prefix] = OpcionFormSet(instance=elemInstancia, prefix='opcion_formset-%s' % newId) - if request.method == 'POST': + + if request.method == 'POST': + todoValido = True + dictElemForm = {} #diccionario que contiene todos los formset de elementos + dictOpcionForm = {} #diccionario que contiene todos los formset de objetos + + #obtenemos los formset de secciones, elementos y opciones y hacemos todas las validaciones seccionFormset = SeccionFormSet(request.POST, prefix='seccion_formset') - seccionFormset.is_valid() + if not seccionFormset.is_valid(): + todoValido = False + for seccion in seccionFormset.forms: + seccionInstancia = seccion.instance + seccionFormsetId = (seccion.prefix.split('-').pop()) + elementoFormset = ElementoFormSet(request.POST, instance=seccionInstancia, prefix='elemento_formset-%s' % seccionFormsetId) + if not elementoFormset.is_valid(): #generamos el cleaned data + todoValido = False + dictElemForm[seccion.prefix] = elementoFormset + + #obtenemos el opcionformset de cada elemento + for elemento in elementoFormset.forms: + elemInstancia = elemento.instance + elemFormsetId = elemento.prefix.split('-') + newId = elemFormsetId[1] + '-' + elemFormsetId[2] + opcionFormset = OpcionFormSet(request.POST, instance=elemInstancia, prefix='opcion_formset-%s' % newId) + if not opcionFormset.is_valid(): #generamos el cleaned data + todoValido = False + dictOpcionForm[elemento.prefix] = opcionFormset #añadimos el opcionFormset a el diccionario de opcionesformset + + #verificamos que un formulario vacio no tenga formularios dependientes de el con datos + #si es asi, no es valido, y agregamos los errores manualmente + if (elemento.cleaned_data and not seccion.cleaned_data and not elemento.cleaned_data['DELETE']): + todoValido = False + seccion.cleaned_data['error'] = 'Los campos de la sección son obligatorios' + seccion.add_error(None, seccion.cleaned_data['error']) + for opcionForm in opcionFormset: + if (opcionForm.cleaned_data and not elemento.cleaned_data and not opcionForm.cleaned_data['DELETE']): + todoValido = False + elemento.cleaned_data['error'] = 'Los campos de la pregunta son obligatorios' + elemento.add_error(None, elemento.cleaned_data['error']) + if (opcionForm.cleaned_data and not seccion.cleaned_data and not opcionForm.cleaned_data['DELETE']): + todoValido = False + seccion.cleaned_data['error'] = 'Los campos de la sección son obligatorios' + seccion.add_error(None, seccion.cleaned_data['error']) + #los formularios de los formset se reordenan para que el formulario extra default quede ultimo non_empty_forms = [] empty_forms = [] for form in seccionFormset.forms: @@ -39,117 +80,50 @@ def configEstudio(request): non_empty_forms.append(form) else: form.childAsinfo = 'on' - empty_forms.append(form) - # Unir ambas listas para tener los formularios no vacíos al principio y los vacíos al final - ordered_forms = non_empty_forms + empty_forms - # Actualizar el formset con la nueva lista de formularios - seccionFormset.forms = ordered_forms - - seccionFormset.is_valid() + empty_forms.append(form) + ordered_forms = non_empty_forms + empty_forms + seccionFormset.forms = ordered_forms + + for elementoFormset in dictElemForm.values(): + + non_empty_forms = [] + empty_forms = [] + for form in elementoFormset.forms: + if form.cleaned_data: + non_empty_forms.append(form) + else: + empty_forms.append(form) + ordered_forms = non_empty_forms + empty_forms + elementoFormset.forms = ordered_forms + + for opcionFormset in dictOpcionForm.values(): + + non_empty_forms = [] + empty_forms = [] + for form in opcionFormset.forms: + if form.cleaned_data: + non_empty_forms.append(form) + else: + empty_forms.append(form) + ordered_forms = non_empty_forms + empty_forms + opcionFormset.forms = ordered_forms + + #imprimir datos para debug + #''' + print('\n\n\n\n\nInicio Debug') for seccion in seccionFormset: + print('\n-----seccion '+seccion.prefix+' -----') print(seccion.cleaned_data) - - if seccionFormset.is_valid(): # and elementoFormset.is_valid(): - print('secciones es valida') - todoValido = True - dictElemForm = {} - dictOpcionForm = {} - - for seccion in seccionFormset.forms: - seccionInstancia = seccion.instance - print(seccion.cleaned_data) - - if (seccion.cleaned_data and seccion.cleaned_data['DELETE']): - if seccionInstancia.id is not None: - seccionInstancia.delete() - else : - - print('dentro de seccion : ') - print(seccion.cleaned_data) - seccionFormsetId = (seccion.prefix.split('-').pop()) - elementoFormset = ElementoFormSet(request.POST, prefix='elemento_formset-%s' % seccionFormsetId, instance=seccionInstancia) - elementoFormset.is_valid() - - print('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') - print(elementoFormset.cleaned_data) - - non_empty_forms = [] - empty_forms = [] - for form in elementoFormset.forms: - if form.cleaned_data: - non_empty_forms.append(form) - else: - empty_forms.append(form) - # Unir ambas listas para tener los formularios no vacíos al principio y los vacíos al final - ordered_forms = non_empty_forms + empty_forms - # Actualizar el formset con la nueva lista de formularios - elementoFormset.forms = ordered_forms - dictElemForm[seccion.prefix] = elementoFormset - - if elementoFormset.is_valid() and seccion.is_valid(): - if (seccion.cleaned_data ): #La seccion no esta en blanco - #seccion.save() - pass - print('elementos es valida') - else: - print('elemntos no valido') - print(elementoFormset.errors) - todoValido = False - - - for elemento in elementoFormset.forms: - elementoInstancia = elemento.instance - print(elemento.cleaned_data) - - if (elemento.cleaned_data and elemento.cleaned_data['DELETE']): - if elementoInstancia.id is not None: - elementoInstancia.delete() - else : - print('dentro de elemento : ') - print(elemento.cleaned_data) - elemFormsetId = elemento.prefix.split('-') - newId = elemFormsetId[1] + '-' + elemFormsetId[2] - opcionFormset = OpcionFormSet(request.POST, instance=elementoInstancia, prefix='opcion_formset-%s' % newId) - opcionFormset.is_valid() - - for opcion in opcionFormset: - print(opcion.cleaned_data) - - non_empty_forms = [] - empty_forms = [] - for form in opcionFormset.forms: - if form.cleaned_data: - non_empty_forms.append(form) - else: - empty_forms.append(form) - # Unir ambas listas para tener los formularios no vacíos al principio y los vacíos al final - ordered_forms = non_empty_forms + empty_forms - # Actualizar el formset con la nueva lista de formularios - opcionFormset.forms = ordered_forms - dictOpcionForm[elemento.prefix] = opcionFormset - - if opcionFormset.is_valid() and elemento.is_valid() and seccion.is_valid(): - if (elemento.cleaned_data and seccion.cleaned_data ): - print('elementos es valida') - #elemento.save() - #opcionFormset.save() - - else: - print('opciones no valido') - print(opcionFormset.errors) - todoValido = False - - if (elemento.cleaned_data and not seccion.cleaned_data): - todoValido = False - for opcionForm in opcionFormset: - if (opcionForm.cleaned_data and not elemento.cleaned_data): - todoValido = False - - #error se crean duplicados de los items validos si es que falla la rutina de validacion para el hijo de otro item - print("todo valido: ") - print(todoValido) - - if todoValido: + for elemento in dictElemForm[seccion.prefix]: + print('\n'+elemento.prefix) + print(elemento.cleaned_data) + for opcion in dictOpcionForm[elemento.prefix]: + print(opcion.prefix) + print(opcion.cleaned_data) #''' + + if todoValido: + #''' + print('=============== Todo es valido ===============\n') #''' seccionFormset.save() for elemFormset in dictElemForm.values(): if elemFormset.instance.id is not None: @@ -159,8 +133,18 @@ def configEstudio(request): OpcionFormset.save() return redirect('estudioSE:AConfigEstudio') else: - print('seccion no valid') + #imprimir datos pra debug + #''' + print('\n--------------- Todo no valido ---------------\n') + print(seccionFormset.prefix) print(seccionFormset.errors) + for elemFormset in dictElemForm.values(): + print(elemFormset.prefix) + print(elemFormset.errors) + for OpcionFormset in dictOpcionForm.values(): + print(OpcionFormset.prefix) + print(OpcionFormset.errors) #''' + print('--------------- Todo no valido ---------------\n') diff --git a/static/css/main.css b/static/css/main.css index bbd1a922387c23338c2ab090ffce1125cd46756e..219d78d02da7536fbbd7c55c3efdb24e8a19f02d 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -170,8 +170,8 @@ body { border: 1px dashed #000; /* Puedes ajustar el color y el grosor según tus necesidades */ } -.altura-min-100px { - min-height: 30px; +.conte-sort { + min-height: 15px; } /* Login */