How do I get the Selected Value of a DropDownList in ASP.NET Core MVC App - asp.net-core

I have the following dropdownlist in my view:
#{
var listado = new List<SelectListItem>()
{
new SelectListItem()
{
Text ="YES",
Value ="1"
},
new SelectListItem()
{
Text = "NO",
Value = "2"
}
};
}
<div class="form-group">
<label class="control-label">Is it True ?</label>
#Html.DropDownList("miDropDownList",listado)
</div>
I want to get the selected value 'YES' or 'NO' to do something in the controller like so:
IActionResult ControllerAction(){
var theValue = dropdownList.SelectedValue //this is pseudocode syntax but you understand I want to get
//the value
// with the value I will do something like this:
User userinstance = new User {
Id = 1,
Name = "john",
isJohnTall = theValue.Value
}
}
I want something simple in other answers I've seen DropDownLists that are bound to models, but I just want to get strings selected in the dropdown and be able to do something with them in the controller.

You can use JQuery with ajax.
Something like this:
<div class="form-group">
<label class="control-label">Is it True ?</label>
#Html.DropDownList("miDropDownList", listado, new { #onchange = "GetYesOrNo()"})
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
function GetYesOrNo() {
var selectElement = document.querySelector('#miDropDownList');
var option = selectElement.value;
$.ajax({
url: '/Home/GetYesOrNo',
type: 'GET',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
mimeType: 'text/html',
data: { getOption : option },
success: function (returnValue) {
alert(returnValue);
}
});
};
</script>
And in Home Controller, add this JsonResult:
public JsonResult GetYesOrNo(int getOption)
{
if (getOption == 1) return Json("Option: YES");
return Json("Option: NO");
}

You can use a form to submit your data.
The form will submit Value, so you can modify your value as Text.
You can change your code like below.
View:
#{
var listado = new List<SelectListItem>()
{
new SelectListItem()
{
Text ="YES",
Value ="YES"
},
new SelectListItem()
{
Text = "NO",
Value = "NO"
}
};
}
#using (Html.BeginForm("GetYesOrNo", "User"))
{
<div class="form-group">
<label class="control-label">Is it True ?</label>
#Html.DropDownList("miDropDownList", listado)
</div>
<button type="submit">Find</button>
}
Action:
public IActionResult GetYesOrNo(string miDropDownList)
{
//.....
return View();
}
Test result:
And how to bind to the model with dropdownlist,you can see my this reply,it may helpful.

Related

Can not find a way to check or uncheck checkbox in my view

