How to create a dynamic dropdown in mvc - asp.net-mvc

How to create a dropdown whose option values are coming from controller.
controller will be getting it from database table's any column value.
for example if that dropdown is for selecting country, and i have 3 country in my database table's country column, in dropdown it should show the 3 country. And if I add one more value in country table, that also should come in dropdown.
I am new to MVC an this is found bit difficult. I am using mvc5.
NB: since I already one model is refered inside the view, I cant add the model for this dropdown

I have done the same in my own website. This is how I do it:
Firstly, create a action for controller which returns JSON value:
public ActionResult GetCountryNames()
{
List<string> CountryNames = new List<string>();
CountryNames = context.GetCountries(); // your EF context to get countrynames from database
return Json(CountryNames.ToArray());
}
Then in your view add this html mark up:
<select id="countrylist" onchange="DoSomething();"></select>
This is your dropdownlist. It has javascript function declared in "onchange" event, if you want to do something when value changes.
Lastly, you need to add your javascript function, which does ajax call to your controller action, gets values and set it to your dropdownlist:
function GetCountryList() {
var serviceURL = '/Home/GetCountryNames';
$.ajax({
type: "post",
dataType: "json",
url: serviceURL,
success: successFunc,
async: false,
error: errorFunc
});
function successFunc(data, status) {
var countrylist = $('#countrylist');
countrylist.empty();
for (var i = 0; i < data.length; i++) {
var $option = $("<option>", { id: "option" + i });
$option.append(data[i]);
countrylist.append($option);
}
}
function errorFunc(data, status) {
alert('error');
}
}
And when your document is ready, run function GetCountryList().
Probably easiest is to do it with jQuery. Like this:
<script type="text/javascript">
$(document).ready(function () {
GetCountryList();
});
</script>

Related

View content is not displayed correctly after redirected in controller in asp.net mvc

