how to use cascading dropdownlist in mvc - asp.net-mvc-3

am using asp.net mvc3, i have 2 tables in that i want to get data from dropdown based on this another dropdown has to perform.for example if i select country it has to show states belonging to that country,am using the following code in the controller.
ViewBag.country= new SelectList(db.country, "ID", "Name", "--Select--");
ViewBag.state= new SelectList("", "stateID", "Name");
#Html.DropDownListFor(model => model.Country, (IEnumerable<SelectListItem>)ViewBag.country, "-Select-")
#Html.DropDownListFor(model => model.state, (IEnumerable<SelectListItem>)ViewBag.state, "-Select-")
but by using this am able to get only the countries.

There is a good jQuery plugin that can help with this...
You don't want to refresh the whole page everytime someone changes the country drop down - an ajax call to simply update the state drop down is far more user-friendly.

Jquery Ajax is the best Option for these kind of questions.
Script Code Is Given below
<script type="text/javascript">
$(function() {
$("##Html.FieldIdFor(model => model.Country)").change(function() {
var selectedItem = $(this).val();
var ddlStates = $("##Html.FieldIdFor(model => model.state)");
$.ajax({
cache:false,
type: "GET",
url: "#(Url.Action("GetStatesByCountryId", "Country"))",
data: "countryId=" ,
success: function (data) {
ddlStates.html('');
$.each(data, function(id, option) {
ddlStates.append($('<option></option>').val(option.id).html(option.name));//Append all states to state dropdown through returned result
});
statesProgress.hide();
},
error:function (xhr, ajaxOptions, thrownError){
alert('Failed to retrieve states.');
statesProgress.hide();
}
});
});
});
</script>
Controller:
public ActionResult GetStatesByCountryId(string countryId)
{
// This action method gets called via an ajax request
if (String.IsNullOrEmpty(countryId))
throw new ArgumentNullException("countryId");
var country = GetCountryById(Convert.ToInt32(countryId));
var states = country != null ? GetStatesByConutryId(country.Id).ToList() : new List<StateProvince>();//Get all states by countryid
var result = (from s in states
select new { id = s.Id, name = s.Name }).ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}

