MVC3 razor view error Microsoft JScript runtime error: Object doesn't support property or method 'datepicker'` - asp.net-mvc-3

I am trying to display a datepicker for my Html.EditorFor
To do this I created an EditorTemplate in my Views\Shared\EditorTemplate folder , Named it DateTime.cshtml
but it is not working ,instead I am getting error ---Microsoft JScript runtime error: Object doesn't support property or method 'datepicker'
Plz help me to fix this error
This is my razor view page
#model MyWebRole.ViewModels.ViewModelEvents
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset style="width:50%">
<legend>Event Details:</legend>
<div>
<table>
<tr>
<td>
#Html.EditorFor(model => model.vmStartDate)
#Html.ValidationMessageFor(model => model.vmStartDate)
</td>
</tr>
</table>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
and here is my DateTime.cshtml (pasted below)
#model System.DateTime?
<div class="editor-field">
#Html.TextBox("", String.Format("{0:MM/dd/yyyy}",(Model == DateTime.MinValue)? null : Model), new { #class="text"})
</div>
<script type="text/javascript">
$(document).ready(function () {
$("##ViewData.ModelMetadata.PropertyName").datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'mm/dd/yy',
gotoCurrent: true
});
});
</script>
I am able to get datepicker working on another view
#model MyWebRole.Models.Events
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset style="width:50%">
<legend>Event Details:</legend>
<div>
<table>
<tr>
<td>
#Html.EditorFor(model => model.StartDate)
#Html.ValidationMessageFor(model => model.StartDate)
</td>
</tr>
</table>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
The difference between the two razor views is that
-->the first one( (datepicker not working) is using a ViewModel as model ie(mywebrole.ViewModels.EventViewModel)
--> and the second one is using the myWebrole.models.Events (datepicker working fine)
Is this an issue ?

Given that error, I think the problem is the selector. Instead of $("##ViewData.ModelMetadata.PropertyName"), try this one:
$("input.text").datepicker({ ...
(Alternatively, you could #Html.TextBoxFor(model => model) instead of #Html.TextBox, so that way the input would get id=PropertyName, and thus the selector should work).
Also, you're sure the script for the datepicker JQuery plugin loaded successfully on the page, right?

Related

required attribute not generating in mvc partial razor view (using Edmx Models)

#model eDurar.Models.BuyOnlineAddress
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>BuyOnlineAddress</legend>
<div class="editor-label">
Address Details
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Details, new {#required="required" })
#Html.ValidationMessageFor(model => model.Details)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
This is partial view, in the html generated, there is no required attribute
When I manually insert it in the html editor, works fine, but this method usually works for normal views
I haven't loaded any scripts this time
Thanks I got it now, I changed
#Html.EditorFor(model => model.Details, new {#required="required" })
to
#Html.TextBoxFor(model => model.Details, new {#required="required" })

View values not returned to the controller action

Can anyone tell whats wrong with my view? my model values is displayed correctly in my view but it is not returned to the controller action. public ActionResult DeleteConfirmed(ClientModel contacts) my ClientModel is returned null.
View:
#model ContactManager.Models.ClientModel
#{
ViewBag.Title = "Delete Information";
}
<h2>Delete Information</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>Details</legend>
<div class="display-label">ID</div>
<div class="display-field">
#Html.DisplayFor(model => model.CanaClie0012.Client00130012)
</div>
<div class="display-label">Name</div>
<div class="display-field">
#Html.DisplayFor(model => model.Clientes0013.Nombre0013)
</div>
<div class="display-label">Contact Number</div>
<div class="display-field">
#Html.DisplayFor(model => model.CanaClie0012.Direcc0012)
</div>
<div class="display-label">Country</div>
<div class="display-field">
#Html.DisplayFor(model => model.CanaClie0012.F1Pais00200012)
</div>
</fieldset>
#using (Html.BeginForm()) {
<p>
<input type="submit" value="Delete" /> |
#Html.ActionLink("Back to List", "Index")
</p>
}
Controller Action:
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(ClientModel contacts)
{
contacts.Clientes0013.Client0013 = contacts.CanaClie0012.Client00130012;
contacts.Clientes0013.F1Pais00200013 = contacts.CanaClie0012.F1Pais00200012;
Clientes0013 clientes0013 = db.Clientes0013.Find(contacts.Clientes0013.Client0013, contacts.Clientes0013.F1Pais00200013);
db.Clientes0013.Remove(clientes0013);
db.SaveChanges();
return RedirectToAction("Index");
}
1. Keep the helpers inside the Form like below.
#using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, null))
{
#Html.DisplayFor(i => i.PropertyName);
<input type="submit" name="Submit" value="Submit" />
}
2. In order to Submit the form and send the model in Post Action Method, you have to use a Hidden Field along with each DisplayFor Helper.
#using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, null))
{
#Html.HiddenFor(i => i.PropertyName);
#Html.DisplayFor(i => i.PropertyName);
<input type="submit" name="Submit" value="Submit" />
}
3. You will not be able to see the Model values in Post Action Method when the View is like below..
#Html.HiddenFor(i => i.PropertyName);
#Html.DisplayFor(i => i.PropertyName);
#using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, null))
{
<input type="submit" name="Submit" value="Submit" />
}
This is because you are using DisplayFor for all your properties. DisplayFor will not send anything in a POST, it doesn't create an input.
You could add #Html.HiddenFor(model => model.CanaClie0012.Client00130012) , etc. to each one of your properties in order for your view to send anything back.

How to use #model IEnumerable<> and #model <> in the same page (List / Create) MVC3

Lets say i have a class 'Location', and I'm using MVC3 to create a scaffolding list(index.cshtml). The index html page uses #model IEnumerable. If i want to add a new location to the list, i press create, and i end up with a new html page using #model Project.Models.Location.
Instead of going to a new page, i would like to have the create page as a popup using modal in boostrap(twitter). I've tried using partialview without any luck. Whatever i do i get the dictionary error message.
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[Project.Models.Location]', but this dictionary requires a model item of type 'Project.Models.Location'.
The modal(bootstrap) itself is working when i'm not fetching the partialview. The partialview itself is exactly the same as the generated create(CRUD).
EDIT: I rewrote the whole thing.
Index:
#model IEnumerable<LoLStats.Models.Location>
#{
ViewBag.Title = "Index";
}
#foreach (var item in Model) {
<ul>
<li>#Html.DisplayFor(modelItem => item.LocationName)</li>
</ul>
}
<a class="btn" data-toggle="modal" href="#myModal" >Create</a>
<div class="modal hide" id="myModal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Modal header</h3>
</div>
<div class="modal-body">
<p>#Html.Partial("_createLocation")</p>
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
_createLocation:
#model LoLStats.Models.Location
#{
ViewBag.Title = "Create"; }
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
Location
<div class="editor-label">
#Html.LabelFor(model => model.LocationName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LocationName)
#Html.ValidationMessageFor(model => model.LocationName)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset> }
You could make a view model that has two properties:
The IEnumerable for the parent view
A singular object for the modal
Then strongly type both views to the view model and you should be all set.
Edit
ViewModel:
public class MyViewModel()
{
public IEnumerable<LoLStats.Models.Location> Locations {get; set;}
public LoLStats.Models.Location Location {get; set;}
}
Index:
#model myNamespace.MyViewModel
...
#foreach (var item in Model.Locations) {
<ul>
<li>#Html.DisplayFor(modelItem => item.Locations.LocationName)</li>
</ul>
...
_createLocation:
#model myNamespace.MyViewModel
...
<div class="editor-label">
#Html.LabelFor(model => model.Location.LocationName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Location.LocationName)
#Html.ValidationMessageFor(model => model.Location.LocationName)
</div>
...
Hopefully that's enough detail to get you going
try this in the Index view:
... <p>#Html.Partial("_createLocation", Model.FirstOrDefault())</p>
on the other hand, maybe this will make more sence:
... <p>#Html.Partial("_createLocation", new LoLStats.Models.Location())</p>
hope it works for you.
Your pop-up would need to have a model defined as Project.Models.Car (singular item). After successfully saving the single item you need to update your original list view. Which you can do using jQuery by inserting a new item into the DOM or just by refreshing the page by navigating to the action that gave you the list to begin with.

