Asp.net Modal Edit Partial View Not Keeping Dropdownlist Value - ajax

When the modal pops open the values that were originally selected for the drop down list have been changed to the first item on the list. How do I keep the values that were originally selected?
Controller:
public ActionResult AddEditExam(int exam_id)
{
exam exam = new exam();
ViewBag.credential_id = new SelectList(db.credentials, "credential_id", "credential_code", exam.credential_id);
ViewBag.credential_status_id = new SelectList(db.credential_status, "credentials_status_id", "credentials_status_description", exam.credential_status_id);
if (exam_id > 0)
{
exam ex = db.exams.SingleOrDefault(x => x.exam_id == exam_id);
exam.exam_id = ex.exam_id;
exam.credential_id = ex.credential_id;
exam.credential_status = ex.credential_status;
exam.exam_desc = ex.exam_desc;
exam.exam_last_update = ex.exam_last_update;
exam.exam_passing_score = ex.exam_passing_score;
exam.exam_time = ex.exam_time;
}
return PartialView("AddEdit", exam);
}
Partial View: Slimmed down to drop down list
#Html.LabelFor(model => model.credential_id, "credential_id", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList("credential_id", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.credential_id, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.credential_status_id, "credential_status_id", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList("credential_status_id", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.credential_status_id, "", new { #class = "text-danger" })
<script>
$(document).ready(function () {
$("#btnSubmit1").click(function () {
$("#loaderDiv").show();
var myModelBody1 = $("#myForm").serialize();
if (!$("#myForm").valid()) {
return false;
}
$.ajax({
type: "POST",
url: "#Url.Action("index", "exams")",
data: myModelBody1,
success: function () {
$("#loaderDiv").hide();
$('#myModalAddEdit').modal('hide');
window.location.href = "#Url.Action("index", "exams")";
}
});
});
});
Original View: Modal
<div class="modal fade" id="myModalAddEdit">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title"><strong style="color:#ff9c21">EDIT </strong> Exam</h3>
</div>
<div class="modal-body" id="myModelBody1">
</div>
<div class="modal-footer">
Update
Close
</div>
</div>
</div>
Original View: Modal Script
var AddEditExam = function (exam_id) {
var exam_id = exam_id;
var url = '#Url.Action("AddEditExam", "exams")?exam_id=' + exam_id;
//var url = "http://localhost/NAHP/exams/AddEditExam?exam_id="+exam_id;
$("#myModelBody1").load(url,
function() {
$("#myModalAddEdit").modal('show');
});
}

Related

Multi Select Values Not Saving on User Create

