In my ASP.NET MVC4 application, I have a view with "from" and "to" fields, for which I use a JQuery UI DatePicker control.
I'm using HtmlHelper to build my form, as the following code shows:
<p>
#Html.LabelFor(x => x.CustomerId)
#Html.DropDownListFor(x => x.CustomerId, new SelectList(Model.Customers, "Id", "Name"))
<span class="datePicker">
#Html.LabelFor(x => x.FromDate)
#Html.EditorFor(x => x.FromDate)
</span>
<span class="datePicker">
#Html.LabelFor(x => x.ToDate)
#Html.EditorFor(x => x.ToDate)
</span>
</p>
<p>
#Html.LabelFor(x => x.IsActiveOnly)
#Html.CheckBoxFor(x => x.IsActiveOnly)
</p>
On the model, I use the [DataType(DataType.Date)] and [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] attributes for the two DateTime properties, which renders the DatePicker correctly in Chrome - but without the default values - but not in IE or FF.
Is there a way to work with HtmlHelper (or with minimal JS) to display the DatePicker in all 3 browsers?
why not set the datePicker class to the texboxes as passing it to the TextBoxFor method's objectHtml attribute
#Html.TextBoxFor(model => model.FromDate, "{0:d}", new { #class = "datePicker"})
EDIT :
As as example to the above solution
#model MvcApplication3.Models.MVCTEST2
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="../../Scripts/jquery-1.9.1.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-ui-1.10.1.custom.js" type="text/javascript"></script>
<link href="../../Content/jquery-ui-1.10.1.custom.min.css" rel="stylesheet" type="text/css" />
<link href="../../Content/jquery-ui-1.10.1.custom.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(function () {
$(".datePicker").datepicker();
})
</script>
<title>Index</title>
</head>
<body>
<div>
#Html.TextBoxFor(model => model.FromDate, "{0:d}", new { #class = "datePicker" })
</div>
</body>
</html>
TESTED on IE FF and GC
Related
I'm new to ASP.Net, I tried to create a simple login page. Layout page has a jumbotron. But my login controls are overlapped with the jumbotron.
Appreciate your help
_Layout.cshtml - file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - Title</title>
<link href="~/Content/Site.css" rel="stylesheet" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/css/Main.scss" rel="stylesheet" type="text/css"/>
<script src="~/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="container-fluid">
<div class="jumbotron">
<h2>Welcome to Application</h2>
</div>
</div>
</div>
<div id ="main" class="col-lg-8">
#RenderBody()
</div>
</body>
</html>
Login.cshtml - Login View
#{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Login";
}
#using (Html.BeginForm("Login", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
if (#ViewBag.LoginErrorMsg != null)
{
<div class="form-group has-error">
#ViewBag.LoginErrorMsg
</div>
}
<div class="container body-content">
<div class="container-fluid">
<div class="col-md-4"></div>
<div class="col-md-4">
<div class="form-group">
#Html.LabelFor(a => a.email, new { #class = "control-label" })
#Html.TextBoxFor(a => a.email, new { #class = "form-control" })
#Html.ValidationMessageFor(a => a.email)
</div>
<div class="form-group">
#Html.LabelFor(a => a.Password, new { #class = "control-label" })
#Html.TextBoxFor(a => a.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(a => a.Password)
</div>
<button type="submit" class="btn btn-default">Login</button>
</div>
<div class="col-md-4"></div>
</div>
</div>
}
This is the result I get screenshot
Read the Bootstrap documentation on Fixed to Top.
Body padding required
The fixed navbar will overlay your other
content, unless you add padding to the top of the . Try out your
own values or use our snippet below. Tip: By default, the navbar is
50px high.
body { padding-top: 70px; }
Make sure to include this after the core Bootstrap CSS.
I am using JQuery Mobile 1.4 and MVC 4 to test dialog. But I don’t know what should be returned in dialog post action.
There are two questions:
1. What should be returned for dialog action
2. The input data in master page will be lost after dialog post
Master page View Code:
#model MvcApplication4.Models.ViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TestDialog</title>
<meta name="viewport" content="width=device-width" />
<link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="/Content/site.css" rel="stylesheet"/>
<link href="/Content/jquery.mobile-1.4.0-beta.1.css" rel="stylesheet" />
<script src="/Scripts/modernizr-2.6.2.js"></script>
<script src="/Scripts/jquery-2.0.3.js"></script>
<script src="/Scripts/jquery-ui-1.10.3.js"></script>
<script src="/Scripts/jquery.mobile-1.4.0-beta.1.js"></script>
</head>
<body>
<div id="layoutPage" data-role="page" data-theme="a">
<div id="layoutHeader" data-role="header">
<h2>TestDialog</h2>
</div>
<div id="layoutContent" data-role="content">
#using (Html.BeginForm())
{
<div>
<div class="editor-label">
#Html.LabelFor(model => model.IDDocument)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IDDocument)
#Html.ValidationMessageFor(model => model.IDDocument)
</div>
</div>
<div data-role="controlgroup" data-type="horizontal" data-mini="true">
<a id="addDetail" href="#Url.Action("ShowDialog", "SampleTest")" data-rel="dialog" data-role="button" >Test dialog</a>
</div>
}
</div>
</div>
<script>
$(document).on("mobileinit", function () {
$.mobile.ajaxEnabled = false;
});
</script>
</body>
</html>
Dialog View Code:
#model MvcApplication4.Models.ViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>DialogView</title>
</head>
<body>
<div id="detailPage1" data-role="dialog" >
#using (Html.BeginForm("ShowDialogActioinPost", "SampleTest", FormMethod.Post))
{
<div data-role="header">
<button type="submit" data-icon="check" class="ui-submit" data-inline="true" data-mini="true">Save</button>
<h2 >Dialog Information</h2>
<a data-rel="back" data-icon="back">Go back</a>
</div> //end header
<div data-role="content">
<div class="editor-label">
#Html.LabelFor(model => model.SeqNo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SeqNo)
#Html.ValidationMessageFor(model => model.SeqNo)
</div>
</div>
}
</div>
</body>
</html>
Controller Code:
[HttpGet]
public ActionResult ShowDialog()
{
return View("DialogView");
}
[HttpPost]
public ActionResult ShowDialogActioinPost(ViewModel vm)
{
return View("Index"); // should return to master page, but it doesn't work
}
Thanks
Wilson
Try RedirectToAction("Index"); instead of View("Index");
You have to return the model to your master page.
[HttpPost]
public ActionResult ShowDialogActioinPost(ViewModel vm)
{
return View("Index", vm);
}
The answer is here.
Thanks
Wilson
I have a multi-level Layout master pages in an ASP.NET MVC 4.
I have the following:
<title>#ViewBag.Title</title>
The order of Layout pages is as follows:
_Layout.cshtml
_SubLayout.cshtml (based on _Layout.cshtml)
Index.cshtml (based on _SubLayout.cshtml)
I am setting the #ViewBag.Title inside Index Action. However, I get the following exception:
Value cannot be null or empty. Parameter name: contentPath
Here is the code I have. I am simply making the code of ASP.NET Design Patterns books work for VS 2012 / MVC 4
_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="main">
<div id="header">
<span><a href="#Url.Content("")">
<img alt="Agatha's Clothing Store"
src="#Url.Content("/Content/Images/Structure/lg_logo.png")"
border="0" /></a></span>
</div>
<div id="headerSummary">
#RenderSection("headerBasketSummary", required: false)
</div>
<div class="topBarContainer">
<div id="background">
<div id="navigation">
#RenderSection("MenuContent", required: false)
</div>
<div id="content">
#RenderBody()
</div>
<div style="clear: both;" />
</div>
</div>
#Html.Partial("_SiteFooter")
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.0/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.js"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery-jtemplates.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/agatha-common-scripts.js")"></script>
</body>
</html>
_ProductCatalogProduct.cshtml
#model BaseProductCatalogPageView
#using Agathas.Storefront.Controllers.ViewModels.ProductCatalog
#using Agathas.Storefront.UI.Web.MVC.Helpers
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#if (IsSectionDefined("MenuContent"))
{
#RenderSection("MenuContent", required: false)
}
else
{
#Html.Partial("_Categories", ((BaseProductCatalogPageView)Model).Categories)
}
#RenderBody();
Index.cshtml
#model HomePageView
#using Agathas.Storefront.Controllers.ViewModels.ProductCatalog
#using Agathas.Storefront.Services.ViewModels
#using Agathas.Storefront.UI.Web.MVC.Helpers
#{
Layout = "~/Views/Shared/_ProductCatalogLayout.cshtml";
ViewBag.Title = "Home Page";
}
<img width="559" height="297"
src="#Url.Content("~/Content/Images/Products/product-lifestyle.jpg")"
style="border-width: 0px; padding: 0px; margin: 0px" />
<div style="clear: both;"></div>
<h2>Top Products</h2>
<div id="items" style="border-width: 1px; padding: 0px; margin: 0px">
<ul class="items-list">
#foreach (ProductSummaryView product in Model.Products)
{
<li class="item-detail">
<a class="item-productimage-link" href="#Url.Action("Detail", "Product", new { id = product.Id }, null)">
<img class="item-productimage" src="#Url.Content("~/Content/Images/Products/" + product.Id.ToString() +".jpg"))" /></a>
<div class="item-productname">#Html.ActionLink(product.BrandName + " " + product.Name, "Detail", "Product", new { id = product.Id }, null)</div>
<div class="item-price">#product.Price</div>
</li>
}
</ul>
</div>
Many thanks
This piece of code is throwing the exception: <a href="#Url.Content("")">. This happens because contentPath parameter of Url.Content method cannot be null or empty.
This can happen if you are assigning a value in the Child Razor view file that is also set in the parent one, but is displayed in a partial called by the Layout.cshtml
For example
_Layout.cshtml
|
(parent of)
|
Parent.cshtml
|
(parent of)
|
Page1.cshtml
In Page1.cshtml I do
ViewBag.Title= "Value1";
In Parent.cshtml I do the same but using the Umbraco call:
ViewBag.Title = Umbraco.Field("value").ToString();
The fix is to remove the assignment in Parent.cshtml. This appears to be a bug and I'm afraid that this is the only fix I've found. Hope it helps you out...
You should check if path not null or empty before use it as source of image
#foreach (var post in Model)
{
<div class="col-md-6">
<div class="product-list post-list">
#if (!string.IsNullOrWhiteSpace(post.Photo))
{
<a href="#" class="product-list-img">
<img src="#Url.Content(post.Photo)" alt="">
</a>
}
</div>
</div>
I am using Kendo UI Grid to show mail list, when i click on a row, i need to select a row and show mail body in editor from mail object which i already have in client side.
But can not get the selected row value.
Here is the view code:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MVC3toHTML5.Models.MailModel>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Index</title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<link href="<%= Url.Content("/Content/web/kendo.common.min.css") %>" rel="stylesheet" type="text/css" />
<link href="<%= Url.Content("/Content/web/kendo.rtl.min.css") %>" rel="stylesheet" type="text/css" />
<link href="<%= Url.Content("/Content/web/kendo.default.min.css") %>" rel="stylesheet" type="text/css" />
<link href="<%= Url.Content("/Content/shared/examples-offline.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="<%= Url.Content("/Scripts/jquery.min.js") %>"></script>
<script src="<%= Url.Content("/Scripts/kendo.web.min.js") %>"></script>
<script src="<%= Url.Content("/Scripts/kendo.aspnetmvc.min.js") %>"></script>
<script src="<%= Url.Content("/Scripts/console.min.js") %>"></script>
<script src="<%= Url.Content("/Scripts/prettify.min.js") %>"></script>
</head>
<body>
<div style="font-size:medium;">
<%: Html.Kendo().Grid(Model.mailList)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.MailId).Width(200);
columns.Bound(p => p.From.Value).Width(200);
columns.Bound(p => p.Subject).Width(200);
})
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.Groupable()
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Events(events => events.Change("Grid_OnRowSelectUID"))
)
.Selectable()
%>
</div>
<div style="margin-left:220px;">
<% Html.Kendo().Editor()
.Name("Editor")
.HtmlAttributes(new { style = "width: 740px;height:440px;" })
.Render();
%>
<script type="text/javascript">
function Grid_OnRowSelectUID() {
var dataSource = new kendo.data.DataSource({
change: function (e) {
alert("datasource");
}
});
dataSource.bind("change", function (e) {
alert("Bind");
});
}
</script>
</div>
</body>
</html>
Controller is as follows:
namespace MVC3toHTML5.Controllers
{
public class Home2Controller : Controller
{
public ActionResult Index()
{
MailModel mailModelobj = new MailModel();
mailModelobj.GetMailList();
return View(mailModelobj);
}
}
}
I am getting mail from webservice.
What is the correct way to achieve that ?
Use the change event of the Grid not the change event of the dataSource.
<%: Html.Kendo().Grid(Model.mailList)
.Name("Grid")
.Selectable()
.Events(ev=>ev.Change("onSelectRow"))
//...
<script>
function onSelectRow(e){
var currentSelectedItem = this.dataItem(this.select());
alert(currentSelectedItem.SomeProp);
$('#Editor').data().kendoEditor.value(currentSelectedItem.SomeProp);
}
</script>
I cannot for the life of me figure out why this postback sometimes does an ajax one as it is supposed to and sometimes it does not. Here is the relevant code:
JS:
<html>
<head>
<title>Index</title>
<link href="/Content/screen.css" rel="stylesheet" type="text/css" />
<!--[if lt IE 8]><link href="/Content/ie.css" rel="stylesheet" type="text/css" /><![endif]-->
<link href="/Content/plugins/fancy-type/screen.css" rel="stylesheet" type="text/css" />
<link href="/Content/plugins/buttons/screen.css" rel="stylesheet" type="text/css" />
<link href="/Content/plugins/link-icons/screen.css" rel="stylesheet" type="text/css" media="screen, projection" />
<link href="/Content/jQueryUI/css/cupertino/jquery-ui-1.8.9.custom.css" rel="stylesheet" type="text/css" />
<link href="/Content/HelpDesk.css" rel="stylesheet" type="text/css" />
<link href="/Content/droppy.css" rel="stylesheet" type="text/css" />
<link href="/Content/tablesorter.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery-ui.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.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/jquery.droppy.js" type="text/javascript"></script>
<script src="/Scripts/jquery.cascadingDropDown.js" type="text/javascript"></script>
<script src="/Scripts/jquery.tablesorter.min.js" type="text/javascript"></script>
<script type='text/javascript'>
$(function () {
$('#nav').droppy();
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#targetStartDate").datepicker();
$("#targetEndDate").datepicker();
$("#ticketsHTMLTable").tablesorter({ sortList: [[0, 0], [1, 0]] });
$(".fakeLink").mouseover(function () {
$(this).css("color", "red");
});
$(".fakeLink").mouseout(function () {
$(this).css("color", "black");
});
});
</script>
</head>
Here is my View (Razor):
#using (Ajax.BeginForm("Index", "Problem", new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "ticketsTable",
InsertionMode = InsertionMode.Replace
}))
{
<div class="notice">
<div class="prepend-1 span-2">
<label for="targetPriorityID">
Priority</label>
</div>
<div class="prepend-1 span-3">
<label for="targetStatusID">
Status</label>
</div>
<div class="span-3">
<label for="targetBusinessUnitID">
Business Unit</label>
</div>
<div class="span-3 prepend-1">
<label for="targetStartDate">
Start Date</label></div>
<div class="span-3 prepend-2">
<label for="targetEndDate">
End Date</label></div>
<div class="prepend-1 span-3 last">
 
</div> <div class="prepend-1 span-2">
#Html.DropDownList("targetPriorityID",
new SelectList(ViewBag.Priorities as System.Collections.IEnumerable,
"ID", "Title"), "All", new { #onchange = " this.form.submit();" })
</div>
<div class="prepend-1 span-3">
#Html.DropDownList("targetStatusID",
new SelectList(ViewBag.Statuses as System.Collections.IEnumerable,
"ID", "Title"),"All", new { #onchange="this.form.submit();" })
</div>
<div class="span-3">
#Html.DropDownList("targetBusinessUnitID",
new SelectList(ViewBag.BusinessUnits as System.Collections.IEnumerable,
"ID", "Title"), "All", new { #onchange = "this.form.submit();" })
</div>
<div class="span-3 prepend-1">#Html.TextBox("targetStartDate", "", new { onchange = "this.form.submit();" })</div>
<div class="span-3 prepend-2">#Html.TextBox("targetEndDate", "", new { onchange = "this.form.submit();" })</div>
<div class="prepend-1 span-3 last">
<input type="submit" value="Hide" />
</div>
<br />
<br />
<br />
</div>
}
<div id="ticketsTable">
#Html.Partial("_AllTickets", Model)
</div>
And finally the controller,
[HttpPost]
public ActionResult Index(int targetPriorityID = -1, int targetBusinessUnitID = -1, int targetStatusID = -1, string targetStartDate = "", string targetEndDate ="")
{
Repository<Priority> priorityRepository = new Repository<Priority>();
Repository<BusinessUnit> businessUnitRepository = new Repository<BusinessUnit>();
Repository<Status> statusRepository = new Repository<Status>();
ViewBag.Priorities = priorityRepository.GetAll();
ViewBag.BusinessUnits = businessUnitRepository.GetAll();
ViewBag.Statuses = statusRepository.GetAll();
var results = problemRepository.GetAll();
results = (targetPriorityID != -1) ? results.Where(t => t.PriorityID == targetPriorityID) : results;
results = (targetBusinessUnitID != -1) ? results.Where(t => t.BusinessUnitID == targetBusinessUnitID) : results;
results = (targetStatusID != -1) ? results.Where(t => t.StatusID == targetStatusID) : results;
results = (targetStartDate != "") ? results.Where(t => t.DateReported >= DateTime.Parse(targetStartDate)) : results;
results = (targetEndDate != "") ? results.Where(t => t.DateReported <= DateTime.Parse(targetEndDate)) : results;
if (Request.IsAjaxRequest())
{
return PartialView("__AllTickets", results);
}
return View(results);
}
Any thoughts?
I would suggest you to use normal form that will be AJAXified later:
#using (Html.BeginForm("Index", "Problem")
{
<div class="notice">
<div class="prepend-1 span-2">
<label for="targetPriorityID">Priority</label>
</div>
<div class="prepend-1 span-3">
<label for="targetStatusID">Status</label>
</div>
<div class="span-3">
<label for="targetBusinessUnitID">Business Unit</label>
</div>
<div class="span-3 prepend-1">
<label for="targetStartDate">Start Date</label></div>
<div class="span-3 prepend-2">
<label for="targetEndDate">End Date</label>
</div>
<div class="prepend-1 span-3 last">
 
</div>
<div class="prepend-1 span-2">
#Html.DropDownList("targetPriorityID", new SelectList(ViewBag.Priorities as System.Collections.IEnumerable, "ID", "Title"), "All")
</div>
<div class="prepend-1 span-3">
#Html.DropDownList("targetStatusID", new SelectList(ViewBag.Statuses as System.Collections.IEnumerable, "ID", "Title"), "All")
</div>
<div class="span-3">
#Html.DropDownList("targetBusinessUnitID", new SelectList(ViewBag.BusinessUnits as System.Collections.IEnumerable, "ID", "Title"), "All")
</div>
<div class="span-3 prepend-1">
#Html.TextBox("targetStartDate", "")
</div>
<div class="span-3 prepend-2">
#Html.TextBox("targetEndDate", "")
</div>
<div class="prepend-1 span-3 last">
<input type="submit" value="Hide" />
</div>
<br />
<br />
<br />
</div>
}
<div id="ticketsTable">
#Html.Partial("_AllTickets", Model)
</div>
and then in a separate file AJAXify it:
$(function() {
$('form :input').change(function() {
var form = $('form');
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: form.serialize(),
success: function(result) {
$('#ticketsTable').html(result);
}
});
});
});
Another improvement I that I would suggest you is to use view models and get rid of ViewData and use strongly typed helpers.
One problem I can see is that your AJAX options in your Razor view specify the GET HTTP method, but the action filter on the controller action specifies POST.
I wonder if Request.IsAjaxRequest() is causing the problem. I would look at removing that code and always return PartialView("__AllTickets", results); instead.