MVC3 razor How to repeatedly add Set of fields to my page on clicking a button?

How to repeatedly add Set of fields to my page on clicking a button?
I have a button "Add records" on my ParentView.cshtml
on Click of this "Add records" button ,I need the below mentioned razor view(childView.cshtml) to be appended on my ParentView.Each time I click of this "Add records" button ,I need new empty ChildView.cshtml to be appended to my Parent view.Can some one help me how can I achieve this functionality ?
ChildView.cshtml
<p>Record index
#Html.EditorFor(model => model.Name)
#Html.EditorFor(model => model.Address)
#Html.EditorFor(model => model.Location)
<input type="submit" id="btnSave" value="Save" />
My ParentView.cshtml will look like below
#model MyWebRole.ViewModels.MyViewModel
#{
ViewBag.Title = "Address Book";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
<fieldset>
<legend style="font-size: small;">Add Address records </legend>
<br />
<table>
<tr>
<td rowspan="5">
<img alt="" id="imageBox" src="" width="395" height="225" />
</td>
<td>
<span>Address Book </span>
<br />
</td>
<td>
#Html.EditorFor(model => model.REcordTitle)
#Html.ValidationMessageFor(model => model.REcordTitle)
</td>
</tr>
------------------------
------------------------
</table>
<div><input type="submit" id="btnAdd records" value="Add Records" /></div>
</fieldset>
}
You could use the built-in Ajax helpers?
#model MyWebRole.ViewModels.MyViewModel
#{
ViewBag.Title = "Address Book";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Ajax.BeginForm(new AjaxOptions() {
UpdateTargetId = "RecordSection",
InsertionMode = InsertionMode.InsertAfter,
}))
{
<fieldset>
<legend style="font-size: small;">Add Address records </legend>
<br />
<table>
<tr>
<td rowspan="5">
<img alt="" id="imageBox" src="" width="395" height="225" />
</td>
<td>
<span>Address Book </span>
<br />
</td>
<td>
#Html.EditorFor(model => model.REcordTitle)
#Html.ValidationMessageFor(model => model.REcordTitle)
</td>
</tr>
------------------------
------------------------
</table>
<div><input type="submit" id="btnAdd records" value="Add Records" /></div>
</fieldset>
}
<div id="RecordSection">
#* New Partial Views will be rendered here *#
</div>
Then in the Action which handles this you can use the Get/Post/Redirect design pattern to put a new PartialView on the Page:
[HttpPost]
public ActionResult AddressBook(MyViewModel model)
{
// do stuff with model, then pass an Id?
// to the Action which renders the partial view
return RedirectToAction("AddRecord", new { id = model.Id });
}
public ActionResult AddRecord(int id)
{
MyChildModel model = new MyChildModel();
model.Id = id;
return PartialView("_ChildView", model);
}
$('#btnAddRecords').click(function(){
$.getJSON("/MyController/AddRecord", null
function (data) {
$('#divToAddRecords').append(data);
});
})
In Controller:
public JsonResult AddRecord()
{
...
var res = SerializeControl("~/Views/Folder/ChildView.cshtml", viewModel);
return Json(res, JsonRequestBehavior.AllowGet);
}
private string SerializeControl()
{
var control = new RazorView(ControllerContext, controlPath, null, false, null);
ViewData.Model = model;
var writer = new HtmlTextWriter(new StringWriter());
control.Render(new ViewContext(ControllerContext, control, ViewData, TempData, writer), writer);
string value = writer.InnerWriter.ToString();
return value;
}
And change so that button that adds records does not submit

