jQuery ui Dialog with PartialView will not validate (MVC3) - jquery-ui

Can someone please help me.
I cannot get my jQuery ui-dialog to validate.
I have tried to find a solution on this site and countless others but although everyone seems to have some sort of solution, I cannot get any of them to work.
I understand that it can sometimes be difficult to describe a problem so I have written a complete application that contains the minimum necessary to hopefully make things clear.
In the VIEW, there is an alert("saved"); which I do not want to see as the Dialog should prevent this getting that far.
Any suggestions will be most gratefully received.
CONTACTMESSAGE
using System.ComponentModel.DataAnnotations;
namespace TestValidation.Models
{
public class ContactMessage
{
[Required(ErrorMessage = "Message is Requried")]
public string Message { get; set; }
}
}
CONTROLLER:
namespace TestValidation.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Edit()
{
return PartialView("MessageForm",
new ContactMessage{Message="Test"});
}
public ActionResult Save()
{
return Content("Saved");
}
}
}
VIEW:
#model TestValidation.Models.ContactMessage
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>ViewPage1</title>
<link href="#Url.Content("~/Content/themes/base/jquery.ui.all.css")" rel="Stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
</head>
<body>
Dialog
<div id="Placeholder" title=""></div>
</body>
</html>
<script type="text/javascript">
$(function () {
$("#Placeholder").dialog({
autoOpen: false, width: 400, height: 330, modal: true,
buttons: {
"Save": function () {
$.post("/Home/Save",
$("#EditForm").serialize(),
function (data) {
alert("saved");
$("#Placeholder").dialog("close");
});
},
Cancel: function () { $(this).dialog("close"); }
}
});
$("#editButton").click(function () {
$("#Placeholder").html("")
.dialog("option", "title", "Edit Message")
.load("/Home/Edit/", function () {
$("#Placeholder").dialog("open");
});
});
});
</script>
PARTIAL VIEW:
#model TestValidation.Models.ContactMessage
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("null", "null", FormMethod.Post, new { id = "EditForm" }))
{
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.Message)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Message)
#Html.ValidationMessageFor(model => model.Message)
</div>
}

just after loading form into DOM do this
jQuery.validator.unobbstrusive.parse(jQuery('#EditForm'));

Related

Bootstrap fileinput

I'm trying to use Krajee's Bootstrap Fileinput (http://plugins.krajee.com/file-input) and having some problems getting it to work with .Net MVC.
I'm doing a normal form submit (I need to do this because there is a lot of processing on the client side)
This is a cut down version of the code:
My model is:
public class AddFormModel
{
public string txtName { get; set; }
public HttpPostedFileBase[] fileUpload { get; set; }
}
Index.Html:
#model TestSystem.Models.AddFormModel
#{
Layout = null;
}
<!DOCTYPE html>
<html lang="">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" />
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/js/plugins/piexif.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/js/plugins/sortable.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/js/plugins/purify.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/js/fileinput.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/themes/fa/theme.min.js"></script>
</head>
<body>
<form id="frmMain" action="#Url.Action("AddObject", "Home")" method="post" enctype="multipart/form-data">
#Html.AntiForgeryToken()
<div class="container">
<div class="row">
<div class="form-group">
#Html.TextBoxFor(m => m.txtName, null, new { #required = "", #class = "form-control", data_val = "false" })
</div>
</div>
<div class="row">
<div class="form-group">
<div class="file-loading">
<input id="fileUpload" name="fileUpload" class="file" type="file" multiple data-min-file-count="1" data-upload-url="#">
</div>
</div>
</div>
</form>
<script>
$("#fileUpload").fileinput({
theme: 'fa',
showUpload: false,
showClose: false,
showRemove: false,
allowedFileExtensions: ['jpg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'],
overwriteInitial: false,
minFileCount: 0,
maxFileCount: 5,
maxFileSize: 4000,
validateInitialCount: true,
slugCallback: function (filename) {
return filename.replace('(', '_').replace(']', '_');
},
enctype: 'multipart/form-data',
fileActionSettings: {
showRemove: true,
showUpload: false,
showZoom: false,
showDrag: false,
}
});
</script>
</body>
</html>
My Controller:
public class HomeController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddObject(AddFormModel model)
{
// ****When I look at the model here I only see 1 file ****
// model.txtName <- this is ok
// model.fileUpload <- If I just put one file in the upload
// I can see it
// model.fileUpload <- If I put more than one file in the upload
// I can only see the last one
}
}
UPDATE
I meant to put:
[HttpPost]
[ValidateAntiForgeryToken]
around the Controller method - my mistake when posting
If you want to upload more than one file, you need to use enctype="multipart/form-data" which you already have in form tag.
And Model list of HttpPostedFileBase to catch multiple files you have sent
public class AddFormModel
{
public string txtName { get; set; }
public IEnumerable<HttpPostedFileBase> fileUpload { get; set; }
}
All other parts seems fine to me.
UPDATE
I have tried your code it's working fine at my side when i posted form with more than one file all file has been retrieved in controller's method model.fileUpload.Count();
One more thing to notice [HttpPost] is on wrong place it should on the method rather than on controller class