I have a partial view ,which I throw to another view ,In my partial view there is a checkbox which is checked by default I want to change its current (checked/unchecked) option from main view. Here is my partial view code:
<td class="sevenCol" name="sevenCol">
<input type="checkbox" checked/>
</td>
Below shows partial view content:
$("#btnSubmit").click(function () {
var mobnum = $("#mobNo").val();
var message = $("#txtMessage").val();
alert(mobnum);
$.ajax({
url: "SmsSendFromOneToOne",
type: "POST",
data: { contactList: mobnum, message: message },
success: function (data) {
$("#gridGenerate").html(data);
}
});
});
Below verifies checkbox is checked or unchecked but it always returns true so how can I fix this?
$("#sendbtn").click(function () {![enter image description here][1]
var maskId = $("#MASKLIST").val();
var campaignName = $("#campaignName").val();
var dataArray = {};
$(".loadingmessage").show();
$("#gridGenerate tr").each(function (iii, val) {
var trId = $(this).attr("id");
var isChecked = $('td[name=sevenCol]').find('input[type="checkbox"]').is(':checked');
//alert(isChecked);
if (isChecked) {
dataArray[iii] = {
'mobile': $(this).find(".secondCol").text(),
'message': $(this).find(".thirdCol").text(),
'type': $(this).find(".fifthCol").text()
};
}
});
Controller:
[HttpPost]
public ActionResult SmsSendFromOneToOne(string contactList, string message)
{
IList<GridPanel> cellInfoForForm1 = _smsService.GetForm1ForViewing(contactList, message);
return PartialView("partialGridPanel", cellInfoForForm1);
}
Thanks
it is a lot simpler if you put the selector directly on the field. try adding a class to your checkbox
<input type="checkbox" class="mobileCheck" checked/>
then in your script you can replace
var isChecked = $('td[name=sevenCol]').find('input[type="checkbox"]').is(':checked');
with
var isChecked = $('.mobileCheck').is(':checked');
Finally got my answer ,As i am binding a partial view and checkbox exits in it so i have to use jquery .live( events, data, handler(eventObject) )to solve the issue ..
$( selector ).live( events, data, handler );
Again thanks for responding

Pass ViewModel back to controller

I have a working application integrating Bootstrap and Knockout. This app pulls data from my controller and displays this in the UI as I would expect. I can see values are updated when I click or change a value but I can't seem to see that data passed back to my controller for the purposes of saving it. All I need to know is how to fix what I have to allow me to pass the selectedRequestorName back to the controller.
Here is a sample class
public class Requestor
{
public int Id { get; set; }
public string Name { get; set; }
}
Interface
interface IRequestorRepository
{
IList<Requestor> GetAllRequestors();
}
Here is the repository with the seed data
public class RequestorRepository : IRequestorRepository
{
private List<Requestor> requestors = new List<Requestor>();
private int _nextId = 1;
public RequestorRepository()
{
Add(new Requestor{ Id = 1, Name = "Brian" });
Add(new Requestor { Id = 2, Name = "Steve" });
Add(new Requestor { Id = 3, Name = "Jake" });
}
public IList<Requestor> GetAllRequestors()
{
return requestors;
}
public Requestor Add(Requestor item)
{
if (item == null)
{
throw new ArgumentNullException("Null Requestor");
}
item.Id = _nextId++;
requestors.Add(item);
return item;
}
}
My HomeController looks like the following
public class HomeController : Controller
{
static readonly IRequestorRepository req_repository = new RequestorRepository();
// GET: /Home/
public ActionResult Index()
{
ViewBag.DateNow = DateTime.Now.ToShortDateString();
return View();
}
public JsonResult GetRequestors()
{
return Json(req_repository.GetAllRequestors(), JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult SaveDetails(Requestor selectedRequestorName)
{
int id = -1;
return Json(id, "json");
}
}
In my Index.cshtml I have the following in a script tag at the top of the page
// Global variable
var viewModel = null;
$(document).ready(function () {
function ViewModel() {
//Make the self as 'this' reference
var self = this;
// Requestors
self.RequestorId = ko.observable("");
self.RequestorName = ko.observable("");
self.RequestorSourceDatabase = ko.observable("");
var RequestorNames = {
Id: self.RequestorId,
Name: self.RequestorName,
SourceDatabase: self.RequestorSourceDatabase
};
self.selectedRequestorName = ko.observable();
self.RequestorNames = ko.observableArray(); // Contains the list of RequestorNames
// Initialize the view-model for Requestors
$.ajax({
url: '#Url.Action("GetRequestors", "Home")',
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.RequestorNames(data);
}
});
// END Requestors
// Reset
self.reset = function () {
self.Name("");
}
// Cancel
self.cancel = function () {
self.Name(null);
}
}
viewModel = new ViewModel();
ko.applyBindings(viewModel);
});
$(function () {
$('#Save').click(function (e) {
// Check whether the form is valid. Note: Remove this check, if you are not using HTML5
if (document.forms[0].checkValidity()) {
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("SaveDetails", "Home")',
data: ko.toJSON(viewModel.selectedRequestorName),
contentType: 'application/json; charset=utf-8',
async: true,
beforeSend: function () {
// Display loading image
},
success: function (result) {
if (result > 0) {
alert("This work request has been successfully saved in database. The Document ID is: " + result);
} else {
alert("The Work Request was not saved, there was an issue.");
}
},
complete: function () {
// Hide loading image.
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle error.
}
});
}
else {
alert("Form is not valid");
}
});
});
And finally the control that contains the displayed data for the user to select from...
<p>Current selection is <span data-bind="text:selectedRequestorName"></span></p>
<!-- Requestors -->
<div class="input-group col-sm-8">
<input type="text" data-bind="value:selectedRequestorName" class="form-control item" placeholder="Requestor Name" name="Requestor">
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle item" data-toggle="dropdown">Select <span class="caret"></span></button>
<ul class="dropdown-menu" data-bind="foreach: RequestorNames">
<li class="dropdown">
</li>
</ul>
</div>
</div>
<div>
<button id="Save" type="submit" class="btn btn-default btn-success">Create</button>
</div>
create an action method on your controller that accepts an selectedRequestorName (string?) as argument.
create a function in your knockout viewmodel that reads the selectedRequestorName from the ko vm, JsonStringify it and pass it back to the above action method via ajax.
[HttpPost]
public JsonResult SaveDetails(String selectedRequestorName)
{
int id = -1;
return Json(id, "json");
}
change type of selectedRequestorName to String from Requestor as above that should work.
note not tested.but let me know if it helps.
Within $('#Save').click(), would you please change the line
data: ko.toJSON(viewModel.selectedRequestorName)
with
data: ko.toJSON(viewModel.selectedRequestorName())
hope, this will help.

Pass selected item from drop down list to viewmodel

I have four controls on the page, a simple form with first and last names, date of birth and this drop down that contains some names of countries. When I make changes to the these controls I am able to see those changes in my viewModel that is passed in as a parameter in the SavePersonDetails POST below, but I never see the LocationId updated in that view model and I am not sure why.
This is what I have in my markup, Index.cshtml:
#model Mvc4withKnockoutJsWalkThrough.ViewModel.PersonViewModel
#using System.Globalization
#using Mvc4withKnockoutJsWalkThrough.Helper
#section styles{
#Styles.Render("~/Content/themes/base/css")
<link href="~/Content/Person.css" rel="stylesheet" />
}
#section scripts{
#Scripts.Render("~/bundles/jqueryui")
<script src="~/Scripts/knockout-2.1.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script src="~/Scripts/Application/Person.js"></script>
<script type="text/javascript">
Person.SaveUrl = '#Url.Action("SavePersonDetails", "Person")';
Person.ViewModel = ko.mapping.fromJS(#Html.Raw(Json.Encode(Model)));
var userObject = '#Html.Raw(Json.Encode(Model))';
var locationsArray = '#Html.Raw(Json.Encode(Model.Locations))';
var vm = {
user : ko.observable(userObject),
availableLocations: ko.observableArray(locationsArray)
};
ko.applyBindings(vm);
</script>
}
<form>
<p data-bind="with: user">
Your country:
<select data-bind="options: $root.availableLocations, optionsText: 'Text', optionsValue: 'Value', value: LocationID, optionsCaption: 'Choose...'">
</select>
</p>
</form>
This is my View Model:
public class PersonViewModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public string LocationId { get; set; }
public IEnumerable<SelectListItem> Locations { get; set; }
}
I have a simple controller that loads my Person and a drop down list containing three countries.
private PersonViewModel _viewModel;
public ActionResult Index()
{
var locations = new[]
{
new SelectListItem { Value = "US", Text = "United States" },
new SelectListItem { Value = "CA", Text = "Canada" },
new SelectListItem { Value = "MX", Text = "Mexico" },
};
_viewModel = new PersonViewModel
{
Id = 1,
FirstName = "Test",
LastName = "Person",
DateOfBirth = new DateTime(2000, 11, 12),
LocationId = "", // I want this value to get SET when the user changes their selection in the page
Locations = locations
};
_viewModel.Locations = locations;
return View(_viewModel);
}
[HttpPost]
public JsonResult SavePersonDetails(PersonViewModel viewModel)
{
int id = -1;
SqlConnection myConnection = new SqlConnection("server=myMachine;Trusted_Connection=yes;database=test;connection timeout=30");
try
{
// omitted
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
myConnection.Close();
}
return Json(id, "json");
}
Lastly, here is my Person.js file, I am using knockout
var Person = {
PrepareKo: function () {
ko.bindingHandlers.date = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
element.onchange = function () {
var observable = valueAccessor();
observable(new Date(element.value));
}
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var observable = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(observable);
if ((typeof valueUnwrapped == 'string' || valueUnwrapped instanceof String) && valueUnwrapped.indexOf('/Date') === 0) {
var parsedDate = Person.ParseJsonDate(valueUnwrapped);
element.value = parsedDate.getMonth() + 1 + "/" + parsedDate.getDate() + "/" + parsedDate.getFullYear();
observable(parsedDate);
}
}
};
},
ParseJsonDate: function (jsonDate) {
return new Date(parseInt(jsonDate.substr(6)));
},
BindUIwithViewModel: function (viewModel) {
ko.applyBindings(viewModel);
},
EvaluateJqueryUI: function () {
$('.dateInput').datepicker();
},
RegisterUIEventHandlers: function () {
$('#Save').click(function (e) {
// Check whether the form is valid. Note: Remove this check, if you are not using HTML5
if (document.forms[0].checkValidity()) {
e.preventDefault();
$.ajax({
type: "POST",
url: Person.SaveUrl,
data: ko.toJSON(Person.ViewModel),
contentType: 'application/json',
async: true,
beforeSend: function () {
// Display loading image
},
success: function (result) {
// Handle the response here.
if (result > 0) {
alert("Saved");
} else {
alert("There was an issue");
}
},
complete: function () {
// Hide loading image.
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle error.
}
});
}
});
},
};
$(document).ready(function () {
Person.PrepareKo();
Person.BindUIwithViewModel(Person.ViewModel);
Person.EvaluateJqueryUI();
Person.RegisterUIEventHandlers();
});
As you can see, I have the data in the page but none of them show as selected
Your solution is overly complex and is leading to certain weirdness with your data. Instead of trying to patch the Titanic, your best bet is to start over and simplify:
Your page's model contains all the information you need. There's no need to try to create two totally separate view models to work with the user data versus locations. With the mapping plugin, you can specify different "view models" for various objects in your main view model, and there's a simpler pattern that can be followed to set all that up. Here's what I would do:
// The following goes in external JS file
var PersonEditor = function () {
var _init = function (person) {
var viewModel = PersonEditor.PersonViewModel(person);
ko.applyBindings(viewModel);
_wireEvents(viewModel);
}
var _wireEvents = function (viewModel) {
// event handlers here
}
return {
Init: _init
}
}();
PersonEditor.PersonViewModel = function (person) {
var mapping = {
'Locations': {
create: function (options) {
return new PersonEditor.LocationViewModel(options.data)
}
}
}
var model = ko.mapping.fromJS(person, mapping);
// additional person logic and observables
return model;
}
PersonEditor.LocationViewModel = function (location) {
var model = ko.mapping.fromJS(location);
// additional location logic and observables
return model;
}
// the following is all you put on the page
<script src="/path/to/person-editor.js"></script>
<script>
$(document).ready(function () {
var person = #Html.Raw(#Json.Encode(Model))
PersonEditor.Init(person);
});
</script>
Then all you need to bind the select list to the locations array is:
<p>
Your country:
<select data-bind="options: Locations, optionsText: 'Text', optionsValue: 'Value', value: LocationId, optionsCaption: 'Choose...'">
</select>
</p>
Based on your updated question, do this.
1.We do not need locationsArray actually. Its already in user.Locations (silly me)
2.On Index.cshtml, page change the JavaScript like this.
var userObject = #Html.Raw(Json.Encode(Model)); // no need for the quotes here
jQuery(document).ready(function ($) {
Person.PrepareKo();
Person.EvaluateJqueryUI();
Person.RegisterUIEventHandlers();
Person.SaveUrl = "#Url.Action("SavePersonDetails", "Knockout")";
Person.ViewModel = {
user : ko.observable(userObject)
};
Person.BindUIwithViewModel(Person.ViewModel);
});
3.On your Person.js page, inside RegisterUIEventHandlers #Save button click event, do this.
$('#Save').click(function (e) {
var updatedUser = Person.ViewModel.user();
updatedUser.Locations.length = 0; // not mandatory, but we don't need to send extra payload back to server.
// Check whether the form is valid. Note: Remove this check, if you are not using HTML5
if (document.forms[0].checkValidity()) {
e.preventDefault();
$.ajax({
type: "POST",
url: Person.SaveUrl,
data: ko.toJSON(updatedUser), // Data Transfer Object
contentType: 'application/json',
beforeSend: function () {
// Display loading image
}
}).done(function(result) {
// Handle the response here.
if (result > 0) {
alert("Saved");
} else {
alert("There was an issue");
}
}).fail(function(jqXHR, textStatus, errorThrown) {
// Handle error.
}).always(function() {
// Hide loading image.
});
}
});
5.Finally, our markup
<p data-bind="with: user">
Your country:
<select data-bind="options: Locations,
optionsText: 'Text',
optionsValue: 'Value',
value: LocationId,
optionsCaption: 'Choose...'">
</select>
</p>
On an unrelated side-note,
The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are
deprecated as of jQuery 1.8. To prepare your code for their eventual
removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

