MVC3 view rendering twice when I have Glimpse and use a MVC control toolkit DateTimeFor element - asp.net-mvc-3

I have an MVC application with glimpse installed, I am also using the MVCControlToolkit for dymanic validation.
The issue I have is when I have a view that uses DateTimeFor to display the date time calendar with validation, but only in a very limited set of circumstances (if I only have datetimefor elements this doesn't happen), the body gets rendered on the page twice.
It looks like the rendering is getting restarted by something, but I haven't been able to work it out.
Any help would be appreciated
My view code is
#using LeaveTracker.Models
#using LeaveTracker.Models.Leave
#using MVCControlsToolkit.Controls
#using MVCControlsToolkit.Controls.Validation
#model LeaveTracker.Models.Leave.LeaveAllocation
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_LayoutMaintenance.cshtml";
}
#Html.AntiForgeryToken()
<div class="page-header">
<h1>
Edit Leave Allocation
#if (Model.ID > 0) { <small> #Model.TypeOfLeave.Name till #Model.AppliesUntil.ToString("dd/MM/yyyy")</small> }
</h1>
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<link href="#Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/jquery.ui.datepicker.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.16.min.js")" type="text/javascript"></script>
#Html.JQueryDatePickerGlobalizationScript("en-GB")
<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/ValidationSetup.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MVCControlToolkit.Controls-1.5.0.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Leave Allocation Details</legend>
#Html.HiddenFor(model => model.ID)
<div class="clearfix">
#Html.LabelFor(model => model.TypeOfLeave)
<div class="input">
#Html.DropDownListFor(model => model.TypeOfLeave,
LeaveFactory.GetAllLeaveTypes().Select(fl => new SelectListItem
{
Text = fl.Name,
Value = fl.ID.ToString()
}))
<span class="help-inline">#Html.ValidationMessageFor(model => model.TypeOfLeave)</span>
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.AppliesFrom)
<div class="input">
#Html.DateTimeFor(model => model.AppliesFrom, DateTime.Today, true).DateCalendar(
inLine: false,
calendarOptions: new CalendarOptions
{
ChangeYear = true,
ChangeMonth = true
})
<span class="help-inline">#Html.ValidationMessageFor(model => model.AppliesFrom)</span>
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.AppliesUntil)
<div class="input">
#Html.DateTimeFor(model => model.AppliesUntil, DateTime.Today, true).DateCalendar(
inLine: false,
calendarOptions: new CalendarOptions
{
ChangeYear = true,
ChangeMonth = true
})
<span class="help-inline">#Html.ValidationMessageFor(model => model.AppliesUntil)</span>
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.DefaultAllocation)
<div class="input">
#Html.EditorFor(model => model.DefaultAllocation)
<span class="help-inline">#Html.ValidationMessageFor(model => model.DefaultAllocation)</span>
</div>
</div>
</fieldset>
<fieldset>
<legend>Leave Carried Over</legend>
<div class="clearfix">
#Html.LabelFor(model => model.MaxCarriesOver)
<div class="input">
#Html.EditorFor(model => model.MaxCarriesOver)
<span class="help-inline">#Html.ValidationMessageFor(model => model.MaxCarriesOver)</span>
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.LeaveUseByDate)
<div class="input">
#Html.DateTimeFor(model => model.LeaveUseByDate, DateTime.Parse("01/01/1900"), true).DateCalendar(
inLine: false,
calendarOptions: new CalendarOptions
{
ChangeYear = true,
ChangeMonth = true
})
<span class="help-inline">#Html.ValidationMessageFor(model => model.LeaveUseByDate)</span>
<span class="help-block">The year on this field doesn't matter, only the month and day will be taken into account</span>
</div>
</div>
<div class="actions">
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn" })
<input class="btn primary" type="submit" value='Save'>
</div>
</fieldset>
}

Lee,
We believe we have fixed this issue.
Can you please test and confirm by installing the alpha build of Glimpse 0.87 from MyGet at http://www.myget.org/F/getglimpse/
If we get confirmation that this fixes your issue - and with a bit more testing - we will release to the main NuGet.org repository.
EDIT
Glimpse version 0.87 is now available from the main NuGet.org Glimpse feed

Related

HttpPost method is not fired if the submit button is disabled

