AJAX Cascading Dropdowns ASP.NET MVC - c#

I am working on a request form for work. The request deals with series of products. There are many series, so I am trying to filter them down by the product line that they are produced on. I am attempting this using cascading dropdown lists from Ajax. I know the script is working to a degree, because the default selected option changes to "Make Selection". However, the rest of the dropdown does not populate.
Here are the two dropdowns.
#Html.DropDownListFor(model => model.SelectedProductLine, new SelectList(Model.ProductLines, "Value", "Text"), "Select a Product Line", new { #class = "form-control", #style = "width: 400px;", #id = "ProductLineID"})
#Html.DropDownListFor(model => model.SelectedSeries, new SelectList(string.Empty, "Value", "Text"), "Select a Series", new { #class = "form-control", #id = "SeriesID"})
The Ajax Script.
$(document).ready(function () {
//Dropdownlist Selectedchange event
$('#ProductLineID').change(function () {
$.ajax({
url: '/SMRMaster/RequestForm/GetSeries',
type: 'GET',
datatype: 'JSON',
data: { id: $('#ProductLineID').val() },
success: function (result) {
$('#SeriesID').html('');
$('#SeriesID').append($('<option>Make Selection</option>'));
$.each(result, function (index, item) {
$('#SeriesID').append($('<option></option>').val(item.Value).html(item.Text));
});
}
});
});
});
The Controller.
public JsonResult GetSeries(string id)
{
int Id = Convert.ToInt32(id);
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNOCMMITTED;");
var productLineName = "";
switch (Id)
{
case 0:
productLineName = "Electric";
break;
case 1:
productLineName = "Europe Gas";
break;
case 2:
productLineName = "Gas";
break;
case 3:
productLineName = "Miscellaneous";
break;
case 4:
productLineName = "Water";
break;
default:
productLineName = "Electric";
break;
}
IEnumerable<SelectListItem> series = (from s in db.Series
where s.ProductLineName == productLineName
select new SelectListItem { Value = s.ProductLineName, Text = s.ProductLineName }).ToList();
return Json(series, JsonRequestBehavior.AllowGet);
}
public List<ProductLine> GetProductLines()
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var productLineList = (from p in db.ProductLines
select p).ToList();
return productLineList;
}
public ActionResult RequestForm()
{
var count = 0;
var productLineList = new List<SelectListItem>();
foreach (var item in GetProductLines())
{
productLineList.Add(new SelectListItem { Text = item.ProductlineName, Value = count.ToString() });
}
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var requestViewModel = new RequestViewModel { SMRMaster = new SMRMaster(), Engineers = GetEngineers(), ProductLines = productLineList };
return View(requestViewModel);
}
And the view model.
public class RequestViewModel
{
public List<SelectListItem> ProductLines { get; set; }
public string SelectedProductLine { get; set; }
public SMRMaster SMRMaster { get; set; }
public List<string> Engineers { get; set; }
[Required(ErrorMessage = "Engineer is required.")]
public string SelectedEngineer { get; set; }
public List<Series> Series { get; set; }
public string SelectedSeries { get; set; }
}
I do not know where the error is coming from. Any help is appreciated.

Try this
$.each(result, function (i, item) {
var optionData = '<option value="' + item.Value + '">' + obj.Text + '</option>';
$(optionData).appendTo('#SeriesID')
});
Or debug and see what's your response from server.

