2011-07-23 13 views
13

Estoy trabajando en un proyecto con MVC3 y estoy tratando de integrar qTip2 con la validación de jQuery para mostrar los errores como sugerencias flotantes. El problema que estoy teniendo es que al parecer llamar a errorPlacement en la validación del formulario no está haciendo nada, supongo que tiene algo que ver con la forma en que MVC lo maneja.Integración de qTip con MVC3 y jQuery Validación (errorPlacement)

Básicamente, lo que quiero hacer es usar la validación integrada entre MVC3 y jQuery (anotaciones) pero también se integra con qTip para cambiar cómo se muestra el mensaje de error.

He buscado por todas partes y lo mejor que he podido encontrar es que alguien sugirió modificar la función jquery.validate.unobtrusive.js - onError, pero lo he comprobado y no tenía idea de cómo modificarlo correctamente, y preferiría un solución que no requería que alterara las secuencias de comandos existentes.

Gracias por su ayuda.

Lo que tengo hasta ahora:

Mi Modelo:

public class User 
{ 
    [Required] 
    public string Id { get; set; } 

     [Required] 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    public string FirstName { get; set; } 

    public string SecondName { get; set; } 

    public string LastName { get; set; } 
} 

Mi Javascript en mi opinión:

$('#Form').validate({ 
    errorClass: "errormessage", 
    errorClass: 'error', 
    validClass: 'valid', 
    errorPlacement: function (error, element) { 
     // Set positioning based on the elements position in the form 
     var elem = $(element), 
      corners = ['left center', 'right center'], 
      flipIt = elem.parents('span.right').length > 0; 

     // Check we have a valid error message 
     if (true) { 
      // Apply the tooltip only if it isn't valid 
      elem.filter(':not(.valid)').qtip({ 
       overwrite: false, 
       content: error, 
       position: { 
        my: corners[flipIt ? 0 : 1], 
        at: corners[flipIt ? 1 : 0], 
        viewport: $(window) 
       }, 
       show: { 
        event: false, 
        ready: true 
       }, 
       hide: false, 
       style: { 
        classes: 'ui-tooltip-red' // Make it red... the classic error colour! 
       } 
      }) 

      // If we have a tooltip on this element already, just update its content 
      .qtip('option', 'content.text', error); 
     } 

     // If the error is empty, remove the qTip 
     else { elem.qtip('destroy'); } 
    }, 
    success: $.noop // Odd workaround for errorPlacement not firing! 
}) 

$('#Form').submit(function() { 
    if (!$(this).valid()) 
     return false; 

    $.ajax({ 
     url: this.action, 
     type: this.method, 
     data: $(this).serialize(), 
     beforeSend: function() { 
     }, 
     success: function (result) { 
     }, 
     error: function (result) { 
     } 
    }); 
    return false; 
}); 

Respuesta

11

alternativo

Mi primera solución funcionó, sino que también causó una cierta behaivior inesperado en cierta situación. Me fijo mediante la inclusión de un código errorPlacement en la función onError en el mismo archivo JS:

function onError(error, inputElement) { // 'this' is the form element 
    var container = $(this).find("[data-valmsg-for='" + inputElement[0].name + "']"), 
     replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false; 

    container.removeClass("field-validation-valid").addClass("field-validation-error"); 
    error.data("unobtrusiveContainer", container); 

    if (replace) { 
     container.empty(); 
     error.removeClass("input-validation-error").appendTo(container); 
    } 
    else { 
     error.hide(); 
    } 

    var element = inputElement; 
    // Set positioning based on the elements position in the form 
    var elem = $(element), 
         corners = ['left center', 'right center'], 
         flipIt = elem.parents('span.right').length > 0; 

    // Check we have a valid error message 
    if (!error.is(':empty')) { 
     // Apply the tooltip only if it isn't valid 
     elem.filter(':not(.valid)').qtip({ 
      overwrite: false, 
      content: error, 
      position: { 
       my: corners[flipIt ? 0 : 1], 
       at: corners[flipIt ? 1 : 0], 
       viewport: $(window) 
      }, 
      show: { 
       event: false, 
       ready: true 
      }, 
      hide: false, 
      style: { 
       classes: 'ui-tooltip-red' // Make it red... the classic error colour! 
      } 
     }) 

     // If we have a tooltip on this element already, just update its content 
     .qtip('option', 'content.text', error); 
    } 

    // If the error is empty, remove the qTip 
    else { elem.qtip('destroy'); } 
} 

