I'm following this tutorial to display a datepicker when I click into a textbox... But the date picker doesn't display...
Model Class (Reservation):
[Required(ErrorMessage = "Date requise.")]
[Display(Name = "Date")]
[Column("Date")]
[DataType(DataType.DateTime)]
public DateTime Date { get; set; }
EditorHookup.js
/// <reference path="~/Scripts/jquery-1.5.1.js" />
/// <reference path="~/Scripts/jquery-ui-1.8.11.js" />
$(document).ready(function () {
$('.date').datepicker({ dateFormat: "dd/mm/yy" });
});
Partial View (Date.cshtml)
#inherits System.Web.Mvc.WebViewPage<System.DateTime?>
#model DateTime
#Html.TextBox("", Model.ToString("dd/MM/yyyy"),
new{#class="date"})
** TODO Wire up the date picker! **
My view
#model TennisOnline.Models.Reservation
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</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 src="#Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script>
<link href="#Url.Content("~/Content/themes/base/jquery.ui.all.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/EditorHookup.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Reservation</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Date)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Date)
#Html.ValidationMessageFor(model => model.Date)
</div>
So, do you know why the date picker doesn't display please ? Thanks in advance
Your partial view model is not called because the DataType of your property is wrong. Replace
[DataType(DataType.DateTime)]
with
[DataType(DataType.Date)]
and everything should work as intended.
Edit
You should also remove the #inheritsline from your partial view as inherits is not allowed with model.
I think your view is missing a reference to the ="~/Scripts/jquery-1.5.1.js" script.
I think your partial view may need to be named DateTime.cshtml to match the type of your model property.
Related
What I would Like
I would like to trigger client-side validation in my View with an event of my choice. It could be 'onblur' maybe another button but something other than the submit button.
Relevant Links
How to trigger validation without using a submit button
Applying unobtrusive jquery validation to dynamic content in ASP.Net MVC
What I've tried
Given a various event listener, I've fired the following methods with no luck:
$(selector).validate();
$(selector).valid();
$.validator.unobtrusive.parseDynamicContent(selector);
$.validator.unobtrusive.parse($(selector));
Summary
So I need client-side validation to fire on a given event (other than on submit) and show the corresponding validation messages. I dont feel like any of the Markup/Razor syntax is necessary as client-validation fires on submit and all the corresponding validation messages show as expected.
$('form').valid() should work. Let's exemplify.
Model:
public class MyViewModel
{
[Required]
public string Foo { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
}
View:
#model MyViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.Foo)
#Html.EditorFor(x => x.Foo)
#Html.ValidationMessageFor(x => x.Foo)
}
<div id="validate">Hover here to trigger validation</div>
<script type="text/javascript">
$('#validate').hover(function () {
$('form').valid();
});
</script>
Manual validation of custom messages injected directly to HTML
#{using (Html.BeginForm("addBuyOnlinepostA", "BuyOnline", FormMethod.Post, new { #enctype = "multipart/form-data", #id = "form1" }))
{
#Html.ValidationSummary(true)
<div class="row">
<div class="col-sm-10">
Product Qty
<input class="inputs" required type="number" id="price" name="price" placeholder="Enter Price in AED"
data-val="true" data-val-required="Please enter a value" data-val-regex="Please enter a valid number."
data-val-regex-pattern="\d{1,20}" />
<span class="field-validation-valid" data-valmsg-for="price" data-valmsg-replace="true"
style="color: Red;"></span>
</div>
</div>
<input type="button" onclick="$('form').valid()" />
}
}
I have MVC application with a model like this :
public class ListOfMyModel
{
public List<MyModel> MyModels { get; set; }
public Guid MyID { get; set; }
}
public class MyModel
{
// Some code like :
public string MyString { get; set; }
}
And my post method in my controller is like this :
[HttpPost]
public ActionResult EditMe(ListOfModel myList)
{
try
{
if (ModelState.IsValid)
{
List<MyModel> myModels = myList.MyModels;
foreach (MyModel model in myModels)
// Some code
return RedirectToAction("Index");
}
catch
{
// Some code
return View(myList)
}
return View(myList);
}
And my view : ( I use Kendo UI ) ( P.S : Some code has been stripped away and replaced by comment code )
#model MyApplication.Web.Models.ListOfMyModel
#{
ViewBag.Title = MyTitle;
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
<div class="span1"></div>
<div class="span8">
<div id="list-wrapper">
<div class="k-content">
<form id="form" class="form-horizontal well span8 offset2" method="post" action="#Url.Action("EditMe")">
<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 src="#Url.Content("~/Scripts/jquery-1.9.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/kendo/2013.1.514/kendo.web.min.js")"></script>
<script src="#Url.Content("~/Scripts/kendo/2013.1.514/kendo.aspnetmvc.min.js")"></script>
<div class="offset2 span2">
<fieldset>
<legend> My title </legend>
<p>Some code :</p>
#Html.HiddenFor(m => m.MyID)
#for (int i = 0; i < Model.MyModels.Count; i++)
{
// Some code
<div class="control-group">
<label class="control-label">MyText : </label>
<div class="controls">
#(Html.Kendo().DropDownListFor(c => Model.MyModels[i].MyString)
.DataTextField("Text")
.DataValueField("Value")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetSomeThings", "MyController"))
)
.Value(Model.MyModels[i].MyString)
)
</div>
</div>
}
<div class="form-actions">
<button type="submit" class="btn btn-primary">Validate</button>
</div>
</fieldset>
</div>
</form>
</div>
</div>
</div>
But the problem is that when I push the submit button in my view, the method of my controller is called with all the data expected ( saw in Chrome ) but in this method, all of the model is null : The ID and the list... I don't known where the problem is ?
Thank you all for reading and trying to understand this, if you want more informations please tell me.
The MyId should be correctly received with your existing code.
The model binder can only match the value of inputs whose name have a matching property in the form. I.e. if you have an input like this <input name='bikes' ...> then your model should have a property Bikes so that the model binder can transfer the value from the input to the property. In your case you're creating input with dynamic names that doesn't have a matching property name. (NOTE: thei referes to the model you're using as the action parameter).
The farthest you can go is giving a series of input elements the same name, i.e. several elements like <input name='categories' ...> and receive it in an array parameter like string[] categories or a model which has a property like string[] Categories {get;set;}
In short, you have to redesign your model and view. If you used a List<string> instead of a List<MyModel>, and the view had a fixed name for the dropdow lists, like DropDownListFor(c => Model.MyModels, then the model binder would fill the MyModels property with the list of selected strings in each drop down list.
Hint: you can use a model for the View and receive a different model (or series of parameters) in the Action. In this way you can send more information to render the View, and receive a post with the essential data to process the user input.
See my answer to this question for alternatives. It explains something similar to this question.
I've been trying to figure out how to do this all afternoon, but can't seem to get a grip on how to get DatePicker to work with my site.
Also, if possible I would like to remove the Time part of the DateTime, as I'm only interested in the Date the entry gets posted.
I've included the code so far below, I've pretty much removed everything I've attempted so far so it is back to the beginning. I've referenced the JQuery files at the top of _Layout.cshtml which I think is correct.
I've looked at many guides on the web, but struggled to make much sense of them, although I will keep reading.
I've added these lines to the top of my _Layout.cshtml (I've also unpacked and copied the JQuery folders to the locations referenced below as well)
<link href="#Url.Content("~/Content/jquery-ui/redmond/jquery-ui-1.8.21.custom.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/ui/minified/jquery.ui.core.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/ui/minified/jquery.ui.datepicker.min.js")" type="text/javascript"></script>
My View code looks like this:
#model dale_harrison.Models.News
#{
ViewBag.Title = "Create";
}
<h2>Create</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>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>News</legend>
<div class="editor-label">
#Html.LabelFor(model => model.News_Entry)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.News_Entry)
#Html.ValidationMessageFor(model => model.News_Entry)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.News_Date)
</div>
<div class="editor-field">
#*#Html.EditorFor(model => model.News_Date)*#
#Html.EditorFor(model => model.News_Date, new object{ id = "news_date" } )
#Html.ValidationMessageFor(model => model.News_Date)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#news_date").datepicker({ dateFormat: 'dd/mm/yy' });
});
</script>
My Model is here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace dale_harrison.Models
{
public class News
{
public int ID { get; set; }
public string News_Entry { get; set; }
public DateTime News_Date { get; set; }
}
public class NewsDBContext : DbContext
{
public DbSet<News> News_Entries { get; set; }
}
}
Many thanks in advance to anyone for helping
Try this first:
Add your html code without the html helper:
<input type="text" id="news_date" name="news_date" />
Or, if you want to add the id with the Html helper:
#Html.EditorFor(model => model.News_Date, new { id = "news_date" } )
And then add this javascript code:
$(document).ready(function () {
$("#news_date").datepicker({ dateFormat: 'dd/mm/yy' });
});
You can try this first to check if you have set it all the configuration in your project correctly. You should solve your problem with those lines.
After you get this working in your site, read about html helpers and how to encapsulate code so you do not have to rewrite this everytime.
Hope it helps!
On the Views/Shared/EditorTemplates folder you need to create a template for DateTime types, so every time you use #Html.EditorFor MVC display whatever you define on your Template
You may also wish to hide the time from the text box so that you see "08/11/2007" as opposed to "08/11/2007 00:00:00".
To do this, add "[DataType(DataType.Date)]" to your news class as below;
public class News
{
public int ID { get; set; }
public string News_Entry { get; set; }
[DataType(DataType.Date)]
public DateTime News_Date { get; set; }
}
EditorFor neglects extra attributes. Either use TextBoxFor or write EditorFor template...
I'm using C#, MVC3 and VS2010
I noticed that even though the valdiation results to false, the controller method still gets executed. This makes the validation useless on the server-side. Unless there is a way to get the result.
---- EDITS -----
Here is how i'm using it. Is it done properly? At least the validation messages show up, and the textbox turns red.
Model:
public class CategoriaModel
{
[Required(ErrorMessage="Nome é obrigatório!")]
[StringLength(10, ErrorMessage = "First Name max length is 10")]
public string Nome { get; set; }
}
View:
#Html.ValidationSummary(true)
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.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>
#using (Html.BeginForm("Salvar", "Test", FormMethod.Post))
{
#Html.LabelFor(m => m.Nome)
#Html.EditorFor(m => m.Nome)
#Html.ValidationMessageFor(m=>m.Nome)
<input type="submit" value="Salvar" />
}
Controller:
public ActionResult Salvar(CategoriaModel catModel)
{
ViewBag.StatusMessage = "Ok!";
return View("Index");
}
testing ModelState.IsValid property, however if client side validation fails the Action should not be called. Check if you're actually validating all your Model properties.
I have a classes like this:
public class member
{
public string name {get;set;}
public IList<Note> notes {get;set;}
}
public class note
{
public string text {get;set;}
public datetime created {get;set;}
}
I want to have a page which inserts the member class - which i am fine with. My question lies in how to go about adding multiple notes to the member on the same page?
What would be the best way to go about this? (maybe some ajax solution to show sub forms for the note class)
Can anyone point me in the right direction of some related examples learning material?
Thanks in advance.
I'd create an Ajax form that posts to a method called AddNote(AddNoteViewModel viewModel) on your controller. AddNoteViewModel would contain all the information you need to create a new note. The AddNote Action Method would add the new note, SaveChanges and return a list of notes for the given Member. You can use a partial view for the content that is returned from AddNote.
On the Ajax form you should set UpdateTargetId to the id of the <div> you want to update with the latest list of notes.
Another option might be to use JQuery.
Here is a good example of both: Using Ajax.BeginForm with ASP.NET MVC 3 Razor
UPDATE : I've adapted Darin Dimitrov's example (from the link) to suit your scenario. This is off the top of my head so won't be perfect but it should give you a decent starting point
Model:
public class AddNoteViewModel
{
[Required]
public int MemberId { get; set; }
[Required]
public string Text { get; set; }
}
Controller:
[HttpPost]
public ActionResult AddNote(AddNoteViewModel model)
{
var member = //Get member from db using model.MemberId
member.Notes.Add(new Note{Text = model.Text, Created = DateTime.Now});
//SaveChanges();
var notes = //Get notes for member
return View(notes);
}
View:
#model AppName.Models.AddNoteViewModel
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<div id="result"></div>
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" }))
{
#Html.HiddenFor(x => x.MemberId)
#Html.EditorFor(x => x.Text)
#Html.ValidationMessageFor(x => x.Text)
<input type="submit" value="OK" />
}
Using JQuery:
View:
#model AppName.Models.AddNoteViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/index.js")" type="text/javascript"></script>
<div id="result"></div>
#using (Html.BeginForm())
{
#Html.HiddenFor(x => x.MemberId)
#Html.EditorFor(x => x.Text)
#Html.ValidationMessageFor(x => x.Text)
<input type="submit" value="OK" />
}
index.js:
$(function () {
$('form').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
success: function (result) {
$('#result').html(result);
}
});
}
return false;
});
});