GridMvc disappear after refresh by filter or sorting

I am using the GridMvc from this link:
https://gridmvc.codeplex.com
I don't have problem when I have a grid in a simple new page. but when my grid is under menu(menu seems is refreshing the page) when I use sort or filter on the grid, grid disappears.
This is my controller code:
public ActionResult Index()
{
DAL.DataManager dal = new DAL.DataManager();
List<data> data = new List<data>();
data = dal.get_AllDate();
return View(data);
}
and this is my view:
#using GridMvc.Html
#model IEnumerable<data>
#{
ViewBag.Title = "Index";
}
<script src="#Url.Content("~/Scripts/jquery.min.js")" type="text/javascript"> </script>
<link href="#Url.Content("~/Content/Gridmvc.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/gridmvc.min.js")" type="text/javascript"> </script>
#Html.Grid(Model).Columns(columns =>
{
columns.Add(model => model.dataUser).Titled("User").SetWidth(110);
columns.Add(model => model.Create_Date).Titled("Create Date").SetWidth(110).Filterable(true).Format("{0:dd/MM/yyyy}");
......
}).WithPaging(20).Sortable().Filterable().WithMultipleFilters()
I got this error too, as I noted it was performing GET and not POST, so as a workaround, I used the following at the end of the cshtml file:
#section Scripts {
<script type="text/javascript">
$(function(){
$(".grid-header-title").click(function (e) {
if ($(e.target).is("a")) {
// It was the anchor element that was clicked -- meaning, its sortable
e.preventDefault();
// '/Search' should be replaced with your form action
$(document.forms[0]).attr("action", '/Search' + $(e.target).attr("href"));
$(document.forms[0]).submit();
}
});
});
</script>
}

How to show entered order no and selected product name and id

i am new in mvc. so could not figure out what to add in code to show entered order no and selected product name and id.
here is full code and dotnetfiddle url https://dotnetfiddle.net/6vn2GO
Model code
using System;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Collections.Generic;
namespace HelloWorldMvcApp
{
public class OrderViewModel
{
[Display(Name = "Order number")]
public int? OrderNumber { set; get; }
[Display(Name = "Product")]
[Required(ErrorMessage = "Please select a product")]
public int SelectedProductId { set; get;}
public SelectList ProductList { get; set; }
}
public class Product
{
public int ID { set; get; }
public string Name { set; get; }
}
public static class Repository
{
public static IEnumerable<Product> FetchProducts()
{
return new List<Product>()
{
new Product(){ ID = 1, Name = "Ketchup" },
new Product(){ ID = 2, Name = "Mustard" },
new Product(){ ID = 3, Name = "Relish" }
};
}
}
}
Controller code
using System;
using System.Web.Mvc;
using System.Collections.Generic;
namespace HelloWorldMvcApp
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
OrderViewModel model = new OrderViewModel();
model.OrderNumber=null;
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
public ActionResult Index(OrderViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
// save and redirect
// but for testing purposes
ConfigureViewModel(model);
return View(model);
}
private void ConfigureViewModel(OrderViewModel model)
{
IEnumerable<Product> products = Repository.FetchProducts();
model.ProductList = new SelectList(products, "ID", "Name");
}
}
}
View.cshtml code
#model HelloWorldMvcApp.OrderViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<!-- template from http://getbootstrap.com/getting-started -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
<!-- CSS Includes -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style type="text/css">
.field-validation-error {
color: #ff0000;
}
</style>
</head>
<body>
<div class="container">
<div class="col-md-6 col-md-offset-3">
<h1>Hello Stranger</h1>
#using (Html.BeginForm())
{
<div class="form-group">
#Html.LabelFor(m => m.OrderNumber)
#Html.TextBoxFor(m => m.OrderNumber, new {#class="form-control"})
#Html.ValidationMessageFor(m => m.OrderNumber)
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedProductId)
#Html.DropDownListFor(m => m.SelectedProductId, Model.ProductList, "-Please select-", new {#class="form-control"})
#Html.ValidationMessageFor(m => m.SelectedProductId)
</div>
<button type="submit" class="btn btn-success submit">Save</button>
}
</div>
</div>
<!-- JS includes -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
</script>
</body>
</html>
please tell me what code i need to add in view html to show entered order no and selected product name and id. thanks
You could set the value of your order number on the [HttpPost] Action method and check if it's null on the view side and show/hide stuff accordingly.
Another (probably better) alternative would be to just create a new view and return that when the model state is valid. To get the order number, you'll need to fetch the inserted ID from the database and pass that to the view.
Edit to show some code:
Controller Code:
using System;
using System.Web.Mvc;
using System.Collections.Generic;
namespace HelloWorldMvcApp
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
OrderViewModel model = new OrderViewModel();
model.OrderNumber=null;
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
public ActionResult Index(OrderViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
// save and redirect
// but for testing purposes
ConfigureViewModel(model);
// you'll need to figure out how you're generating your
// order numbers
//
model.OrderNumber = 1; // just set this statically for now for POC
return View(model);
}
private void ConfigureViewModel(OrderViewModel model)
{
IEnumerable<Product> products = Repository.FetchProducts();
model.ProductList = new SelectList(products, "ID", "Name");
}
}
}
View Code:
#model HelloWorldMvcApp.OrderViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<!-- template from http://getbootstrap.com/getting-started -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
<!-- CSS Includes -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style type="text/css">
.field-validation-error {
color: #ff0000;
}
</style>
</head>
<body>
<div class="container">
#{
if(Model.OrderNumber == null)
{
<div class="col-md-6 col-md-offset-3">
<h1>Hello Stranger</h1>
#using (Html.BeginForm())
{
<div class="form-group">
#Html.LabelFor(m => m.OrderNumber)
#Html.TextBoxFor(m => m.OrderNumber, new {#class="form-control"})
#Html.ValidationMessageFor(m => m.OrderNumber)
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedProductId)
#Html.DropDownListFor(m => m.SelectedProductId, Model.ProductList, "-Please select-", new {#class="form-control"})
#Html.ValidationMessageFor(m => m.SelectedProductId)
</div>
<button type="submit" class="btn btn-success submit">Save</button>
}
</div>
} else {
<div>show your confirmation stuff here</div>
}
}
</div>
<!-- JS includes -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
</script>
</body>
</html>
that will reuse the same view, though as I said, I'd recommend using a different view.