I have a view as follows: DemoView.cshtml
#model Mvc3Razor.Models.UserModel
#{
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>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>UserModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
<p>
<input type="submit" value="Create" /></p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript">
$(function () {
$('input[type="submit"]').click(function () {
$(this).attr('disabled', 'disabled');
});
});
</script>
And a controller: HomeController.cs
[HttpPost]
public ViewResult Create(UserModel um)
{
if (!TryUpdateModel(um))
{
ViewBag.updateError = "Create Failure";
return View(um);
}
_usrs.Create(um);
return View("Details", um);
}
In order to prevent multiple button clicks, I am trying to disable the button once user clicks the Create button but once the Create button is disabled it is not firing the HttpPost method.
Can anyone help me out in order to resolve this issue?
Try disabling the button when the form is submitted and not when the submit button is clicked:
$("form").submit(function() {
$(this).attr("disabled", "disabled");
return true;
});
What I will suggest is to redirect user back to Index Page upon Successfull Post. You want use PRG Pattern
Post, Redirect, Get (PRG) pattern in which it is "to help avoid
duplicate form submissions and allow web applications to behave more
intuitively with browser bookmarks and the reload button"
usrs.Create(um);
//Redirect to Index Page here
see this SO question for more details

Main View eliminates a filter after I create an element from a partial view

Mi trouble is this: I have a View called "Create" it refers to the creation of promotions. Each promotion has Genres according to the user, so, when I do enter to the "create promotions" I have a list (dropdown) with the genres of the user, but if there is no an adecuate genre I must create it without leaving the current page, so I used a partial view for creating new genres and I inserted it in the main view (Create promotions) It do works, but after the genre is created, the main view shows ALL the genres and not only those who correspond to the current user.
This is the main view:
#model Points2Pay.Models.Promocion
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script type="text/javascript">
$(document).ready(function () {
$(".slidingDiv").hide();
$(".show_hide").show();
$('.show_hide').click(function () {
$(".slidingDiv").slideToggle();
});
});
#using (Html.BeginForm())
{
Show/hide
<div class="slidingDiv" id="partialView">
#{Html.RenderAction("Create2", "Genre");}
</div>
}
#using (Html.BeginForm("Create","StoreManager"))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Promocion</legend>
<div class="editor-label">
#Html.LabelFor(model => model.GenreId, "Genre")
</div>
<div class="editor-field" id="DROPDOWN">
#Html.DropDownList("GenreId", String.Empty)
#Html.ValidationMessageFor(model => model.GenreId)
</div>
<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.Price)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Price)
#Html.ValidationMessageFor(model => model.Price)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Puntos)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Puntos)
#Html.ValidationMessageFor(model => model.Puntos)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PromocionArtUrl)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PromocionArtUrl)
#Html.ValidationMessageFor(model => model.PromocionArtUrl)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>`
THIS IS THE SECONDARY VIEW
#model Points2Pay.Models.Genre
<script src="#Url.Content("~/Scripts/jquery-1.5.1.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>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<legend>New Genre</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<p>
<input type="submit" value="Create new Genre" />
</p>
}
AND THIS IS THE CONTROLLER
[ChildActionOnly]
public ActionResult Create2()
{
return PartialView("Create2");
}
//
// POST: /Genre/Create2
[HttpPost]
public ActionResult Create2(Genre genre)
{
var ComercioActual = (Guid)System.Web.Security.Membership.GetUser().ProviderUserKey;
if (ModelState.IsValid)
{
genre.ComercioId = ComercioActual;
db.Genres.Add(genre);
db.SaveChanges();
return PartialView("Create2");
}
return PartialView("Create2");
}
Hope you can help me.

ASP.Net MVC 3 Jquery UI Dialog Form

I am trying to make a popup dialog to allow the user to fill in a form.
When they click submit I want to submit the form.
I figured out how to make the modal popup but cannot figure out how to get it to submit the form when the form is clicked. Does anyone know how to do this?
#using (Html.BeginForm())
{
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
#Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</div>
<div class="editor-label">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
<p>
<input type="submit" value="Log On" />
</p>
</fieldset>
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$("#dialog-form").dialog({
modal: true,
buttons: {
"Submit": function () {
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
});
</script>
You need to make sure you have a valid POST method in your controller for the form to submit to. Your form here looks valid as long as you aren't expecting the dialog's submit button to submit the form. If that is the case then you will need to give the form an ID and call submit from your function for the dialog "Submit" button.
<div id="dialog-form">
#using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { id = "LogOnForm" })) {
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
#Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</div>
<div class="editor-label">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
<p>
<input type="submit" value="Log On" style="display:none;" />
</p>
</fieldset>
</div>
}
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#dialog-form").dialog({
modal: true,
buttons: {
"Submit": function () {
$("#LogOnForm").submit();
},
Cancel: function () {
$(this).dialog("close");
}
}
});
});
</script>

