Quiero agregar automáticamente nuevos formularios a un conjunto de formularios de Django usando Ajax, para que cuando el usuario haga clic en un botón "agregar" ejecute JavaScript que agrega un nuevo formulario (que es parte del conjunto de formularios) a la página.
260
Respuestas:
Así es como lo hago, usando jQuery :
Mi plantilla:
En un archivo javascript:
Que hace:
cloneMore
aceptaselector
como primer argumento, ytype
of formset como el segundo. Lo queselector
debería hacer es pasarle lo que debería duplicar. En este caso, lo pasodiv.table:last
para que jQuery busque la última tabla con una clase detable
. La:last
parte de esto es importante porqueselector
también se usa para determinar después de qué se insertará el nuevo formulario. Es más que probable que lo desee al final del resto de los formularios. Eltype
argumento es para que podamos actualizar elmanagement_form
campo, en particularTOTAL_FORMS
, así como los campos de formulario reales. Si tiene un conjunto de formularios lleno de, por ejemplo,Client
modelos, los campos de administración tendrán IDid_clients-TOTAL_FORMS
yid_clients-INITIAL_FORMS
, mientras que los campos de formulario estarán en un formato deid_clients-N-fieldname
conN
siendo el número de formulario, comenzando con0
. Así, con eltype
argumento de lascloneMore
miradas de la función de cuántas formas hay actualmente, y pasa a través de cada entrada y etiqueta dentro de la nueva forma de la sustitución de todos los nombres de campo / nº ID de algo así comoid_clients-(N)-name
queid_clients-(N+1)-name
y así sucesivamente. Una vez finalizado, actualiza elTOTAL_FORMS
campo para reflejar el nuevo formulario y lo agrega al final del conjunto.Esta función es particularmente útil para mí porque la forma en que está configurada me permite usarla en toda la aplicación cuando quiero proporcionar más formularios en un conjunto de formularios, y no hace que necesite tener un formulario oculto de "plantilla" para duplicar siempre que lo pase, el nombre del formulario y el formato en que se presentan los formularios. Espero eso ayude.
fuente
prefix
miembro del objeto Formset. Este debería ser el mismo valor que eltype
argumento para lacloneMore
función.Versión simplificada de la respuesta de Paolo usando
empty_form
como plantilla.fuente
CompetitorFormSet = modelformset_factory(ProjectCompetitor, formset=CompetitorFormSets)
ctx['competitor_form_set'] = CompetitorFormSet(request.POST)
solo obtengo un formulario, en método limpio. ¿Puedes explicar cómo manejar esto en las vistas?empty_form
), lo cual agradezco.He publicado un fragmento de una aplicación en la que trabajé hace un tiempo. Similar a Paolo, pero también le permite eliminar formularios.
fuente
La sugerencia de Paolo funciona de maravilla con una advertencia: los botones de retroceso / avance del navegador.
Los elementos dinámicos creados con la secuencia de comandos de Paolo no se representarán si el usuario regresa al conjunto de formularios con el botón Atrás / Adelante. Un problema que puede ser un factor decisivo para algunos.
Ejemplo:
1) El usuario agrega dos nuevos formularios al conjunto de formularios con el botón "Agregar más"
2) El usuario completa los formularios y envía el conjunto de formularios
3) El usuario hace clic en el botón Atrás en el navegador
4) El conjunto de formularios ahora se reduce al formulario original, todos los formularios agregados dinámicamente no están allí
Esto no es un defecto con el guión de Paolo; pero un hecho de la vida con manipulación dom y caché del navegador.
Supongo que uno podría almacenar los valores del formulario en la sesión y tener algo de magia ajax cuando el conjunto de formularios se carga para crear los elementos nuevamente y volver a cargar los valores de la sesión; pero dependiendo de qué tan anal quiera ser sobre el mismo usuario y las múltiples instancias del formulario, esto puede ser muy complicado.
¿Alguien tiene una buena sugerencia para lidiar con esto?
¡Gracias!
fuente
Consulte las siguientes soluciones para los formularios dinámicos de django:
http://code.google.com/p/django-dynamic-formset/
https://github.com/javisantana/django-dinamyc-form/tree/master/frm
Ambos hacen uso de jQuery y son específicos de django. El primero parece un poco más pulido y ofrece una descarga que viene con demos que son excelentes.
fuente
Simula e imita:
<input>
campos.<input>
cambiaron los campos.Si bien sé que los conjuntos de formularios usan
<input>
campos ocultos especiales y sé aproximadamente lo que debe hacer el script, no recuerdo los detalles de la parte superior de mi cabeza. Lo que describí anteriormente es lo que haría en su situación.fuente
Hay un complemento jquery para esto , lo utilicé con el conjunto inline_form en Django 1.3, y funciona perfectamente, incluida la prepoblación, la adición, eliminación y múltiples conjuntos de formularios del lado del cliente.
fuente
Una opción sería la creación de un juego de formularios con todas las formas posibles, pero en un principio establecer las formas que no se necesiten en Oculto - es decir,
display: none;
. Cuando sea necesario mostrar un formulario, configure su pantalla css enblock
o lo que sea apropiado.Sin saber más detalles de lo que está haciendo su "Ajax", es difícil dar una respuesta más detallada.
fuente
Otra versión cloneMore, que permite la desinfección selectiva de campos. Úselo cuando necesite evitar que se borren varios campos.
fuente
Hay un pequeño problema con la función cloneMore. Dado que también está limpiando el valor de los campos ocultos generados automáticamente por django, hace que django se queje si intenta guardar un conjunto de formularios con más de un formulario vacío.
Aquí hay una solución:
fuente
Creo que esta es una solución mucho mejor.
¿Cómo crearías un formato dinámico en Django?
¿Las cosas clonadas no?
fuente
Para los codificadores que están buscando recursos para comprender un poco mejor las soluciones anteriores:
Conjuntos de formularios dinámicos de Django
Después de leer el enlace anterior, la documentación de Django y las soluciones anteriores deberían tener mucho más sentido.
Documentación del formulario de Django
Como resumen rápido de lo que me estaba confundiendo: El formulario de administración contiene una descripción general de los formularios que contiene. Debe mantener esa información precisa para que Django conozca los formularios que agrega. (Comunidad, por favor dame sugerencias si alguna de mis palabras está fuera de aquí. Soy nuevo en Django).
fuente
@Paolo Bergantino
para clonar todos los controladores adjuntos simplemente modifique la línea
para
para evitar este problema
fuente
Sí, también recomendaría simplemente mostrarlos en el html si tiene un número finito de entradas. (Si no lo hace, tendrá que usar otro método).
Puedes ocultarlos así:
Entonces el js es realmente simple:
fuente
Como todas las respuestas anteriores usan jQuery y hacen que algunas cosas sean un poco complejas, escribí el siguiente script:
Primero debe establecer auto_id en falso y así deshabilitar la duplicación de id y nombre. Debido a que los nombres de entrada deben ser únicos en su forma, toda la identificación se realiza con ellos y no con los ID. También tiene que reemplazar el
form
,type
y el contenedor del juego de formularios. (En el ejemplo anteriorchoices
)fuente