MVC 3 Razor AJAX doesn't work

In EditPhoto.cshtml:
#model vg_music.Models.images
#{
ViewBag.Title = "EditPhoto";
}
<h2>
EditPhoto2</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 (Ajax.BeginForm(new AjaxOptions{UpdateTargetId = "AjaxDiv"})) {
#Html.ValidationSummary(true)
<div id="AjaxDiv">
#Html.Partial("EditPhotoForm")
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
EditPhotoForm.cshtml:
#model vg_music.Models.images
<fieldset>
<legend>images</legend>
#Html.HiddenFor(model => model.id)
<div class="editor-label">
#Html.LabelFor(model => model.title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.title)
#Html.ValidationMessageFor(model => model.title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.comment)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.comment)
#Html.ValidationMessageFor(model => model.comment)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.filename)
</div>
<div class="editor-field">
<img src="#Url.Content("~/uploads/images/little/"+Model.filename)" alt="#Model.title"/><br />
</div>
<p>
<input type="submit" value="Сохранить" />
</p>
</fieldset>
PhotosController.cs:
....
[HttpPost]
public ActionResult EditPhoto(images obj)
{
if (ModelState.IsValid)
{
var db = new EditImagesModel();
db.SaveImage(obj);
if (Request.IsAjaxRequest()) //This does not work.
{
return PartialView("EditPhotoForm");
}
return RedirectToAction("EditPhotos");
}
return View();
}
....
Why is not satisfied:
if (Request.IsAjaxRequest())
{
return PartialView("EditPhotoForm");
}
Why is not satisfied:
Because you forgot to include:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
in your EditPhoto.cshtml page. And because of this the Ajax.BeginForm helper doesn't perform any AJAX request but a simple form POST.
Contrary to ASP.NET MVC 1.0 and 2.0 where Ajax.* helpers such as Ajax.ActionLink and Ajax.BeginForm were polluting your markup with javascript obtrusively, in ASP.NET MVC 3 they simply generate HTML5 data-* attributes on the corresponding DOM elements. This way markup and javascript is kept separate. And you need javascript to interpret those attributes. This javascript is located in the jquery.unobtrusive-ajax.js script which needs to be included.

Resources