cascading the dropdown menu - javascript

this is jquery function-
now i am able to pass the city name and save it to database but how to change locality with change in city name. i am zero at jquery.Unable to understand this line $.getJSON(localityUrl, { ID: $(this).val() }, function (data) { plzzz suggest me some changes to be made--
<script type="text/javascript">
$(document).ready(function () {
var localityUrl = '#Url.Action("FetchLocalities")';
var localities = $('#SelectedLocality');
$('#SelectedCity').change(function () { localities.empty();
subLocalities.empty();
$.getJSON(localityUrl, { ID: $(this).val() }, function (data) {
if (!data) {
return;
}
localities.append($('<option></option>').val('').text('Please select'));
$.each(data, function (index, item) {
localities.append($('<option></option>').val(item.Value).text(item.Text));
// localities.append($('<option data-lat=' + item.Latitude + ' data-lng=' + item.Longitude + '></option>').text(item.Text));
});
});
})
and my city drop down is like this ---------
<div class="editor-label">
#Html.LabelFor(model => model.SelectedCity)
</div>
<div class="editor-field">
<select id="SelectedCity" name="SelectedCity">
#foreach (var thisCity in Model.CityList)
{
<option value="#thisCity.Name" data-lat="#thisCity.Latitude" data-long="#thisCity.Longitude" data-name="#thisCity.Name" >#thisCity.Name</option>
}
</select>
#Html.ValidationMessageFor(model => model.SelectedCity)
</div>
and my cities in the service layer are like this---
public List<City> FetchCities()
{
List<City> cities = new List<City>();
cities.Add(new City() { Id = 1, Name = "--Select Your City--", Latitude = 28.6139M, Longitude = 77.2090M });
cities.Add(new City() { Id = 2, Name = "Faridabaad", Latitude = 28.4211M, Longitude = 77.3078M });
return cities;
}
and my localities are like this---
public List<Locality> FetchLocalities()
{
List<Locality> localities = new List<Locality>();
localities.Add(new Locality() { Id = 1, CityName = "Faridabaad", Name = "East Faridabaad" });
localities.Add(new Locality() { Id = 2, CityName = "Faridabaad", Name = "West Faridabaad" });
return localities;
}
now my controller is something like this to fetch localities--
public JsonResult FetchLocalities(string name)
{
var data = _localityService.FetchLocalities()
//.Where(l => l.CityId == Id)
.Where(l => l.CityName == name)
.Select(l => new { Value = l.CityName, Text = l.Name });
return Json(data, JsonRequestBehavior.AllowGet);
}

localityUrl is the url your calling- in your case it would be var localityUrl = '#Url.Action("FetchLocalities", "yourControllerName")';
{ ID: $(this).val() } is the data your passing to the controller, in your case it needs to be { name: $(this).val() } because your method has parameter string name (not ID) and $(this).val() equates to the value of the selected option
and data in function (data) is the data your returning back from the controller method, in your case a collection of objects containing 2 properties, Value and Text

Instead of using $.getJSON() you can make an ajax call to your controller action and reload all the localities separately by passing the desired parameter.

Related

I need to replace ActionLink for Dropdownlist

I'm having a foreach that it gives me a list of values that when click it call a controller:
#foreach (var item in Model)
{
<div>#Html.ActionLink(item.Text, "UpdateController",
new { subSectionID = item.Value, subsectionName = item.Text })</div>
}
I would like to do this but now using a dropdown list where clicking on the value redirects me to the controller.
If someone knows how to do it or do it in some other way, maybe using Select in html, it would help me, thanks!
Try the following:
<script type="text/javascript">
$('#subsec').change(function () {
var url = $(this).val();
if (url != null && url != '') {
window.location.href = url;
}
});
</script>
#Html.DropDownListFor(m => Model.GetEnumerator().Current,
Model.Select(d =>
{
return new SelectListItem() {
Text = d.Text,
Value = Url.Action("Your_Action_Name", "Your_Controller_Name", new { subSectionID = d.Value, subsectionName = d.Text })
};
}),
"-Select a value-",
new { id = "subsec" })
A similar solution you can find here: https://stackoverflow.com/a/6088047/6630084

Checkboxes with array model in angularjs using asp.mvc

I am using Asp.MVC 5 for an application and I want to generate many checkboxes with different angularjs models, and I thought the best option is by using array model in angularjs. I tried the code below inside a foreach:
#{
int i = 0;
foreach (var selectedVesselViewModel in Model.SelectedVesselViewModels)
{
using (Html.BeginForm("SelectNotificaiton", "Admin", new { area = "DashBoard" }, FormMethod.Post, new { id = "filterVesselsForm_" + i}))
{
#Html.HiddenFor(item => selectedVesselViewModel.VesselId, new {ng_model= "SelectedVessels[" + i + "].VesselId" })
<li class="row">
<div class="col-md-10">
<a href="#" class="text-admin-area">
#selectedVesselViewModel.VesselName
</a>
</div>
<div class="col-md-2">
<div class="pull-right">
<div class="checkbox checkbox-inline">
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng_model = "SelectedVessels[" + i + "].Selected"
})
<label for="SelectedVesselViewModels_#(i++)__Selected"></label>
</div>
</div>
</div>
</li>
}
}
}
i variable is an incrementing variable:
in the angularjs controller I have something like this:
(function (app) {
"use strict";
app.controller("DashboardCtrl", ['$scope',
function ($scope) {
function init() {
// $scope.SelectedVessels = [];
}
$scope.SelectedVessels = [];
init();
$scope.RefreshSideBarVessels = function() {
angular.forEach($scope.SelectedVessels, function (value, key) {
alert($scope.SelectedVessels[key].VesselId);
});
}
}]);
})(adminModule);
When I use angularjs foreach loop the $scope.SelectedVessels seems to be empty but I dont know why!
angular.forEach($scope.SelectedVessels, function (value, key) {
alert($scope.SelectedVessels[key].Selected);
});
Does anybody know where is the problem, why I cant access the inner properties of the $scope.SelectedVessels array and why it is empty ?
How you are adding values to your array ie. $scope.SelectedVessels is important
Please have a look at below example.
var values = {name: 'Raja', gender: 'male'};
var log = [];
angular.forEach(values, function(value, key) {
this.push(key + ': ' + value);
}, log);
expect(log).toEqual(['name: Raja', 'gender: male']);
Here is the solution to this problem:
I had to use ng-init to each checkbox to instantiate the ng-model.
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng_model = "SelectedVessels[" + i + "].Selected",
ng_init = "SelectedVessels[" + i + "].Selected="+ selectedVesselViewModel.Selected.ToString().ToLower()
})
First off , its ng-model not ng_model (- vs _) but that could be typo.
Second, try this code
$scope.onChange = function (index, value) {
$scope.SelectedVessels[index] = value;
}
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
SelectedVessels[i] = selectedVesselViewModel.Selected
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng-model = "SelectedVessels[" + i + "].Selected",
on-change="onChange(i,selectedVesselViewModel.Selected)
})