AJAX Cascading with MVC4

I used the below method for doing Async postback using AJAX. This works fine on clicking submit. But i would like to know, is that possible to call various ActionMethods in a controller via AJAX.
I would like to implement something like cascading dropdown. How to call different ActionMethod via AJAX on dropdown value change?
Here is the code which call only one ActionMethod on submitting form.
View
#{
ViewBag.Title = "Index";
var options = new AjaxOptions()
{
Url = Url.Action("Index", "City"),
LoadingElementId = "saving",
LoadingElementDuration = 2000,
Confirm = "Are you sure you want to submit?"
};
}
<h2>Index</h2>
#using (Ajax.BeginForm(options))
{
<div id="saving">Loading...</div>
#Html.DropDownList("Countries",ViewBag.Countries as SelectList)<input type="submit" />
}
Controller
public ActionResult Index()
{
IEnumerable<SelectListItem> selectListItems = new []
{
new SelectListItem{ Text = "US",Value = "1" }
};
ViewBag.Countries = selectListItems;
return View();
}
public ActionResult GetState(string countryId)
{
IEnumerable<SelectListItem> selectListItems = new[]
{
new SelectListItem { Text = "Tennesse", Value = "1" },
new SelectListItem { Text = "Newyork", Value = "2" }
};
return View();
}
The answer to your first question "is that possible to call various ActionMethods in a controller via AJAX" is a big yes. You may call any action method from your controller through Ajax though the only result generated depends on various things like whether you send a view or partial view or JSON result.
for your next question :
I will be posting some codes
Controller.cs
public JsonResult getCity(string country)
{
var temp = (from cntry in db.Table3.OrderBy(s => s.country)
where (string.Compare(cntry.country, country) == 0)
select cntry.city).ToList();
return Json(temp, JsonRequestBehavior.AllowGet);
}
View
<h1>
Countries</h1>
<select name="countries" class="combo">
<option value=""></option>
#{
foreach (var t in (List<string>)ViewBag.countries)
{
<option value=#t>#t</option>
}
}
</select>
<h1>
State</h1>
<select name="city" class="combo2">
</select>
<div id="tese">
</div>
#*
The following jquery code finds the selected option from country dropdown
and then sends an ajax call to the Home/getcity method
and finally populate it to the city dropdown
*#
<script type="text/javascript">
$('body').on('change', '.combo', function () {
var selectedValue = $(this).val();
alert(selectedValue);
$.get("/Home/getcity", { country: selectedValue }, function (data) {
$("#tese").html(data);
$(".combo2").html("<option value = \"\"></option>")
$.each(data, function (index, value) {
$(".combo2").append("<option value = \"" + value + "\">" + value + "</option>");
});
$(".combo2").html()
});
});
</script>
This will show a dropdown of countries list. Once a country is selected it will render a new dropdown of city list
public JsonResult getCity(string country)
{
var temp = (from cntry in db.Table3.OrderBy(s => s.country)
where (string.Compare(cntry.country, country) == 0)
select cntry.city).ToList();
return Json(temp, JsonRequestBehavior.AllowGet);
}
View
<h1>
Countries</h1>
<select name="countries" class="combo">
<option value=""></option>
#{
foreach (var t in (List<string>)ViewBag.countries)
{
<option value=#t>#t</option>
}
}
</select>
<h1>
State</h1>
<select name="city" class="combo2">
</select>
<div id="tese">
</div>
#*
The following jquery code finds the selected option from country dropdown
and then sends an ajax call to the Home/getcity method
and finally populate it to the city dropdown
*#
<script type="text/javascript">
$('body').on('change', '.combo', function () {
var selectedValue = $(this).val();
alert(selectedValue);
$.get("/Home/getcity", { country: selectedValue }, function (data) {
$("#tese").html(data);
$(".combo2").html("<option value = \"\"></option>")
$.each(data, function (index, value) {
$(".combo2").append("<option value = \"" + value + "\">" + value + "</option>");
});
$(".combo2").html()
});
});
</script>

