I'm having the problem that I cannot get client-side validation to fire from within my partial view, that loads into a div after a user clicks a button. In this example I've stopped the div from "toggling" to see if the validation fires, but to no avail, nothing happens.
Luckily, the model doesn't accept any invalid input, but it also doesn't warn the user of the actual mistake. Any help would be appreciated.
Here is my Model:
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; }
}
Here is my Controller:
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
Here is my Main View:
<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
And here is my partial view, that loads into the main page's 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>
}
Everytime you perform an AJAX call and substitute some part of your DOM with partial HTML contents returned by the controller action you need to reparse the client side unobtrusive validation rules. So in your AJAX success callbacks when after you call the .html()
method to refresh the DOM you need to parse:
$('form').removeData('validator');
$('form').removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse('form');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With