Try this,
<script type="text/javascript">
$(document).ready(function () {
$("#Country").change(function () {
var Id = $("#Country").val();
$.ajax({
url: '#Url.Action("GetCustomerNameWithId", "Test")',
type: "Post",
data: { Country: Id },
success: function (listItems) {
var STSelectBox = jQuery('#state');
STSelectBox.empty();
if (listItems.length > 0) {
for (var i = 0; i < listItems.length; i++) {
if (i == 0) {
STSelectBox.append('<option value="' + i + '">--Select--</option>');
}
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
else {
for (var i = 0; i < listItems.length; i++) {
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
}
});
});
});
</script>
View
#Html.DropDownList("Country", (SelectList)ViewBag.country, "--Select--")
#Html.DropDownList("state", new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"), "-- Select --")
Controller
public JsonResult GetCustomerNameWithId(string Country)
{
int _Country = 0;
int.TryParse(Country, out _Country);
var listItems = GetCustomerNameId(_Country).Select(s => new SelectListItem { Value = s.CountryID.ToString(), Text = s.CountryName }).ToList<SelectListItem>();
return Json(listItems, JsonRequestBehavior.AllowGet);
}

Related

i cant populate select in jquery,my code is in razor c#, i try this

the content of the table is this
enter image description here
#section scripts{
<script>
function adddata() {
$.ajax({
type: "POST",
url: '?handler=GetItems',
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
data: { Id: $("#IdSelectIdPuesto").val() },
success: function (data) {
for (var i = 0; i < data.length; i++) {
$("#IdSelectlocalidad").append("<option value='" + data[i].value +
"' selected>" + data[i].text + "</option>");
}
},
error: function (result) {
alert("fail");
}
})
}
</script>
}
public JsonResult OnPostGetItems(int Id)
{
//displaydata1 = rTDBContext.Turnos.ToList();
var displayda = (from c in displaydata1
select c.LocNombre).Distinct().ToList();
return new JsonResult(new List<SelectListItem> = { new SelectListItem { Value = "1", Text = "LOcalidad" + 1 }, new SelectListItem { Value = "2", Text = "LOcalidad" + 2 } });
}
i'm trying a select distinct and add to the specified select the id and the locNombre to the text
If you want to change the options of $("#IdSelectlocalidad") with the id passed from ajax,here is a demo:
public JsonResult OnPostGetItems(int Id)
{
//displaydata1 = rTDBContext.Turnos.ToList();
var displayda = (from c in l
where c.Id==Id select new SelectListItem { Text=c.LocNombre, Value=c.Id+""}).Distinct().ToList();
return new JsonResult(displayda);
}
js(remove selected in the option,with the code it will select the first option by default):
#section scripts{
<script>
function adddata() {
$.ajax({
type: "POST",
url: '?handler=GetItems',
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
data: { Id: $("#IdSelectIdPuesto").val() },
success: function (data) {
for (var i = 0; i < data.length; i++) {
$("#IdSelectlocalidad").append("<option value='" + data[i].value +
"' >" + data[i].text + "</option>");
}
},
error: function (result) {
alert("fail");
}
})
}
</script>
}
[thanks Yiyi You, ifound the correct answer i doit this way]
[enter image description here][1]
[1]: https://i.stack.imgur.com/KWsIi.png do as folow
displaydata1 = rTDBContext.Turnos.ToList();
var display = displaydata1.DistinctBy(x => x.LocNombre ).ToList();
var displayda = (from c in display
select new SelectListItem { Text = c.LocNombre, Value = c.IdLocalidad + "" }).Distinct().ToList();
now is working as desired.

Populate One Dropdown on selection of other -MVC

I am trying to populate one dropdown list based on the selection of other dropdown list. This is what I have till now.
My Controller:
[HttpPost]
public JsonResult LoadReasonsByCategory(string resId)
{
var queryy = from item in db.T_SD_CD_GROUP
where resId.Contains(item.SCG_CD_TYPE)
select new
{
item.SCG_CD_TYPE,
item.SCG_CD_DESC
};
var ObjList = new List<SelectListItem>();
foreach (var item in queryy)
{
ObjList.Add(new SelectListItem() { Text = item.SCG_CD_DESC.ToString(), Value = (item.SCG_CD_TYPE) });
}
return Json(ObjList, JsonRequestBehavior.AllowGet);
}
JS
$("#ddlReasonCategory").on('change', function () {
var item = $(this).find("option:selected");
var value = $("#ddlReasonCategory").val(); //get the selected option value
//var text = item.html(); //get the selected option text
//alert(item.val());
$.ajax({
url: '/CRActual/LoadReasonsByCategory',
type: 'POST',
datatype: 'application/json',
contentType: 'application/json',
data: JSON.stringify({ resId: value}),
success: function (data) {
alert("sUccess");
$("#ddlReasonType").html("");
ddlReasonType.append($('<option></option>').val("").html("Please select a City"));
for (var i = 0; i < data.length; i++) {
ddlReasonType.append($('<option></option>').val(data[i].Text).html(data[i].Text));
}
},
error: function () {
alert("Fail")
},
});
View:
#Html.DropDownList("ddlReasonCategory", (IEnumerable<SelectListItem>)ViewBag.ddlReasonCategory, new { #class = "chosen-select col-md-3", #data_placeholder = "Please select" })
#Html.DropDownList("ddlReasonType", new SelectList(string.Empty, "Value", "Text"), "Please select a Reason", new { #class = "chosen-select col-md-3", #data_placeholder = "Please select" })
The codes runs absolutely without any errors, but the second drop down binding fails. Where am I going Wrong?
If your LoadReasonsByCategory method returns data correctly then write the success function code in the Ajax as follows:
success: function (data) {
var ddlResonTypeSelector = $("#ddlReasonType");
ddlResonTypeSelector.empty();
if (data.length > 0) {
ddlResonTypeSelector.append($("<option>").val("").text("Please select a Reason Type"));
$(data).each(function(index, item) {
ddlResonTypeSelector.append($("<option>").val(item.value).text(item.text));
});
} else {
ddlResonTypeSelector.append($("<option>").val("").text("Reason Type List is empty!"));
}
},

ASP.net cascading dropdown list

trying to implement country state dropdown in mvc but couldn't..
conotroller :-
[HttpGet]
public ActionResult GetCities(int StateId)
{
Business.Services.City cityService = new Business.Services.City();
List<Business.Models.City> stateList = cityService.GetCityByStateId(StateId);
//var jsonSerialiser = new JavaScriptSerializer();
//var json = jsonSerialiser.Serialize(stateList);
return Json(new { stateList }, JsonRequestBehavior.AllowGet);
}
method:
public List<Models.City> GetCityByStateId(int StateId)
{
try
{
var list = new List<SelectListItem>();
Collection<DBParameters> parameters = new Collection<DBParameters>();
parameters.Add(new DBParameters() { Name = "StateId", DBType = DbType.Int32, Value = StateId });
var city = this.ExecuteProcedure<Models.City>("GetCityByState", parameters).ToList();
//if (city != null && city.Count > 0)
//{
// list = city.Select(x => new SelectListItem { Text = x.CityName, Value = x.StateId.ToString() }).ToList();
//}
return city;
}
catch (Exception ex)
{
throw;
}
}
change event:
$('.ddlstate').change(function () {
debugger;
$.ajax({
url: '#Url.Action("GetCities", "User")',
type: "GET",
data: { StateId: $(this).val() },
dataType: "json",
success: function (result) {
debugger;
//alert(result.stateList[0].CityId);
$.each(result.stateList, function () {
debugger;
$('.cityddl').append($("<option></option>").val(CityId).html(CityName));
});
},
error: function (result, status, jQxhr) {
alert("Error: " + result + "-" + status + "-" + jQxhr);
}
});
});
i get count of the citites in method and controller but when i run project and change state dropdown i got blank city dropdown. what is wrong?
It looks like you're missing a couple of things in the $.each() call.
You should pass the JSON result from the ajax call to the $.each
You also need to provide a parameter to the callback function so that the callback function has something to work with
It could look something like this:
$.each(result.stateList, function(index, city) {
$('.cityddl').append($("<option></option>").val(city.CityId).html(city.CityName));
});

how to load a partial view inside an anchor tag which has been generated via Ajax

I have a form with a dropdownlist. When selecting an option, I make an ajax call to dynamically add a list of links in the view. When I click on one of the links, I want to update the existing page with a partial view returned by the PostListSubCategory() method.
Currently, clicking on one of the links does a redirect and shows the partial view in a new page. How can I update the the existing page?
<script language="javascript" type="text/javascript">
function GetSubCategory(_categoryId) {
var procemessage = "<a='0'> Please wait...</a>";
$("#SubCategoryID").html(procemessage).show();
var url = "/Posts/GetSubCategoryById/";
$.ajax({
url: url,
data: { categoryid: _categoryId },
cache: false,
type: "POST",
success: function (data) {
var markup = "";
for (var x = 0; x < data.length; x++) {
var num = data[x].Text;
markup += "<a href='/posts/postlistsubcategory?subcategoryid=" + data[x].Text + "'>" + data[x].Text + "</a><br />";
// markup += "<a href=" + Url.Action("postlistsubcategory", new { subcategoryid = num });
}
$("#SubCategoryID").html(markup).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
$.ajax({
url: "/Posts/PostListCategory",
data: { categoryid: _categoryId },
cache: false,
type: "POST",
success: function (data) {
$("#postList").html(data).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
</script>
#using (Html.BeginForm())
{
#Html.ListBoxFor(m => m.CategoryModel, new SelectList(Model.CategoryModel, "CategoryId", "Name"), new { #id = "ddlcategory", #style = "width:200px;", #onchange = "javascript:GetSubCategory(this.value);" })
<br />
<br />
<div id="SubCategoryID" name="SubCategoryID" style="width: 200px"></div>
<br /><br />
}
In the controller
public PartialViewResult PostListSubCategory(string subcategoryid)
{
if (subcategoryid == null)
{
return PartialView(db.Posts.ToList());
}
return PartialView("PostList", db.Posts.Include(i => i.SubCategory).Where(p => p.SubCategory.Name == subcategoryid));
}
You currently dyamically generating links with an href attribute so clicking on them will do a redirect. You need to handle the click event of those links using event delegation and then use ajax to update the existing DOM. There a some other bad practices in your code and I suggest you use the following
#using (Html.BeginForm())
{
// no need to override the id attribute and use Unobtrusive Javascript (don't pollute markup with behavior)
#Html.ListBoxFor(m => m.CategoryModel, new SelectList(Model.CategoryModel,"CategoryId", "Name"))
}
<div id="SubCategoryID"></div> // no point adding a name attribute
<div id="postList"></div>
var subcategories = $('#SubCategoryID');
$('#CategoryModel').change(function() {
var url = '#Url.Action("GetSubCategoryById", "Posts")'; // don't hard code url's
var category = $(this).val();
subcategories.empty(); // clear any existing links
$.post(url, { categoryid: category }, function(data) { // this could be a GET?
$.each(data, function(index, item) {
subcategories.append($('<a></a>').text(item).attr('href','#').addClass('subcategory')); // see note below
});
});
});
Note: Since your ajax only needs one property to generate the links (the value to display in the link), then your GetSubCategoryById() should be returning IEnumerable<string> not a collection of complex objects (you current code suggest your returning other data which you never use). If you do need to return a collection of objects, then change the above to use .text(item.Text). The above code will generate
.....
for each item you return. Then add an additional script to handle the .click() event of the links (since the links are dynamically added, you need event delegation using the .on() method)
var posts = $('#postList');
$('#SubCategoryID').on('click', '.subcategory', function() {
var url = '#Url.Action("postlistsubcategory", "posts")';
var subcategory = $(this).text();
posts.load(url, { subcategoryid: subcategory });
});

How to include the #Html.AntiForgeryToken() when deleting an object using a Delete link

i have the following ajax.actionlink which calls a Delete action method for deleting an object:-
#if (!item.IsAlreadyAssigned(item.LabTestID))
{
string i = "Are You sure You want to delete (" + #item.Description.ToString() + ") ?";
#Ajax.ActionLink("Delete",
"Delete", "LabTest",
new { id = item.LabTestID },
new AjaxOptions
{ Confirm = i,
HttpMethod = "Post",
OnSuccess = "deletionconfirmation",
OnFailure = "deletionerror"
})
}
but is there a way to include #Html.AntiForgeryToken() with the Ajax.actionlink deletion call to make sure that no attacker can send a false deletion request?
BR
You need to use the Html.AntiForgeryToken helper which sets a cookie and emits a hidden field with the same value. When sending the AJAX request you need to add this value to the POST data as well.
So I would use a normal link instead of an Ajax link:
#Html.ActionLink(
"Delete",
"Delete",
"LabTest",
new {
id = item.LabTestID
},
new {
#class = "delete",
data_confirm = "Are You sure You want to delete (" + item.Description.ToString() + ") ?"
}
)
and then put the hidden field somewhere in the DOM (for example before the closing body tag):
#Html.AntiForgeryToken()
and finally unobtrusively AJAXify the delete anchor:
$(function () {
$('.delete').click(function () {
if (!confirm($(this).data('confirm'))) {
return false;
}
var token = $(':input:hidden[name*="RequestVerificationToken"]');
var data = { };
data[token.attr('name')] = token.val();
$.ajax({
url: this.href,
type: 'POST',
data: data,
success: function (result) {
},
error: function () {
}
});
return false;
});
});
Now you could decorate your Delete action with the ValidateAntiForgeryToken attribute:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
...
}
Modifying the answer by Bronx:
$.ajaxPrefilter(function (options, localOptions, jqXHR) {
var token, tokenQuery;
if (options.type.toLowerCase() !== 'get') {
token = GetAntiForgeryToken();
if (options.data.indexOf(token.name)===-1) {
tokenQuery = token.name + '=' + token.value;
options.data = options.data ? (options.data + '&' + tokenQuery)
: tokenQuery;
}
}
});
combined with this answer by Jon White
function GetAntiForgeryToken() {
var tokenField = $("input[type='hidden'][name$='RequestVerificationToken']");
if (tokenField.length == 0) { return null;
} else {
return {
name: tokenField[0].name,
value: tokenField[0].value
};
}
Edit
sorry - realised I am re-inventing the wheel here SO asp-net-mvc-antiforgerytoken-over-ajax/16495855#16495855

Resources