y luego se puede enviar un formulario, la comprobación de la validación de esta manera:

$('#frm').submit(function() { 
    if (!$(this).valid()) 
     return false; 

    $.ajax({ 
     url: this.action, 
     type: this.method, 
     data: $(this).serialize(), 
     beforeSend: function() { 
     }, 
     success: function (result) { 
     }, 
     error: function (result) { 
     } 
    }); 
    return false; 
}); 
+0

La solución anterior resolvió el problema que mencioné también. ¡Gracias! –

+0

¿Alguna idea sobre cómo mostrar la sugerencia para los mensajes de validación del lado del servidor que vuelven después de una publicación en el servidor? –

+0

@ Nick-Olsen: la integración de qTip funciona con la validación del lado del cliente de jQuery ... Para implementarlo para la validación del lado del servidor, supongo que debe programarlo caso por caso. Pero no estoy seguro si hay una mejor manera. Creo que esta podría ser una pregunta en sí misma. Publiquelo para que pueda obtener ayuda de toda la comunidad ... – AJC

2

encontrado la respuesta ... la publicación de referencia.

1) Primero, busque la secuencia de comandos jquery.validate.unobtrusive.js proporcionada por microsoft.

2) En segundo lugar, en el guión localizar la función validationInfo (forma) y sustituir la instrucciónerrorPlacement en la estructura de opciones con el proporcionado por QTIP, o cualquiera de su elección.

3) Lo mismo ocurre con el estilo y otras opciones que desea cambiar en la forma en que se maneja la validación.

4) Incluye todos los archivos necesarios.

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

Ejemplo de código: Solución

function validationInfo(form) { 
    var $form = $(form), 
     result = $form.data(data_validation); 

    if (!result) { 
     result = { 
      options: { // options structure passed to jQuery Validate's validate() method 
       //errorClass: "input-validation-error", 
       errorClass: "error", 
       errorElement: "span", 
       //errorPlacement: $.proxy(onError, form), 
       errorPlacement: function (onError, form) { 
        var error = onError; 
        var element = form; 
        // Set positioning based on the elements position in the form 
        var elem = $(element), 
         corners = ['left center', 'right center'], 
         flipIt = elem.parents('span.right').length > 0; 

        // Check we have a valid error message 
        if (!error.is(':empty')) { 
         // Apply the tooltip only if it isn't valid 
         elem.filter(':not(.valid)').qtip({ 
          overwrite: false, 
          content: error, 
          position: { 
           my: corners[flipIt ? 0 : 1], 
           at: corners[flipIt ? 1 : 0], 
           viewport: $(window) 
          }, 
          show: { 
           event: false, 
           ready: true 
          }, 
          hide: false, 
          style: { 
           classes: 'ui-tooltip-red' // Make it red... the classic error colour! 
          } 
         }) 

         // If we have a tooltip on this element already, just update its content 
         .qtip('option', 'content.text', error); 
        } 

        // If the error is empty, remove the qTip 
        else { elem.qtip('destroy'); } 
       }, 
       invalidHandler: $.proxy(onErrors, form), 
       messages: {}, 
       rules: {}, 
       success: $.proxy(onSuccess, form) 
      }, 
      attachValidation: function() { 
       $form.validate(this.options); 
      }, 
      validate: function() { // a validation function that is called by unobtrusive Ajax 
       $form.validate(); 
       return $form.valid(); 
      } 
     }; 
     $form.data(data_validation, result); 
    } 

    return result; 
} 
+0

Gracias por la Sugerencia anterior, pero los cambios en el archivo jquery.validate.unobtrusive.js lo hacen para que el formulario se envíe incluso si hay errores. ¿Cómo se restaura el comportamiento predeterminado donde el formulario no se envía cuando hay errores? –

+1

