fill model's fields before post - asp.net-mvc

i pass a model to my view . and it's fields are hiddenfor.
and my tds are here(in this view)
how can i say when i click on button(submit-btn2) , first my java script codes execute . and then my filled model will be post ?
my Partialview :
#Html.HiddenFor(m => m.username)
#Html.HiddenFor(m => m.Tell)
#Html.HiddenFor(m => m.Name)
#Html.HiddenFor(m => m.Mobil)
#Html.HiddenFor(m => m.Lname)
<button class="btn btn-medium btn-general input-block-level" id="submit-btn2" type="submit">save</button>
//all tds are here in this page(this view)
// $(document).ready(function () {
//$('#submit-btn2').click(function () {
//$("#username").val($(".tdBuyername").val());
//$("#Tell ").val($(".tdPhone").val());
//$("#Name ").val($(".tdRecievername").val());
//$("#Mobil ").val($(".tdMobile").val());
//$("#Lname ").val($(".tdLname").val());
//});
// });
<script type="text/javascript">
$("#submit-btn2").click(function () { saveMyModel();});
function SaveMyModel()
{
var e = document.getElementById("id_purchase");
var str = e.options[e.selectedIndex].value;
var e2 = document.getElementById("id_spend");
var str2 = e.options[e.selectedIndex].value;
$.ajax({
url: '#Url.Action("Save", "Home")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
jsonMyModel: {
username: $(".tdBuyername").val(),
Tell: $(".tdPhone").val(),
Name: $(".tdRecievername").val(),
Mobil: $(".tdMobile").val(),
Lname: $(".tdLname").val(),
id_purchase: $("# id_purchase ").val(str),
id_spend: $("# id_spend ").val(str2),
}
})
});
}
Mycontroller:
[HttpGet]
public ActionResult Customer()
{
var obj = new Project.Models.ModelClasses.ViewModelX();
return PartialView(obj);
}
[HttpPost]
public JsonResult Save(ViewModelX jsonMyModel)
{
var result = true;
if (ModelState.IsValid)
{
result= MyClass.Insert (jsonMyModel.Address, jsonMyModel.Cod,
jsonMyModel.idpurchase,
jsonMyModel.idspend, jsonMyModel.Lname,
jsonMyModel.Name, jsonMyModel.Tell, jsonMyModel.username);
}
else
{
}
return Json(result, JsonRequestBehavior.AllowGet);
}
MyClass:
public class ViewModelX
{
public Nullable< long > idpurchase { get; set; }
public Nullable<long> idspend { get; set; }
public string username { get; set; }
public string Name { get; set; }
public string Lname { get; set; }
public string Tell { get; set; }
public string Address { get; set; }
public string CodPosti { get; set; }
}

Just add the following to the end of your click handler:
$('#myForm').submit();
Where myForm is the id attribute of your form.
Assuming your controller action accepts a parameter matching the class that your view is typed to, the model binder should take care of it as usual.

Are you using a strongly typed model?
What you have described can be done in two ways.
Using AJAX to post your data without page reload.
Using normal form post to post data.
Using AJAX
Having assumed that your controller method is like:
[HttpPost]
public JsonResult Save(MyModel jsonMyModel)
{
//do saving stuff
}
where , your model MyModel looks like
public class MyModel()
{
public string Username { get; set;}
public string Tell { get; set;}
public string Name { get; set;}
public string Mobile { get; set;}
public string LastName { get; set;}
}
You can create the model that your controller method accepts using normal jquery or javascript and post it using AJAX as below:
$("#submit-btn2").click(function () { saveMyModel();});
function SaveMyModel()
{
$.ajax({
url: '#Url.Action("Method", "SomeController")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
jsonMyModel: {
Username: $("#username").val(),
Tell: $("#Tell ").val(),
Name: $('#listviewlabel').val(),
Mobile: $("#Name ").val(),
LastName:$("#Lname ").val()
})
});
}
Using normal form post
You can directly google out this thing. You can even find this in your account controller.

Related

MVC Drop Down List issue : There is no Viewdata item of type 'IEnumerable<SelectListItem>' that has the key

