modal example ejemplos close bootstrap jquery twitter-bootstrap ruby-on-rails-3.2 simple-form

example - modal jquery



Mostrar errores en lĂ­nea con simple_form en un Bootstrap Ajax modal (2)

He encontrado preguntas similares sobre StackOverflow aquí y aquí, pero todavía no puedo hacer que esto funcione.

Estoy usando Rails 3.2.8, SimpleForm 2.0.4 y Twitter Bootstrap 2.1.1 (a través de la gema bootstrap-sass 2.1.1.0).

El usuario debería poder agregar un contacto desde una ventana emergente modal. Si hay errores de validación, deberían aparecer en línea, como si el usuario estuviera usando una versión no modal del formulario (borde rojo alrededor del campo, mensaje de error al lado del campo).

Yo cargo el modal así:

<a data-toggle="modal" data-target="#new-contact-modal">Go modal!</a>

Aquí está el modal Bootstrap, que llama a los mismos contacts/contact_fields parciales utilizados en la versión no modal. app / views / contacts / _new_modal.html.erb :

<div id="new-contact-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="new-contact-modal-label" aria-hidden="true"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h3 id="new-contact-modal-label"><%= t("contacts.new.header") %></h3> </div> <%= simple_form_for(@contact, :remote => true, :html => {:class => "form-horizontal", "data-type" => :json }) do |contact_form| %> <div id="new-contact-body" class="modal-body"> <%= render ''contacts/contact_fields'', :f => contact_form %> </div> <div class="modal-footer"> <%= contact_form.submit :class => "btn btn-primary", :"data-loading-text"=> (''simple_form.creating'') %> <%= t(''simple_form.buttons.or'') %> <a data-dismiss="modal" aria-hidden="true"> <%= t(''simple_form.buttons.cancel'') %> </a> </div> <% end %> </div>

app / controllers / contacts_controller.rb (intencionalmente comentado la línea format.json ya que estoy tratando de volver a enviar todo el modal usando JavaScript):

def create @contact = Contact.new(params[:contact]) <...some additional processing...> respond_to do |format| if @contact.save format.html { flash[:success] = "Contact added." redirect_to @contact } format.json { render json: @contact, status: :created, location: @contact} else format.html { render action: "new" } #format.json { render json: @contact.errors, status: :unprocessable_entity } format.js { render ''new_modal_error'' } end

app / views / contacts / new_modal_error.js.erb

var modal = "<%= escape_javascript(render :partial => ''contacts/new_modal'', :locals => { :contact => @contact.errors }) %>"; $("#new-contact-modal").html($(modal));

app / assets / javascripts / contacts.js Algunos JQuery para restablecer el formulario y cerrar el modal en caso de éxito.

$(function($) { $("#new_contact") .bind("ajax:success", function(event, data, status, xhr) { // http://simple.procoding.net/2008/11/22/how-to-reset-form-with-jquery : $(this).each(function(){ this.reset(); }); $("#new-contact-modal").modal("hide"); }) });

La buena noticia es que esto funciona cuando el formulario no tiene errores: el contacto se agrega y el modal está oculto. Sin embargo, si hay errores de validación, aparece el mensaje "JSON.parse: carácter inesperado". Esto viene de jquery.js, línea 515, que es la declaración de return en este fragmento:

// Attempt to parse using the native JSON parser first if ( window.JSON && window.JSON.parse ) { return window.JSON.parse( data ); }

Si inspecciono los data , veo que es el contenido de mi archivo new_modal_error.js , completamente expandido con los errores de formulario, y escapé para JavaScript. Pero no es JSON.

¿Qué me estoy perdiendo? ¿Cómo hago para que la página procese new_modal_error.js como un archivo JavaScript, no una variable JSON? ¿O hay una manera más fácil de manejar esto por completo?


No entiendo por qué necesitas restablecer el formulario. Creo que no es necesario.

$(function($) { $("#new_contact") .bind("ajax:success", function(event, data, status, xhr) { ... }) });

Una cosa que necesita corregir es debajo de la línea en su new_model_error.js.erb , de lo contrario tendrá divs duplicados con id = "new-contact-modal" .

old: $("#new-contact-modal").html($(modal)); new: $("#new-contact-modal").html($(modal).html());

Avísame si todavía tienes problemas.


El problema principal aquí era llamar al formulario con data-type => :json . Eso significa que esperará una respuesta JSON, pero quiero que devuelva JavaScript. La solución es establecer data-type => :script (o simplemente dejarlo y dejar que Rails infiera JavaScript):

:html => {:class => "form-horizontal", "data-type" => :script }) do |contact_form| %>

Gracias a este artículo por explicar los diversos tipos de datos y aclarar que el tipo de datos se refiere a la respuesta , no a la presentación de datos:

Rieles 3 enlaces remotos y formularios Parte 2: tipo de datos (con jQuery)

"El método .ajax() jQuery proporciona un parámetro opcional llamado dataType para especificar el tipo de datos deseado de la respuesta".

Otro problema que creo que @wanghq estaba señalando es que el método .html() JQuery actualiza el innerHTML de un objeto. Terminé creando un parcial que contiene solo el formulario, llamando al parcial dentro de un <div id="new-contact-form-wrapper"> , y luego dirigiendo el contenedor para reemplazar el formulario:

var myForm = "<%= escape_javascript(render :partial => ''contacts/new_modal_form'', :locals => { :contact => @contact.errors }) %>"; $("#new-contact-form-wrapper").html(myForm);

Todavía estoy trabajando para obtener las variables aprobadas, el formulario borrado en caso de éxito, etc. Como estoy usando un parcial del controlador, probablemente continuaré y pondré todo el JQuery (tanto para el éxito como para el fracaso) allí No necesitaré la aplicación / assets / javascripts / contacts.js .