A colleague helped me solve this problem. Firstly, the Ajax script was using the wrong URL. Secondly, my controller functions were unnecessarily complicated.
Here is the updated AJAX script:
$(document).ready(function () {
//Dropdownlist Selectedchange event
$('#ProductLine').change(function () {
$.ajax({
url: '/SMRMaster/GetSeries',
type: 'GET',
datatype: 'JSON',
data: { productLine: $('#ProductLine').val() },
success: function (result) {
$('#SeriesID').html('');
$('#SeriesID').append($('<option>Make Selection</option>'));
$.each(result, function (i, item) {
var optionData = '<option value="' + item.Value + '">' + item.Text + '</option>';
$(optionData).appendTo('#SeriesID')
});
}
});
});
});
And here is the updated Controller:
public JsonResult GetSeries(string productLine)
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
List<SelectListItem> series = (from s in db.Series
where s.ProductLineName == productLine
select new SelectListItem { Value = s.SeriesName, Text = s.SeriesName }).Distinct().ToList();
return Json(series, JsonRequestBehavior.AllowGet);
}
public List<ProductLine> GetProductLines()
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var productLineList = (from p in db.ProductLines
select p).ToList();
return productLineList;
}
public ActionResult RequestForm()
{
var productLineList = new List<SelectListItem>();
foreach (var item in GetProductLines())
{
productLineList.Add(new SelectListItem { Text = item.ProductlineName, Value = item.ProductlineName });
}
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var requestViewModel = new RequestViewModel { SMRMaster = new SMRMaster(), Engineers = GetEngineers(), ProductLines = productLineList };
return View(requestViewModel);
}

Related

Filter products based on multiple check boxes

I am working on e-commerce site. I want to filter product based on multiple check boxes. I use ajax. It sends check boxes' IDs to the controller. But selected counts zero like in the picture. What is wrong with this code?
Ajax:
<script type="text/javascript">
$(function () {
$('.filterprod').click(function () {
var ProdID = "";
$('.checks').each(function () {
if ($(this).is(':checked')) {
ProdID += $(this).val() + ",";
}
});
var data = {};
data.Id = ProdID.slice(0, ProdID.length - 1);
$.ajax({
url: '/Shop/GetProd',
method: 'POST',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(data),
success: function (response) {
$("#Prodlist").remove();
},
error: function (err, response) {
console.log(err, response);
alert(err, response.responseText);
}
})
});
});
</script>
Controller:
[HttpPost]
public JsonResult GetProd(string Id)
{
var ids = new List<int>();
IQueryable<Product> prods = null;
if (!string.IsNullOrEmpty(Id))
{
for (int i = 0; i < Id.Split(',').Length; i++)
{
ids.Add(Convert.ToInt32(Id.Split(',')[i]));
}
prods =_context.Products.Where(t => ids.Contains(t.id));
}
else
{
prods = _context.Products.Take(5);
}
var selected = (from v in prods
select new
{
v.ProdName,
v.Price,
v.Description
}).ToList();
return Json(selected, JsonRequestBehavior.AllowGet);
}
Try to do it in a console like this: https://dotnetfiddle.net/AMwxiP
using System;
using System.Collections.Generic;
using System.Linq;
public class Product
{
public int Id { get; set; }
public string ProdName { get; set; }
public decimal? Price { get; set; }
public string Description { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
IQueryable<Product> products = (new List<Product> {
new Product
{
Id = 1,
},
new Product
{
Id = 2,
}
}).AsQueryable<Product>();
var Id = "1,2";
var ids = new List<int>();
IQueryable<Product> prods = null;
if (!string.IsNullOrEmpty(Id))
{
for (int i = 0; i < Id.Split(',').Length; i++)
{
ids.Add(Convert.ToInt32(Id.Split(',')[i]));
}
prods = products.Where(t => ids.Contains(t.Id));
}
else
{
prods = products.Take(5);
}
var selected = (from v in prods
select new
{
v.ProdName,
v.Price,
v.Description
}).ToList();
Console.WriteLine(selected.Count);
}
}

MVC ASP.NET Dropdown onchange load another dropdown