Contoller:
public async Task<ActionResult> GetAssiginee()
{
var AssigineeList = await this.handsService.GetTeamTask();
var content = from p in AssigineeList.Data
orderby p.claimid
select new { p.claimid, p.Assiginee};
var x = content.ToList().Select(c => new List<SelectListItem>
{
new SelectListItem { Text = c.claimid, Value = c.Assiginee},
}).ToList();
ViewBag.FirstName = x;
return View();
}
Model :
public class ClaimDetails
{
public int Assigineeid { get; set; }
public List<ClaimDetails> AssigineeList { get; set; }
public int ID { get; set; }
public string claimid { get; set; }
public string contactID { get; set; }
public string Creator { get; set; }
public string Description { get; set; }
public string status { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public string ForensicDueDate { get; set; }
public string ForensicDueTime { get; set; }
public string PatientFirstName { get; set; }
public string PatientLastName { get; set; }
public string Client { get; set; }
public string ProviderName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PreScreen { get; set; }
public string Priority { get; set; }
public string Edit { get; set; }
public string Comment { get; set; }
public string Assiginee
{
get
{
return string.Format("{0} {1}", this.FirstName ?? string.Empty, this.LastName ?? string.Empty).Trim();
}
set
{
}
}
public string Patient
{
get
{
return string.Format("{0} {1}", this.PatientFirstName ?? string.Empty, this.PatientLastName ?? string.Empty).Trim();
}
}
}
}
View DropDown List:
I try for those DropDownList ,but showing Error Message
#Html.DropDownListFor(m => m.FirstName,
new SelectList(ViewBag.FirstName as IEnumerable<SelectListItem> Enumerable.Empty<SelectListItem>(), "claimid", "FirstName"),
"Select Assiginee",
new { #style = "width: 180px;height:30px;", id = "ddlAssiginee", #class = "form-control" })
#Html.DropDownList("dropdownCountry", new SelectList(string.Empty, "claimid", "FirstName"), "Select Assiginee", new { #class = "form-control", #style = "width:250px;" })
#Html.DropDownListFor(model => model.ID, ViewBag.FirstName as IEnumerable<SelectListItem>)
#Html.DropDownList("ddldepartmentlist", ViewBag.FirstName as IEnumerable<SelectListItem>)
JavsScript Function:
<script language="javascript" type="text/javascript">
$(function () {
$.ajax({
type: "GET",
url: "/TeamTaskScreen/GetAssiginee",
datatype: "Json",
success: function (data) {
$.each(data, function (index, value) {
$('#ddldepartmentlist').append('<option value="' + value.claimid + '">' + value.FirstName + '</option>');
debugger;
});
}
});
});
</script>
values are coming in Contoller but I Got Error Message in DropDownList
There is no Viewdata item of type IEnumerable<SelectListItem> that has the key
Please help any one.
ViewBag works when you set it in a GET action and try to access it in the view returned by that action method. But in your code, you are making an ajax call to get the data for the dropdown. Your ajax call's success method is expecting an array of items each with claimId and FirstName, but currently you server method is trying to return a view result!
Your view is expecting the a ViewBag item with name FirstName which has the collection of SelectListItems to render the SELECT element options. That means you need to set this ViewBag item in the GET Action method which returns this view, not in some other action method called by an ajax call.
So update your GET action to set this data.
public ActionResult Create()
{
// your existing code to load content collection here
var x = content.Select(c => new List<SelectListItem>
{
Text = c.claimid,
Value = c.Assiginee},
}).ToList();
ViewBag.FirstName = x;
return View();
}
Another option is to simply use the Ajax method. For this, you may return the data in JSON format from your GetAssiginee method.
public async Task<ActionResult> GetAssiginee()
{
var AssigineeList = await this.handsService.GetTeamTask();
var content = from p in AssigineeList.Data
orderby p.claimid
select new { p.claimid, p.Assiginee};
var x = content.Select(c => new claimid= c.claimid,
FirstName= c.Assiginee}).ToList();
return Json(x,JsonRequestBehavior.AllowGet);
}
The above code will return a json array like below
[
{ "claimid":"1","FirstName":"Some Name"},
{ "claimid":"2","FirstName":"Some Other Name"}
]
and your current js code will be able to loop through the array and append options to the select element.
Now since you are populating the data via ajax, no need to use VieBag. Simple replace
#Html.DropDownList("ddldepartmentlist", ViewBag.FirstName as IEnumerable<SelectListItem>)
with
<SELECT name="ddldepartmentlist"></SELECT>