how can i get the value selected in #Html.DropDownList in a MVC3

I have this code, how can I get the selected value of the #htmlDropDownList to put this value in my #Url.Action instead of 1, I have read using javascript o jquery but i cant figure out how can i do that in the view directly, and this is not working for my
var idempresa = $('IdEmpresa').val()
<a href="#Url.Action("List","Script")?idempresa=**idempresa**"
the code:
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Script</legend>
<div class="editor-label">
#Html.LabelFor(model => model.IdEmpresa, "Empresa")
</div>
<div class="editor-field">
#Html.DropDownList("IdEmpresa", String.Empty )
#Html.ValidationMessageFor(model => model.IdEmpresa)
</div>
</fieldset>
}
href="#Url.Action("List","Script")?idempresa=**1**"
pd. thank you for the help
Edit:
#using System.Web.Mvc.Html
#model SistemaDispositivos.Models.Script
#{
ViewBag.Title = "Script";
}
<h2>Script</h2>
<script src="../../Scripts/jquery-1.6.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>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Script</legend>
<div class="editor-label">
#Html.LabelFor(model => model.IdEmpresa, "Empresa")
</div>
<div class="editor-field">
#Html.DropDownList("IdEmpresa", String.Empty)
#Html.ValidationMessageFor(model => model.IdEmpresa)
</div>
</fieldset>
}
<script type="text/javascript" language="javascript">
$(document).ready(function () {
var url1 = '#Url.Action("List","Script")?idempresa=';
$('IdEmpresa').change(function() {
$urlId = $('urlid');
$urlId.attr('href', url + $(this).val());
});
});
</script>
<a id="urlid" href="#Url.Action("List","Script")?idempresa=url1"> </a>
What iam missing?
well it work now this is what I wanted thank for the help:
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Script</legend>
<div class="editor-label">
#Html.LabelFor(model => model.IdEmpresa, "Empresa")
</div>
<div class="editor-field">
#Html.DropDownList("IdEmpresa", string.Empty )
#Html.ValidationMessageFor(model => model.IdEmpresa)
</div>
</fieldset>
}
<script type="text/javascript" language="javascript">
function valid() {
var listaScriptUrl = '#Url.Action("List", "Script", new { idempresa = 0})';
var input = $('#IdEmpresa').val();
$('#Lista-Script').load(listaScriptUrl.replace('0', input));
}
</script>
<input type="button" value="Click Here" onclick="valid()">
<div id="Lista-Script">
</div>
so now in the div Lista-Script when I click the button I get my view that I wanted
The view would render HTML so you cannot get the selected value of dropdown list and put it back to the variable of the view which has already executed in the server side. What you could do is put an id on the tag and update the href on change event of dropdown.
$(document).ready(function(){
$('IdEmpresa').change(function(){
var val = $(this).val();
var newurl = $("urlid").attr("href") + val;
$("urlid").attr("href",newurl);
});
});
<a id="urlid" href="#Url.Action("List","Script")?idempresa="> </a>
I would approach this much like Bipins posted, with one major exception.
<fieldset>
<legend>Script</legend>
<div class="editor-label">
#Html.LabelFor(model => model.IdEmpresa, "Empresa")
</div>
<div class="editor-field">
#Html.DropDownList("IdEmpresa", *This needs to be a list of ListItems*, new { id = "idEmpresa" })
#Html.ValidationMessageFor(model => model.IdEmpresa)
</div>
</fieldset>
$(document).ready(function()
{
var url = '#Url.Action("List","Script")?idempresa=';
$('#idEmpresa').change(function()
{
$urlId = $('urlid');
$urlId.attr('href', $urlId.attr('href') + $('this').val());
}
});
By caching the original URL in a js variable, you always have a clean slate to append to.

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