I have 2 dropdownlist on a page.When i select some value from first dropdown list then in second dropdownlist all the values should load according to the value selected (Subcategories loaded according to Categories). Here is what I tried but it doesn't work:
Model
public class Product
{ ...
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
public int SubCategoryId { get; set; }
public virtual SubCategory SubCategory { get; set; }
public IEnumerable<SelectListItem> SubCategories { get; set; }
...
}
View
<label>Select Category</label>
#Html.DropDownListFor(m => m.CategoryId, new SelectList(Model.Categories, "Value", "Text"), "Select Category", new { id = "catList", #class = "form-control" })
<label>Selectat Subcategory</label>
#Html.DropDownListFor(m => m.SubCategoryId, new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"), "Selectat Subcategory", new { id = "subcatList", #class = "form-control" })
<script type="text/javascript">
$(document).ready(function () {
$("#catList").change(function () {
var cID = $(this).val();
$.getJSON("../Product/New/LoadSubCategories", { catId: cID },
function (data) {
var select = $("#subcatList");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Selecteaza o subcategorie"
}));
$.each(data, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
</script>
Controller
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult LoadSubCategories(string catId)
{
var subCatList = GetAllSubCategories(Convert.ToInt32(catId));
return Json(subCatList, JsonRequestBehavior.AllowGet);
}
[NonAction]
public IEnumerable<SelectListItem> GetAllSubCategories(int selectedCatId)
{
//generate empty list
var selectList = new List<SelectListItem>();
var subcategories = from sbcat in db.SubCategories
where sbcat.CategoryId == selectedCatId
select sbcat;
foreach (var subcategory in subcategories)
{
//add elements in dropdown
selectList.Add(new SelectListItem
{
Value = subcategory.SubCategoryId.ToString(),
Text = subcategory.SubCategoryName.ToString()
});
}
return selectList;
}
you need to change your getJson to Ajax method
here is the ajax sample code
$.ajax({
type: "GET",
url: '/Product/New/LoadSubCategories',
data: {catId: cID},
success: successFunc,
error: errorFunc
});
function successFunc(data) {
var select = $("#subcatList");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Selecteaza o subcategorie"
}));
$.each(data, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
}
function errorFunc() {
alert('error');
}
});
this ajax code you need to write on dropdown change and in success of ajax call, you need to write the code you want to do when dropdown's value changes and data received successfully
For change the second Drop down value according to first drop down value, you need to write an Onchange event, then only it will get change.. please check below stackoverflow question an answer it will be help full to you
Click here

asp.net mvc Html.DropDownListFor: how to handle selected id

I have a problem with using #Html.DropDownListFor element.
What i have:
Model 'DatabaseModel':
public class DirectionEntity
{
public string Id { get; set; }
public string DirectionName { get; set; }
}
public class ViewModel
{
public int SelectedDirectionID { get; set; }
public List<DirectionEntity> DirectionList { get; set; }
}
Model 'DataFactory':
public class DataFactory
{
public static ViewModel Refresh()
{
using (var db = new MyDatabase())
{
return new ViewModel()
{
DirectionList = db.Directions.Select(_ => new { _.Id, _.DirectionName })
.ToList()
.Select(_ => new DirectionEntity() { Id = _.Id.ToString(), DirectionName = _.DirectionName })
.ToList(),
};
}
}
}
Controller:
public System.Web.Mvc.ActionResult AddNewDocument()
{
var db = DataFactory.Refresh();
return View(db);
}
[HttpPost]
public System.Web.Mvc.ActionResult AddNewEntry(ViewModel m)
{
m = DataFactory.Save(m);
ModelState.Clear();
return View(<some view>);
}
View:
#using (Html.BeginForm())
{
#Html.DropDownListFor(m => m.SelectedDirectionID, new SelectList(Model.DirectionList.Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.DirectionName }), "Value", "Text"), new { #class = "Duration", required = "required" })
<button type="submit" class="btn btn-default SaveAll">Save</button>
}
The question:
How to handle 'SelectedDirectionID' value, after user selected some position on dropdownlist, but not yet sent the request to the server using a POST-method.
See what the id of your dropdown is and then you can subscribe to the change event on the client side. You can do this using jQuery.
$("#idOfYourDropDown").change(function () {
// Do whatever you need to do here
// Here are some ways you can get certain things
var end = this.value;
var selectedText = $(this).find("option:selected").text();
var selectedValue = $(this).val();
alert("Selected Text: " + selectedText + " Value: " + selectedValue);
});
Also you should see my answer here on why you should not return a view from a POST action the way you are.
In this case you have to use Jquery. As per your view id for your drop down is 'SelectedDirectionID';
Your Js:
$(document).ready(function () {
var selectedValue = $('#SelectedDirectionID').val();
var selectedText = $("#SelectedDirectionID option:selected").text();
});
Or Inside drop down change event.
$('#SelectedDirectionID').change(function () {
var selectedValue = $(this).val();
var selectedText = $(this).find("option:selected").text();
});

