Populate second Droplist depending on values of first Droplist - asp.net-mvc

How can I change the selection of a second drop down list depending on the first selected dropdown value? For example in the code below if the listDepartments is "Sales" I only want the choice for listCatagory droplist to be Customers, and when selecting HR I only want the choice to be "Resumes" Is this possible with the code below or do I need a new approach, and if so is there a good example somewhere?
Thanks,
EB
List<SelectListItem> listDepartments = new List<SelectListItem>();
listDepartments.Add(new SelectListItem
{
Text = "Sales",
Value = "Sales",
});
listDepartments.Add(new SelectListItem
{
Text = "HR",
Value = "HR"
});
List<SelectListItem> listCatagory = new List<SelectListItem>();
listCatagory.Add(new SelectListItem
{
Text = "Customers",
Value = "Customers",
});
listCatagory.Add(new SelectListItem
{
Text = "Resumes",
Value = "Resumes",
});
When selecting the department is does nothing.
OK I added this to my controller:
public JsonResult GetCategory(int id)
{
var department = db.Documents.Where(t => t.ID == id).FirstOrDefault();
return Json(new SelectList(db.Catagories.Where(t => (t.Department == department.Department)), "Category", "Text"));
}
But I am not sure where it get the data for data: { id: $("#droplist_Departments_ID").val() }, from??
Do I need to change way the droplist is for the departments?
listDepartments.Add(new SelectListItem
{
Text = "Customer Service",
Value = "CustomerService",

You'll have to use Javascript in order to make an Ajax request passing the previous droplist selected item to a method in the controller which will return a SelectList, something like this:
$.ajax({
type: 'POST',
url: 'GetCategory',
dataType: 'json',
data: { id: $("#droplist_Departments_ID").val() },
success: function (mems) {
// states contains the JSON formatted list
// of states passed from the controller
$.each(mems, function (i, member) {
$("#droplist_Category_ID").append('<option value="' + member.Value + '">' + member.Text + '</option>');
});
},
error: function (ex) {
console.log('Failed to retrieve states. Exception: ' + ex);
}
});
In the controller something like (adapt to your db schema, obviously):
public JsonResult GetCategory(int id)
{
var department = db.Departments.Where(t => t.Id == id).FirstOrDefault();
return Json(new SelectList(db.Categories.Where(t => (t.DepartmentId == department.Id)), "CategoryId", "Text"));
}

Related

How to get data to DropDownList based on other dropdown?

I have a table (dept) on database and fields are:
1 - id
2 - Division
3 - Designation
I am retrieving division data on dropdown, this is my code:
public JsonResult GetDivision()
{
var division = db.Depts.GroupBy(x => x.Division)
.Select(x => x.FirstOrDefault()).OrderBy(x => x).ToList();
return Json(division);
}
Now I want to get the designation data on 2nd dropdown based on division name
public JsonResult GetDesignation(int StateId)
{
var department = db.Depts.Where(x => x.DeptId == StateId)
.OrderBy(x => x.Designation);
return Json(department);
}
Ajax code:
$(document).ready(function () {
$('#division').change(function () {
$('#designation').empty();
$.ajax({
type: "POST",
url: "/Official/GetDesignation",
datatype: "Json",
data: { StateId: $('#division').val() },
success: function (data) {
$('#designation').append('<option value>--Select--</option>');
$.each(data, function (index, value) {
$('#designation').append('<option value="' + value.deptId + '">' + value.designation + '</option>');
console.log(value);
});
}
});
});
html:
#Html.DropDownList("division", new SelectList(string.Empty, "Value", "Text"), "--Select--", null)
#Html.DropDownList("designation", new SelectList(string.Empty, "Value", "Text"), "--Select--", null)
When I select divison from dropdown, I get only one designation, which is getting from id, but I want to get all designation based on division name for exmaple I have this type of data
id division designation
1 CORPORATE AFFAIRS Manager Corporate Affairs
2 CORPORATE AFFAIRS Manager BPR & PMO
3 CORPORATE AFFAIRS Jr. Executive Corporate Governance
in 1st dropdown I am getting one "corporate affairs", but when I select "corporate affairs" I need to get all designation in 2nd dropdown
Ok, I think you need to understand the following...
This line here:
var department = db.Depts.Where(x => x.DeptId == StateId)
.OrderBy(x => x.Designation);
Is making a SQL query at the end, which will traduce into something like:
SELECT * FROM Depts WHERE DeptId = Something ORDER BY Designation
I assume that DeptId is a PRIMARY KEY, which is a unique value on the table, when you process the query above it will bring only one or zero results depending on if there is a match.
I think you should correct the value that you are passing from the ajax POST, you could use:
data: { StateId: $('#division').text() }
instead of:
data: { StateId: $('#division').val() }
This way you are passing the Division name as string and modify your function as follows:
public JsonResult GetDesignation(string Division)
{
var department = db.Depts.Where(x => x.Division == Division)
.OrderBy(x => x.Designation);
return Json(department);
}

How to refresh Html.DropDownGroupList after another dropdown changes

I have difficulties to refresh an Html.DropDownGroupList.
I have two dropdowns which depends on each other: Makes and Models. The Models dropdown should be grouped, as you can see in the attached screenshot.
When I enter in the page the Models dropdown is filled with data and it is grouped correctly, but when I change the first dropdown, the Model is not refreshing correctly.
In the controller I have this code:
public ActionResult GetModels(string id)
{
if (!string.IsNullOrEmpty(id))
{
int number;
bool result = Int32.TryParse(id, out number);
if (!result)
return Json(null);
var selectedMake = makeRepository.GetMakeByID(number);
var list1 = db.Models.Where(m => m.MakeID == selectedMake.ID).ToList();
List<GroupedSelectListItem> models = new List<GroupedSelectListItem>();
foreach (var items in list1)
{
models.Add(new GroupedSelectListItem
{
Text = items.Name,
Value = items.ID.ToString(),
GroupName = items.GroupName,
GroupKey = items.GroupName
});
}
ViewBag.Alma = models;
return Json(models, JsonRequestBehavior.AllowGet);
}
return Json(null);
}
and in the View :
#Html.DropDownGroupList("models", ViewBag.Alma as List<GroupedSelectListItem>, "Select Model", new
{
#class = "dropdown-toggle col-md-9 form-control"
})
This is the code where I try to refresh the dropdown:
$.ajax({
type: 'POST',
url: '#Url.Action("GetModels")',
dataType: 'json',
data: { id: $("#makes").val() },
success: function (models) {
if (window.console) {
console.log(JSON.stringify(models))
}
$.each(models, function (i, model) {
$("#models").append
('<optgroup label="'+ model.GroupName + '"><option value="' + model.Value + '">' +
model.Text + '</option></optgroup>'
);
});
}
});
This is the way the dropdown looks after the refresh
The grouping is not working anymore. I know that this is the problem:
$("#models").append('<optgroup label="'+ model.GroupName + '"><option value="' + model.Value + '">' + model.Text + '</option></optgroup>');
but how to do this ajax call to group my dropdown? I don't have so much experience with ajax, javascript.
Can you please advise how to refresh the Model dropdown?
Your GetModels() method is returning List<GroupedSelectListItem> which is a special class used by the DropDownGroupList() method and is not suitable for building your html (at least without a lot of extra code to group data in the script).
Start by creating view models to represent the hierarchical data you need
public class GroupVM
{
public string Name { get; set; }
public IEnumerable<OptionVM> Options { get; set; }
}
public class OptionVM
{
public int Value { get; set; }
public string Text { get; set; }
}
Then modify the controller to group your data and project the results to the view model
public ActionResult GetModels(int? id)
{
if (!id.HasValue)
{
return Json(null);
}
var data = db.Models.Where(x => x.MakeID == id.Value).GroupBy(x => x.GroupName).Select(x => new GroupVM()
{
Name = x.Key,
Options = x.Select(y => new OptionVM()
{
Value = y.ID,
Text= y.Name
})
});
return Json(data);
}
And modify your script to
var models = $('#models'); // cache it
$('#makes').change(function () {
var id = $(this).val();
$.ajax({
type: 'POST',
url: '#Url.Action("GetModels")',
dataType: 'json',
data: { id: id },
success: function (data) {
models.empty(); // clear existing options
$.each(data, function (index, group) {
var optGroup = $('<optgroup></optgroup>').attr('label', group.Name);
$.each(group.Options, function (index, option) {
var option = $('<option></option>').val(option.Value).text(option.Text);
optGroup.append(option);
});
models.append(optGroup);
});
}
});
})

how to set selected values to a multi select dropdown list on form load in .net mvc

I am using a multi select dropdown for a particular entry, which is retrieved from a table. If I am trying to edit this entry the selected dropdown is not showing.
This is my script.
<script type="text/javascript">
$(document).ready(function () {
//$('#Supplier').click(function () {
var sku = $("#SKU").val();
alert(sku);
//var pay = null;
//alert(suppid);
$.ajax({
url: '/SKUMasterSetup/supplierlist',
type: 'POST',
dataType: 'json',
data: { id: sku },
success: function (Supplierdata) {
alert("hi");
alert(Supplierdata);
var x = Supplierdata.length();
alert(x);
//<option value="{$T.data.Value}">{$T.data.Text}</option>
//for (var i = 0; i < Supplierdata.length; i++) {
// $("#supplier").append("Selected", Supplierdata[i], "selected").attr('selected', true);
for (var i in Supplierdata) {
var optionVal = Supplierdata[i];
$("#supplier").find("option[value=" + optionVal + "]").prop("selected", "selected");
}
// $('.class1').append("<option>" + "Please select" + "</option>");
},
//error : function (Supplier) { alert("Error !"); };
});
});
</script>
And my controller code is:
[HttpPost]
public JsonResult supplierlist(int id)
{
var Supplierdata = (from item in db.SupplierSKUMaps
where item.SKU == id
select item.SupplierMaster.SupplierName).ToList();
return Json(Supplierdata, JsonRequestBehavior.AllowGet);
}
And my dropdownlist is:
#Html.DropDownList("Supplier", ViewBag.Supplier as MultiSelectList, new { #class = "chosen", #id="supplier", #multiple = "multiple" })
you could always use #Value = #Html.Action(getMyFields) and within your controller, place an action method that returns Content result(MyData.ToList()).
More information on creating dropdowns can be found here: http://odetocode.com/blogs/scott/archive/2013/03/11/dropdownlistfor-with-asp-net-mvc.aspx

Cannot get value of HtmlAttributes item in kendo MVC treeview

I am using the Kendo MVC wrapper extensions to create a TreeView from my models. I would like to pass some data from the model with HtmlAttributes to the view.
Here is my Action :
public ActionResult Index()
{
var nodeList = new List<TreeViewItemModel>();
nodeList.Add(new TreeViewItemModel
{
Id = "1",
Text = "Item 1",
HasChildren = true,
HtmlAttributes = new Dictionary<string, string>
{
{"class","XXXX"}
},
Items = new List<TreeViewItemModel>
{
new TreeViewItemModel{Id="1.1", Text = "sub Item 1.1",HasChildren = false},
new TreeViewItemModel{Id="1.2", Text = "sub Item 1.2",HasChildren = false}
});
nodeList.Add(new TreeViewItemModel { Id = "2", Text = "Item 2", HasChildren = false });
return View(nodeList);
}
Here is my view :
#using Kendo.Mvc.UI
#model IEnumerable<Kendo.Mvc.UI.TreeViewItemModel>
#(Html.Kendo().TreeView()
.Name("treeView")
.BindTo(Model)
.DragAndDrop(true)
)
Here is the element from Chrome
<li class="k-item k-first" data-id="1" data-uid="6263f4c5-85f3-446c-a843-7d3786fb0f68" role="treeitem" id="treeView_tv_active">
As you can see there isn't any class:XXX in my li Tag So how can I give The XXX class to li Tag?
I can't figure out how to do this automatically, so here's a workaround.
C# passes back a List<Kendo.Mvc.UI.TreeViewItemModel>() to the treeview->datasource->transport->read event:
var items = new List<Kendo.Mvc.UI.TreeViewItemModel>();
////////////////////////////////////////////////////////////////////////////////
// areas of expertise
var aoe = new Kendo.Mvc.UI.TreeViewItemModel()
{
Text = "Areas of Expertise",
Id = "resume-treeview-category-AreasOfExpertise",
HasChildren = false,
HtmlAttributes = new Dictionary<string, string>(){{ "class", "resume-treeview-category"}, {"cat-id", "AreasOfExpertise" }},
};
items.Add(aoe);
return Json(items, JsonRequestBehavior.AllowGet);
I then hook the dataBound event to add the above attributes into the treeview item.
jQuery(document).ready(function ($) {
$("#document-treeview").kendoTreeView({
dataTextField: "Text",
dataSource: {
transport: {
read: {
type: 'POST',
url: "#Url.Action("GetAllTreeData", "Document2")",
contentType: 'application/json; charset=utf-8',
dataType: 'json'
},
parameterMap: function (data, type) {
if (type == "read") {
return JSON.stringify({
id: ResumeId
});
}
}
},
schema: {
model: {
id: "Id",
hasChildren: "HasChildren",
children: "Items"
}
}
},
dataBound: function(e) {
// Apparently reading an item after treeview creation doesn't apply the html attributes. Do that here.
var len = this.dataSource.data().length;
for (var i = 0; i < len; i++)
{
var dataItem = this.dataSource.data()[i];
var uid = dataItem.uid;
var li = $('#document-treeview li[data-uid="' + uid + '"]');
li.addClass(dataItem['HtmlAttributes']['class']);
li.attr('cat-id', dataItem['HtmlAttributes']['cat-id']);
}
}
});
}
Note the HtmlAttributes added from C# are explicitly handled in JavaScript =/

cascading dropdownlist with partial view issue

I have a problem with cascading dropdownlists where the second ddl should appear in a partial view and I can't handle it by myself. Please help me to figure out why I have the following bag?
So, I have a view with the first ddl where the user can choose a brand:
#Html.DropDownList("brands", new SelectList(
#ViewBag.Brands, "Id", "BrandName"),
"--select a Brand--",
new
{
id = "ddlBrands",
data_url = Url.Action("ChooseModel", "Home")
})
<div id="divModel"></div>
The ChooseModel method returns the following partial view :
<div id="chooseModel">
<div class="lead">Model</div>
#Html.DropDownList("models", new SelectList(Enumerable.Empty<SelectListItem>
(), "Id", "ModelName"),
"--select a Model--",
new { id = "ddlModels" })
</div>
When a user selects an item in ddlBrands another dropdownlist for models should appear. So, the script looks like this:
$(function () {
$("#ddlBrands").change(function () {
var url = $(this).data('url');
var value = $(this).val();
$('#divModel').load(url, { id: value });
var brandId = $(this).val();
$('#divModel').html("");
$.getJSON("../Home/LoadModels", { brandId: brandId },
function (modelData) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', {
value: 0,
text: "-- select a Model --"
}));
$.each(modelData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
And, finally, LooksModels method loading the models for the particular brand:
public JsonResult LoadModels(string brandId)
{
if (string.IsNullOrEmpty(brandId))
return Json(HttpNotFound());
var modelList = unitOfWork.ModelRepository
.GetModelListByBrand(Convert.ToInt32(brandId)).ToList();
var modelData = modelList.Select(m => new SelectListItem()
{
Text = m.ModelName,
Value = m.Id.ToString()
});
return Json(modelData, JsonRequestBehavior.AllowGet);
}
So, when I launch the application and choose a brand in the first ddl, the child models showing fine in second one. Then I choose another brand, and again the right models appeared. But when I choose the brand that I chose first time, I can't choose any models - ddlModels shows me only --select a Model--.
Can you please tell me what error in script (I suppose) I have?
Try this Script :
<script type="text/javascript">
$(document).ready(function () {
$("#ddlBrands").change(function () {
firstDDLValue = $("#ddlBrands").val();
$.post('#Url.Action("LoadModels", "Home")', { fstValue: firstDDLValue }, function (result) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', { value: '', text: '--Select--' }));
$.each(result, function (index, Data) {
select.append($('<option/>', {
value: Data.Value,
text: Data.Text
}));
});
});
});
});
</script>
Use This at Controller:
public JsonResult LoadModels(string fstValue)
{
YourClassname obj= new YourClassname ();
int Id = 0;
if (fstValue != "")
Id = Convert.ToInt32(fstValue);
var result = obj.GetModelListByBrand(Convert.ToInt32(Id ));
IList<SelectListItem> Data = new List<SelectListItem>();
for (int i = 0; i < result.Count; i++)
{
Data.Add(new SelectListItem()
{
Text = result[i].Text,
Value = result[i].Value,
});
}
return Json(Data, JsonRequestBehavior.AllowGet);
}

Resources