I've a model that contains 3 tables in my view.
public class InExam
{
public AutoTests TheTest { get; set; }
public List<InTest> TheQuestions { get; set; }
public IEnumerable<Result> SingleQuee { get; set; }
}
First one made to get the detailed page, like "admin/AutoTests/id"
Second one made to get a list of questions linked to the page
Third one is to save radio button strings to post it back into the controller
my plan is to get (say) 20 questions that are linked with the detailed page, Adding 4 radio buttons for each question, and post back every selected button to the controller.
my view form :
#using (Html.BeginForm("Test", "Exams", new { id = Model.TheTest.id }, FormMethod.Post))
{
foreach (var item in Model.TheQuestions)
{
Kafo.Models.Result singleQuee = Model.SingleQuee.Where(x => x.Question == item.Question).FirstOrDefault();
<div class="container" style="padding-top:50px;direction:rtl;">
<h4 style="text-align:right;font-weight:bold;">#item.Question</h4>
<div class="container">
<div class="row" style="direction:rtl;">
<div class="col-lg-7" style="text-align:right;margin-right:10px;">
<div class="row">
#Html.RadioButtonFor(x => singleQuee.Question, new { #class = "form-control dot", #Name = singleQuee.Question, #Value = "1" })
<h5 style="padding-top:3px;padding-right:8px;">#item.RightAnswer</h5>
</div>
</div>
<div class="col-lg-7" style="text-align:right;margin-right:10px;">
<div class="row">
#Html.RadioButtonFor(x => singleQuee.Question, new { #class = "form-control dot", #Name = singleQuee.Question, #Value = "2" })
<h5 style="padding-top:3px;padding-right:8px;">#item.Answer2</h5>
</div>
</div>
<div class="col-lg-7" style="text-align:right;margin-right:10px;">
<div class="row">
#Html.RadioButtonFor(x => singleQuee.Question, new { #class = "form-control dot", #Name = singleQuee.Question, #Value = "3" })
<h5 style="padding-top:3px;padding-right:8px;">#item.Answer3</h5>
</div>
</div>
<div class="col-lg-7" style="text-align:right;margin-right:10px;">
<div class="row">
#Html.RadioButtonFor(x => singleQuee.Question, new { #class = "form-control dot", #Name = singleQuee.Question, #Value = "4" })
<h5 style="padding-top:3px;padding-right:8px;">#item.Answer4</h5>
</div>
</div>
#Html.HiddenFor(m => singleQuee.Question)
</div>
</div>
</div>
}
<button class="btn botton" type="submit" onclick="return confirm('');">END</button>
}
i used this line "Kafo.Models.Result singleQuee = Model.SingleQuee.Where(x => x.Question == item.Question).FirstOrDefault();" in my view because i can't use tuple foreach ( C# ver. 5 )
This is my controller code :
[HttpGet]public ActionResult Test(int? id)
{
using (KafoEntities db = new KafoEntities())
{
InExam model = new InExam();
model.TheTest = db.AutoTests.Where(x => x.id == id).FirstOrDefault();
model.TheQuestions = db.InTest.Where(x => x.UserEmail == currentUser.Email && x.ExamId == model.TheTest.id).OrderByDescending(x => x.id).Take(Convert.ToInt32(model.TheTest.QuestionsNumber)).ToList();
model.SingleQuee = db.Result.ToList();
return View(model);
}
}
[HttpPost]
public ActionResult Test(int? id, List<Result> singleQuee)
{
using (KafoEntities db = new KafoEntities())
{
int result = 0;
foreach (Result item in singleQuee)
{
Result sets = db.Result.Where(x => x.id == item.id).FirstOrDefault();
sets.Question = item.Question;
db.SaveChanges();
var check = db.InTest.Where(x => x.Question == item.Question).FirstOrDefault();
if (check != null)
{
if (item.Question == "1")
{
result++;
}
}
}
return RedirectToAction("Results", "Exams", new { Controller = "Exams", Action = "Results", id = done.id });
}
}
I first save the new string that came from the radio button value into the result record, then i call it back in the if condition to check it's value
The problem here is i get a
Object reference not set to an instance of an object.
when i post the test, it means that the list is empty, so i need to know what makes the radio buttons not working,
Thanks.
If you want to bind a List of object in Mvc, you should name the controller like "ModelName[indx].PropertyName". In your case it should be "singleQuee[0].Question".
Code Sample
var Indx = 0;
foreach (var item in Model.TheQuestions)
{
.....
var radioName = $"singleQuee[{Indx}].Question";
<div class="col-lg-7" style="text-align:right;margin-right:10px;">
<div class="row">
<input type="radio" name="#radioName" value="1" />
<h5 style="padding-top:3px;padding-right:8px;">#item.RightAnswer</h5>
</div>
</div>
.....
}
Action Method
I'm facing a problem in mvc 4, i have create action method where i insert the data in db and then return model to View but the model data not bind to hidden Field like Id and Voucher number,
in other fields data binds properly but the issue is with these Id and VoucherNum, Id is primary key and VoucherNum is Unique.
I have mentioned the code and html.
Code:
[HttpPost]
public ActionResult Create(Payment payment)
{
payment.VoucherNum = db.Payments.Count() + 1;
Ledger ledger = new Ledger();
ledger.CusId = payment.CustomerId;
ledger.Date = payment.Date;
ledger.Remarks = payment.Remarks;
ledger.Type = payment.Type;
string negativeAmount;
negativeAmount = "-" + payment.Amount;
ledger.Amount = Convert.ToInt32(negativeAmount);
ledger.IsActive = true;
payment.IsActive = true;
db.Payments.Add(payment);
db.Ledgers.Add(ledger);
db.SaveChanges();
ViewBag.CustomerId = new SelectList(db.Customers.ToList()
.Select(x => new { Id = x.Id, CustomerCode = x.Name + "-" + x.CustomerCode }
), "Id", "CustomerCode", payment.CustomerId);
var model = db.Payments.Find(payment.Id);
return View(model);
}
<h2>Payments</h2>
<hr />
<div class="row">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Vocher#</label>
#Html.TextBoxFor(model => model.VoucherNum, new { #class = "form-control", #readonly="true"})
#Html.HiddenFor(model=>model.Id)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Customer</label>
#Html.DropDownList("CustomerId", (IEnumerable<SelectListItem>)ViewBag.CusId, "--Select Customer--", new { #class = "form-control" })
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Date</label>
#Html.TextBoxFor(model => model.Date, new { #class = "form-control", #id = "date"})
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Amount</label>
#Html.TextBoxFor(model => model.Amount, new { #class = "form-control" })
</div>
<div class="form-group">
<label class="control-label">Type</label>
#Html.TextBoxFor(model => model.Type, new { #class = "form-control" })
</div>
</div>
<div class="col-md-8">
<div class="form-group">
<label class="control-label">Remarks</label>
#Html.TextAreaFor(model => model.Remarks, new { #class = "form-control", #rows = "5" })
</div>
<input type="submit" value="Payment Receive" class="btn btn-primary pull-right" />
</div>
}
</div>
Because the helper method will look in to the model state dictionary first to populate the value of the input. The model state dictionary currently has null value for the VoucherNum before you saved it, and the helper method will use this value to generate the value of the input field.
To fix this, you can explicitly clear the model state dictionary before returning to the view,
db.Payments.Add(payment);
db.SaveChanges();
ModelState.Clear();
var p = db.Payments.Find(model.Id);
return View(p);
Or even better, follow the PRG pattern. With the Post-Redirect-Get pattern, After successfully updating the database, you will return a Redirect Response back to the client and the client will issue a totally new GET request to the server.
In your case, You can use RedirectToAction to return a 302 response.
db.SaveChanges();
return RedirectToAction("Edit",new {id=payment.Id});
This will tell the browser to issue a new GET request for Edit action method with the new id in the request url. Your GET action method will use this id and get the entity from db and return it.
public ActionResult Edit(int id)
{
var model = db.Payments.Find(id);
return View(model);
}
I strongly recommend you using the PRG pattern.
I am buidling a mvc web application with entity framework.
Error:
An exception of type 'System.ObjectDisposedException' occurred in
EntityFramework.dll but was not handled in user code
Additional information: The ObjectContext instance has been disposed
and can no longer be used for operations that require a connection.
This is the entity framework part:
Like you see I already include "Alineas" and do .ToList()
public IList<Kop> Handle(RetrieveKoppenForDocumentQuery query)
{
using (var db = new BmDataContext())
{
var koppen = db.Kop.Where(s => s.Document.Id == query.Id)
.Include(s => s.TegelAfbeelding)
.Include(s => s.CollageAfbeeldingen)
.Include(s => s.FinancieleAfbeeldingen)
.Include(s => s.Alineas)
.ToList();
return _orderKoppenByIndex(koppen);
}
}
This is the view KopListItems.cshtml:
#using PGE.Bestuursmonitor.Contracts.DataTypes
#model IList<Kop>
#* Helper for recursively rendering koppen*#
#helper SortableItem(Kop kop)
{
<div class="sortable-item" data-kopid="#kop.Id">
<div class="row">
<div class="col-md-7 title-column">
<i class="fa fa-arrows"></i> #kop.Titel
</div>
<div class="col-md-5">
<div class="col-md-3">
<span>
#kop.KopType
</span>
</div>
<div class="col-md-3">
<span>
#kop.Status
</span>
</div>
<div class="col-md-6">
<span class="pull-right">
#if (#kop.Alineas != null) // on this line I receive the exception
{
// here I would like to do some logic
}
</span>
</div>
</div>
</div>
<div class="sortable-container">
#foreach (var subKop in kop.Koppen)
{
#SortableItem(subKop);
}
</div>
</div>
}
#* Recursively render all kop items *#
<div id="koppen_sortable" class="sortable-container">
#foreach (Kop kop in Model)
{
#SortableItem(kop);
}
</div>
This is the view KoppenList.cshtml:
#model PGE.Bestuursmonitor.ViewModels.Koppen.IKoppenListViewModel
<h1>#Model.DocumentTitel</h1>
#* Render kop list header *#
<div id="koppen_sortable_header">
<div class="row">
<div class="col-md-7"><strong>Titel</strong></div>
<div class="col-md-5">
<div class="col-md-3">
<strong>Type</strong>
</div>
<div class="col-md-3">
<strong>Status</strong>
</div>
<div class="col-md-6">
<span class="pull-right">
<button type="button" id="btn_add_sub" class="btn btn-success" title="Kop aanmaken" role="button" onclick="BM.Koppen.LoadAddKopView(null);">
<i class="fa fa-plus fa-lg"></i> Kop aanmaken
</button>
</span>
</div>
</div>
</div>
</div>
<div id="koppen_sortable_body">
#{ Html.RenderPartial("~/Views/Koppen/KopListItems.cshtml", #Model.Koppen); }
</div>
#* Store document id in html DOM, so javascript can reach it from multiple places *#
<input type="hidden" id="document_id" value="#Model.DocumentId" />
Action in controller:
[HttpGet]
public ActionResult KoppenList(string id)
{
ViewBag.PageId = id;
Document document = _retrieveStartPcDocumentQueryHandler.Handle(new RetrieveStartPcDocumentQuery());
RetrieveKoppenForDocumentQuery query = new RetrieveKoppenForDocumentQuery
{
Id = document.Id
};
IList<Kop> koppen = _retrieveKoppenForDocumentQueryHandler.Handle(query);
_koppenListViewModel.Koppen = koppen;
_koppenListViewModel.DocumentTitel = document.Titel;
_koppenListViewModel.DocumentId = document.Id;
return View("~/Views/Koppen/KoppenList.cshtml", _koppenListViewModel);
}
Like you see in KopListItems.cshtml there are 2 foreach loops. The outer foreach loop is working fine and can read "Alineas". The inner foreach which shows the sub items gives this strange error. What is going wrong? Im stuck.
This is the solution. You need to get the alineas and content also on sub level:
public IList<Kop> Handle(RetrieveKoppenForDocumentQuery query)
{
using (var db = new BmDataContext())
{
var koppen = db.Kop.Where(s => s.Document.Id == query.Id)
.Include(s => s.TegelAfbeelding)
.Include(s => s.CollageAfbeeldingen)
.Include(s => s.FinancieleAfbeeldingen)
.Include(s => s.Alineas.Select(a => a.Content))
.Include(s => s.Koppen.Select(k => k.Alineas.Select(a => a.Content)))
.Include(s => s.Koppen.Select(k => k.Koppen.Select(x => x.Alineas.Select(a => a.Content))))
.ToList();
return _orderKoppenByIndex(koppen);
}
}
I have been working on this for a while and i think i am close. I am trying edit MVC applicationUsers with a bootstrap modal. I am using Angular for the binding, When I click on the User the id is being passed to the Angular controller then to the MVC controller. I thought I could post to the Edit Action in the controller and return the modal with the model. I can not get that work. I created a Action for the modal and it opens just fine. But there is no model attached. How can I can I make this work?
Angular
$scope.editUser = function (id) {
var modalInstance = $modal.open({
templateUrl: 'UsersAdmin/EditUserModal',
controller: $scope.modalEdit,
//matches of the id of your item to recover object model in the controller of the modal
resolve: {
id: function () {
return id
}
}
});
};
//controller of the modal. Inside you can recover your object with ajax request
$scope.modalEdit = function ($scope, $modalInstance, id) {
if (angular.isDefined(id)) {
var reqGetCustomer = $http({ url: '/UsersAdmin/Edit/' + id, method: 'GET' });
reqGetCustomer.success(function (dataResult) {
$scope.model = dataResult;
});
} else { alert('id is undefined'); }
//function to close modal
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
}
}
View with List of Users
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FullName)
</td>
<td class="text-left" style="width:225px">
#Html.ActionLink("Edit", "Edit", null, new { ng_click = "editUser('" + #item.Id + "')" })
</td>
</tr>
}
</tbody>
MVC controller
public ActionResult EditUserModal(string id)
{
return View();
}
// GET: /Users/Edit/1
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ViewBag.RoleId = new SelectList(RoleManager.Roles, "Id", "Name");
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
var userRoles = await UserManager.GetRolesAsync(user.Id);
var companies = await _userCompanyService.GetCompaniesAsync();
var selectedCompanies = companies.Where(c => c.Users.Any(u => u.Id == user.Id)).Select(c => c.Id).ToArray();
var model = new EditUserViewModel()
{
Id = user.Id,
UserName = user.UserName,
FullName = user.FullName,
RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
{
Selected = userRoles.Contains(x.Name),
Text = x.Name,
Value = x.Name
}),
CompanyList = new MultiSelectList(companies.Select(c => new
{
Name = c.Name,
Id = c.Id
}),
"Id", "Name", selectedCompanies),
SelectedCompanies = selectedCompanies
};
return View(model);
}
BootstrAP MODAL
#model TransparentEnergy.Models.EditUserViewModel
#{
Layout = null;
}
<div class="modal-header">
<h3 class="modal-title">Edit User</h3>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Id)
<div class="card-body card-padding">
<div class="form-group">
<label for="UserName" class="col-md-2 control-label">UserName</label>
<div class="col-md-10">
<div class="fg-line">
#Html.TextBoxFor(m => m.UserName, new { #class = "form-control fg-input" })
#Html.ValidationMessageFor(model => model.UserName)
</div>
</div>
</div>
<div class="col-sm-9">
<div class="form-group fg-line">
<label for="SelectedRoles" class="control-label">Roles</label>
#foreach (var item in Model.RolesList)
{
<input type="checkbox" name="SelectedRoles" value="#item.Value" checked="#item.Selected" class="checkbox-inline" />
#Html.Label(item.Value, new { #class = "control-label" })
}
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<button type="submit" class="btn bgm-blue waves-effect btn-width">Save</button>
</div>
</div>
</div>
}
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="modal-footer">
<button class="btn bgm-orange waves-effect btn-width" ng-click="cancel()">Close</button>
</div>
</div>
</div>
the best practice is:
1) Write method in controller (or better if you will write WebApi for pass data to client)
2) Write Angular SERVICE which will work against your API.
3) Write Controller and directives for you page.
the all will very easy. When you need data - you just call your angular service from directive. Anf in view (bootstrap model) you work with your directive properties.
This a little example:
public class DoorsController : ApiContollerBase
{
[HttpGet]
public IEnumerable<DoorViewModel> AdminGetDictionaries()
{
//here i just return List of my doors
return Doors.GetDoors();
}
}
Client side:
Service:
angular
.module('adminApp.services.adminData', ['ngResource'])
.factory('AdminData', ['$resource', 'AppConfig', function ($resource, AppConfig) {
return function (dataName, customActionNames) {
customActionNames = customActionNames || {};
var actions = {
getItem: { method: 'GET', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['getItem'] || 'Test') + '/:id' },
getItems: { method: 'GET', isArray: true, url: AppConfig.apiUrl + dataName + '/' + (customActionNames['getItems'] || 'AdminGet') + '/' },
getItemsForTable: { method: 'POST', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['getItemsForTable'] || 'AdminGetForTable') + '/' },
getDictionaries: { method: 'GET', isArray: true, url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['getDictionaries'] || 'AdminGetDictionaries') + '/' },
postItem: { method: 'POST', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['postItem'] || 'AdminPost') + '/' },
putItem: { method: 'PUT', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['putItem'] || 'AdminPut') + '/:id' },
deleteItem: { method: 'DELETE', url: AppConfig.apiUrl + dataName + '/' + (customActionNames['deleteItem'] || 'AdminDelete') + '/:id' },
};
var resource = $resource(AppConfig.apiUrl + dataName + '/:id', null, actions);
return {
getItem: function (id) {
return resource.getItem({ id: id });
},
getItems: function () {
return resource.getItems();
},
getItemsForTable: function (params) {
return resource.getItemsForTable(params);
},
getDictionaries: function (params) {
return resource.getDictionaries(params);
},
createItem: function (item) {
return resource.postItem({}, item);
},
updateItem: function (id, item) {
return resource.putItem({ id: id }, item);
},
deleteItem: function (id) {
return resource.deleteItem({ id: id });
}
}
}
}]);
Directive:
(function () {
'use strict';
angular
.module('adminApp.directives.adminTableArea', ['adminApp.directives', 'adminApp.services'])
.directive('adminTableArea', function () {
return {
restrict: 'E',
replace: true,
templateUrl: '/App/Admin/views/General/admin-table-area.html',
scope: {
options: "="
},
controller: ['$scope', '$translate', 'AdminData', 'DictionaryProvider', '$state', '$window',
function ($scope, $translate, AdminData, DictionaryProvider, $state, $window) {
var vm = this;
var data = AdminData(vm.dataSource, vm.dataActionNames);
....etc...
I hope its will help you.
Good luck.
Regards,
David
Finally got it figured out in the simplest way possible. no custom MVC helpers or unnecessary jquery.
Here is the Index View with the table
<div class="table-responsive">
<table class="table table-vmiddle">
<thead>
<tr>
<th>Full Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td class="text-left" style="width:100px">
#Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { #class = "btn bgm-gray waves-effect edit" })
</td>
<td class="text-left" style="width:100px">
#Html.ActionLink("Delete", "Edit", null, new { ng_click = "deleteUser('" + #item.Id + "')", #class = "btn" })
</td>
</tr>
}
</tbody>
</table>
</div>
here is the angular controller
$('a.edit').on('click', function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
success: function (result) {
$('#myModal').html(result).find('.modal').modal({
show: true,
backdrop: false
});
}
});
return false;
});
$scope.deleteUser = function (id) {
ApplicationUserDelete.remove(id).success(function (result) {
}).error(function (err, result) {
console.log(err, result);
});
};
MVC controller action returning PartialView
// GET: /Users/Edit/1
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ViewBag.RoleId = new SelectList(RoleManager.Roles, "Id", "Name");
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
var userRoles = await UserManager.GetRolesAsync(user.Id);
var companies = await _userCompanyService.GetCompaniesAsync();
var selectedCompanies = companies.Where(c => c.Users.Any(u => u.Id == user.Id)).Select(c => c.Id).ToArray();
var model = new EditUserViewModel()
{
Id = user.Id,
UserName = user.UserName,
FullName = user.FullName,
RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
{
Selected = userRoles.Contains(x.Name),
Text = x.Name,
Value = x.Name
}),
CompanyList = new MultiSelectList(companies.Select(c => new
{
Name = c.Name,
Id = c.Id
}),
"Id", "Name", selectedCompanies),
SelectedCompanies = selectedCompanies
};
return PartialView(model);
}
Partial Modal View
#model TransparentEnergy.Models.EditUserViewModel
#{
Layout = null;
}
<div class="modal fade" tabindex="-1" role="dialog" aria- labelledby="myModalLabel" data-ng-controller="ApplicationUserController">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit User</h4>
</div>
<div class="modal-body margin-top30px">
<div class="row">
<div class="col-md-12">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Id)
<div class="z-depth-1 padding20 background-white">
<div class="card-body card-padding">
<div class="form-group margin-bottom10px">
<label for="FullName" class="col-md-2 control-label">Full Name</label>
<div class="col-md-10">
<div class="fg-line">
#Html.TextBoxFor(m => m.FullName, new { #class = "form-control fg-input" })
#Html.ValidationMessageFor(model => model.FullName)
</div>
</div>
<td> </td>
</div>
<div class="form-group margin-bottom10px">
<label for="UserName" class="col-md-2 control-label">Email</label>
<div class="col-md-10">
<div class="fg-line">
#Html.TextBoxFor(m => m.UserName, new { #class = "form-control fg-input" })
#Html.ValidationMessageFor(model => model.UserName)
</div>
</div>
<td> </td>
</div>
<div class="form-group margin-bottom10px">
<label for="SelectedRoles" class="col-md-2 control-label">Roles</label>
<div class="col-md-10">
#foreach (var item in Model.RolesList)
{
<label class="checkbox checkbox-inline m-r-20">
<input type="checkbox" name="SelectedRoles" value="#item.Value" checked="#item.Selected" />
<i class="input-helper"></i>
#Html.Label(item.Value, new { #class = "control-label" })
</label>
}
</div>
<td> </td>
</div>
<div class="form-group margin-bottom10px">
<label for="SelectedCompanies" class="col-md-2 control-label">Companies</label>
<div class="col-md-10">
<div class="fg-line">
#Html.ListBoxFor(model => model.SelectedCompanies, Model.CompanyList, new { #class = "form-control" })
</div>
</div>
<td> </td>
</div>
<div class="form-group" style="margin-bottom:60px">
<div class="col-md-2">
<button type="submit" class="btn bgm-blue waves-effect btn-width">Save</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="modal-footer">
<button class="btn bgm-orange waves-effect btn-width" data-dismiss="modal">Close</button>
</div>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
</div>
</div>
</div>
The View model was untouched in regards to any of this. hopefully this helps someone. cant believe there isnt a streamlined way to do this!
I am developing an asp.net MVC4 web app where I need to show StateList and CountryList. I am having a dropdownlist for Countries and on changing i am getting a partial view to display the corresponding States through an ajax request. The partial view has the dropdownlist for States. But once rendered, the dropdownlist for States is not expanding. Here is the code.
First View:
<div class="row" style="margin-left: 12%">
<div class="col-md-12 control-group">
<label class="col-md-4 control-label" style="margin-top :1%;"><b>Country:</b></label>
<div class="col-md-4" style="">
#Html.DropDownListFor(Function(model) model.SelectedCountryId, Model.CountryList, New With {.style = "width:100px", .type = "text", .id = "country"})
#Html.ValidationMessageFor(Function(model) model.SelectedCountryId)
</div>
</div>
</div>
<div id="stateDiv"></div>
Script:
$(document).ready(function () {
var rootUrl = $('#rootUrl').val();
$('#country').change(function () {
var countryCode = $(this).val();
$.get(rootUrl + 'GetStateList', { countryCodeId: countryCode }, function (data) {
$('#stateDiv').html(data);
}, 'html');
var isUSCAN = false;
if ($(this).val() == 1 || $(this).val() == 2) {
isUSCAN = true;
}
$('#stateSelect').toggle(isUSCAN);
$('#stateText').toggle(!isUSCAN);
var isCAN = $(this).val() == 2;
$('#provinceLabel').toggle(isCAN);
$('#stateLabel').toggle(!isCAN);
}).change();
});
Controller:
Function GetStateList(countryCodeId As Integer) As ActionResult
Return PartialView("PartialStateList", Defendant)
End Function
PartialStateList View
<div class="row" style="margin-left: 12%">
<div class="col-md-12 control-group">
<label id="stateLabel" class="col-md-4 control-label" style="margin-top :1%;"><b>State:</b></label>
<label id="provinceLabel" class="col-md-4 control-label" style="margin-top :1%;"><b>Province:</b></label>
<div class="col-md-4" style="">
#Html.DropDownListFor(Function(model) model.SelectedStateId, Model.StateList, New With {.style = "width:100px", .type = "text", .id = "stateSelect"})
#Html.TextBoxFor(Function(model) model.SelectedStateId, New With {.style = "width:100px", .value = "", .type = "text", .id = "stateText"})
#Html.ValidationMessageFor(Function(model) model.SelectedStateId)
</div>
</div>
</div>
The html that is rendered when i check in browser has the entire list of states, but when i click on the dropdownlist, it is not expanding and showing the list. Please let me know if there is something I am missing.