Asp.Net MVC EnableClientValidation doesn't work - validation

I want as well as Client Side Validation as Server Side Validation. I realized this as the following:
Model: ( The model has a DataModel(dbml) which contains the Test class )
namespace MyProject.TestProject
{
[MetadataType(typeof(TestMetaData))]
public partial class Test
{
}
public class TestMetaData
{
[Required(ErrorMessage="Please enter a name.")]
[StringLength(50)]
public string Name { get; set; }
}
}
Controller is nothing special.
The View:
<% Html.EnableClientValidation(); %>
<% using (Ajax.BeginForm("Index", "Test", FormMethod.Post,
new AjaxOptions {}, new { enctype = "multipart/form-data" }))
{%>
<%= Html.AntiForgeryToken()%>
<fieldset>
<legend>Widget Omschrijving</legend>
<div>
<%= Html.LabelFor(Model => Model.Name) %>
<%= Html.TextBoxFor(Model => Model.Name) %>
<%= Html.ValidationMessageFor(Model => Model.Name) %>
</div>
</fieldset>
<div>
<input type="submit" value="Save" />
</div>
<% } %>
To make this all work I added also references to js files:
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
Eventually it has to work, but it doesnt work 100%:
It does validates with no page refresh after pressing the button.
It also does "half" Client Side Validation. Only when you type some text into the textbox and then backspace the typed text. The Client Side Validation appears. But when I try this by tapping between controls there's no Client Side Validation.
Do I miss some reference or something? (I use Asp.Net MVC 2 RTM)

Change the order of the loaded javascript...
<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
Had the exact same problem and this cleared it up for me...

I thought I was missing something too, but I do know that the jQuery validation plug in doesn't react to mouseEnter/mouseLeave. According to the documentation for that plug in (at the plug in page - look for the section labeled "A few things to look for when playing around with the demo"):
Before a field is marked as invalid, the validation is lazy: Before submitting the form for the first time, the user can tab through fields without getting annoying messages - he won't get bugged before he had the chance to actually enter a correct value
I assume it's the same rule with MVC 2 client-side validation. I can't be sure of that because the documentation doesn't say anything but "it works on my machine" :).
I went with the jQuery validation route, which is supported in MVC Futures (note that the documentation for that is non-existent). To use it, you just need to replace the script tags for MicrosoftAjax.js, MicrosoftMvcAjax.js and MicrosoftMvcValidation.js files with these two tags:
<script src="/js/jquery.validate.js" type="text/javascript"></script>
<script src="/js/MicrosoftMvcJQueryValidation.js" type="text/javascript"></script>
replacing the path with yours.
I also found the need to upgrade to the latest version of jquery.validate.js from the developer's page, because we are using a later version of jQuery (1.4) here.
Hope that helps.

hm..., it's late to answer but try this:
<script src="<%= Url.Content("ScriptFile.js") %>" type="text/javascript"></script>

Related

Telerik jQuery conflict asp.net mvc

I am using Telerik along with regular jQuery UI.
I have include files like this,
JQuery:
<script src="<%: Url.Content("~/Scripts/jquery-1.7.2.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery-ui-1.8.20.custom.min.js") %>" type="text/javascript"></script>
Telerik
I tried,
<%= Html.Telerik().ScriptRegistrar() %>
and
<%= Html.Telerik().ScriptRegistrar().jQuery(false).jQueryValidation(false) %>
With jQuery(false).jQueryValidation(false) I am getting error:
Microsoft JScript runtime error: Object doesn't support property or method 'apply'
without jQuery(false).jQueryValidation(false) i.e with <%= Html.Telerik().ScriptRegistrar() %>
The jQuery UI is not working. Error: Microsoft JScript runtime error: Object doesn't support property or method 'button'
<button id="Button1">Button1</button>
<script language="javascript" type="text/javascript">
$(function () {
$("#Button1").button().click(function () {
location.href = '/One/Two';
});
});
</script>
This sounds like the same (or very similar) problem that we had after setting up Telerik. I'm assuming the scripts and telerik code you posted above is all on your master page(or layout)? Try deleting
<%= Html.Telerik().ScriptRegistrar() %>
from the master page and paste it to the bottom of each individual view that actually uses a telerik control. That is what worked for us.

why is jquery not working in mvc 3 application?

