jquery ajax / django – presente la forma en un modo de arranque y volver a mostrar si la validación no tuvo éxito

mi caso de uso es:

a) Presente un formulario cargado a través de ajax en un modo de arranque, el efecto de superposición de fantasía … Seguí estas instrucciones .

Esto funciona bien. (ver código abajo)

b) Vuelva a enviar este formulario a mi aplicación Django, intente validarlo y, si no lo hace, vuelva a mostrar el formulario con los errores en el elegante modo de arranque.

Puedo recargar el formulario a través de ajax, pero no puedo representarlo nuevamente en el modo modal.

Nota: No incluí la vista ya que no hace nada especial. Solo instanciar y validar el formulario.

Bastante para leer a continuación, así que continúe si cree que el caso de uso parece interesante …

Mi taskList.html tiene este aspecto:

Name Edit
Task 1 edit

.js para cargar el formulario + que muestra el formulario de enlace modal + bootstrap a una llamada de envío .jquery:

 $(document).ready(function() { modalConnect(); });  //connects the modal load for each  with class editItem //Functionality 1 //loads an item edit form from the server and replaces the itemFormModal with the form //presents the modal with $("#itemFormModal").modal('show'); //Functionality 2 //loads some extra js "modalExtraJsHtml" //calls the function "submitItemModalFormBind" which has been loaded via "modalExtraJsHtml" function modalConnect(){ $(".editItem").click(function(ev) { // for each edit item  ev.preventDefault(); // prevent navigation url = ($(this)[0].href); //get the href from  $.get(url, function(results){ var itemForm = $("#ajax_form_modal_result", results); var modalExtraJs = $("#modalExtraJs", results); //get the html content var modalExtraJsHtml = modalExtraJs.html(); //update the dom with the received results $('#itemFormModal').html(itemForm); $('#modalExtraJsPlaceholder').html(modalExtraJsHtml); $("#itemFormModal").modal('show'); submitItemModalFormBind(); //bind loaded form to ajax call }, "html"); return false; // prevent the click propagation }) }  

El itemForm devuelto de la vista se ve así:

  

Cargando y mostrando el modal funciona bien. Pero ahora viene la segunda parte que no funciona como se esperaba. El tema es el siguiente. Si el formulario no se valida, la vista devuelve el formulario. El formulario devuelto debe mostrarse nuevamente en el modo de rutina de carga. Pero el resultado es que SOLAMENTE el formulario se presenta en el navegador, todo lo demás se pierde. No css, no tabla, solo la forma. Bastante feo … Por lo tanto no logré actualizar el ajax_form_modal_result_div. ¿Puede alguien ayudarme aquí lo que estoy haciendo mal …??

La vista también devuelve la función js ‘submitItemModalFormBind’ que evita el comportamiento predeterminado del formulario y lo envía a través de ajax.

 
//ajax bind for update item form visualized via modal function submitItemModalFormBind(){ var url = "{% url updateItem item.pk %}"; $('#ajax_form_modal_result').submit(function(){ $.ajax({ type: "POST", url: "{% url updateTask item.pk %}", data: $(this).serialize(), success:function(response){ var div = $("ajax_form_modal_result_div", response); $('#ajax_form_modal_result_div').html(div); }, error: function (request, status, error) { console.log("failure"); console.log(request.responseText); } }); }); return false; }

Encontró un enfoque de trabajo (basado en esta solución , y lo mejoró con el manejo de formularios no válidos) y lo publicará para cualquiera que también quiera usar los impresionantes y hermosos modales de arranque con django. El principal problema con el código anterior fue que no desactivé correctamente el comportamiento predeterminado del botón de envío y el enfoque para cargar js adicionales no fue una buena idea. Así que cambié mi estrategia.

En el evento documentReady o ajaxStop, enlace el evento click de los hipervínculos a la función modalConnect. Tenga en cuenta que solo necesita la función ajaxStop si tiene algún tipo de ajax que actualice el contenido de su tabla (que tengo):

   

La función modalConnect que carga el formulario que queremos presentar en el modal y un formUpdateURLDiv:

  

formUpdateURL incluye una url generada por el servidor (ver vista incluida a continuación) a la cual el formulario cargado tiene que hacer su llamada de envío de formulario. Usamos esta url para “iniciar” la función submitItemModalFormBind:

  

..y para ver qué está pasando en el servidor, vea a continuación la vista que maneja la lógica:

 class UpdateTaskModalView(LoginRequiredMixin, View): template = 'list_management/crud/item/update_via_modal.html' def get_logic(self, request, task_id, **kwargs): task = get_object_or_404(Task.objects, pk=task_id) task_form = TaskForm(instance=task) context = { 'model_form': task_form, 'item': task, } return context def post_logic(self, request, task_id, **kwargs): task = get_object_or_404(Task.objects, pk=task_id) task_form = TaskForm(request.POST, instance=task) if task_form.is_valid(): task = task_form.save(commit=False) task.modified_by = request.user task.save() messages.add_message(request, messages.INFO, 'Item "%s" successfully updated' % (task.name)) return ('redirect', HttpResponseRedirect(reverse('show_list_after_item_update', kwargs={'list_id':task.list.pk, 'item_id':task.pk}))) context = { 'model_form' : task_form, 'list': task.list, 'item': task, } return ('context', context) def get(self, request, task_id, **kwargs): context = self.get_logic(request, task_id, **kwargs) return render_to_response( self.template, context, context_instance = RequestContext(request), ) def post(self, request, task_id, **kwargs): post_logic_return = self.post_logic(request, task_id, **kwargs) if post_logic_return[0] == 'redirect': return post_logic_return[1] if post_logic_return[0] == 'context': context = post_logic_return[1] return render_to_response( self.template, context, context_instance = RequestContext(request), ) 

..la plantilla de formulario ya está incluida en mi pregunta: ajax_form_modal_result_div, solo tiene que proporcionar también formUpdateURL. Lo hice a través de la plantilla, lo que parece bastante extraño ahora que escribo este post. Se podría proporcionar fácilmente a través del contexto de vista.

¡Voila – Formas Django con Modales Bootstrap! Dale sabor a tu interfaz de usuario!

Espero que esto ayude a alguien a resolver un problema similar.

Escribí este simple AJAX que hizo el truco por mí, espero que ayude:

 $(document).on('submit', 'div.modal-body form', function(e) { var form_el = $(this); e.preventDefault(); $.ajax({ type: $(this).attr('method'), url: $(this).attr('action'), data: $(this).serialize(), success: function (xhr, ajaxOptions, thrownError) { if ( $(xhr).find('.errorlist').length > 0 ) { form_el.parents('.modal-body').html(xhr); } else { form_el.parents('.modal-body').html('

Formulario enviado correctamente

'); } }, error: function (xhr, ajaxOptions, thrownError) { form_el.parents('.modal-body').html(xhr); } }); });

Oh, por cierto, también necesitarás algo como esto para cargar tu formulario en el modal:

 $('.modal-class').on('click',function(){ let dataURL = $(this).attr('data-href'); $('.modal-body').load(dataURL,function(){ $('#modal_crear').modal({show:true}); }); });