Repopulate Dropdown List After Ajax Request [duplicate]

This is how i am loading on page load state and city dropdown:
My Controller method:
This is the first method which is calling when page is loaded.
public ActionResult Index()
{
var states = GetStates();
var cities = Enumerable.Empty<SelectListItem>();
ViewBag.States = states;
ViewBag.Cities = cities;
}
private IEnumerable<SelectListItem> GetStates()
{
using (var db = new DataEntities())
{
return db.States.Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() });
}
}
[HttpGet]
public ActionResult GetCities(int id)
{
using (var db = new DataEntities())
{
var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
}
My View:
IEnumerable<SelectListItem> States = ViewBag.States;
IEnumerable<SelectListItem> Cities = ViewBag.Cities;
#Html.DropDownList("State", States, "Select State", new { onchange="loadCities(this)"})
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"})
function loadCities(obj) {
$.ajax({
url: "/Home/GetCities",
data: { id: $(obj).val() },
contentType:"application/json",
success:function(responce){
var html = '<option value="0">Select City</option>';
$(responce).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
}
});
}
Any better way then this to load state and city dropdown?
public class HomeController : Controller
{
public ActionResult Index(int id=0)
{
Person model = null;
var states = GetStates().ToList();
var cities = Enumerable.Empty<SelectListItem>();
if (id > 0)
{
using (var db = new DataEntities())
{
model = db.People.Include("City").FirstOrDefault(d => d.Id == id);
if (model == null)
model = new Person();
else
{
states.First(d => d.Value == model.City.StateId.ToString()).Selected = true;
cities = db.Cities.Where(d => d.StateId == model.City.StateId).ToList().Select(d => new SelectListItem { Text = d.CityName,Value=d.Id.ToString(),Selected=d.Id==model.CityId });
}
}
}
else
{
model = new Person();
}
ViewBag.States = states;
ViewBag.Cities = cities;
ViewBag.Persons = GetPersons();
return View(model);
}
[HttpGet]
public ActionResult GetCities(int id)
{
using (var db = new DataEntities())
{
var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
}
public ActionResult SavePersonDetail([Bind(Exclude = "Id")] Person model)
{
// var employeeDal= new Emploee();
//employee.firstname=model.
if (ModelState.IsValid)
{
var Id = model.Id;
int.TryParse(Request["Id"], out Id);
using (var db = new DataEntities())
{
if (Id > 0)
{
var person = db.People.FirstOrDefault(d => d.Id == Id);
if (person != null)
{
model.Id = Id;
db.People.ApplyCurrentValues(model);
}
}
else
{
db.People.AddObject(model);
}
db.SaveChanges();
}
}
if (!Request.IsAjaxRequest())
{
ViewBag.States = GetStates();
ViewBag.Persons = GetPersons();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
return View("Index");
}
else
{
return PartialView("_personDetail",GetPersons());
}
}
public ActionResult Delete(int id)
{
using (var db = new DataEntities())
{
var model = db.People.FirstOrDefault(d => d.Id == id);
if (model != null)
{
db.People.DeleteObject(model);
db.SaveChanges();
}
}
if (Request.IsAjaxRequest())
{
return Content(id.ToString());
}
else
{
ViewBag.States = GetStates();
ViewBag.Persons = GetPersons();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
return View("Index");
}
}
private IEnumerable<SelectListItem> GetStates()
{
using (var db = new DataEntities())
{
return db.States.ToList().Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() });
}
}
private IEnumerable<Person> GetPersons()
{
using (var db = new DataEntities())
{
return db.People.Include("City").Include("City.State").ToList();
}
}
public ActionResult HomeAjax()
{
ViewBag.States = GetStates();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
using (var db = new DataEntities())
{
var data = db.States.Include("Cities").Select(d => new { Id = d.Id, Name = d.StateName, Cities = d.Cities.Select(x => new { Id=x.Id,Name=x.CityName}) }).ToList();
ViewBag.CityStateJson = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(data);
}
ViewBag.Persons = GetPersons();
return View();
}
}
#model IEnumerable<Person>
<div>
<table>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Email
</th>
<th>
City
</th>
<th>
State
</th>
<th>
Edit
</th>
</tr>
#if (Model.Count() == 0)
{
<tr>
<td colspan="6">
<h3>No data available</h3>
</td>
</tr>
}
else {
foreach (var item in Model) {
<tr data-id="#item.Id">
<td data-id="fn">#item.FirstName</td>
<td data-id="ln">#item.LastName</td>
<td data-id="email">#item.Email</td>
<td data-id="cn">#item.CityName<input type="hidden" value="#item.CityId" /></td>
<td>#item.StateName</td>
<td>
#if (ViewBag.Title == "Home Ajax" || Request.IsAjaxRequest())
{
Update
<span>#Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {OnSuccess="deleteSuccess",OnBegin="showLoader",OnComplete="hideLoader" })</span>
}
else {
<span>#Html.ActionLink("Update", "Index", new { id = item.Id })</span>
<span>#Html.ActionLink("Delete", "Delete", new { id = item.Id })</span>
}
</td>
</tr>
}
}
</table>
</div>
#model Person
#{
ViewBag.Title = "Home Ajax";
IEnumerable<Person> persons = ViewBag.Persons;
IEnumerable<SelectListItem> States = ViewBag.States;
IEnumerable<SelectListItem> Cities = ViewBag.Cities;
IEnumerable<State> fullStates=ViewBag.CityStates;
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
</hgroup>
</div>
</section>
}
#section styles{
<style type="text/css">
td,th {
border:1px solid;
padding:5px 10px;
}
select {
padding:5px 2px;
width:310px;
font-size:16px;
}
</style>
}
#section scripts{
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
var jsonArray = #Html.Raw(ViewBag.CityStateJson)
function clearValues() {
$("input[type='text'],select").val('');
$("input[type='hidden'][name='Id']").val(0);
}
function loadCities(obj) {
for (var i = 0; i < jsonArray.length; i++) {
if (jsonArray[i].Id == parseInt($(obj).val())) {
fillCity(jsonArray[i].Cities);
break;
}
}
}
function Edit(obj, Id) {
// alert("hi")
$("input[type='hidden'][name='Id']").val(Id);
var tr = $(obj).closest("tr");
$("#txtfirstName").val($("td[data-id='fn']", tr).text().trim());
$("#txtlastName").val($("td[data-id='ln']", tr).text().trim());
$("#txtemail").val($("td[data-id='email']", tr).text().trim());
var city = $("td[data-id='cn'] input[type='hidden']", tr).val();
var state;
for (var i = 0; i < jsonArray.length; i++) {
for (var j = 0; j < jsonArray[i].Cities.length; j++) {
if (jsonArray[i].Cities[j].Id == parseInt(city)) {
state = jsonArray[i].Id;
break;
}
}
if (state) {
fillCity(jsonArray[i].Cities);
break;
}
}
$("#ddlState").val(state);
$("#ddlCity").val(city);
}
function fillCity(obj) {
var html = '<option value="0">Select City</option>';
$(obj).each(function () {
html += '<option value="' + this.Id + '">' + this.Name + '</option>'
});
$("#ddlCity").html(html);
}
function deleteSuccess(responce) {
alert("record deleted successfully");
$("tr[data-id='" + responce + "']").remove();
}
function insertSuccess() {
alert("Record saved successfully");
clearValues();
}
function showLoader() {
$("#overlay").show();
}
function hideLoader() {
$("#overlay").hide();
}
</script>
}
<h3>Add Personal Detail</h3>
#using (Ajax.BeginForm("SavePersonDetail", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "personList" ,OnSuccess="insertSuccess",OnBegin="showLoader",OnComplete="hideLoader"}))
{
#Html.HiddenFor(m => m.Id);
<ol class="round">
<li>
#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName, new { id = "txtfirstName" })
#Html.ValidationMessageFor(m => m.FirstName)
</li>
<li>
#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName, new { id = "txtlastName" })
#Html.ValidationMessageFor(m => m.LastName)
</li>
<li>
#Html.LabelFor(m => m.Email)
#Html.TextBoxFor(m => m.Email, new { id = "txtemail" })
#Html.ValidationMessageFor(m => m.Email)
</li>
<li>
#Html.Label("State")
#Html.DropDownList("State", States, "Select State", new { onchange = "loadCities(this)", id = "ddlState" })
</li>
<li>
#Html.LabelFor(m => m.CityId)
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id = "ddlCity" })
#Html.ValidationMessageFor(m => m.CityId)
</li>
</ol>
<input type="submit" value="Save" />
<input type="button" value="Cancel" onclick="clearValues();"/>
}
<h2>
Person List
</h2>
<div style="position:fixed;text-align:center;top:0;bottom:0;left:0;right:0;z-index:10;background-color:black;opacity:0.6;display:none;" id="overlay">
<img style="position:relative;top:370px" src="~/Images/ajax-loader.gif" />
</div>
<div id="personList">
#Html.Partial("_personDetail", persons)
</div>
You approach using ajax is fine although I would recommend a few better practices including using a view model with properties for StateID, CityID StateList and CityList, and using Unobtrusive JavaScript rather than polluting you markup with behavior, and generating the first ("please select") option with a null value rather than 0 so it can be used with the [Required] attribute
HTML
#Html.DropDownList(m => m.StateID, States, "Select State") // remove the onchange
#Html.DropDownListFor(m => m.CityID, Cities, "Select City") // why change the default ID?
SCRIPT
var url = '#Url.Action("GetCities", "Home")'; // use the helper (dont hard code)
var cities = $('#CityID'); // cache the element
$('#StateID').change(function() {
$.getJSON(url, { id: $(this).val() }, function(response) {
// clear and add default (null) option
cities.empty().append($('<option></option>').val('').text('Please select'));
$.each(response, function(index, item) {
cities.append($('<option></option>').val(item.Value).text(item.Text));
});
});
});
If you were rendering multiple items (say you were asking the user to select their last 10 cities they visited), you can cache the result of the first call to avoid repeated calls where their selections may include cities from the same state.
var cache = {};
$('#StateID').change(function() {
var selectedState = $(this).val();
if (cache[selectedState]) {
// render the options from the cache
} else {
$.getJSON(url, { id: selectedState }, function(response) {
// add to cache
cache[selectedState] = response;
.....
});
}
});
Finally, in response to your comments regarding doing it without ajax, you can pass all the cities to the view and assign them to a javascript array. I would only recommend this if you have a few countries, each with a few cities. Its a matter of balancing the slight extra initial load time vs the slight delay in making the ajax call.
In the controller
model.CityList = db.Cities.Select(d => new { City = d.CountryID, Text = d.CityName, Value = d.Id }).ToList();
In the view (script)
// assign all cities to javascript array
var allCities= JSON.parse('#Html.Raw(Json.Encode(Model.CityList))');
$('#StateID').change(function() {
var selectedState = $(this).val();
var cities = $.grep(allCities, function(item, index) {
return item.CountryID == selectedState;
});
// build options based on value of cities
});
This is a correct approach, but you can simplify your javascript:
function loadCities(obj) {
$.getJSON("/Home/GetCities", function (data) {
var html = '<option value="0">Select City</option>';
$(data).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
});
}
Further possible simplification:
Add the default item (Select City) server-side, so your javascript will be smaller.
Here's how I'd do it without the page refresh, assuming the list of cities isn't too long.
I'm assuming you can create a GetStatesAndCities method to return a Dictionary.
public ActionResult Index()
{
Dictionary<string, List<String>> statesAndCities = GetStatesAndCities();
ViewBag.StatesAndCities = Json(statesAndCities);
}
Then in the view:
var states = JSON.parse(#ViewBag.StatesAndCities);
function loadCities(obj) {
var cities = states[$(obj).val()];
var html = '<option value="0">Select City</option>';
$(cities).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
}
This way when the state is changed the cities field with update immediately with no need for callback.
disclaimer: This is not a code answer, there are plenty other answers.
I think best way to keep yourself happy to seperate UI pages from data => turn them into API calls:
/GetCities
/GetStates
Now you can simply leave the select's empty on Razor rendering the page. And use a Jquery/Bootstrap plugin to create an AJAX select box.
This way when the user stops typing his search, this search string can than be send with the AJAX call (eg: /GetStates?search=test) and then a small result set can be send back to the website.
This gives:
Better separation in serveside code
Better User eXperience.
Smaller page loads (since you no longer send all the options to user when he requests the page, only when he opens the select box).
How about using Knockout?
Knockout is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model
You have to use ajax for your cities. But with knockout you dont need to write
var html = '<option value="0">Select City</option>';
$(responce).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'});
$("#ddlCity").html(html);
in your javascript.Knockout makes it simple.
You can simply write:
function CityModel() {
var self = this; // that means this CityModel
self.cities = ko.observableArray([]);
self.getCities = function () {
$.ajax({
url: "/Home/GetCities",
data: { id: $(obj).val() },
contentType: "application/json",
success: self.cities
});
}
}
ko.applyBindings(new CityModel());
thats all. But you have to bind your data into html elements.
Instead of using :
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"})
You can use:
<select data-bind="options:cities,optionsValue:"Id",optionsText:"CityName",optionsCaption:"Select City""></select>
or you can mix razor and knockout:
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity",data_bind:"options:cities,optionsValue:\"Id\",optionsText:\"CityName\""})
One more thing you have to call GetCities when State changes, you can :
#Html.DropDownList("State", States, "Select State", new {data_bind:"event:\"change\":\"$root.GetCities\""})
Dont be scare with \"\" things this because " is an escape character and we have to say to razor i want to use " by using \ before it.
You can find more info about knockout :Knockout
And mixing with razor: Razor and Knockout
Ps: yes using knockout is suspend us from Razor and Mvc. You have to write another ViewModel . But like this situations ko is helpful. Mixing razor and knockout is another option for you.