Unobtrusive Javascript - And Ajax Requests

I've got a simple example here. Basically a form which when submitted will reload itself via an ajax request. The problem is when this happens, the unobtrusive javascript no longer works. I assume I could add the validate and unobtrusive files in the html i get back from the ajax call, but there must be an easier way to re-wire the validators, no?
Notice I'm hijacking my submit button in order to do an AJAX request which will replace the form in the dom, from the html which is returned from the ajax request.
Model:
public class Foo
{
public int Bar { get; set; }
}
Controller:
public class FooController : Controller
{
public ActionResult Index()
{
return View(new Foo{});
}
[HttpPost]
public ActionResult Form(Foo model)
{
return View(model);
}
[HttpPost]
public ActionResult Index(Foo model)
{
return View();
}
}
Index.cshtml
#model PartialPostBackValidation.Models.Foo
#{
ViewBag.Title = "Index";
}
<h2>#Html.ActionLink("Index", "Index")</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script>
$(function () {
$("body").on("click", ".ajax-submit", function () {
var form = $(this).parents("form");
$.post(
form.attr("action"),
form.serialize(),
function (html) {
form.replaceWith(html);
}
);
return false;
});
});
</script>
#{Html.RenderPartial("Form");}
Form.cshtml
#model PartialPostBackValidation.Models.Foo
#{
ViewBag.Title = "Index";
Layout = null;
}
#using (Html.BeginForm("Form", "Foo")) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Foo</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Bar)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Bar)
#Html.ValidationMessageFor(model => model.Bar)
</div>
<p>
<input type="submit" value="Create" class="ajax-submit" />
</p>
</fieldset>
}
To get the validation to work you simply have to re-enable it on the form once content is loaded dynamically:
$('#form-id').removeData('validator');
$('#form-id').removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse('#form-id'); <<<<<< Just having this could be enough but some people complain that without removingData first it doesn’t always work.
p.s. Ofcourse you're going to need to add an id attribute to your #using (Html.BeginForm("Form", "Foo"))

How to validate manually at client in Asp.net MVC 3?

I want to validate form when click client button out of form, i tryed some method but all failed,help please?
source code:
#model MvcTest.Models.Movie
#{
ViewBag.Title = "Home Page";
Html.EnableClientValidation(true);
}
<script src="../../Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
#using (Html.BeginForm("TestValidate", "Home", FormMethod.Post, new { id = "tf" }))
{
#Html.LabelFor(m => m.Title)
#Html.EditorFor(m => m.Title)
#Html.ValidationMessageFor(m => m.Title)
}
<a onclick="test(event)" href="#">
<script type="text/javascript">
function test() {
//How to write here?
}
</script>
namespace MvcTest.Models
{
public class Movie
{
public int ID { get; set; }
[Required(ErrorMessage = "Error Message Test,I want you")]
public string Title { get; set; }
}
public class MovieDBContext : DbContext {
public DbSet<Movie> Movies { get; set; }
}
}
I invoked valid but ,it always warning the object form don't support this methord "validate()"
$(document).ready(function () {
$("#myform").validate();
$("test").click(function() {
alert("Valid: " + $("#myform").valid());
return false;
});
});
I have import js like this:
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/lib/jquery.delegate.js"></script>
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/jquery.validate.js"></script>
or these:
<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
You're looking for the valid method.

Resources