I got a jquery reference in my _Layout.cshtml . It does not look like this is working in my Index.cshtml page though: the /Home/GetSquareRoot is not hit? (it works when I uncomment the jquery reference in the index.cshtml though)
ViewStart.cshtml
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<h2>#ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
http://asp.net/mvc</a>.
</p>
#*<script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>*#
<script type="text/javascript">
function calculateSquareRoot(numberToCalculate) {
$.ajax({
type: 'GET',
url: '/Home/GetSquareRoot',
data: { number: numberToCalculate },
success: function (data) { alert(data.result); }
});
}
</script>
<button type="button" onclick="calculateSquareRoot(9);">
Calculate Square</button>
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.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/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="../../Scripts/jquery-1.5.1-vsdoc.js" type="text/javascript"></script>
</head>
<body>
<div class="page">
<header>
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
#Html.Partial("_LogOnPartial")
</div>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
</ul>
</nav>
</header>
<section id="main">
#RenderBody()
</section>
<footer>
</footer>
</div>
</body>
</html>
homecontroller
public JsonResult GetSquareRoot(long number)
{
var square = Math.Sqrt(number);
return Json(new { result = square }, JsonRequestBehavior.AllowGet);
}
It works when you have the jQuery reference commented out, because your _Layout.cshtml file has the reference as well (just stating the facts, I realise you probably know this).
This also means that you have your routing set up correctly and that there is nothing wrong with the URL '/Home/GetSquareRoot'
The code looks fine, the only unknown that I can see is that ../../Scripts/ actually goes to the same place as ~/Scripts/ (will depend on what the URL of your page looks like).
I would use Google Chrome to check for script errors on your page: go to your page, right click and 'inspect element' on the page, then check that you don't have any script errors (bottom right of the inspector will have a red circle if you do).
If you have script errors that could be stopping the AJAX call from running.
When referring to hard-coded content URLs in your application, it's always a good idea to use Url.Content.
So instead of this:
<script src="../../Scripts/jquery-1.5.1-vsdoc.js" type="text/javascript"></script>
use this:
<script src="#Url.Content("~/Scripts/jquery-1.5.1-vsdoc.js")" type="text/javascript"></script>
This way the correct URL to the jQuery script file will always be used, no matter what the URL of the page is.
Try out this one...
public JsonResult GetSquareRoot(long? number)
{
var square = Math.Sqrt(number);
return Json(new { result = square }, JsonRequestBehavior.AllowGet);
}

MVC3 client validation: how to prevent page reloading?

I have page with form:
#using (Html.BeginForm("Create", "Theme", FormMethod.Post, new { id = "frm_post", enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
#Html.TextBoxFor(model => model.Name)
#Html.ValidationMessageFor(m => m.Name)
<input type="image" src="img.png"
onclick="javascript:if(func()){document.getElementById('frm_post').submit();}else{return false;}"/>
}
I included scripts to page:
<script src="#Url.Content("~/Scripts/jquery-1.5.2.min.js")" type="text/javascript"></script>
<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>
I have such strings in web.config:
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
I have [Required] for Name in Model.
But when I left textbox Name empty and submit form, error message is shown for some seconds and then page reload. How can I stop reloading of page?
O-o-ops... I just should remove form.submit() from onclick event of my button.
So, if I use
<input type="image" src="img.png"
onclick="javascript:if(!func()){return false;}"/>
it works fine.
It looks like you might want to remove that inline onclick handler and consider writing instead a custom validator. This http://blogs.msdn.com/b/stuartleeks/archive/2011/01/25/asp-net-mvc-3-integrating-with-the-jquery-ui-date-picker-and-adding-a-jquery-validate-date-range-validator.aspx is a good example of how to write one in MVC3 using unobtrusive validation. It's for a custom datepicker but the same principle can be applied for your custom validation.

Using the jquery datepicker in ASP.Net MVC3 projects