I am trying to save a multi select list on my user create in MVC 5, but the values are not saving. Values are saving only in edit. For some reason it's not working on create and it seems the issue is tied to the identity user. I have the same method implemented in a different controller for another entity and it's working fine.
I am trying to assign multiple health professionals to a user in the below code. I am not getting any errors or a break on save, it just doesn't save the values.
Can anyone please have a look at my code and give me a solution to this problem.
Here is my controller code relevant to creating a user:
public ActionResult Create()
{
PopulateDepartmentsDropDownList();
PopulateSuperiorsDropDownList();
// Show a list of available groups:
ViewBag.GroupsList = new SelectList(this.GroupManager.Groups, "Id", "Name");
var applicationUser = new ApplicationUser();
applicationUser.HealthProfessionals = new List<HealthProfessional>();
PopulateAssignedHealthProfessionals(applicationUser);
return View();
}
[HttpPost]
public async Task<ActionResult> Create([Bind(Exclude = "ProfilePicture")]RegisterViewModel userViewModel, ApplicationUser applicationUser, string[] selectedHealthProfessionals, params string[] selectedGroups)
{
if (selectedHealthProfessionals != null)
{
applicationUser.HealthProfessionals = new List<HealthProfessional>();
foreach (var healthProfessional in selectedHealthProfessionals)
{
var healthProfessionalToAdd = db.HealthProfessionals.Find(int.Parse(healthProfessional));
applicationUser.HealthProfessionals.Add(healthProfessionalToAdd);
}
}
if (ModelState.IsValid)
{
// To convert the user uploaded Photo as Byte Array before save to DB
byte[] imageData = null;
if (Request.Files.Count > 0)
{
HttpPostedFileBase poImgFile = Request.Files["UserPhoto"];
using (var binary = new BinaryReader(poImgFile.InputStream))
{
imageData = binary.ReadBytes(poImgFile.ContentLength);
}
}
var user = new ApplicationUser
{
UserName = userViewModel.Email,
FirstName = userViewModel.FirstName,
LastName = userViewModel.LastName,
Position = userViewModel.Position,
DepartmentID = userViewModel.DepartmentID,
SuperiorID = userViewModel.SuperiorID,
OfficeNumber = userViewModel.OfficeNumber,
CellNumber = userViewModel.CellNumber,
Email = userViewModel.Email
};
//Here we pass the byte array to user context to store in db
user.ProfilePicture = imageData;
var adminresult = await UserManager
.CreateAsync(user, userViewModel.Password);
//Add User to the selected Groups
if (adminresult.Succeeded)
{
if (selectedGroups != null)
{
selectedGroups = selectedGroups ?? new string[] { };
await this.GroupManager
.SetUserGroupsAsync(user.Id, selectedGroups);
}
return RedirectToAction("Users");
}
}
ViewBag.Groups = new SelectList(await RoleManager.Roles.ToListAsync(), "Id", "Name");
PopulateDepartmentsDropDownList(userViewModel.DepartmentID);
PopulateSuperiorsDropDownList(userViewModel.SuperiorID);
PopulateAssignedHealthProfessionals(applicationUser);
return View(applicationUser);
}
private void PopulateAssignedHealthProfessionals(ApplicationUser applicationUser)
{
var allHealthProfessionals = db.HealthProfessionals;
var userHealthProfessionals = new HashSet<int>(applicationUser.HealthProfessionals.Select(i => i.HealthProfessionalID));
var viewModel = new List<AssignedHealthProfessionals>();
foreach (var healthProfessional in allHealthProfessionals)
{
viewModel.Add(new AssignedHealthProfessionals
{
HealthProfessionalID = healthProfessional.HealthProfessionalID,
HealthProfessionalName = healthProfessional.Name,
HealthProfessionalSurname = healthProfessional.Surname,
Assigned = userHealthProfessionals.Contains(healthProfessional.HealthProfessionalID)
});
}
ViewBag.HealthProfessionals = viewModel;
}
Here is my create view:
#model MyApp.Models.RegisterViewModel
#{
ViewBag.Title = "Create User";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="#Url.Content("~/Content/CSS/dropify.min.css")" rel="stylesheet" type="text/css" />
<div class="m-grid__item m-grid__item--fluid m-wrapper">
<div class="m-subheader ">
<div class="d-flex align-items-center">
<div class="mr-auto">
<h3 class="m-subheader__title m-subheader__title--separator">
Add User
</h3>
<ul class="m-subheader__breadcrumbs m-nav m-nav--inline">
<li class="m-nav__item m-nav__item--home">
<a href="#Url.Action("Dashboard","Home")" class="m-nav__link m-nav__link--icon">
<i class="m-nav__link-icon la la-home"></i>
</a>
</li>
<li class="m-nav__separator">
-
</li>
<li class="m-nav__item">
<a href="#Url.Action("Users","UserManagement")" class="m-nav__link">
<span class="m-nav__link-text">
Users
</span>
</a>
</li>
</ul>
</div>
<div>
</div>
</div>
</div>
#using (Html.BeginForm("Create", "UserManagement", FormMethod.Post, new { #class = "m-form m-form--fit m-form--label-align-right", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="m-content">
<div class="m-portlet m-portlet--mobile">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
User Details
</h3>
</div>
</div>
</div>
<div class="m-portlet__body">
<div class="m-form__section m-form__section--first">
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label>
Email Address
</label>
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
First Name
</label>
#Html.TextBoxFor(m => m.FirstName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
Last Name
</label>
#Html.TextBoxFor(m => m.LastName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.LastName, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label>
Position
</label>
#Html.TextBoxFor(m => m.Position, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Position, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
Department
</label>
#Html.DropDownList("DepartmentID", null, "Choose Department", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.DepartmentID, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
Superior
</label>
#Html.DropDownList("SuperiorID", null, "Choose Superior", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SuperiorID, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label>
Password
</label>
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>
Confirm Password
</label>
#Html.PasswordFor(m => m.ConfirmPassword, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.ConfirmPassword, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label>
Office Number
</label>
#Html.TextBoxFor(m => m.OfficeNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.OfficeNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>
Cell Number
</label>
#Html.TextBoxFor(m => m.CellNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.CellNumber, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label>
User Groups
</label>
<div class="m-checkbox-list">
#foreach (var item in (SelectList)ViewBag.GroupsList)
{
<label class="m-checkbox m-checkbox--success">
<input type="checkbox" name="selectedGroups" value="#item.Value">
#Html.Label(item.Text, new { #class = "control-label" })
<span></span>
</label>
}
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>
Health Professionals
</label>
<div class="m-checkbox-list">
#{
int cnt = 0;
List<MyApp.ViewModels.AssignedHealthProfessionals> healthProfessionals = ViewBag.HealthProfessionals;
foreach (var healthProfessional in healthProfessionals)
{
if (cnt++ % 3 == 0)
{
}
<label class="m-checkbox m-checkbox--success">
<input type="checkbox" name="selectedHealthProfessionals" value="#healthProfessional.HealthProfessionalID" #(Html.Raw(healthProfessional.Assigned ? "checked=\"checked\"" : ""))>
#Html.Label(healthProfessional.HealthProfessionalName, new { #class = "control-label" }) #Html.Label(healthProfessional.HealthProfessionalSurname, new { #class = "control-label" })
<span></span>
</label>
}
}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label>
Profile Picture
</label>
<input type="file" name="UserPhoto" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" class="dropify" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="m-portlet__body">
<!-- Form Actions Start -->
<div class="m-portlet">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
Actions
</h3>
</div>
</div>
</div>
<div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions">
<input type="submit" class="btn btn-accent m-btn m-btn--custom m-btn--icon m-btn--air m-btn--pill" value="Save" />
#Html.ActionLink("Cancel", "Users", null, new { #class = "btn m-btn--pill m-btn--air btn-brand m-btn m-btn--custom" })
</div>
</div>
</div>
<!-- Form Actions End -->
</div>
</div>
}
</div>
<script src="#Url.Content("~/Scripts/jquery.min.js")"></script>
<script src="#Url.Content("~/Scripts/dropify.min.js")"></script>
<script>
$(document).ready(function () {
// Basic
$('.dropify').dropify();
// Translated
$('.dropify-fr').dropify({
messages: {
default: 'Glissez-déposez un fichier ici ou cliquez',
replace: 'Glissez-déposez un fichier ou cliquez pour remplacer',
remove: 'Supprimer',
error: 'Désolé, le fichier trop volumineux'
}
});
// Used events
var drEvent = $('#input-file-events').dropify();
drEvent.on('dropify.beforeClear', function (event, element) {
return confirm("Do you really want to delete \"" + element.file.name + "\" ?");
});
drEvent.on('dropify.afterClear', function (event, element) {
alert('File deleted');
});
drEvent.on('dropify.errors', function (event, element) {
console.log('Has Errors');
});
var drDestroy = $('#input-file-to-destroy').dropify();
drDestroy = drDestroy.data('dropify')
$('#toggleDropify').on('click', function (e) {
e.preventDefault();
if (drDestroy.isDropified()) {
drDestroy.destroy();
} else {
drDestroy.init();
}
})
});
</script>
Here is the controller for the edit function which works:
public async Task<ActionResult> Edit(int id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ApplicationUser applicationUser = db.Users.Include(h => h.HealthProfessionals).Where(h => h.Id == id).Single();
PopulateAssignedHealthProfessionals(applicationUser);
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
// Display a list of available Groups:
var allGroups = this.GroupManager.Groups;
var userGroups = await this.GroupManager.GetUserGroupsAsync(id);
var model = new EditUserViewModel()
{
Id = user.Id,
Email = user.Email,
FirstName = user.FirstName,
LastName = user.LastName,
Position = user.Position,
DepartmentID = user.DepartmentID,
SuperiorID = user.SuperiorID,
OfficeNumber = user.OfficeNumber,
CellNumber = user.CellNumber
};
foreach (var group in allGroups)
{
var listItem = new SelectListItem()
{
Text = group.Name,
Value = group.Id,
Selected = userGroups.Any(g => g.Id == group.Id)
};
model.GroupsList.Add(listItem);
}
PopulateDepartmentsDropDownList(user.DepartmentID);
PopulateSuperiorsDropDownList(user.SuperiorID);
return View(model);
}
private void PopulateAssignedHealthProfessionals(ApplicationUser applicationUser)
{
var allHealthProfessionals = db.HealthProfessionals;
var userHealthProfessionals = new HashSet<int>(applicationUser.HealthProfessionals.Select(i => i.HealthProfessionalID));
var viewModel = new List<AssignedHealthProfessionals>();
foreach (var healthProfessional in allHealthProfessionals)
{
viewModel.Add(new AssignedHealthProfessionals
{
HealthProfessionalID = healthProfessional.HealthProfessionalID,
HealthProfessionalName = healthProfessional.Name,
HealthProfessionalSurname = healthProfessional.Surname,
Assigned = userHealthProfessionals.Contains(healthProfessional.HealthProfessionalID)
});
}
ViewBag.HealthProfessionals = viewModel;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Email,Id,FirstName,LastName,Position,DepartmentID,SuperiorID,OfficeNumber,CellNumber", Exclude = "ProfilePicture")] EditUserViewModel editUser, ApplicationUser applicationUser, int? id, string[] selectedHealthProfessionals, params string[] selectedGroups)
{
if (ModelState.IsValid)
{
// To convert the user uploaded Photo as Byte Array before save to DB
byte[] imageData = null;
if (Request.Files.Count > 0)
{
HttpPostedFileBase poImgFile = Request.Files["UserPhoto"];
using (var binary = new BinaryReader(poImgFile.InputStream))
{
imageData = binary.ReadBytes(poImgFile.ContentLength);
}
}
var user = await UserManager.FindByIdAsync(editUser.Id);
if (user == null)
{
return HttpNotFound();
}
var applicationUserToUpdate = db.Users.Include(h => h.HealthProfessionals).Where(h => h.Id == id).Single();
if (TryUpdateModel(applicationUserToUpdate, "",
new string[] { }))
{
try
{
UpdateUserHealthProfessionals(selectedHealthProfessionals, applicationUserToUpdate);
db.SaveChanges();
return RedirectToAction("Users");
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
PopulateAssignedHealthProfessionals(applicationUserToUpdate);
// Update the User:
user.UserName = editUser.Email;
user.Email = editUser.Email;
user.FirstName = editUser.FirstName;
user.LastName = editUser.LastName;
user.Position = editUser.Position;
user.DepartmentID = editUser.DepartmentID;
user.SuperiorID = editUser.SuperiorID;
user.OfficeNumber = editUser.OfficeNumber;
user.CellNumber = editUser.CellNumber;
//Here we pass the byte array to user context to store in db
user.ProfilePicture = imageData;
await this.UserManager.UpdateAsync(user);
// Update the Groups:
selectedGroups = selectedGroups ?? new string[] { };
await this.GroupManager.SetUserGroupsAsync(user.Id, selectedGroups);
return RedirectToAction("Users");
}
ModelState.AddModelError("", "Something failed.");
PopulateDepartmentsDropDownList(editUser.DepartmentID);
PopulateSuperiorsDropDownList(editUser.SuperiorID);
return View();
}
It's something strange with parameters in your methods.
Best way is to pass user object as parameter.
https://stackoverflow.com/a/18005264/2114398
For quick fix you can update multi-select parameter manually, by removing selectedHealthProfessionals and selectedGroups parameters from method and then initialize them as local variables
[HttpPost]
public async Task<ActionResult> Create([Bind(Exclude = "ProfilePicture")]RegisterViewModel userViewModel, ApplicationUser applicationUser)
{
var selectedGroups = (Request.Form["selectedGroups"] ?? "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
var selectedHealthProfessionals = (Request.Form["selectedHealthProfessionals"] ?? "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
applicationUser.HealthProfessionals = new List<HealthProfessional>();
foreach (var healthProfessional in selectedHealthProfessionals)
{
var healthProfessionalToAdd = db.HealthProfessionals.Find(int.Parse(healthProfessional));
applicationUser.HealthProfessionals.Add(healthProfessionalToAdd);
}
if (ModelState.IsValid)
{
...

Partial View not printing values in mvc 5

I'm using ajax call to execute partial view controller action to print max batch number. Everything executes, but the value doesn't print in partial view. On selected dropdown list I'm calling ajax method to execute. Below is my code that i'm using.
Models.Batch.cs
[Required]
[StringLength(100)]
[DataType(DataType.Text)]
[Display(Name = "Batch Number")]
public string BatchNumber { get; set; }
BatchController.cs
public PartialViewResult GetBatchNumber(string CourseID)
{
Context.Batches contBatch = new Context.Batches();
Models.Batches b = new Models.Batches();
b.BatchNumber = contBatch.GetallBatchList().ToList().Where(p => p.CourseId == CourseID).Select(p => p.BatchNumber).Max().FirstOrDefault().ToString();
ViewBag.Message = b.BatchNumber;
return PartialView(b);
}
CreateBatch.cshtml
<div class="col-md-10">
#Html.DropDownListFor(m => m.CourseId, Model.Courses, new { id = "ddlCourse" })
<div id="partialDiv">
#{
Html.RenderPartial("GetBatchNumber", Model);
}
</div>
<script>
$("#ddlCourse").on('change', function () {
var selValue = $('#ddlCourse').val();
$.ajax({
type: "GET",
url: '/Batch/GetBatchNumber?CourseId=' + selValue,
dataType: "json",
data: "",
success: function (data) {
$("#partialDiv").html(data);
},
failure: function (data) {
alert('oops something went wrong');
}
});
});
</script>
</div>
GetBatchNumber.cshtml
#model WebApplication1.Models.Batches
<div class="form-group">
#Html.LabelFor(model => model.BatchNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.BatchNumber)
#Html.ValidationMessageFor(model => model.BatchNumber, "", new { #class = "text-danger" })
</div>
</div>

populating textboxes based on selection of kendo combo box

I need to populate two textbox controls based on a selection of combo box in my MVC 5 application. The combo box is a kendo MVC control. The values that need to be assigned to the text box controls are there in the collection that is bound to the combo box control. Could somebody let me know how to go about it. Does this need to be handled in javascript/ jquery or is it handled in kendo combo box events. An example would be great.
Combo box
#Html.LabelFor(model => model.Name1, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-4">
<div class="editor-field">
#(Html.Kendo().ComboBoxFor(model => model.Name1)
.HtmlAttributes(new { style = "width:300px" })
.DataTextField("Name1")
.DataValueField("CustomerMasterDataId")
.DataSource(dataSource => dataSource
.Read(read => read.Action("RequestHeader_CustomerData", "Request").Type(HttpVerbs.Post))
)
)
</div>
#Html.ValidationMessageFor(model => model.CustomerNumber, "", new { #class = "text-danger" })
</div>
Textbox
<div class="form-group">
#Html.LabelFor(model => model.CustomerNumber, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
<div class="editor-field">
#Html.EditorFor(model => model.CustomerNumber, new { htmlAttributes = new { #class = "form-control" } })
</div>
#Html.ValidationMessageFor(model => model.CustomerNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="clearfix"></div>
<div class="form-group">
#Html.LabelFor(model => model.CustomerGroup, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
<div class="editor-field">
#Html.EditorFor(model => model.CustomerGroup, new { htmlAttributes = new { #class = "form-control" } })
</div>
#Html.ValidationMessageFor(model => model.CustomerGroup, "", new { #class = "text-danger" })
</div>
</div>
Controller method that poulates the combo
public ActionResult RequestHeader_CustomerData()
{
var response = requestRepository.GetCustomerData().AsQueryable().ProjectTo<CustomerViewModel>();
var jsonResult = Json(response, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
Please note that the CustomerNumber and Name1 field would be used to populate the text boxes
ViewModel
public class CustomerViewModel
{
public int CustomerMasterDataId { get; set; }
public int CustomerNumber { get; set; }
[Display(Name = "Customer Name")]
public string Name1 { get; set; }
[Display(Name = "Customer Group")]
public string CustomerGroup { get; set; }
}
Yes, handle the change event:
#(Html.Kendo().ComboBoxFor(model => model.Name1)
.HtmlAttributes(new { style = "width:300px" })
.DataTextField("Name1")
.DataValueField("CustomerMasterDataId")
.DataSource(dataSource => dataSource
.Events(e => e.Change(onComboChange))
.Read(read => read.Action("RequestHeader_CustomerData", "Request").Type(HttpVerbs.Post))
)
)
Now handle it in js:
#section scripts
{
<script type="text/javascript">
function onComboChange(e) {
var dataItem = e.sender.dataItem();
if (dataItem) {
//set the value of text box (input)
$("#CustomerNumber").val(dataItem.CustomerNumber);
$("#CustomerGroup").val(dataItem.CustomerGroup);
};
};
</script>
}
Here is a js equivalent: http://jsfiddle.net/sg53719/74LwhebL/1/

how to save items of cascading drop down list in database with asp.net mvc

My Drop-Downs works well the problem is when I want to save my form.
here is my controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,TourId,StartDate,EndDate")] TourDate tourDate)
{
if (ModelState.IsValid)
{
db.TourDates.Add(tourDate);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
ViewBag.TourId = new SelectList(db.Tours, "Id", "TourName", tourDate.TourId);
return RedirectToAction("Index", "test");
}
[HttpPost]
public JsonResult GetT(int? id)
{
var tours = db.Tours.Where(e => e.CountryId == id).ToList()
.Select(e => new
{
Id = e.Id,
TourName= e.TourName
}).ToList();
return Json(tours);
}
and here is My form. in this From, selecttag with id=TourId is filling with data in ajax from the outer drop down dropdownId and it works fine
#Html.DropDownList("dropdownId",
Model.Countries.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.CountryName
}),
new { #class = "form-control" })
#using (Html.BeginForm("Create", "test"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TourDate</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TourDate.TourId, "TourId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<select class="form-control" id="TourId"></select>
#Html.ValidationMessageFor(model => model.TourDate.TourId, "", new { #class = "text-danger" })
</div>
</div>
<br />
<div class="form-group">
#Html.LabelFor(model => model.TourDate.StartDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TourDate.StartDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TourDate.StartDate, "", new { #class = "text-danger" })
</div>
</div>
<br />
<div class="form-group">
#Html.LabelFor(model => model.TourDate.EndDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TourDate.EndDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TourDate.EndDate, "", 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>
}
the problem is when I submit the form no diffrent which Tour is chosen always there is TourId=0.
Appreciate any help and also here is the ajax if needed
$("#dropdownId").change(function () {
$('#TourId').empty();
var countrySelected = $(this).val();
$.ajax
({
url: '/test/GetT/' + countrySelected,
type: 'POST',
data: {
'countryId': countrySelected
},
success: function (data)
{
var $select = $('#TourId');
for (var i = 0; i < data.length; i++)
{
$('<option/>').attr('value', data[i].Id).html(data[i].TourName).appendTo('#TourId');
}
}
});
});
The reason your second <select> element does not submit a value is because it does not have a name attribute. It would need to be
<select class="form-control" name="TourDate.TourId" id="TourId"></select>
However there are multiple other errors and problems with your code. To note just a couple of them:
The model in your view is is not typeof TourDate (its a model
containing a property which is TourDate) so none of your controls
can be bound to your TourDate tourDate parameter in the POST
method (the model in the parameter needs to be the same as the model
in the view, or you need to use the [Bind(Prefix = "TourDate")]
attribute and you also need to remove the [Bind(Include = "..")]
attribute).
Your not getting client side validation associated with your
dropdownlists and in the POST method, if ModelState is invalid,
your just redirecting (the user would just assume the object has
been saved and not understand what is going on). You need to return
the view so errors can be corrected, but in your case, the values
the user has entered will be reset to the defaults (an annoying user
experience).
Your editing data, so you should always use a view model and in the controller method you need to populate the SelectList's to account for initial values and edited values (for when you need to return the view). You code should be
public class TourDateVM
{
[Required(ErrorMessage = "Please select a country")]
[Display(Name = "Country")]
public int? SelectedCountry { get; set; }
[Required(ErrorMessage = "Please select a tour")]
[Display(Name = "Country")]
public int? SelectedTour { get; set; }
[Required(ErrorMessage = "Please enter a start date")]
[Display(Name = "Start date")]
public DateTime? StartDate { get; set; }
.... // ditto above for EndDate
public IEnumerable<SelectListItem> CountryList { get; set; }
public IEnumerable<SelectListItem> TourList { get; set; }
}
And in the controller
public ActionResult Create()
{
TourDateVM model = new TourDateVM();
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
public ActionResult Create(TourDateVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
TourDate tour = new TourDate()
{
TourId = model.SelectedTour,
StartDate = model.StartDate,
EndDate= model.EndDate
};
db.TourDates.Add(tour);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
private ConfigureViewModel(TourDateVM model)
{
var counties = db.Countries;
model.CountryList = new SelectList(counties, "ID", "Name"); // adjust to suit your property names
if (model.SelectedCountry.HasValue)
{
var tours = db.Tours.Where(e => e.CountryId == model.SelectedCountry);
model.TourList = new SelectList(tours, "Id", "TourName");
}
else
{
model.TourList = new SelectList(Enumerable.Empty<SelectListItem>());
}
}
and finally in the view (note that both dropdownlists need to be inside the <form> element)
#model TourDateVM
....
#using Html.BeginForm())
{
....
<div class="form-group">
#Html.LabelFor(m => m.SelectedCountry, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.SelectedCountry, Model.CountryList, "- Please select -", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedCountry, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedTour, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.SelectedTour, Model.TourList, "- Please select -", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedTour, "", new { #class = "text-danger" })
</div>
</div>
....
}
and the script should be
var url = '#Url.Action("GetT")'; // assumes its in the same controller
var tours = $('#SelectedTour');
$('#SelectedCountry').change(function() {
tours.empty();
$.post(url , { id: $(this).val() }, function(data) {
if (!data) {
return;
}
tours.append($('<option></option>').val('').text('- Please select -'));
$.each(data, function(index, item) {
tours.append($('<option></option>').val(item.Id).text(item.TourName));
});
});
})

Button isn't sending to correct view

I am using ajax to send values to my controller from the view:
View where information is collected to send to a different controller:
#using (Html.BeginForm(null, null, FormMethod.Get, htmlAttributes: new { id = "GenerateForm" }))
{
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Choose AC:", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("AC", null, "-- Select AC --", htmlAttributes: new { id = "AC", #class = "form-control" })
</div>
</div>
</div>
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Choose Month:", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Months", null, "-- Select Month --", htmlAttributes: new { id = "Month", #class = "form-control" })
</div>
</div>
</div>
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Year:", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Years", null, "-- Select Year --", htmlAttributes: new { id = "Year", #class = "form-control" })
</div>
</div>
</div>
<br />
<input type="submit" id="SendToController" class="btn btn-primary" value="Generate" />
}
<script type="text/javascript">
$('#SendToController').on('click', function() {
sendToController();
return false;
});
function sendToController(){
var selectedAC = $('#AC').val();
var selectedMonth = $('#Month').val();
var chosenYear = $('#Year').val();
$.ajax({
url: '/MonthReports/Generate',
data: { 'id' : selectedAC, 'monthValue' : selectedMonth, 'year' : chosenYear },
type: 'GET',
cache: false,
success: function(data){},
});
}
Controller Method:
public ActionResult Generate(int id, int monthValue, string year)
{
List<DailySum> lstDailySum = db.DailySum.Where(x => x.AID == id && x.Day.Month == monthValue + 1 && x.Day.Year.ToString() == year && x.deleted == false).ToList();
List<string> lstInc = lstDailySum.Select(x => x.codeAC.text).Distinct().ToList();
List<MReport> lstMReport = new List<MReport>();
foreach (var inc in lstInc)
{
MReport mReport = new MReport();
mReport.Inc = inc;
mReport.Count = lstDailySum.Where(x => x.codeAC.text == incident).Count();
lstMReport.Add(mReport);
}
return View(lstMReport);
}
Now the values are being passed through when the button is clicked, and the whole method works, except the View doesn't show up.. it just stays on the View where the button was originally clicked... no Generate View appears.
I have placed a breakpoint on the Generate view and it does get hit but the view doesn't show?
I don't know how else to explain it.. the cshtml code is hit with a breakpoint, but the page doesn't show.. it just stays on the page where the button was clicked.
Any help is appreciated.
Because you are using ajax, you should handle the data in the success callback of your ajax call. The way your code is written, you do nothing with the view. The View is rendered to the data variable.
Try something like this:
$.ajax({
url: '/MonthReports/Generate',
data: { 'id' : selectedAC, 'monthValue' : selectedMonth, 'year' : chosenYear },
type: 'GET',
cache: false,
success: function(data){
$("body").html(data);
}
});

Resources