Updating an input field when button clicked not working - javascript

I am writing a small mvc.net web application that takes some input from the user and when the user clicks the button the input data is calculated and displayed in two input fields. However when the button is clicked (see file Index.cshtml) nothing is displayed in the two input fields. Would appreciate any help to figure out what might be wrong. :)
An image of the web application.
Here follows my code...
SelectPurchaseModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TheMakingOfAWebApplication.Models
{
public class SelectPurchaseModel
{
public string Name { get; set; }
public IEnumerable<Article> Articles { get; set; }
public int Quantity { get; set; }
public double Price { get; set; }
public double AmountExVat { get; set; }
public double AmountInVat { get; set; }
}
}
Article.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TheMakingOfAWebApplication.Models
{
public class Article
{
public string Name { get; set; }
}
}
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TheMakingOfAWebApplication.Models;
namespace TheMakingOfAWebApplication.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
//List<Article> articles;
SelectPurchaseModel model = new SelectPurchaseModel();
model.Name = "";
model.Articles = new List<Article>{
new Article { Name = "Bananas"},
new Article { Name = "Apples"},
new Article { Name = "Oranges"},
new Article { Name = "Melons"},
new Article { Name = "Grapes"},
new Article { Name = "Sallad"},
new Article { Name = "Potatoes"},
new Article { Name = "Cucumber"},
new Article { Name = "Beans"},
new Article { Name = "Tomatoes"}
};
model.Quantity = 0;
model.Price = 0.0;
model.AmountExVat = 0.0;
model.AmountInVat = 0.0;
return View(model);
}
// POST: Home
[HttpPost]
public ActionResult Index(SelectPurchaseModel purchase)
{
purchase.Articles = new List<Article>{
new Article { Name = "Bananas"},
new Article { Name = "Apples"},
new Article { Name = "Oranges"},
new Article { Name = "Melons"},
new Article { Name = "Grapes"},
new Article { Name = "Sallad"},
new Article { Name = "Potatoes"},
new Article { Name = "Cucumber"},
new Article { Name = "Beans"},
new Article { Name = "Tomatoes"}
};
purchase.AmountExVat = purchase.Quantity * (purchase.Price - (purchase.Price * 0.10));
purchase.AmountInVat = purchase.Quantity * (purchase.Price * 1.10);
return View(purchase);
}
}
}
Index.cshtml
#model TheMakingOfAWebApplication.Models.SelectPurchaseModel
#{
ViewBag.Title = "Index";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$(".btn btn-default").click(function () {
debugger;
var quantity = $("#Quantity").attr('value');
var price = $("#Price").attr('value');
var AmountExVat = quantity * (price - (price * 0.10));
var AmountInVat = quantity * (price * 1.10);
$("#AmountExVat").val(AmountExVat);
$("#AmountInVat").val(AmountInVat);
});
});
</script>
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Article</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<fieldset>
<p>
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownListFor(m => m.Name, new SelectList(Model.Articles, "Name", "Name"))
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</p>
<p>
#Html.LabelFor(model => model.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.Quantity)
#Html.ValidationMessageFor(model => model.Quantity, "", new { #class = "text-danger" })
</p>
<p>
#Html.LabelFor(model => model.Price, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.Price)
#Html.ValidationMessageFor(model => model.Price, "", new { #class = "text-danger" })
</p>
<p>
<input type="submit" value="Save" class="btn btn-default" />
</p>
<p>
#Html.LabelFor(model => model.AmountExVat, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.AmountExVat)
#Html.ValidationMessageFor(model => model.AmountExVat, "", new { #class = "text-danger" })
</p>
<p>
#Html.LabelFor(model => model.AmountInVat, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.AmountInVat)
#Html.ValidationMessageFor(model => model.AmountInVat, "", new { #class = "text-danger" })
</p>
</fieldset>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>