@ Nick-Olsen - Personalmente, cada envío que hago es con jQuery Ajax, antes de realizar la llamada Ajax, valido el formulario explícitamente así: if (! $ (This) .valid()) return false; Sin embargo, tenga en cuenta que desde que publiqué esta solución por primera vez, realicé una mejora que resuelve algunos problemas que tengo con esta configuración en particular ... Lo agregaré como otra respuesta para que pueda verlo. – AJC

13

Gran solución gracias , He usado esto en mi aplicación.

... Para agregar más, en lugar de modificar el archivo jquery.validate.unobtrusive.min.js directamente utilicé lo siguiente para modificar el comportamiento predeterminado de la validación discreta.

$(document).ready(function() { 

      var settngs = $.data($('form')[0], 'validator').settings; 
      settngs.errorPlacement = function(error, inputElement) { 
       // Modify error placement here 
      }; 
}); 

Eagerly Performing ASP.NET MVC 3 Unobtrusive Client Side Validation

5

Mi solución - se puede utilizar en el archivo .js separadas y si se coloca en la página principal, funciona para todo el sitio.

$(document).ready(function() { 
    //validation - make sure this is included after jquery.validate.unobtrusive.js 
    //unobtrusive validate plugin overrides all defaults, so override them again 
    $('form').each(function() { 
     OverrideUnobtrusiveSettings(this); 
    }); 
    //in case someone calls $.validator.unobtrusive.parse, override it also 
    var oldUnobtrusiveParse = $.validator.unobtrusive.parse; 
    $.validator.unobtrusive.parse = function (selector) { 
     oldUnobtrusiveParse(selector); 
     $('form').each(function() { 
      OverrideUnobtrusiveSettings(this); 
     }); 
    }; 
    //replace validation settings function 
    function OverrideUnobtrusiveSettings(formElement) { 
     var settngs = $.data(formElement, 'validator').settings; 
     //standard qTip2 stuff copied from sample 
     settngs.errorPlacement = function (error, element) { 
      // Set positioning based on the elements position in the form 
      var elem = $(element); 


      // Check we have a valid error message 
      if (!error.is(':empty')) { 
       // Apply the tooltip only if it isn't valid 
       elem.filter(':not(.valid)').qtip({ 
        overwrite: false, 
        content: error, 
        position: { 
         my: 'center left', // Position my top left... 
         at: 'center right', // at the bottom right of... 
         viewport: $(window) 
        }, 
        show: { 
         event: false, 
         ready: true 
        }, 
        hide: false, 
        style: { 
         classes: 'qtip-red' // Make it red... the classic error colour! 
        } 
       }) 
       // If we have a tooltip on this element already, just update its content 
       .qtip('option', 'content.text', error); 
      } 

      // If the error is empty, remove the qTip 
      else { elem.qtip('destroy'); } 
     }; 

     settngs.success = $.noop; 
    } 
}); 
+0

Esto funcionó muy bien pero no parece estar aplicando las clases: 'qtip-red' en mi proyecto mvc. Siempre me sale el amarillo? ¿Alguna idea de por qué haría esto? – Spafa9

0

Con Mantisimo & AJC respuestas (gracias a él), he escrito el siguiente script, que está bien y funciona sin ningún problema, pero jquery.validate.unobtrusive.js genera un error como el siguiente en cada forma de presentación:

$(document).ready(function() { 
    var $forms = $.data($('form')[0], 'validator'); 
    if ($forms == undefined) return; 
    var settngs = $forms.settings; 
    settngs.errorPlacement = function (error, inputElement) { 
     var element = inputElement; 
     var elem = $(element), 
      corners = ['left center', 'right center'], 
      flipIt = elem.parents('span.right').length > 0; 
     if (!error.is(':empty')) { 
      elem.filter(':not(.valid)').qtip({ 
       overwrite: false, 
       content: error, 
       position: { 
        my: corners[flipIt ? 0 : 1], 
        at: corners[flipIt ? 1 : 0], 
        viewport: $(window) 
       }, 
       show: { 
        event: false, 
        ready: true 
       }, 
       hide: false, 
       style: { 
        classes: 'qtip-red', 
       } 
      }) 
      .qtip('option', 'content.text', error); 
     } 
     else { elem.qtip('destroy'); } 
    }; 
}); 

jquery.validate.unobtrusive.js error

he probado con MVC 5 y QTIP 2.2.0

Cuestiones relacionadas