How to marked checkbox in function jquery

I have a listbox in view.
This Listbox use template
Listbox
<div id="UsersLoad" style="width: 50%">
#Html.EditorFor(i => i.Users, "UsersForEdit")
</div>
Template UserForEdit (Part of the code)
#model string[]
#{
if (this.Model != null && this.Model.Length > 0)
{
foreach(var item in this.Model)
{
listValues.Add(new SelectListItem { Selected = true, Value = item, Text = item });
}
}
else
{
listValues = new List<SelectListItem>();
}
}
<div class="field-#size #css">
<h3>#Html.LabelFor(model => model):</h3>
#Html.ListBoxFor(model => model, listValues, new { id = id })
</div>
In another view div "Users" is called.
function LoadUsersCheckBox() {
$("#UsersLoad").load('#Url.Action("LoadUsers", "User")' + '?idUser=' + idUser);
}
LoadUsers Controller
public JsonResult LoadUsers(int? idUser)
{
var users = Service.GetSystemUsers(idUser);
var model = users.Select(x => new
{
Value = x,
Description = x
});
return this.Json(model, JsonRequestBehavior.AllowGet);
}
The controller method returns what I want.
But instead of it select the items in the listbox it overwrites the listbox with only the text of found users.
How to mark the items in the listbox on the function LoadUsersCheckBox?
Sorry for my bad English
The jQuery load() method "loads data from the server and places the returned HTML into the matched element." Note the words "the returned HTML". See http://api.jquery.com/load/
To select existing items, you should try get() instead (http://api.jquery.com/jQuery.get/). In the success callback handler, you will need to parse the returned data to an array. Then use an iterator to go over the items in the listbox, and if they exist in the parsed array, mark them as selected. Something like:
$.get("action url", function(data) {
var users = $.parseJSON(data);
$("#UsersLoad option").each(function() {
var opt = $(this),
value = opt.attr("value");
opt.removeAttr("selected");
if (users.indexOf(value) > -1) {
opt.attr("selected", "selected");
}
});
});

need help to resolve - Uncaught ReferenceError: data is not defined

I know there are many questions/tutorials for this subject, but cannot solve my problem.
I have to ask for your help. Second day cannot find out the solution to this simple problem.
I am trying as in this tutorial - http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/cascading-dropdownlist-in-Asp-Net-mvc/
That is working fine, but once i try from DB, i am getting error "Uncaught ReferenceError: data is not defined"
Here is my web page
#model testEmpty.Models.Address
#{
ViewBag.Title = "Create";
}
#Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/myScripts/myScripts.js"></script>
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Address</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group col-md-10">
#Html.Label("Zone")
#Html.DropDownList("ZoneId", ViewBag.ZoneName as SelectList, "--Select a Zone--", new { id = "ZoneId" })
#Html.ValidationMessage("Zone", "*")
</div>
<div class="form-group">
<div class="col-md-10">
#Html.Label("Districts of SZ")
<select id="DistrictSZ" name="DistrictSZ"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Controller
private myContext db = new myContext();
// GET: Addresses
public ActionResult Index()
{
var zones = db.Addresses.Include(a => a.Zone);
ViewBag.ZoneName = new SelectList(zones, "Value", "Text");
return View(zones.ToList());
}
public JsonResult DistrictList(int id)
{
var district = from s in db.Districts
where s.ZoneId == id
select s;
return Json(new SelectList(district.ToArray(), "ZoneId", "Name"), JsonRequestBehavior.AllowGet);
}
Script
$(function () {
$('#ZoneId').change(function () {
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts (data));
});
});
function getDistricts(data) {
var items = '<option>Select a District</option>';
$.each(data, function (i, district) {
items += "<option value='" + district.Value + "'>" + district.Text + "</option>";
});
$('#DistrictSZ').html(items);
}
As i understand, my problem is with JSON. what am I doing wrong?
Firstly you do not need to return a SelectList (javascript knows nothing about a c# class)
public JsonResult DistrictList(int id)
{
var district = db.Districts.Where(d => d.ZoneId == id).Select(d => new
{
Value = d.ZoneId, // this look wrong - see note below
Text = d.Name
});
return Json(district, JsonRequestBehavior.AllowGet);
}
Then in your script
var url = '#Url.Action("DistrictList")'; // ensure your url's are properly generated
var districts = $('#DistrictSZ'); // cache it
$('#ZoneId').change(function () {
$.getJSON(url, { id: $(this).val() }, function (data) {
districts.empty(); // remove existing options
districts.append($('</option>').val('').text('Select a District'));
$.each(data, function (i, district) {
districts.append($('</option>').val(district.Value).text(district.Text));
});
});
});
In fact, since ZoneId is always the same, you could just return a collection of the Name values
var district = db.Districts.Where(d => d.ZoneId == id).Select(d => d.Name);
and
$('#ZoneId').change(function () {
var zoneID = $(this).val();
$.getJSON(url, { id: zoneID }, function(data) {
districts.empty(); // remove existing options
districts.append($('</option>').val('').text('Select a District'));
$.each(data, function (i, district) {
districts.append($('</option>').val(zoneID).text(district));
});
});
});
However your code is generating all options with the same value (ZoneId) which does not make much sense, so I suspect you really want to use another property of District - i.e. its Id (or DistrictId?) property.
You're passing the returned value of getDistricts to the callback variable of $.getJSON.
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts (data));
You need to pass the function reference like this
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts);
maybe you should handle your callback function with a anonymous function like this:
$.getJSON('DistrictList/' + $('#ZoneId').val(), success(data){
getDistricts(data);
})

Categories