2012-02-28 14 views
11

Tengo el problema de que no puedo activar la validación del lado del cliente desde mi vista parcial, que se carga en un div después de que un usuario hace clic en un botón. En este ejemplo, he detenido el div de "alternar" para ver si la validación se dispara, pero fue en vano, no pasó nada.MVC 3 Razor. La validación de la vista parcial no funciona

Afortunadamente, el modelo no acepta ninguna entrada no válida, pero tampoco advierte al usuario del error real. Cualquier ayuda sería apreciada.

Aquí es mi modelo:

public class Help 
{ 
    [HiddenInput(DisplayValue=true)] 
    public int HelpID { get; set; } 

    [Required(ErrorMessage = "Please enter a proper URL")] 
    public string URL { get; set; } 

    [Required(ErrorMessage = "Please enter a content description:")] 
    [DataType(DataType.MultilineText)] 
    public string HelpContent { get; set; } 

    /*? 2 properites are nullable*/ 
    public DateTime? createDateTime { get; set; } 
    public DateTime? modifiedDateTime { get; set; }   
} 

Aquí está mi controlador:

namespace HelpBtn.WebUI.Controllers 
{ 
    /*Create the admin controller*/ 
    public class AdminController : Controller 
    { 
     //declare interface object 
     private IHelpRepository repository; 

     /*Pass a db interface to controller*/ 
     public AdminController(IHelpRepository repo) 
     { 
      repository = repo; 
     } 

     /*default admin screen. displays help table obs*/ 
     public ViewResult Index() 
     { 
      return View(); 
     } 

     /*Returns add view form*/ 
     public ViewResult AddForm() 
     { 
      return View(); 
     } 

     /*Returns edit view form, searches for object to edit with id 
      if no id provided, 0 by default*/ 
     public ViewResult EditForm(int helpID = 0) 
     { 
      Help help = repository.Help.FirstOrDefault(q => q.HelpID == helpID); 
      return View(help); 
     } 

     /*Will handle the post for the edit screen after user has 
      submitted edit information*/ 
     [HttpPost] 
     [ValidateInput(false)] //this allows admin to place html in field. may cause validation problems 
     public ActionResult EditForm(Help help) 
     { 

      if (ModelState.IsValid) //if all fields are validated 
      { 
       //set the edit date 
       help.modifiedDateTime = DateTime.Now; 
       repository.SaveHelp(help); 
       return RedirectToAction("Index"); 
      } 
      else //there is something wrong. send back to view    
      { 
       return View(help); 
      } 
     } 

     /*Delete action method, searches with id*/ 
     [AcceptVerbs(HttpVerbs.Post)] 
     [GridAction] 
     public ActionResult Delete(int helpId) 
     { 
      Help helpDel = repository.Help.FirstOrDefault(p => p.HelpID == helpId); 
      if (helpDel != null) //if the object is found, delete 
      { 
       repository.DeleteHelp(helpDel); 
      } 

      //in all cases return to index 
      return RedirectToAction("Index"); 
     } 

     /*Used by the telerik table to rebind grid*/ 
     [GridAction] 
     public ActionResult AjaxBinding() 
     { 
      return View(new GridModel(repository.Help)); 
     } 
    }//end admin class 
}//end namespace 

Aquí está mi vista Principal:

<div id="addContent" style="display: none"></div> 

//Select Function. saves selected row 
function onRowSelect(e) { 
    HelpID = e.row.cells[0].innerHTML; 
} //end onRowSelect 

//Refresh grid function 
function refreshGrid() { 
    $("#Grid").data('tGrid').rebind(); 
} //end refresh grid 

//Variables. '$' b4 name for intellisense 
var HelpID; 
var $editContent = $("#editContent"); 
var $addContent = $("#addContent"); 
//end variables 

//Add Form call. loads partial view to div:content 
$("#Add").click(function() { 
    $editContent.hide(); 
    $editContent.html(""); 
    $.ajax({ 
     type: "Get", 
     url: "/Admin/AddForm", 
     datatype: "html", 
     success: function (data) { 
      $addContent.html(data); 
      $addContent.toggle(); 
     } //end success 
    }); //end ajax 
});  //end add 