How to databind a dropdownlist using knockout and MVC and Entity Framework

I have two cascading dropdownlists which I would like to bind based on my knockout.js. Essentially what I want to achieve is two dropdownlist that populate from a database for each branch of the company and one which will populate the various departments based on the branch that was selected in the other dropdownlist. I am having problems converting to a list and then binding to dropdownlist.
function CompanyViewModel() {
var self = this;
self.DepartmentName = ko.observable(" ")
self.Department =ko.observableArray([]);
self.DepartmentName = ko.Observable([]);
self.Branch =ko.observableArray([]);
self.BranchName = ko.Observable([])
}
CompanyViewModel = new CompanyViewModel();
ko.applyBindings(CompanyViewModel);
function populateCompanyBranches() {
$.ajax({
type: "GET",
$.when(getSecureData("/api/Branches/" ))
.done(function (Branches) {
Branch.unshift({ "BranchID": 0, "department name": "Please select a Branch." });
CompanyViewModel.Branch(Branch);
})
.fail(function (message) {
$.msgbox(message);
});
};
function populateBranchDepartments() {
$("#Branches").change(function () {
var BranchID = $("#Branches").val();
$.ajax({
type: "GET",
$.when(getSecureData("/api/Departments/GetDepartment" + BranchID))
.done(function (Department) {
CompanyDepartment.unshift({ "CompanyID": 0, "departmentName": "Please select a department" });
CompanyViewModel.Department(Department);
})
.fail(function (message) {
$.msgbox(message);
});
};
}
View
Branch Name: <select data-bind="options: CompanyViewModel. CompanyViewModel, optionsCaption: 'Select a Branch',
optionsValue: function (item) { return item.BranchId; },
optionsText: function (item) { return item.BranchName; }, value: Branch,
valueUpdate: 'change'" id="Branches" name="Branch"></select>
<br />
Deaprtment Name: <select data-bind="options: CompanyViewModel.Department, optionsCaption: 'Choose Department...',
optionsValue: function (item) { return item.DepartmentId; },
optionsText: function (item) { return item.DepartmentName; }, value: DepartmentName,
valueUpdate: 'change'" id="Department" name="Department"></select>
<br />
</div>
public class CompanyDTO
{
public int BranchId { get; set; }
public string BranchName { get; set;}
public int DepartmentId { get; set; }
public string DepartmentName { get; set;}
}
public static class CompanyBranchList
{
public static CompanyDTO DepartmentToBranchDTO(listing e)
{
return new CompanyDTO
{
BranchId = e.BranchId,
BranchName = e.BranchName
DepartmentId = e.DepartmentId
DepartmentName = e.DepartmentName
};
}
public static List<CompanyDTO> ListBranchToDepartmentDTO(List<listing> e)
{
List<CompanyDTO> lstCompanyDTO= e.Select(
lstng => new CompanyDTO()
{
BranchId = lsting.BranchId,
BranchName = lsting.BranchName
DepartmentId = lsting.DepartmentId
DepartmentName = lsting.DepartmentName
}).ToList();
return ListBranchToDepartmentDTO;
}
Repository
public class CompanyRepository : IComapnyRepository
{
public List<CompanyDTO> GetBranches()
{
using (TestDBEntities dbcontext1 = new TestDBEntities())
{
var lstCountries = from r in dbcontext1.Branches select r;
List<CompanyDTO> lst = new List<CompanyDTO>();
lst = CompanyBranchList.DepartmentToBranchDTO(lstCompanyDTO.ToList());
return lst;
}
}
Controller
public List<CompanyDTO> GetDepartments(int deparmentId)
{
using (TestDBEntities dbcontext = new TestDBEntities())
{
var lstDep = dbcontext.States.Where(b => b.DepartmentID == departmentId).ToList();
List<CompanyDTO> list = new List<CompanyDTO>();
list = CompanyBranchList.ListBranchToDepartmentDTO(lstDep.ToList());
return list;
}
}
You achieve cascading dropdown lists by doing this:
// the view model bound to the view
var vm = {
branches: ko.observableArray([]),
selectedBranch: ko.observable(),
departments: ko.observableArray([]),
selectedDepartment: ko.observable()
}
// subscription to listen to changes to the selected branch
vm.selectedBranch.subscribe(function(current, last){
if(!current) return; // do nothing if nothing is selected
if(current == last) return; // do nothing if nothing changed
$.ajax({
type: 'GET',
url: '/api/Departments/GetDepartment/' + current.BranchId,
contentType: 'application/json'
})
.then(function(result){
vm.departments(result)
});
}
// load the list of branches
$.ajax({
type: 'GET',
url: '/api/Branches',
contentType: 'application/json'
})
.then(function(result){
vm.branches(result); // populate branch observable array
ko.applyBindings(vm);// bind view model to view
});

How do I capture a specific value from a POST ajax response?

Refer to the comment inside the ajax success function:
function CreateProjectTree(sc)
{
$.ajax({
type: "POST",
url: "../api/projects/SearchProjects",
data: sc,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data)
{
if ($(data).length === 1)
{
window.location.replace("../ViewProjectDetails.aspx?ProjectId=" + //here's where I need to get the id;
}
else
{
buildTree(data);
}
},
});
}
This is what the controller looks like for the post:
public class ProjectsController : ApiController
{
public List<Item> SearchProjects(GBLProjectSearchCriteria searchCriteria)
{
var ProjectSearchResult = new ProjectSearchResultController();
searchCriteria.SearchType = "P";
searchCriteria.QueryString = "?ProjectId=";
var GBLProjectSearchResultListData = ProjectSearchResult.GetProjectSearchResultList(searchCriteria);
var projectList = (from GBLProjectSearchResult item in GBLProjectSearchResultListData
select new Item
{
Id = item.Id,
Title = item.Title,
Url = item.NavigateUrl + item.QueryString
}).ToList();
foreach (var project in projectList)
{
//seasons
project.Items = new List<Item>();
var SeasonSearchResult = new ProjectSearchResultController();
searchCriteria.Id = project.Id;
searchCriteria.SearchType = "S";
searchCriteria.QueryString = "?ProjectId=" + project.Id + "&SeasonId=";
var GBLSeasonSearchResultListData = SeasonSearchResult.GetProjectSearchResultList(searchCriteria);
foreach (var season in from GBLProjectSearchResult item in GBLSeasonSearchResultListData
select new Item
{
Id = item.Id,
Title = item.Title,
Url = item.NavigateUrl + item.QueryString
})
{
project.Items.Add(season);
project.HasChildren = (project.Items.Count > 0);
}
foreach (var season in project.Items)
{
//episodes
season.Items = new List<Item>();
var episodeSearchResult = new ProjectSearchResultController();
searchCriteria.Id = season.Id;
searchCriteria.SearchType = "E";
searchCriteria.QueryString = "?ProjectId=" + project.Id + "&SeasonId=" + season.Id + "&EpisodeId=";
var GBLEpisodeSearchResultListData = episodeSearchResult.GetProjectSearchResultList(searchCriteria);
foreach (GBLProjectSearchResult item in GBLEpisodeSearchResultListData)
{
var episode = new Item
{
Id = item.Id,
Title = item.Title,
Url = item.NavigateUrl + item.QueryString
};
season.Items.Add(episode);
season.HasChildren = (season.Items.Count > 0);
}
}
}
return projectList;
}
public class Item
{
readonly string take2Root = ConfigurationManager.AppSettings["Take2Root"];
private string url;
public int Id
{
get;
set;
}
public string Title
{
get;
set;
}
public bool HasChildren
{
get;
set;
}
public List<Item> Items
{
get;
set;
}
public string Url
{
get
{
return url;
}
set
{
url = take2Root + value.Replace("..", "");
}
}
}
}
I need to get the ID of the parent node returned by this controller.
I would know how to work with a GET request, however, I have to do a POST here and I'm unsure on how to extract the ID inside the ajax success function.
Can someone give me a hand?
Thanks!
inside your if ($(data).length === 1) statement you can add debugger; (or set a break-point) then examine the data object using chrome's developer tools. The id you're after will be something like data.objects[0].id

Categories

Resources