In my MVC-4 application i take location from geolocation using javaScript and set latitude, longiture and accuracy in Hidden Fields. Values are set correctly in Hidden fields but during PostBack it shows null.
Here is my code :
Razor :
#using (Html.BeginForm()
{
#Html.HiddenFor(x => x.CurrentLocation.Latitude)
#Html.HiddenFor(x => x.CurrentLocation.Longitude)
#Html.HiddenFor(x => x.CurrentLocation.Accuracy)
<input type="submit" name="command" value="Start" />
}
JavaScript :
function SetLocation(position) {
console.log("{0},{1},{2}".format(position.coords.latitude, position.coords.longitude, position.coords.accuracy));
$("#CurrentLocation_Latitude").val(position.coords.latitude);
$("#CurrentLocation_Longitude").val(position.coords.longitude);
$("#CurrentLocation_Accuracy").val(position.coords.accuracy);
}
$(document).ready(function () {
$('form').submit(function () {
LocationService.getCurrentLocation(SetLocation);
});
});
But if I write this code then it`s work
$(document).ready(function () {
$('form').submit(function () {
$("#CurrentLocation_Latitude").val(100);
$("#CurrentLocation_Longitude").val(100);
});
});
This send proper value to the controller.
I don`t understand why this is happening.
Thank`s in advance.
Update 1 :
Model :
[ComplexType]
public class Location
{
public Location()
{
}
public Location(double latitude, double longiture, double? accuracy = null)
{
Latitude = latitude;
Longitude = longiture;
if (accuracy.HasValue)
Accuracy = accuracy.Value;
}
[DisplayName("Latitude : ")]
public double? Latitude { get; set; }
[DisplayName("Longitude : ")]
public double? Longitude { get; set; }
public double? Accuracy { get; set; }
}
public class ServiceInfoEditMetadata : ServiceInfo
{
public Int64 MachineId { get; set; }
[DisplayName("Client Name :")]
public string ClientName { get; set; }
[DisplayName("Site Name :")]
public string SiteName { get; set; }
public Location CurrentLocation { get; set; }
[DisplayName("Client Username :")]
public string ClientUsername { get; set; }
[DisplayName("Client Password :")]
public string ClientPassword { get; set; }
}
Controller :
public ActionResult Edit(Int64 id, ServiceInfoEditMetadata serviceInfoEditMetadata, string command)
{
try
{
switch (command)
{
case "Add":
AddMachineToServiceInfoDetails(serviceInfoEditMetadata);
return View(serviceInfoEditMetadata);
case "Start":
_serviceInfoService.StartService(serviceInfoEditMetadata, User.Identity.Name);
return RedirectToAction("Edit", serviceInfoEditMetadata.Id);
case "Update":
if (!ModelState.IsValid) return View(serviceInfoEditMetadata);
_serviceInfoService.UpdateServiceInfo(serviceInfoEditMetadata, User.Identity.Name);
return RedirectToAction("List");
}
return View(serviceInfoEditMetadata);
}
catch (Exception ex)
{
ModelState.AddModelError("ServiceInfoEditError", ex.Message);
return View(serviceInfoEditMetadata);
}
}
I assume your LocationService.getCurrentLocation is asynchronous. You should then delay form submission until it completes.
maybe you can try :
$(document).ready(function () {
var locationSet =false;
$('form').submit(function (event) {
if(!locationSet)
event.preventDefault();
LocationService.getCurrentLocation(
function(position){
SetLocation(position);
locationSet= true;
$('form').submit();
}
);
});
});
There could be more causes, because the mechanism (e.g mvc binding, ajax) of passing the fields' data is little complex.
I see that in the following js code you're passing handler to function 'SetLocation'. Try to invoke the function:
$(document).ready(function () {
$('form').submit(function () {
LocationService.getCurrentLocation(SetLocation(position));// 'SetLocation' with (position)
});
});
Related
I get each value but it doesn't display on DSChiTiet. How can I fix it? It only gets value TenKH, NgayLap, TongTien.
DSChiTiet doesn't get value from table and displays null. enter image description here
Thank you very much for your help <3.
My model PhieuBanHangModel
public class PhieuBanHangViewModel
{
public int MaPBH { get; set; }
public string TenKH { get; set; }
public DateTime NgayLap { get; set; }
public decimal TongTien { get; set; }
public IEnumerable<CT_PhieuBanHangViewModel> DSChiTiet { get; set; }
}
My model CT_PhieuBanHangModel
public class CT_PhieuBanHangViewModel
{
public int MaPBH { get; set; }
public int MaSP { get; set; }
public int SoLuong { get; set; }
public decimal DonGia { get; set; }
public decimal ThanhTien { get; set; }
}
Controller Create Json
[HttpPost]
public JsonResult Create(PhieuBanHangViewModel phieuBanHang)
{
return Json(data: "", JsonRequestBehavior.AllowGet);
}
Function in View
function ThanhToan() {
var phieuBanHang = {};
var dsct_PhieuBanHang = new Array();
phieuBanHang.TenKH = $("#txtTenKH").val();
phieuBanHang.NgayLap = $("#txtNgayGiaoDich").val();
phieuBanHang.TongTien = $("#txtTongTien").val();
$("table tr:not(:first)").each(function () {
var ct_PhieuBanHang = {};
ct_PhieuBanHang.MaSP = parseFloat($(this).find("td:eq(0))").text());
ct_PhieuBanHang.SoLuong = parseFloat($(this).find("td:eq(4))").text());
ct_PhieuBanHang.DonGia = parseFloat($(this).find("td:eq(6))").text());
ct_PhieuBanHang.ThanhTien = parseFloat($(this).find("td:eq(7))").text());
dsct_PhieuBanHang.push(ct_PhieuBanHang);
});
phieuBanHang.DSChiTiet = dsct_PhieuBanHang;
$.ajax({
async: true,
type: 'POST',
dataType: 'JSON',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(phieuBanHang),
url: '/Manager/CT_PhieuBanHang/Create',
success: function (data) {
},
error: function () {
alert('Lỗi');
}
});
}
You may need to inherit ApiControllerand add the [FromBody] attribute to the binding model:
public class MyController : ApiController
{
/* something else... */
// /Manager/CT_PhieuBanHang/Create
[HttpPost]
public JsonResult Create([FromBody] PhieuBanHangViewModel phieuBanHang)
{
return Json(data: "", JsonRequestBehavior.AllowGet);
}
/* something else... */
}
For your jQuery code, make sure thet:$("table tr:not(:first)") do returns an array contains at least 1 item. (You can verify that by doing a console.log(phieuBanHang) to print out your data).
I have a form with an input that collects a dollar amount (ex: $5,000)
How can I allow an input of $5,000 to not trigger (!ModelState.IsValid) remove comma (,) and $ for POSTing?
ViewModel
public class FormViewModel
{
[Required, RegularExpression("[0-9,]")]
public int? Amount { get; set; }
}
View
<form>
<input asp-for="Amount" />
<span asp-validation-for="Amount"></span>
<button type="submit">Submit</button>
</form>
Controller
[HttpPost]
public IActionResult PostForm(FormViewModel viewModel)
{
if (!ModelState.IsValid)
{
return View(viewModel)
}
else
{
//Post Form
}
}
I'd change the View Model to accept a string instead of int? for the Amount property:
public class FormViewModel {
public string Amount { get; set; }
public int? Value {
get {
int result = 0;
if (Int32.TryParse(Amount, NumberStyles.Currency, CultureInfo.CurrentCulture, result) {
return result;
}
return null;
}
}
}
Now user input is stored in the Amount property, while parsed integer value is stored in Value property.
Have you tried the IModelBinder?
public class DecimalModelBinder: System.Web.Mvc.IModelBinder
{
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
if (valueResult.AttemptedValue != string.Empty)
{
try
{
string attemptedVal = valueResult.AttemptedValue?.Replace(",", ".").Replace("$", "");
actualValue = Convert.ToDecimal(attemptedVal, new CultureInfo("en-US"));
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
Itsnot the same but a similar answer to: error with decimal in mvc3 - the value is not valid for field
Update the model to use data type annotations.
public class FormViewModel {
[DataType(DataType.Currency)]
[Required]
public int? Amount { get; set; }
}
If you want to include cents then change property to decimal
public class FormViewModel {
[DataType(DataType.Currency)]
[Required]
public decimal? Amount { get; set; }
}
I ended up using AutoMapper to map the the properties back and forth.
I changed my ViewModel to a String and then used automapper like below:
//Map From Int To String
CreateMap<Models.ServiceModel, FormViewModel>().ForMember(dest => dest.Amount, opt => opt.MapFrom(src => src.Amount.ToString()));
//Map From String Back To Int
CreateMap<FormViewModel, Models.ServiceModel>().ForMember(dest => dest.Amount, opt => opt.MapFrom(src => int.Parse(src.Amount.Replace(",", ""))));
I have a Controller, View, and Model for an application I am taking over from someone else. The problem I'm having is that when the javascript submits the form, my model object in the Edit function of the Controller is not being filled with the values from the View, all fields are either null or 0. How can I get the object to be properly filled?
I have tried looking at Firebug, but I can't see anything that would indicate a problem. The string parameter id is correctly being passed in the URL, ex: firsttry.com/admin/distribution/edit/sanfran, where sanfran is the id string. Firebug is confirming that the javascript is correctly loaded when it would be called.
#section scripts
{
#Scripts.Render("~/bundles/qmmodules/admin/distribution")
}
DistributionController.cs
namespace JRI.QM.WebUI.Areas.Admin.Controllers
{
public class DistributionController : BaseAdminController
{
[HttpPost]
public ActionResult Edit(string id, DistributionViewModel model)
{
}
}
}
DistributionViewModel.cs
namespace JRI.QM.WebUI.Areas.Admin.Models.ViewModels
{
public class DistributionViewModel
{
public string name;
public string ipAddress;
public string description;
public Byte eyeDee;
public string destinationPath;
public List<JRI.DMP.BLL.Filter> filters;
}
}
Edit.cshtml
#model JRI.QM.WebUI.Areas.Admin.Models.ViewModels.DistributionViewModel
#{
ViewBag.Title = "Edit";
}
#using (Html.BeginForm("Edit", "Distribution", FormMethod.Post, new { id = "editRoleForm" }))
{
<div class="dialog" id="editRoleDialog">
#Html.TextBoxFor(x => x.name)
#Html.HiddenFor(x => x.ipAddress)
#Html.TextBoxFor(x => x.description)
#Html.HiddenFor(x => x.eyeDee)
#Html.HiddenFor(x => x.destinationPath)
#Html.HiddenFor(x => x.filters)
<div id="permissionsDialogFooter" class="dialogFooter newUser_dialogFooter">
<div class="qm_mediumButton submitButton">save</div>
<div class="qm_mediumButton cancelButton">cancel</div>
<br class="clearfloat" />
</div>
</div>
}
distribution.js
QM.ui.Role = (function ($) {
var _xhrInProgress = false;
function init() {
_bindEvents();
}
// private functions
function _bindEvents() {
var addEditRoleEvents = function (formObj) {
formObj.submit(function () {
var $this = $(this);
if ($this.valid()) {
$.post($this.attr("action"), $this.serialize(), function (response) {
if (response.Success) {
if (response.RedirectUrl) {
window.location.href = response.RedirectUrl;
}
}
});
}
return false;
});
formObj.find(".submitButton").click(function () {
formObj.submit();
});
};
// Edit role dialog
$(".dt-edit a").click(function () {
var $this = $(this);
$.get($this.attr("href"), function (data) {
$(".content").after(data);
QM.ui.Mask.show();
addEditRoleEvents($("#editRoleForm"));
});
return false;
});
}
return {
init: init,
};
})(jQuery);
$(document).ready(QM.ui.Role.init);
in RouteConfig.cs
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "JRI.QM.WebUI.Controllers" }
);
The default model binder of ASP.NET MVC, only work with properties. Your model class doesn't have any property, it does have fields.
To fix that use properties instead field in your model class, like below
public class DistributionViewModel
{
public string name { get; set; }
public string ipAddress { get; set; }
public string description { get; set; }
public Byte eyeDee { get; set; }
public string destinationPath { get; set; }
public List<JRI.DMP.BLL.Filter> filters { get; set; }
}
Also I suggest you to follow the C# code convetions, it says that you should use PascalCase for properties, you can see more details here https://msdn.microsoft.com/en-us/library/ms229043(v=vs.110).aspx
Following the convetion, your class should be like that
public class DistributionViewModel
{
public string Name { get; set; }
public string IpAddress { get; set; }
public string Description { get; set; }
public Byte EyeDee { get; set; }
public string DestinationPath { get; set; }
public List<JRI.DMP.BLL.Filter> Filters { get; set; }
}
I'm new to this and got stuck between these codes without getting inserted. Can anybody pls tell me the issue in my post method.
jquery
$.post("Create", { REG_NO : $("#text1").val(), REG_DATE : $("#text2").val() }, function (data) {
alert("done");
});
CarsController (controller file)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,REG_NO,REG_DATE")] Car car)
{
if (ModelState.IsValid)
{
db.Cars.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(car);
}
}
class file
public class Car
{
public int ID { get; set; }
public string REG_NO { get; set; }
public DateTime REG_DATE { get; set; }
}
$.post(
'/controller/action',
{ field_a: "Value a", field_b: "Value b" },
function(data) {
$('#result').html(data);
}
);
I am working with Dual ListBoxes and using two buttons to move data from one listbox to another..
Here following code I have done to move data from one Listbox to another
InstituteInformation.cs
public class InstituteInformation
{
public int Id { get; set; }
public string InstituteName { get; set; }
}
MemberAccessRights.cs
public class MemberAccessRights
{
public int Id { get; set; }
public List<InstituteInformation> AvailableNames { get; set; }
public int[] AvailableSelected { get; set; }
public List<InstituteInformation> RequestedNames { get; set; }
public string[] RequestedSelected { get; set; }
public string SavedRequested { get; set; }
}
//Controller
//
// GET: /MemberDetails/Create
public ActionResult Create()
{
Wrapper1 MD = new Wrapper1();
MD.MAR = new MemberAccessRights{ AvailableNames = getAllInstituteNameList(), RequestedNames = new List<InstituteInformation>() };
return View(MD);
}
//
// POST: /MemberDetails/Create
[HttpPost]
public ActionResult Create(Wrapper1 MD, string add, string remove)
{
try
{
ModelState.Clear();
RestoreSavedState(MD);
if (!string.IsNullOrEmpty(add))
AddNames(MD);
elseif (!string.IsNullOrEmpty(remove))
AddNames(MD);
SaveState(MD);
using (varMDConext = new WrapperDB())
{
MDConext.MBIDBS.Add(MD.MBI);
MDConext.MACDBS.Add(MD.MAC);
MDConext.MARDBS.Add(MD.MAR);
MDConext.MODBS.Add(MD.MO);
}
returnRedirectToAction("Index");
}
catch
{
return View(MD);
}
}
#regionSupportFuncs
void SaveState(Wrapper1 MD)
{
MD.MAR.SavedRequested = string.Join(",", MD.MAR.RequestedNames.Select(p =>p.Id.ToString()).ToArray());
////Available Names = All - Requested
MD.MAR.AvailableNames = getAllInstituteNameList().Except(MD.MAR.RequestedNames).ToList();
}
//RestoreSavedState
void RestoreSavedState(Wrapper1 MD)
{
MD.MAR.RequestedNames = newList<InstituteInformation>();
if (!string.IsNullOrEmpty(MD.MAR.SavedRequested))
{
string[] nameids = MD.MAR.SavedRequested.Split(',');
var name = getAllInstituteNameList().Where(p =>nameids.Contains(p.Id.ToString()));
MD.MAR.RequestedNames.AddRange(name);
}
}
//AddNames
void AddNames(Wrapper1 MD)
{
if (MD.MAR.AvailableSelected != null)
{
var names = getAllInstituteNameList().Where(p =>MD.MAR.AvailableSelected.Contains(p.Id));
MD.MAR.RequestedNames.AddRange(names);
MD.MAR.AvailableSelected = null;
}
}
//RemoveNames
void RemoveNames(Wrapper1 MD)
{
if (MD.MAR.RequestedSelected != null)
{
MD.MAR.RequestedNames.RemoveAll(p =>MD.MAR.RequestedSelected.Contains(p.Id.ToString()));
MD.MAR.RequestedSelected = null;
}
}
#endregion
View
List of Financial Institute
<%:Html.ListBoxFor(model=>model.MAR.AvailableSelected,new MultiSelectList(Model.MAR.AvailableNames,"Id","InstituteName",Model.MAR.AvailableSelected)) %>
<div>
<input id="add" name="add" type="submit" value=">>" />
<br />
<input id="remove" name="remove" type="submit" value="<<" />
</div>
<%:Html.ListBoxFor(m=>m.MAR.RequestedSelected,new MultiSelectList(Model.MAR.RequestedNames,"Id","Name",Model.MAR.RequestedSelected)) %>
But there is the problem is that when I click on add(>>) or remove(<<) button the action is performed on the complete page just like the submit button which save the data from that page to db. Here I wanted to know how to perform the action button after clicking the add(>>) or remove(<<) button.
please help to solve this
The idea was that a form could contain more than one submit button issuing a form post to a different way.