1st: use $(".btn.btn-default") instead of $(".btn btn-default")
2nd use .val() instead of attr('value');
3rd you may need to use parseInt() or pareseFloat();
<script type="text/javascript">
$(document).ready(function () {
$(".btn.btn-default").click(function () {
debugger;
var quantity = $("#Quantity").val();
var price = $("#Price").val();
var AmountExVat = quantity * (price - (price * 0.10));
var AmountInVat = quantity * (price * 1.10);
$("#AmountExVat").val(AmountExVat);
$("#AmountInVat").val(AmountInVat);
});
});
</script>
About using parseInt() and parseFloat()
var quantity = parseInt($("#Quantity").val() , 10);
var price = parseFloat($("#Price").val());
Additional: if all of that not work .. you can try
$(".btn.btn-default").on('click',function () {
or
$("body").on('click',".btn.btn-default",function () {

Your selector is not binding property so fixed as mentioned below and you should use val() instead of attr('value')
$(".btn.btn-default").click(function () {
var quantity = $("#Quantity").val();
var price = $("#Price").val();
var amountExVat = quantity * (price - (price * 0.10));
var amountInVat = quantity * (price * 1.10);
$("#AmountExVat").val(amountExVat);
$("#AmountInVat").val(amountInVat);
});

Related

Add ModelState.AddModelError to the view after submitting form through javascript

I'm new to web development. Currently I'm working on a practice project on asp.net mvc 5. I have a form for users where the admin can add a new user to the system. The new user form opens in a modal and is submitted in the form format
VIEW
#using (Html.BeginForm("AddUser", "User", FormMethod.Post, new { onsubmit = "return SubmitForm(this)" }))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Add New User</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="form-group">
#Html.LabelFor(model => model.user_name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.EditorFor(model => model.user_name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.user_name, "", new { #class = "text-danger" })
#Html.ValidationMessage("UserExist", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.role_id, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.role_id, new SelectList(ViewBag.roles, "role_id", "role_name"), "Select", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.role_id)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.user_password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.user_password, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.user_password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.confirmPassword, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.confirmPassword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.confirmPassword, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.user_email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.user_email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.user_email, "", new { #class = "text-danger" })
#Html.ValidationMessage("EmailExist", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.supervisor, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.supervisor, new SelectList(ViewBag.supervisors, "user_id", "user_name"), "Select Supervisor", new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.region_id, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.region_id, new SelectList(ViewBag.regions, "region_id", "region_name"), "Select Region", new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(model => model.region_id, "", new { #class = "text-danger" })
</div>
<div class="form-group">
<input type="submit" id="submitBtn" value="Submit" class="btn btn-primary" />
<input type="reset" value="Reset" class="btn" />
</div>
</div>
}
Javascript Submit Function
function SubmitForm(form) {
if ($(form).valid()) {
$.validator.unobtrusive.parse(form);
$.ajax({
type: "POST",
url: form.action,
data: $(form).serialize(),
success: function (data) {
if (data.success) {
$('#myModal').modal('hide');
//Popup.dialog('close');
dataTable.ajax.reload();
//notify.js plugin
$.notify(data.message, {
globalPosition: "top center",
className: "success"
})
}
}
});
}
return false;
}
on submit the form goes to the POST action result which works fine and new user is created but when I try to add model error
#region User Already Exists
var isUserExists = isUserExist(newUser.user_name);
if (isUserExists)
{
ModelState.AddModelError("UserExist", "User already exists");
return View(newUser);
}
#endregion
the Model error is not reflected in the view. After debugging I found that my model from POST action result is not returned and the previous model is used. I have been dealing with this issue for a long time now, found some possible solutions but none of them seem to work. Any help or sense of direction will be appreciated.
Using remote here is the ViewModel
public class AddUser
{
[Display(Name = "User name")]
[Required(AllowEmptyStrings = false, ErrorMessage = "User name is required")]
public string user_name { get; set; }
[Display(Name = "Role")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Confirm Password is required")]
public int role_id { get; set; }
[Display(Name = "Password")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Password is required")]
[DataType(DataType.Password)]
[MinLength(6, ErrorMessage = "Minimum 6 characters required")]
public string user_password { get; set; }
[Display(Name = "Confirm Password")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Confirm Password is required")]
[DataType(DataType.Password)]
[System.ComponentModel.DataAnnotations.Compare("user_password", ErrorMessage = "Confirm password and password do not match")]
public string confirmPassword { get; set; }
[Display(Name = "Email")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Email is required")]
[DataType(DataType.EmailAddress)]
[System.Web.Mvc.Remote("CheckExistingEmail", "ModelValidation", HttpMethod = "POST", ErrorMessage = "Email already exists")]
public string user_email { get; set; }
[Display(Name = "Supervisor")]
public Nullable<int> supervisor { get; set; }
[Display(Name = "Region")]
[Required(AllowEmptyStrings = false, ErrorMessage = "User Region is required")]
public int region_id { get; set; }
}
and here is the ValidationController
public class ModelValidationController : Controller
{
[AllowAnonymous]
[HttpPost]
public ActionResult CheckExistingEmail(string Email)
{
try
{
return Json(!IsEmailExist(Email));
}
catch (Exception ex)
{
return Json(false);
}
}
[NonAction]
public bool IsEmailExist(string email)
{
using (mmpEntities mP = new mmpEntities())
{
var v = mP.users.Where(a => a.user_email == email).FirstOrDefault();
//return v == null ? false : true;
return v != null;
}
}
}
For the validation you can use jquery module unobtrusive js, and it will give you live jquery error functionality when you type misleading input. Here is how you can use it:
<script src=" jquery.validate.min.js"></script>
<script src="jquery.validate.unobtrusive.min.js"></script>
<script src="~/vendors/jquery.form.min.js"></script>
<script>
$(document).ready(function () {
$(document).on("click", "#Subscribe", function () {
$('#SubscribeForm').ajaxForm({
success: function (response) {
if (response.Success) {
// You could use toastr notifaction in here }
else {
// You could use toastr notifaction in here
}
}
})
})
})
</script>
Here's what I do inside my controller to send the model state back to the client via success (or done) in ajax:
if (ModelState.IsValid)
{
//your post code to db
}
else
{
var modelState = ModelState.ToDictionary
(
kvp => kvp.Key,
kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
);
return Json(new { modelState }, JsonRequestBehavior.AllowGet);
}
Then in the ajax success or done callback do something like this:
if (data.modelState) {
$.each(data.modelState, function (i, item) {
item.valid(); //run jQuery validation to display error
});
}

How to pass DropDownList Selected Value via Ajax.BeginForm to Controller?

I can't pass data to controller
Controller
[Route("{restaurantId}/Detail/AddDistrict")]
public virtual ActionResult AddDistrict(long? restaurantId)
{
if (restaurantId == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var restaurant = _restaurantService.GetById(Convert.ToInt64(restaurantId));
if (restaurant == null) return HttpNotFound();
var resDistrict = _restaurantService.GetLocationByRestaurantId(Convert.ToInt64(restaurantId));
var districts = _locationService.
GetDistrictsByCityName("اهواز");
ViewBag.Districts = new SelectList(districts, "Id", "Name");
return PartialView(MVC.Admin.Restaurants.Views.Location._AddDistrict, new AddRestaurantLocationViewModel { RestaurantId = restaurant.Id });
[AjaxOnly]
[Route("{restaurantId}/Detail/AddDistrict")]
[HttpPost]
public virtual ActionResult AddDistrict(long? restaurantId, long districtId)
{
var model = new AddRestaurantLocationViewModel
{
DistrictId = districtId,
RestaurantId = Convert.ToInt64(restaurantId),
};
_restaurantService.SetLocation(model);
return RedirectToAction(MVC.Admin.Restaurants.ActionNames.Location, new { restaurantId = restaurantId });
}
_AddDistrict.cshtml as VIEW
#model ViewModels.Admin.Restaurant.Location.AddRestaurantLocationViewModel
#using (Ajax.BeginForm(MVC.Admin.Restaurants.ActionNames.AddDistrict, MVC.Admin.Restaurants.Name, null, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "locations", InsertionMode = InsertionMode.Replace }, htmlAttributes: new { #class = "inline-form", role = "form" }))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.DistrictId, htmlAttributes: new { #class = "control-label" })
<text> : </text>
#Html.DropDownListFor(model => model.DistrictId, ViewBag.Districts as IEnumerable<SelectListItem>, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.DistrictId, "", new { #class = "text-danger" })
</div>
#Html.SubmitGlyph("ثبت", "fa fa-plus", new { #class = "btn btn-success" })
}
AddRestaurantLocationViewModel as Model
public class AddRestaurantLocationViewModel
{
[Required(ErrorMessage = "وارد کردن {0} الزامیست")]
[DisplayName("منطقه")]
public long DistrictId { get; set; }
public long RestaurantId { get; set; }
}
When I submit, returns this error:
jquery-2.2.4.js:9175 POST http://localhost:30936/Admin/Restaurants/4/Detail/AddDistrict 500 (Internal Server Error)
send # jquery-2.2.4.js:9175
ajax # jquery-2.2.4.js:8656
asyncRequest # jquery.unobtrusive-ajax.js:128
(anonymous) # jquery.unobtrusive-ajax.js:183
dispatch # jquery-2.2.4.js:4737
elemData.handle # jquery-2.2.4.js:4549
VM3829:3 XHR Loaded (AddDistrict - 500 Internal Server Error - 23.446000006515533ms - 12.553KB)
http://localhost:30936/Admin/Restaurants/4/Detail/AddDistrict?districtId=3&X-Requested-With=XMLHttpRequest
VM3831:3 XHR Data Object {startedDateTime: "2016-12-23T20:52:49.298Z", time: 23.446000006515533, request: Object, response: Object, cache: Object…}
VM3832:3 Response <!DOCTYPE html>
<html>
<head>
<title>Value cannot be null.<br>Parameter name: entity</title>
<meta name="viewport" c...
Finally I can't pass selectedValue to controller

Phone number doesn't get validated

I have a form everything get validated except phone number i tried and tried without any success, i can figure out where the problem lay
Here is my view
<div class="form-group">
#Html.LabelFor(m => m.Cell, htmlAttributes: new { #class = "col-md-2 control-label" })
<div class="col-md-4">
#Html.TextBoxFor(m => m.Cell, new { #class = "form-control", id = "Cell", placeholder = "Phone Number" })
#Html.ValidationMessageFor(m => m.Cell, "", new { #class = "text-danger" })
</div>
</div>
Javascript
<script>
jQuery(document)
.ready(function () {
jQuery("#Cell").inputmask("099 999 9999");
jQuery("#Cell")
.on("blur",
function () {
var last = $(this).val().substr($(this).val().indexOf("-") + 1);
if (last.length == 4) {
var move = $(this).val().substr($(this).val().indexOf("-") - 1, 1);
var lastfour = move + last;
var first = $(this).val().substr(0, 9);
$(this).val(first + '-' + lastfour);
}
});
});
</script>
Model
public class FeedbackViewModel
{
[MinLength(10)]
[StringLength(13, ErrorMessage = "Please enter a valid phone number")]
public string Cell { get; set; }
}
I got it this is what i did on a model and View
[Required(ErrorMessage = "Your must provide a Phone Number")]
[Display(Name = "Cell")]
[DataType(DataType.PhoneNumber)]
[RegularExpression(#"^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", ErrorMessage = "Not a valid Phone number")]
public string Cell { get; set; }
#Html.EditorFor(m => m.Cell, new { htmlAttributes = new { #class = "form-control", id="Cell", placeholder = "Phone Number" } })

JavaScript (JQuery) validate numbers (decimals) in different cultures and DropDownListFor onchange

I have web app for testing.
My very simple class:
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Value { get; set; }
}
I changed my default controller this way:
// GET: MyClasses/Create
public ActionResult Create()
{
MyClass myClass = new MyClass()
{
Name = "First",
Value = 1
};
var Names = new[]{
new SelectListItem{ Value="First", Text="First" },
new SelectListItem{ Value="Second", Text="Second" },
new SelectListItem{ Value="Third", Text="Third" },
};
ViewBag.Names = new SelectList(Names, "Value", "Text");
return View(myClass);
}
// POST: MyClasses/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,Name,Value")] MyClass myClass, string Action)
{
if (Action == "Change name")
{
myClass.Value = myClass.Name == "First" ? 1 :
myClass.Name == "Second" ? 2 :
myClass.Name == "Third" ? 3 :
0;
ModelState.Clear();
}
else
if (ModelState.IsValid)
{
db.MyClasses.Add(myClass);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
var Names = new[]{
new SelectListItem{ Value="First", Text="First" },
new SelectListItem{ Value="Second", Text="Second" },
new SelectListItem{ Value="Third", Text="Third" },
};
ViewBag.Names = new SelectList(Names, "Value", "Text");
return View(myClass);
}
I changed "Create" view this way:
#using (Html.BeginForm(null, null, FormMethod.Post, new { #id = "MainForm" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MyClass</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.DropDownListFor(model => model.Name, (IEnumerable<SelectListItem>)new SelectList(ViewBag.Names, "Value", "Text", Model.Name), htmlAttributes: new { #class = "form-control", #onchange = "changeName()" })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Value, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Value, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Value, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script>
function changeName() {
var input = $("<input>")
.attr("type", "hidden")
.attr("name", "Action").val("Change name");
$('#MainForm').append($(input));
$('#MainForm').submit();
}
</script>
}
I want make this app multilingual (change culture). I added some code to Global.asax.cs for it:
protected void Application_BeginRequest(object sender, EventArgs e)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("someculture");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("someculture");
}
This app works well when I use "en" or other culture/language ("someculture" in Global.asax.cs), DropDownListFor changes the Value, controller (async Task Create) works as it should.
My browser default culture/language is English. So when I use "fr" or other culture/language I get an error in "Create" view "The field Value must be a number.".
To fix this error user can change "," to "." in "Value", but it is not the solution.
To number validation I added the scripts I use in my other apps. I added its to "Create" view scripts section:
$.validator.methods.number = function (value, element) {
return this.optional(element) ||
!isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture('#(System.Threading.Thread.CurrentThread.CurrentCulture.Name)');
});
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
var val = Globalize.parseFloat(value);
return this.optional(element) || (val >= param[0] && val <= param[1]);
}
});
But after adding this scripts DropDownListFor stopped working. Number validation is works, DropDownListFor - no.
My question is some way to do to work validation and DropDownListFor one time in one View? Or my approach is wrong and I should implement this functionality otherwise.
UPDATE
I found solution.
Added new input in view:
<input type="hidden" value="no" id="submitform" />
And modified scripts this way:
<script>
function changeName() {
var input = $("<input>")
.attr("type", "hidden")
.attr("name", "Action").val("Change name");
$('#MainForm').append($(input));
document.getElementById("submitform").value = "yes";
$('#MainForm').submit();
}
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
var val = Globalize.parseFloat(value);
return this.optional(element) || (val >= param[0] && val <= param[1]);
}
});
$.validator.methods.number = function (value, element) {
if (document.getElementById("submitform").value == "yes") {
document.getElementById("submitform").value = "no";
document.getElementById("MainForm").submit();
}
return this.optional(element) || !isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture('#(System.Threading.Thread.CurrentThread.CurrentCulture.Name)');
});
</script>

Can't post the form from modal popup if using jquery timepicker

I'm creating event calendar using daypilot lite. I'm following this tutorial to create the application in ASP.NET MVC 5.
When I clicked the calendar, for example 30/04/2015 02:00 PM - 30/04/2015 03:00 PM, the popup form will show up. In popup form, I'm using jquery datepicker and jquery timepicker on start and end field. Here is the picture & code to describe what I've done:
Index.cshtml:
#Html.DayPilotCalendar("dp", new DayPilotCalendarConfig
{
BackendUrl = Url.Action("Backend", "Calendar"),
BusinessBeginsHour = 8,
BusinessEndsHour = 19,
ViewType = ViewType.Day,
TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.JavaScript,
TimeRangeSelectedJavaScript = "create(start, end)",
EventClickHandling = EventClickHandlingType.JavaScript,
EventClickJavaScript = "edit(e)",
EventMoveHandling = EventMoveHandlingType.Notify,
EventResizeHandling = EventResizeHandlingType.Notify,
EventDeleteHandling = EventDeleteHandlingType.CallBack
})
<script type="text/javascript">
function create(start, end) {
var m = new DayPilot.Modal();
m.closed = function () {
if (this.result == "OK") {
dp.commandCallBack('refresh');
}
dp.clearSelection();
};
m.showUrl('#Url.Action("Create", "Event")?start=' + start + '&end=' + end);
}
</script>
Create.cshtml:
#model Calendar.ViewModels.CreateEventViewModel
<link href="#Url.Content("~/Content/jquery-ui.min.css")" rel="stylesheet" />
<script src="#Url.Content("~/Scripts/jquery-2.1.3.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.11.4.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
<link rel="stylesheet" type="text/css" href="#Url.Content("~/Content/jquery.timepicker.css")" />
<script src="#Url.Content("~/Scripts/jquery.timepicker.min.js")"></script>
#using (Html.BeginForm())
{
<fieldset>
<legend>Event Details:</legend>
<table>
<tr>
<td>
<label for="name">Event Name</label>
</td>
<td>
#Html.EditorFor(model => model.name, new { htmlAttributes = new { #class = "ui-widget-content ui-corner-all" } })
#Html.ValidationMessageFor(model => model.name, "", new { #class = "" })
</td>
</tr>
<tr>
<td>
<label for="startdate">Start</label>
</td>
<td>
#Html.EditorFor(model => model.startdate, new { htmlAttributes = new { #class = "ui-widget-content ui-corner-all datepicker", #readonly = "readonly" } })
#Html.EditorFor(model => model.starttime, new { htmlAttributes = new { #class = "ui-widget-content ui-corner-all timepicker" } })
#Html.ValidationMessageFor(model => model.startdate, "", new { #class = "" })
</td>
</tr>
<tr>
<td>
<label for="enddate">End</label>
</td>
<td>
#Html.EditorFor(model => model.enddate, new { htmlAttributes = new { #class = "ui-widget-content ui-corner-all datepicker", #readonly = "readonly" } })
#Html.EditorFor(model => model.endtime, new { htmlAttributes = new { #class = "ui-widget-content ui-corner-all timepicker" } })
#Html.ValidationMessageFor(model => model.enddate, "", new { #class = "" })
</td>
</tr>
</table>
</fieldset>
<br />
<div style="text-align: right">
<button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary">Save</button>
Cancel
</div>
}
<script>
$(function () {
$(".datepicker").datepicker({
dateFormat: "dd/mm/yy"
});
$(".timepicker").timepicker({
"forceRoundTime": true,
"timeFormat": "h:i A"
});
$("form").submit(function () {
var f = $("form");
if (f.valid()) {
$.post(f.action, f.serialize(), function (result) {
close(eval(result));
});
}
return false;
});
});
function close(result) {
if (parent && parent.DayPilot && parent.DayPilot.ModalStatic) {
parent.DayPilot.ModalStatic.close(result);
}
}
</script>
CreateEventViewModel.cs
public class CreateEventViewModel
{
[Required]
[StringLength(50)]
public string name { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime startdate { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
public DateTime starttime { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime enddate { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
public DateTime endtime { get; set; }
}
If I clicked Save button it always get focus to starttime textbox. I've debugged using F12 Developer Tools there is no error or post action. The problem solved if I'm not using jquery timepicker.
What am I doing wrong?
i think is the DataFormatString in your class, modify it like this:
public class CreateEventViewModel
{
[Required]
[StringLength(50)]
public string name { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime startdate { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:t}")]
public DateTime starttime { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime enddate { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:t}")]
public DateTime endtime { get; set; }
}
i just changed the {0:HH:mm} hour format to {0:t} on starttime and endtime
My guess is that there is an error inside the submit event handler:
$("form").submit(function () {
var f = $("form");
if (f.valid()) {
$.post(f.action, f.serialize(), function (result) {
close(eval(result));
});
}
return false;
});
The error prevents "return false;" from being called which means the form is posted directly instead of using the $.post() call. The browser JS console is usually cleared on POST and that's why you don't see any error.
The actual problem might be that f.serialize() doesn't serialize the value from jQuery date/time pickers properly.
Try wrapping the code with try { ... } catch (e) { ... } to see the error:
$("form").submit(function () {
try {
var f = $("form");
if (f.valid()) {
$.post(f.action, f.serialize(), function (result) {
close(eval(result));
});
}
return false;
}
catch(e) {
alert("Error while processing the form: " + e);
}
});

Categories