I have a action method in the controller and two views in different language.
public ActionResult Index(Guid id, string languageName)
{
var view = "Welcome_en";
if (languageName == "Spanish")
view = "Welcome_es";
return View(view, model);
}
The default languageName is "English".(In RouteConfig.cs defaults part). So at the beginning, the page is loaded at http://localhost:12091/Some/sssf6bda-9r5e-64d7-9bd2-63c2te616adb.
And I saw the view was Welcome_en.cshtml. in that view I have a dropdown menu for languages to switch active language. I select Spanish then make an ajax call.
$("#Languages").change(function () {
var activeLanguage= $(this).find('option:selected').val();
$.ajax({
url: "/Some/Index",
datatype: "text",
data: { id: '#Model.Guid', languageName: activeLanguage },
type: "POST",
success: function () {
console.log('Success')
}
})
Then I saw the code entered the controller again. The view to be displayed should be Welcome_es.cshtml.
The view Welcome_es.cshtml basically is same as Welcome_en.cshtml. The difference is the content in different language. And I set break points in Welcome_es.cshtml, it did reached. However the final displayed result is still same as Welcome_en.cshtml.
I am not sure why it shows the English view's content, I cleaned the cookies but it is same. Also I set a break point in English page, it didn't go to there when the language was "Spanish".
Your AJAX request is returning your view, but you aren't doing anything with it. If your view is a partial then you can change the success callback in your AJAX call to update the part of the page which the HTML should replace.
$.ajax({
url: "/Some/Index",
datatype: "text",
data: { id: '#Model.Guid', languageName: activeLanguage },
type: "POST",
success: function (html) {
$('.partial').html(html);
}
});
Or if the view is really a full page then don't use AJAX to make the request.
Your current code is making the ajax call, but is not using the response coming from that call.
You should return the partial view result and use that to update the relevant part of your DOM to see the changes. You can do that in the success event of the ajax call
$.ajax({
url: "/Some/Index",
data: { id: '#Model.Guid', languageName: activeLanguage },
type: "POST",
success: function(response) {
$("#someDiv").html(response);
}
});
Assuming you have a div with id someDiv present in your page, the above code will update the inner html of that element with the response coming from your ajax call, which is the html markup generated by the corresponding views (based on the language name you are passing from client side)
I also noticed that you are calling the same action method for your normal page load and the ajax call. In that case, what are you trying to achieve with the ajax call ? You could simply reload the page. No need of ajax.
$(function() {
$("#Languages").change(function() {
var activeLanguage = $(this).val();
window.location.href = "#Url.Action("index","Home")?languageName="
+ activeLanguage +"&id=#Guid.NewGuid()";
});
});
If you are using a page reload, you might want to select the dropdown with the selection from previous page. You may use the Html.DropDownListFor helper with a view model for your page to address this issue.
Add a new property to your view model to store the selected language.
public class YourPageViewModel
{
// Your other existing properties goes here
public string SelectedLanguage { set;get;}
}
Now in your GET action method, you should set the SelectedLanguage property value based on your method parameter.
public ActionResult Index(Guid id, string languageName)
{
var view = "Welcome_en";
if (languageName == "Spanish")
view = "Welcome_es";
var model = new YourPageViewModel();
model.SelectedLanguage = languageName;
return View(view, model);
}
Now in your view, use the DropDownListFor helper method
#model YourPageViewModel
#Html.DropDownListFor(m => m.SelectedLanguage, languages,
new { #class = "form-control" });
Assuming languages is a list of SelectListItem's. Replace it with the collection you have to render the dropdown items.
The helper will render the dropdown with the name and id SelectedLanguage. So make sure you update that in your javasacript as well.
$(function() {
$("#SelectedLanguage").change(function() {
var activeLanguage = $(this).val();
window.location.href = "#Url.Action("index","Home")?languageName="
+ activeLanguage +"&id=#Guid.NewGuid()";
});
});

How to Prevent Page refresh on select change for dropdownlist in MVC

I have a dropdownlist in my razor view MVC like
#Html.DropDownListFor(n => n.EMP_ID, (SelectList)ViewBag.EmployeeList, new { #id = "ddlemployee" },"---choose an Employee Name--").
I have applied select change event to drop-down using jquery, when select Employee name getting Employee names and realted data, but problem is when i select a value in drop-down, dropdownlist setting again set to default first value,
It is not sticking to particular selected value, in terms of Asp.net terminology, how to prevent postback to dropdownlist?
//Redirected to Controller
<script>
$(document).ready(function () {
$("#ddlemployee").change(function () {
location.href ='#Url.Action("GetEmployeeDetails", "Employer")'
});
});
</script>
//Action Method in Employer Controller
public ActionResult GetEmployeeDetails(Timesheetmodel model)
{
try
{
ViewBag.EmployeeList = objts.getEmployeeNames();
var emps = from n in db.TIMESHEETs
where n.RES_ID == model.EMP_ID
select n;
int count = emps.Count();
foreach (TIMESHEET ts in emps)
{
model.PROJ_ID = ts.PROJ_ID;
model.SUN_HRS = ts.SUN_HRS;
model.MON_HRS = ts.MON_HRS;
model.TUE_HRS = ts.TUE_HRS;
model.WED_HRS = ts.WED_HRS;
model.THU_HRS = ts.THU_HRS;
model.FRI_HRS = ts.FRI_HRS;
model.SAT_HRS = ts.SAT_HRS;
}
}
catch (Exception ex)
{
throw ex;
}
return View("Timesheet", model);
}
ASP.Net Webforms achieve StateFullness by using Some thing called ViewState
It is implemented as hidden fields in the page to hold data between requests.
This way , asp.net webforms achieves post back mechanism and was able to hold values in bewteen the requests.
Since Http is a stateless protocol , which means it has no relation between requests.
View State is absent in ASP.Net MVC.
So, you have to stop postback by partially posting back . Which means that you need to send an asynchronous request with out refreshing whole page.
It is possible by using AJAX. You can either use
MVC Ajax or Jquery Ajax.
By using AJax, we can eliminate the post back and then do the partial post back.
Solution:
$("#dropdownid").change(function(event e)
{
//Make your ajax request here..
});
Hope this helps
Updated:
$("#dropdownid").change(function () {
$.ajax({
type: "post",
contentType: "application/json;charset=utf-8",
url: /*Your URL*/,
success: function (data) {
//do your callback operation
}
});
});
Got it.
Passing Empid as querystring from jquery like:
<script>
$(document).ready(function () {
$("#ddlemployee").change(function () {
debugger;
var empid = $("#ddlemployee").val();
location.href = '#Url.Action("GetEmployeeDetails", "Employer")?empid=' + empid ;
});
});
</script>
and assign "empid " to model "Empid" in Action method before foreach loop like
model.EMP_ID = empid;//in Controller Action Method before foreachloop of my code
// and this model.EMP_ID binded to dropdownlist.
this EMP_ID passes same id to dropdownlist which was selected. Thats it.

ASP MVC3 - Make second call to controller once jQuery autocomplete value selected

Below are the jQuery versions that I am referencing in my ASP MVC view
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js" type="text/javascript"></script>
Using the autocomplete widget, I would like the form to fill out a separate text box based on the user's selection from the autocomplete list. On this page, the user will begin typing a bank name. Once the user selects which bank they need, another field by the name of Dynamics ID needs to be populated with the appropriate value. Here is the jQuery as it's written right now
$(function () {
$("#BankNameAuto").autocomplete({
source: '#Url.Action("GetBanks", "AgentTransmission")',
minLength: 1,
onComplete: function (data) {
$.getJSON('#Url.Action("GetDynamicsId", "AgentTransmission")', data, function (result) {
$('Dynamics').val(result);
})
}
});
});
And here are the two controller methods that are called in the above jQuery
//GET
public JsonResult GetBanks(string term)
{
var banks = from c in db.BankListMaster.Where(n => n.BankName.Contains(term))
select c.BankName;
banks = banks.Distinct();
return Json(banks, JsonRequestBehavior.AllowGet);
}
//GET
public JsonResult GetDynamicsId(string term)
{
var dynamics = from c in db.BankListMaster.Where(n => n.BankName.Equals(term))
select c.LinkRepsToDynamicsUniqueId;
dynamics = dynamics.Distinct();
return Json(dynamics, JsonRequestBehavior.AllowGet);
}
Once the user has made a selection from the list, I wanted to be able to send back the ID value to that bank. That serves as the primary key for the BankListMaster table, of which BankName and DynamicsId are both fields. I'm still new to jQuery, however, so I may not be able to do this.
Right now, I've set a breakpoint in the first line of both controller methods. The GetBanks breakpoint fires everytime, however I cannot get the GetDynamicsId to fire at all.
EDIT
Since I'm only selecting the BankName field in the first query, I adjusted the GetDynamicsId method to use the bank name as the parameter.
I do something similar by handling the "select" event. It's not "onComplete" as you had in your example. Your code with this change would be:
$(function () {
$("#BankNameAuto").autocomplete({
source: '#Url.Action("GetBanks", "AgentTransmission")',
minLength: 1,
select: function (event, ui) {
$.getJSON('#Url.Action("GetDynamicsId", "AgentTransmission")', { term: ui.item.value }, function (result) {
$('Dynamics').val(result);
})
}
});
});

ASP.NET MVC Sort Listing by Selected item in DropDownList

I have a List of Listings within my Database. On my View, I have a DropDownList which contains categories. A category contains many listings.
When I select a specific category, I wish to only display those listings which have the category selected.
My main worry is how to generate the JQuery to call my SortListing method in my ListingController.
Here is the current HTML (Razor):
#Html.DropDownListFor(m => m.Categories, Model.Categories, "Select a Category")
My SortListing Method:
public List<Listing> SortListing(string categoryId)
{
var listings = new List<Listing>();
foreach (var listing in _service.ListAllEntities<Listing>())
{
if (listing.CategoryId == categoryId)
{
listings.Add(listing);
}
}
return listings;
}
EDIT I have the following. Put the categoryGuid is coming in null.
This is my code:
$(function () {
$('#SelectedCategoryGuid').change(function () {
var url = $(this).data('url');
var categoryId = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { categoryId: categoryId },
success: function (result) {
// TODO: manipulate the result returned from the controller action
}
});
});
});
</script>
<h2>Index</h2>
#Html.ActionLink("Create New Listing", "Create")
<br/>
<strong>Filter Listings</strong>
#Html.DropDownListFor(
m => m.SelectedCategoryGuid,
Model.Categories,
"Select a Category",
new {
id = "SelectedCategoryGuid",
data_url = Url.Action("SortListing", "Listing")
}
)
My main worry is how to generate the JQuery to call my SortListing
method in my ListingController.
Actually you should be having other worries as well that I will try to cover throughout my answer.
There's an issue with your DropDownListFor helper. You have used the same property on your model for both binding the selected category value and the list of categories which is wrong. The first parameter of the DropDownListFor helper represents a lambda expression pointing to a primitive type property on your view model:
#Html.DropDownListFor(
m => m.CategoryId,
Model.Categories,
"Select a Category",
new {
id = "categoryDdl",
data_url = Url.Action("SortListing", "Listing")
}
)
and then subscribe to the .change() event and trigger the AJAX request:
$(function() {
$('#categoryDdl').change(function() {
var url = $(this).data('url');
var categoryId = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { categoryId: categoryId },
success: function(result) {
// TODO: manipulate the result returned from the controller action
}
});
});
});
Now let's take a look at your SortListing controller action because there are issues with it. In ASP.NET MVC standard convention dictates that controller actions must return ActionResults. In your case you seem to be returning some List<Listing>. So the first thing you have to decide is the format you would like to use. One possibility is to return those listings as JSON formatted values:
public ActionResult SortListing(string categoryId)
{
var listings = _service
.ListAllEntities<Listing>()
.Where(x => x.CategoryId == categoryId)
.ToList();
return Json(listings, JsonRequestBehavior.AllowGet);
}
In this case inside your AJAX success callback you will receive this collection of listings and you will have to update your DOM:
success: function(result) {
// result represents an array of listings
// so you could loop through them and generate some DOM elements
}
Another possibility is to have your controller action return a partial view:
public ActionResult SortListing(string categoryId)
{
var listings = _service
.ListAllEntities<Listing>()
.Where(x => x.CategoryId == categoryId)
.ToList();
return PartialView("Listings", listings);
}
and then you will have a corresponding partial view:
#model List<Listing>
#foreach (var listing in Model)
{
<div>#listing.SomeProperty</div>
}
and then inside the success callback you will refresh some containing placeholder:
success: function(result) {
$('#SomeDivIdThatWrapsAroundTheListingsPartial').html(result);
}
So to recap you could either have the controller action return JSON and then manually build the corresponding DOM tree using javascript or return a partial view which will already contain the corresponding markup and simply refresh some containing div with this partial.