pass a model from partial view to controller by ajax in mvc

My controller is
public ActionResult AddCustomer(Customer SM)
{
DataAccessLayer.ConClass obj = new DataAccessLayer.ConClass();
obj.SaveCustumerDetails(SM);
ModelState.Clear();
return PartialView();
}
my model is
public class Customer
{
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_id { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Contact_Person { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Contact_Person_Designation { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_name { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Address1 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Address2 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_City { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_State { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Country { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_PIN { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Phone1 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Phone2 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Email1 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Email2 { get; set; }
}
Savecutomer is the name of the button .My partaial view code is
<script>
$('#SaveCustomer').click(
function () {
$.ajax({
type: "POST",
url: '#Url.Action("AddCustomer", "Customer")',
data: ' $("myform").serialize() ,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
complete: function (data) {
},
});
});
</script>
My need is to save customer details when i click on savecustomer button I don't want to see the details on url. In this way url holds data. I need to avoid it.
The method you have shown is a GET but its parameter is Customer SM which means that the DefaultModelBinder will generate a query string for each property in your model. I'm guessing that (because this method returns a partial view) your calling it in the main view using #Html.Action() or ajax to load a form into the view.
Firstly you need to methods, one GET and one POST
public ActionResult AddCustomer()
{
// Initialize a new instance of your model and pass it to the view
Customer model = new Customer();
return PartialView(model);
}
[HttpPost]
public JsonResult AddCustomer(Customer SM)
{
DataAccessLayer.ConClass obj = new DataAccessLayer.ConClass();
obj.SaveCustumerDetails(SM);
return Json(true); // see notes below
}
Note if you have included #Html.AntiForgeryToken in the partial, then your will also need to add [ValidateAntiForgeryToken]
Next, delete the script from your partial view and add it to the main view (scripts should never be in partials). Then change the script to
$('#SaveCustomer').click(function() {
$.ajax({
type: "POST",
url: '#Url.Action("AddCustomer", "Customer")',
data: $('#myform').serialize(), // change this to include the #
dataType: 'json',
success: function (data) {
// do something?
},
});
});
Note this assumes your form has id="myform". Note also contentType has been removed (its not required unless you stringify the data). It can also be simplified to
$.post('#Url.Action("AddCustomer", "Customer")', $('#myform').serialize(), function(data) {
// do something
});
Side notes: Its not clear what you want to do in the success callback. I would suggest that in the POST method you use return Json(true); if the save was successful, otherwise return a HTTP error code. Then in the success call back you might do something like
if (data) {
// the save was successful so reset existing form controls
$('#myform').get(0).reset();
// maybe display a message indicating success
}
and similarly you could handle an error by displaying a message indicating the the customer could not be saved.
When i changed to
$('#SaveCustomer').click(
function () {
$.ajax({
type: "POST",
url: '#Url.Action("AddCustomer", "Customer")',
data: "{'Customer_Name' : '" + $('#Customer_Name').val() + "' ," +
" 'Customer_Adress1' : '" + $('#Customer_Address1').val() + "'}" ,
contentType: 'application/json; charset=utf-8',
dataType: 'json'
});
})
and change controller to
public ActionResult AddCustomer(string Customer_Name, string Customer_Address1)
{
DataAccessLayer.ConClass obj = new DataAccessLayer.ConClass();
obj.SaveCustomerDetails( Customer_Name, Customer_Address1);
ModelState.Clear();
return PartialView();
}
it worksss

can i ActionResult as [HttpGet] and JsonReult as [HttpPost]

is my JsonResult Part true?
is it possible [HttpGet] be ActionResult and [HttpPost] be JsonReult? and have diffrent names?
i think i'm wrong in my controller.it dose not work .
Mycontroller:
[HttpGet]
public ActionResult Customer()
{
var obj = new Project.Models.CentricModelClasses.ViewModelX();
return PartialView(obj);
}
[HttpPost]
public JsonResult Save(ViewModelX jsonMyModel)
{
var result = true;
if (ModelState.IsValid)
{
result= MyClass.Insert (jsonMyModel.Address, jsonMyModel.Cod,
jsonMyModel.idpurchase,
jsonMyModel.idspend, jsonMyModel.Lname,
jsonMyModel.Name, jsonMyModel.Tell, jsonMyModel.username);
}
else
{
}
return Json(result, JsonRequestBehavior.AllowGet);
my class :
public class ViewModelX
{
public Nullable< long > idpurchase { get; set; }
public Nullable<long> idspend { get; set; }
public string username { get; set; }
public string Name { get; set; }
public string Lname { get; set; }
public string Tell { get; set; }
public string Address { get; set; }
public string CodPosti { get; set; }
}
partail view :
#Html.HiddenFor(m => m.username)
#Html.HiddenFor(m => m.Tell)
#Html.HiddenFor(m => m.Name)
#Html.HiddenFor(m => m.Mobil)
#Html.HiddenFor(m => m.Lname)
#Html.HiddenFor(m => m.id_purchase)
#Html.HiddenFor(m => m.id_spend)
<script type="text/javascript">
$("#submit-btn2").click(function () { saveMyModel();});
function SaveMyModel()
{
var e = document.getElementById("id_purchase");
var str = e.options[e.selectedIndex].value;
var e2 = document.getElementById("id_spend");
var str2 = e.options[e.selectedIndex].value;
$.ajax({
url: '#Url.Action("Save", "Home")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
jsonMyModel: {
username: $(".tdBuyername").val(),
Tell: $(".tdPhone").val(),
Name: $(".tdRecievername").val(),
Mobil: $(".tdMobile").val(),
Lname: $(".tdLname").val(),
id_purchase: $("# id_purchase ").val(str),
id_spend: $("# id_spend ").val(str2),
}
})
});
}
I think your issue is the jQuery selectors you are using. This (username: $(".tdBuyername").val(), is using a class selector, so will look for any elements with a class of tdBuyername. Likely you actually want id or name.
ID - $("#tdBuyername").val()
Name - $("[name=tdBuyername]").val()
Also make sure yor JSON objects property names match the model you are trying to bind to. e.g. idpurchase won't be populated by the property id_purchase being posted back.
But, to the other question you asked, about whether your save method is correct, I would say it needs some minor improvements. Maybe like this:
[HttpPost]
public JsonResult Save(ViewModelX jsonMyModel)
{
var result = false; //default to false in case Model isn't valid
if (ModelState.IsValid)
{
result= MyClass.Insert (jsonMyModel.Address, jsonMyModel.Cod,
jsonMyModel.idpurchase,
jsonMyModel.idspend, jsonMyModel.Lname,
jsonMyModel.Name, jsonMyModel.Tell, jsonMyModel.username);
}
return Json(result);
}

View model absence in registration form

I have a partial view that contains a registration form with the following fields:
E-Mail
First Name
Last Name
Password
I am posting the form using jQuery Ajax without using View Model.
Question : Is it a good approach to not use View Model in his context ?
Question : Is my approach useless in case of unit test cases?
jQuery
$.ajax({
url: "#Url.Action("Action", "Controller", new { area = "Area" })",
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify({mail : "mails", nam : nam ......}),
traditional: true,
success: function (data) {
alert("wsaved");
}
});
[HpPost]
public Actionresult abc(string mail, string nam, sring lasnam)
{
return Json(new {succss = ru});
}
Is it a good approach to not use View Model in his context ?
No, it will make validation much harder. Suppose that you wanted to validate that the email is not empty and is indeed a valid email address. If you used a view model, all you had to do is decorate the Email property on your view model with the correct validation attributes. With your approach you will now have to write a couple of useless lines of code in your controller action for that.
Here's how your view model might look like:
public class RegisterUserViewModel
{
[Required]
[RegularExpression("PUT YOUR REGEX TO VALIDATE AN EMAIL HERE")]
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Required]
[RegularExpression("PUT YOUR REGEX TO ENFORCE SOME PASSWORD STRENGTH")]
public string Password { get; set; }
}
and now your controller action becomes:
[HttpPost]
public ActionResult Register(RegisterViewModel model)
{
if (!ModelState.IsValid)
{
// validation failed
var errors = ModelState
.Where(x => x.Value.Errors.Count > 0)
.Select(x => new
{
Key = x.Key,
Errors = x.Value.Errors.Select(e => e.ErrorMessage)
}
);
return Json(new { success = false, errors = errors });
}
return Json(new { success = true });
}
IF you are using an ApiController with MVC 4, then you can use a Model to bind to, which will use (by default) Newton Json.NET.
ResponseModel
[DataContact]
public class ResponseModel
{
[DataMember]
public string Status { get; set; }
}
ActionModel
[DataContact]
public class RegisterUserViewModel
{
[Required]
[DataMember(isRequired=true)]
public string Email { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[Required]
[DataMember(isRequired="true")]
public string Password { get; set; }
}
ApiController Action
[HttpPost]
public ReponseModel Register(RegisterActionModel actionModel)
{
if (this.ModelState == valid)
{
//do stuff
return new ResponseModel()
{
Status = "OK"
};
}
else
{
return new ResponseModel()
{
Status = "Invalid Data"
}
}
}

Strange validation problems with a Ajax/jQuery postback in ASP.NET MVC 3

I am having problems with an Ajax/jQuery postback in ASP.NET MVC 3.
If validation fails on the code below, the expected result is given and the form does not post.
If validation succeeds, the function below is not hit upon form submission and the form submits and returns a json file to the browser.
If anybody could shed some light on this, I'd appreciate it.
I've included my partial, view and controller below.
My View
#model TheLayer.EF.NoteAddPartial
#{using (Html.BeginForm("Create", "Note", new { area = "" }, FormMethod.Post, new { id = "noteAdd" }))
{
#Html.TextAreaFor(m => m.Note_Text, new { #class = "note-input" }) //note-input
#Html.ValidationMessageFor(model => model.Note_Text)
<input type="submit" value="Send" />
}}
My client side script (within the view)
<script type="text/javascript">
$(function () {
$('#noteAdd').submit(function (e) {
e.preventDefault();
if ($(this).valid()) {
alert('posting');
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
error: function (xhr, ajaxOptions, thrownError) {
alert('An error occured when processing this request:\r\n\r\n' + thrownError);
},
success: function (result) {
alert(result.s);
}
});
}
return false;
});
});
My Controller
public class NoteController : Controller
{
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult Create(NoteAddPartial model)
{
try
{
NoteMethods.CreateLeadNote(model.Note_Text, SessionManager.Current.ActiveUser.Username, model.ItemId, SessionManager.Current.ActiveUser.Company);
return Json(new { s = "Success" });
}
catch (NoPermissionException)
{
return Json(new { s = "No permission" });
}
}
}
My Partial
namespace XX
{
/// <summary>
/// Partial lead person view
/// </summary>
[MetadataType(typeof(NoteAddPartial_Validation))]
public partial class NoteAddPartial
{
public string Note_Text { get; set; }
public int? Source { get; set; }
public string Username { get; set; }
public int ItemId { get; set; }
public int TypeId { get; set; }
}
public class NoteAddPartial_Validation
{
[Required]
public string Note_Text { get; set; }
[HiddenInput(DisplayValue = false)]
public int ItemId { get; set; }
[HiddenInput(DisplayValue = false)]
public int TypeId { get; set; }
}
}
did you add client side validation libraries?
jquery.validate.min.js
jquery.validate.unobtrusive.min.js
NOTE :
If you configured you app not to work with unobtrusive validation, you
do not need to reference the second library.
Try attaching to the click event on your submit button, and changing your code from this to a selector for the parent form for the button.

Resources