how to do postback on changing dropdownlist selected item in mvc4

I have a dropdown in my page. On selecting a value in dropdown I want the label text to be changed. Here is my code :
#model FND.Models.ViewLender
#{
ViewBag.Title = "Change Lender";
}
#using (Html.BeginForm())
{
#Html.Label("Change Lender : ")
#Html.DropDownList("Ddl_Lender", Model.ShowLenderTypes)
#Html.DisplayFor(model => model.Description)
}
On changing the value in dropdownlist I want the Description to change accordingly.
You could start by putting the description into a div and give your dropdown an unique id:
#model FND.Models.ViewLender
#{
ViewBag.Title = "Change Lender";
}
#using (Html.BeginForm())
{
#Html.Label("Change Lender : ")
#Html.DropDownList("Ddl_Lender", Model.ShowLenderTypes, new { id = "lenderType" })
<div id="description">
#Html.DisplayFor(model => model.Description)
</div>
}
Now all that's left is to subscribe to the onchange javascript event of this dropdown and update the corresponding description.
For example if you are using jQuery that's pretty trivial task:
$(function() {
$('#lenderType').change(function() {
var selectedDescription = $(this).find('option:selected').text();
$('#description').html(selectedDescription);
});
});
This being said I probably misunderstood your question and this description must come from the server. In this case you could use AJAX to query a controller action that will return the corresponding description. All we need to do is provide the url to this action as an HTML5 data-* attribute to the dropdown to avoid hardcoding it in our javascript file:
#Html.DropDownList(
"Ddl_Lender",
Model.ShowLenderTypes,
new {
id = "lenderType",
data_url = Url.Action("GetDescription", "SomeController")
}
)
and now in the .change event we trigger the AJAX request:
$(function() {
$('#lenderType').change(function() {
var selectedValue = $(this).val();
$.ajax({
url: $(this).data('url'),
type: 'GET',
cache: false,
data: { value: selectedValue },
success: function(result) {
$('#description').html(result.description);
}
});
});
});
and the last step of course is to have this controller action that will fetch the corresponding description based on the selected value:
public ActionResult GetDescription(string value)
{
// The value variable that will be passed here will represent
// the selected value of the dropdown list. So we must go ahead
// and retrieve the corresponding description here from wherever
// this information is stored (a database or something)
string description = GoGetTheDescription(value);
return Json(new { description = description }, JsonRequestBehavior.AllowGet);
}