//Edit Form call. loads partial view to div:content 
$("#Edit").click(function() { 
    $addContent.hide(); 
    $addContent.html(""); 
    $.ajax({ 
     type: "Get", 
     url: "/Admin/EditForm", 
     dataType: "html", 
     data: { HelpID: HelpID }, 
     success: function (data) { 
      $editContent.html(data); 
      $editContent.toggle(); 
     } //end sucess 
    }); //end ajax 
});   //end edit 

//Delete call. deletes selected row in table 
$("#Delete").live('click', function() { 
    $.post("/Admin/Delete", { HelpID: HelpID }, function() { 
     $addContent.html(""); 
     $editContent.html(""); 
     refreshGrid(); 
    }); //end function 
}); //end delete 

//post add form data back to server 
     $("#btnAdd").live('click', function (e) { 
      e.preventDefault(); 
      $.post($('#Addx').attr('action'), $('#Addx').serialize(), function (data) { 
       refreshGrid(); 
      $addContent.html(""); 
      }); //end post 
      e.preventDefault(); 
     }); 
     // end .live 

     //post edit form data back to server 
     $("#btnEdit").live('click', function (e) { 
      $.post($('#Editx').attr('action'), $('#Editx').serialize(), function (data) { 
       refreshGrid(); 
       $editContent.html(""); 
      }); 

      e.preventDefault(); 
     }); //end post edit 

Y aquí es mi visión parcial, que se carga en la página principal div:

@model HelpBtn.Domain.Entities.Help 
@*THIS POSTS BACK TO EDIT/ADMIN. needs to be asynchronous*@ 
@using (Html.BeginForm("EditForm", "Admin", FormMethod.Post, new { id = "Addx" })) 
{ 
    <fieldset> 
     <legend>Add Entry</legend> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.URL) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.URL) 
      @Html.ValidationMessageFor(model => model.URL) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.HelpContent, "Help Content") 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.HelpContent) 
      <p> 
       @Html.ValidationMessageFor(model => model.HelpContent, "Enter a value") 
      </p> 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.createDateTime, "Created Date") 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.createDateTime) 
      @Html.ValidationMessageFor(model => model.createDateTime) 
     </div> 
     <p> 
      <input id="btnAdd" type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 
+0

duplicado posible de [validación del lado del cliente jQuery que no trabajan en vista parcial MVC3] (http: // stackoverflow. com/questions/14134949/jquery-client-side-validation-not-working-in-mvc3-partial-view) – Zairja

Respuesta

32

Cada vez que realizan una llamada AJAX y sustituir alguna parte de su DOM con contenido HTML parciales devueltos por la acción del controlador que necesita para vuelva a analizar las reglas de validación discretas del lado del cliente. Por lo que en sus devoluciones de llamada de éxito AJAX cuando después de llamar al método .html() para refrescar el DOM que necesita para analizar:

$('form').removeData('validator'); 
$('form').removeData('unobtrusiveValidation'); 
$.validator.unobtrusive.parse('form'); 
+0

El único problema es que recibo un error cada vez que envío mi formulario. El error es "Error de tiempo de ejecución de Microsoft JScript: no se puede obtener el valor de la propiedad 'discreta': el objeto es nulo o indefinido". ¿Podrías saber por qué? - – user1238864

+0

En realidad, Darin, tu respuesta funciona bien. Aparentemente, el problema es causado tanto por la validación de jquery de Telerik como por el hecho de que Internet Explorer tiene problemas de compatibilidad. Al ejecutar Chrome, '$ .validator.unobtrusive.parse ('elementOrForm')' hace exactamente lo que necesita: reemplazar los controladores de eventos perdidos en lugar de arrojar una excepción "poco definida" si se ejecuta Internet Explorer. También descubrí que, al usar Internet Explorer, esta llamada en la parte superior del código de la vista principal detiene el problema de compatibilidad. 'Html.Telerik(). ScriptRegistrar(). JQuery (falso) .jQueryValidation (falso);' Muchas gracias bruh! – user1238864

+0

Gracias, pero tuve que agregar al fin '$ ('form'). Valid();' para eliminar el error de validación cuando reemplaza la vista parcial. – stom

Cuestiones relacionadas