In this blog it should be explained how to implement the jquery datepicker for all DateTime inputs. I fail miserably however when I try to follow the steps taken. I suspect that I am setting the references wrong somewhere, as there are now already newer (and diffverently named) .js files in my VS project than those mentioned in the blog. Is there a place where the implementation is spoon fed for the absolute jquery NOOB?
EDIT:
I also found this link. After copying in the code as mentioned I am greeted by an exception in jquery 1.5.1-min.js that says that the object doest not support that property or method...
EDIT(2)
I am at my wits' end wth this one, I tried to add the references Tridus suggested, but I have different versions and of some versions I have a .min.js alternative. All the relevant code:
In StandIn.cs:
[DisplayName("Available from")]
[DisplayFormat(DataFormatString="{0:d}",ApplyFormatInEditMode=true,NullDisplayText="(not specified")]
public DateTime? From { get; set; }
In Edit.cshtml:
<div class="editor-field">
#Html.EditorFor(model => model.Standin.From)
#Html.ValidationMessageFor(model => model.Standin.From)
</div>
In _Layout.cshtml:
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<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.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-1.5.1.min.js")" type="text/javascript"></script>
</head>
In \Shared\EditorTemplates\DateTime.cshtml
#model Nullable<System.DateTime>
#if (Model.HasValue)
{
#Html.TextBox("", Model.Value.ToShortDateString(), new { #class = "date" })
}
else
{
#Html.TextBox("",string.Empty)
}
<script type="text/javascript">
$(document).ready(function () { $('.date').datepicker({ dateFormat: "dd/mm/yy" }); });
</script>
Mind: all the code performs without problems until I add the script tags: then on showing Edit.cshtml jquery-1.5.1.min.js throws an exception about a property or method not being supported.
This is a good place to start: http://jqueryui.com/demos/datepicker/
What you're almost certainly missing is just the script references to the right jQuery libraries. These need to be somewhere in the resulting HTML (either in the template for the DateTime object itself, or in your _layout.cshtml so it's just included everywhere). Adjust paths and versions accordingly for what you have in your project.
<script src="#Url.Content("~/Scripts/jquery-1.4.4.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.14.min.js")" type="text/javascript"></script>
If you have it, you probably also need a jQuery UI theme:
<link href="#Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
That's the only thing I didn't see in the blog post. Everything else really is as direct as they say.
I am getting more and more convinced that the problem lays with the .js files that are included with a default MVC3 project in Visual Studio 2010: they must lack some of the requiered dependent .js files. I went to the jquery ui site as suggested by Erik, downloaded the full jquery ui package and used the references and .js files from the default.html in the development-bundle/demo/datepicker folder. That works! However, as a VS MVC3 project comes with a lot of premade custom scripts I had to keep the downloaded .js files separate from those in the Scripts folder. Therefor I created a new JQueryScripts folder that I use for the UI elements. The references to these .js files cannot be added to _Layout.cshtml to avoid a conflict and I did not include the MasterPage (_Layout.cshtml) for the same reason.
For the record the resulting DateTime.cshtml EditorTemplate that works with a Nullable DateTime and shows how to implement localization for one language (Dutch in this case). Note that this code will be made obsolete with a new release of jquery(ui), but it gives an idea:
<link rel="stylesheet" href="../../../JQueryScripts/themes/base/jquery.ui.all.css"/>
<script type="text/javascript" src="#Url.Content("~/JQueryScripts/jquery-1.6.2.js")"></script>
<script type="text/javascript" src="#Url.Content("~/JQueryScripts/ui/jquery.ui.core.js")"></script>
<script type="text/javascript" src="#Url.Content("~/JQueryScripts/ui/jquery.ui.widget.js")"></script>
<script type="text/javascript" src="#Url.Content("~/JQueryScripts/ui/jquery.ui.datepicker.js")"></script>
<script type="text/javascript" src="#Url.Content("~/JQueryScripts/ui/i18n/jquery.ui.datepicker-nl.js")"></script>
<script type="text/javascript">
$(document).ready(function () {
$('.datepicker').datepicker({
dateFormat: "dd-mm-yy",
minDate:0
});
});
</script>
#model Nullable<System.DateTime>
#if (Model.HasValue)
{
#Html.TextBox("", Model.Value.ToShortDateString(), new { #class = "datepicker" })
}
else
{
#Html.TextBox("", string.Empty, new { #class = "datepicker" })
}

Update partial view on partial view's action

I am working just one week with ASP.NET MVC 3. This might be a very basic question or someone might have asked similar question before. I am seeking help to show me right path/method to accomplish the problem I am facing getting the partial view designed.
I have created a partial view login (in side bar) as below. What I would like to achieve here is, when I hit the "login" button, I must be a able update the partial view with information such as
**Welcome [UserName]
Last SuccessFul Login : [DateTime]
Member Since : [Date]**
I am not sure if I need to create another partial view to display this information Or the login partial view can be updated on the fly based on the action.
Login Partial View
#model AlanBeezLab.Models.LoginModel
#using (Ajax.BeginForm("Login","UserLogin", new AjaxOptions { UpdateTargetId =Model.UserName }))
{
<div >User Name
#Html.TextBox(" ")
</div>
<div>Password
#Html.Password(" ")
</div>
<p><input type="submit" value="Let me in!" /></p>
}
Below is the _Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<!--link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />-->
<link href="#Url.Content("~/Content/SiteStyle.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/modernizr-1.7.min.js")" type="text/javascript"></script>
</head>
<body>
<div id="Header" style="background-image: url('/Content/Images/Banner_Final3.png'); background-repeat:no-repeat; width :1500px; height : 150px;" >
</div>
<div id="SideBar">
#Html.Partial("UserControls/UserLogin", new AlanBeezLab.Models.LoginModel())
</div>
<div id="Content">
#RenderBody()
</div>
<div id="Footer">
<p>Copyright © XXXXX</p>
</div>
</body>
</html>
Below is the Login Controller
public class UserLoginController : Controller
{
//
// GET: /UserLogin/
public ActionResult Index()
{
return View();
}
public ActionResult LogIn()
{
return [Not Sure];
}
I am not sure if this is best/right approach to accomplish this. I would appreciate if I am directed to the right path/approach.
Thanks
I've had this discussion with my peers before.
IMO login/logout should not be done via AJAX, it should be a regular HTTP POST.
Why? Well what if your on a page that requires Administrator access, then you logout via AJAX? Your still on the page - when you shouldn't be authorized to do so (unless of course you update the main portion of the page as well, which is kind of silly)
So my advice - make the login button do a regular POST to an action method, then use the PRG pattern to redirect back to the original page.
Of course, if you don't have the concept of administrators/permissions/roles then an AJAX login/logout will be fine.
Regardless, you've done the right thing with the partial view.
Your partial view should figure out if the user is authenticated, then render an appropriate editor/display template based on that.
E.g: _Login.cshtml:
#if(Request.IsAuthenticated) {
#Html.DisplayFor(Context.User.Identity)
} else {
#* editor fields *#
}

Resources