ASP.Net MVC 3 Jquery UI Dialog Form - asp.net-mvc-3

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>

Related

Only append div with certain class in Ajax success function

I have a partial view that is used to return a bunch of html to my main page. In my Ajax call, I need to grab that partial view, but I only want to append certain <div> elements. Is this possible?
Here is the Ajax:
$(document).ready(function () {
$("#addItem").click(function () {
$.ajax({
url: '#Url.Action("BlankDropDownItem", "DropDownValues")',
data: { field: $('#Field').val(), displayPage: $('#DisplayPage').val() },
dataType: 'html',
cache: false,
success: function (html) {
$("#items").append(html);
}
});
return false;
});
});
This calls an ASP MVC controller method which returns this partial view.
<div id="LeftDiv" style="width:250px;float:left;">
<fieldset>
<legend>Category Information</legend>
<div class="M-editor-label">
#Html.LabelFor(model => model.Field)
</div>
<div class="M-editor-field">
#Html.EditorFor(model => model.Field)
#Html.ValidationMessageFor(model => model.Field)
</div>
<div class="M-editor-label">
#Html.LabelFor(model => model.DisplayPage)
</div>
<div class="M-editor-field">
#Html.EditorFor(model => model.DisplayPage)
#Html.ValidationMessageFor(model => model.DisplayPage)
</div>
</fieldset>
</div>
<div id="RightDiv" style="width:300px;float:left; padding-left:50px;">
<fieldset id="items">
<legend>Drop Down Items</legend>
<div class="editor-label">
#Html.LabelFor(model => model.AllowedValue)
</div>
<div class="label-field">
#Html.EditorFor(model => model.AllowedValue)
#Html.ValidationMessageFor(model => model.AllowedValue)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DisplayValue)
</div>
<div class="label-field">
#Html.EditorFor(model => model.DisplayValue)
#Html.ValidationMessageFor(model => model.DisplayValue)
</div>
</fieldset>
</div>
However, I only want to append the label-field and editor-label <div> elements to items.
You can use jQuery to search the returned html too. Not as efficient as it could be, but probably fine for your purposes.
$("#items").append($(html).find(".label-field, .editor-label"));

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.

2 validation groups

I have 2 validation forms on page.
<div id='LogOn' style="background-color: White;">
#using (Ajax.BeginForm("LogOnAjax", "Home", new AjaxOptions { UpdateTargetId = "LogOn", OnSuccess = "logInComplete" }))
{
//ITW2012Mobile.ViewModels.LogOnModel m = Model;
#Html.HiddenFor(model => model.IsLoggedIn)
#Html.HiddenFor(model => model.ReturnUrl)
<div>
#Html.ValidationSummary()
</div>
<div>
#Html.LabelFor(model => model.UserName)
#Html.EditorFor(model => model.UserName)
</div>
<div>
#Html.LabelFor(model => model.Password)
#Html.EditorFor(model => model.Password)
</div>
<div>
<input type="submit" value="Login" />
</div>
}
</div>
and
<fieldset>
#using (Html.BeginForm(Model.ActionMethod, Model.Controller))
{
#Html.ValidationSummary()
.....
<div class="display-label"> E-mail Address * </div>
<div class="display-field">
#Html.EditorFor(model => model.Username)
#Html.ValidationMessageFor(model => model.Username)
</div>
<div class="display-label"> Create Password * </div>
<div class="display-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<p>
<input type="submit" value="Create" />
</p>
}
</fieldset>
How can I mark that ModelState.AddModelError is for first of form, because I see the same error in the both places of validation summary?
How can I mark that ModelState.AddModelError is for first of form
You can't.
What you can do is having ValidationMessageFor for each form properties instead of the ValidationSummary

MVC3 sending hashed password with ajax

I am creating a loginform like this:
#using (Ajax.BeginForm("Login", new AjaxOptions()
{
HttpMethod = "POST",
OnComplete = "onComplete"
}))
{
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.Username, "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.Password, "Wachtwoord")
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Remember, "Remember me")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Remember)
#Html.ValidationMessageFor(model => model.Remember)
</div>
<p>
<input type="submit" value="Inloggen" />
</p>
</fieldset>
}
Now the password is send unhashed over the internet for validation to the model, which is not safe. I want to make sure the password is always hashed going over the line and preventing man in the middle sniffers.
The onBegin won't work because the elements cannot be modified anymore after this, any other ideas?
You can do it without ajax by catching the submit event and hash the password before posting the form
#using (Html.BeginForm("LogOn","Login",FormMethod.Post,new {id = "loginForm"})) {
<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, new {id = "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="Connect" id="submit"/>
</p>
</fieldset>
</div>}
For example with this javascript code :
$(function () {
$("#loginForm").on("submit",function (e) {
var form = $(this);
var pass = $("#password").val();
$("#password").val(MD5(token + MD5(pass)));
form.submit();
});
});

Resources