How to send a model in jQuery $.ajax() post request to MVC controller method

In doing an auto-refresh using the following code, I assumed that when I do a post, the model will automatically sent to the controller:
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
//data: ??????
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
Every time there is a post, I need to increment the value attribute in the model:
public ActionResult Modelpage(MyModel model)
{
model.value = model.value + 1;
return PartialView("ModelPartialView", this.ViewData);
}
But the model is not passed to the controller when the page is posted with jQuery AJAX request. How can I send the model in the AJAX request?
The simple answer (in MVC 3 onwards, maybe even 2) is you don't have to do anything special.
As long as your JSON parameters match the model, MVC is smart enough to construct a new object from the parameters you give it. The parameters that aren't there are just defaulted.
For example, the Javascript:
var values =
{
"Name": "Chris",
"Color": "Green"
}
$.post("#Url.Action("Update")",values,function(data)
{
// do stuff;
});
The model:
public class UserModel
{
public string Name { get;set; }
public string Color { get;set; }
public IEnumerable<string> Contacts { get;set; }
}
The controller:
public ActionResult Update(UserModel model)
{
// do something with the model
return Json(new { success = true });
}
If you need to send the FULL model to the controller, you first need the model to be available to your javascript code.
In our app, we do this with an extension method:
public static class JsonExtensions
{
public static string ToJson(this Object obj)
{
return new JavaScriptSerializer().Serialize(obj);
}
}
On the view, we use it to render the model:
<script type="javascript">
var model = <%= Model.ToJson() %>
</script>
You can then pass the model variable into your $.ajax call.
I have an MVC page that submits JSON of selected values from a group of radio buttons.
I use:
var dataArray = $.makeArray($("input[type=radio]").serializeArray());
To make an array of their names and values. Then I convert it to JSON with:
var json = $.toJSON(dataArray)
and then post it with jQuery's ajax() to the MVC controller
$.ajax({
url: "/Rounding.aspx/Round/" + $("#OfferId").val(),
type: 'POST',
dataType: 'html',
data: json,
contentType: 'application/json; charset=utf-8',
beforeSend: doSubmitBeforeSend,
complete: doSubmitComplete,
success: doSubmitSuccess});
Which sends the data across as native JSON data.
You can then capture the response stream and de-serialize it into the native C#/VB.net object and manipulate it in your controller.
To automate this process in a lovely, low maintenance way, I advise reading this entry that spells out most of native, automatic JSON de-serialization quite well.
Match your JSON object to match your model and the linked process below should automatically deserialize the data into your controller. It's works wonderfully for me.
Article on MVC JSON deserialization
This can be done by building a javascript object to match your mvc model. The names of the javascript properties have to match exactly to the mvc model or else the autobind won't happen on the post. Once you have your model on the server side you can then manipulate it and store the data to the database.
I am achieving this either by a double click event on a grid row or click event on a button of some sort.
#model TestProject.Models.TestModel
<script>
function testButton_Click(){
var javaModel ={
ModelId: '#Model.TestId',
CreatedDate: '#Model.CreatedDate.ToShortDateString()',
TestDescription: '#Model.TestDescription',
//Here I am using a Kendo editor and I want to bind the text value to my javascript
//object. This may be different for you depending on what controls you use.
TestStatus: ($('#StatusTextBox'))[0].value,
TestType: '#Model.TestType'
}
//Now I did for some reason have some trouble passing the ENUM id of a Kendo ComboBox
//selected value. This puzzled me due to the conversion to Json object in the Ajax call.
//By parsing the Type to an int this worked.
javaModel.TestType = parseInt(javaModel.TestType);
$.ajax({
//This is where you want to post to.
url:'#Url.Action("TestModelUpdate","TestController")',
async:true,
type:"POST",
contentType: 'application/json',
dataType:"json",
data: JSON.stringify(javaModel)
});
}
</script>
//This is your controller action on the server, and it will autobind your values
//to the newTestModel on post.
[HttpPost]
public ActionResult TestModelUpdate(TestModel newTestModel)
{
TestModel.UpdateTestModel(newTestModel);
return //do some return action;
}
I think you need to explicitly pass the data attribute. One way to do this is to use the
data = $('#your-form-id').serialize();
This post may be helpful.
Post with jquery and ajax
Have a look at the doc here..
Ajax serialize
you can create a variable and send to ajax.
var m = { "Value": #Model.Value }
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
data: m,
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
All of model's field must bo ceated in m.
In ajax call mention-
data:MakeModel(),
use the below function to bind data to model
function MakeModel() {
var MyModel = {};
MyModel.value = $('#input element id').val() or your value;
return JSON.stringify(MyModel);
}
Attach [HttpPost] attribute to your controller action
on POST this data will get available

Resources