How can I make my dropdown list retain selected item if my list is in the ViewBag? - asp.net-mvc-3

how can I make my dropdown list retain selected item if my list is in the ViewBag?
This first DropdownList works fine:
#Html.DropDownList("searchString", Model.Enrollments.FirstOrDefault().WeekDays.Select(s => new SelectListItem { Text = s.ToString(), Value = s.ToString(), Selected = s.ToString().Equals(selectedItemFromList) }))
And now I would like to have another DropdownList but instead of getting the list from the model I’m getting it from the view bag like this:
#Html.DropDownList("searchString", new SelectList(ViewBag.someList, "text"), "select an item").. Again this works but I want the format like the first Dropdownlist that retains te selected value…something like this…
#Html.DropDownList("searchString", ViewBag.someList.Select(t=> new SelectListItem{ Text= t.ToString(),Value =t.ToString(),Selected =t.ToString().Equals(selectedItemFromList)}))
This doesn’t work because I’m getting my list from a viewbag I suspect. Is there a way to work with ViewBag to retain my selected list item like the first example?

Better way is initializing ViewBag in controller action...
controller
ViewBag.someList = Model.Enrollments.FirstOrDefault().WeekDays
.Select(s => new SelectListItem
{
Text = s.ToString(),
Value = s.ToString(),
Selected = s.ToString().Equals(selectedItemFromList)
}
view
#Html.DropDownList("someList", ViewBag.someList as SelectList, "select one")
you can initialize selected value in controller side.
Check HERE for examples...

This solution does the same as mine except your's is implemented in the controller instead of the view. I'm able to get my list to display but what I wanted was a way to keep the selected item of the list selected upon a revisit of the view. My list is not a model property. I created it in the controller then send it to the view via the viewbag. The first example I showed was accessing the list as a model property. The new list is accessed view the viewbag. I wanted it to be configured like my first list which works ok. Since my original post I've found a solution.
Since i needed the solution in the view finally did:
#Html.DropDownList("theString", listofinstructors.Select(tch => new SelectListItem { Text = tch.ToString(), Value = tch.ToString(), Selected = tch.ToString().Equals(somethingSelected) }))

Related

Filling MVC DropdownList with AJAX source and bind selected value

I have view for showing Member details. Inside there is an EditorFor element which represents subjects taken by the member.
#Html.EditorFor(m => m.Subject)
Inside the editor template there is a Html.DropDownListFor() which shows the selected subject and button to delete that subject
I am using an Html.DropDownListFor element as :
#Html.DropDownListFor(m => m.SubjectID, Enumerable.Empty<SelectListItem>(), "Select Subject",
new { #class = "form-control subjects" })
The second parameter(source) is set empty since I want to load the source from an AJAX request; like below:
$.getJSON(url, function (response) {
$.each(response.Subjects, function (index, item) {
$('.subjects').append($('<option></option>').text(item.Text).val(item.ID));
});
// code to fill other dropdowns
});
Currently the html loads before the dropdowns are filled. So the values of all subject dropdowns are set to the default "Select Subject". Is there a way around this or is it the wrong approach?
Note: There are a number of dropdowns in this page. That's why I would prefer to load them an AJAX request and cache it instead of putting in viewModel and filling it for each request.
** EDIT **
In AJAX call, the action returns a json object containing dropdowns used across all pages. This action is decorated with [Output Cache] to avoid frequent trips to server. Changed the code in $.each to reflect this.
You can initially assign the value of the property to a javascript variable, and use that to set the value of the selected option in the ajax callback after the options have been appended.
// Store initial value
var selectedId = #Html.Raw(Json.Encode(Model.Subject.SubjectID))
var subjects = $('.subjects'); // cache it
$.getJSON(url, function (response) {
$.each(response, function (index, item) {
subjects.append($('<option></option>').text(item.Text).val(item.ID));
});
// Set selected option
subjects.val(selectedId);
});
However its not clear why you are making an ajax call, unless you are generating cascading dropdownlists which does not appear to be the case. What you doing is basically saying to the client - here is some data, but I forgot to send what you need, so waste some more time and resources establishing another connection to get the rest of the data. And you are not caching anything despite what you think.
If on the other hand your Subject property is actually a collection of objects (in which case, it should be Subjects - plural), then the correct approach using an EditorTemplate is explained in Option 1 of this answer.
Note also if Subject is a collection, then the var selectedId = .. code above would need to be modified to generate an array of the SubjectID values, for example
var selectedIds = #Html.Raw(Json.Encode(Model.Subject.Select(x => x.SubjectID)))
and then the each dropdownlist value will need to be set in a loop
$.each(subjects, function(index, item) {
$(this).val(selectedIds[index]);
});
If your JSON tells you what option they have selected you can simply do the following after you have populated your dropdown:
$('.form-control.subjects').get(0).selectedIndex = [SELECTED_INDEX];
Where [SELECTED_INDEX] is the index of the element you want to select inside the dropdown.

Add an "Add New..." option to a Kendo DropDownList

I'm using a Kendo DropDownListFor which populates from a DB table. I want to add an option at the end that says "Add New..." which takes the user to a Create view for that DB table. Is there a way to do this (preferably in the MVC Helper, not in javascript).
Not possible without JavaScript. If using JavaScript you need to use the change event and see if the value is equal to that last item in the list then navigate the page. Something like this:
function onChangeOfDDl(e){
if(...) { //you condition
window.location.href = "/editRecord/" + this.value()
// this.value() will give you the value for the selected item or the text if no underlying value exists
}
}

MVC 3 Bind Model property to 2 fields (e.g. Other Title)

I'm trying to achieve a very common scenario whereas given a list of options to choose from, the last one says "Other" and when selected the user is presented with the input field to specify what "other" is.
In my case, it's a list of Person's titles:
public List<string> TitleList
{
get
{
return new List<string> { "Mr", "Mrs", "Miss", "Dr", "Other" };
}
}
and what I'm trying to do is this:
#Html.DropDownListFor(m => m.Title, new SelectList(Model.TitleList), "Please select...") #Html.TextBoxFor(m => m.Title)
I want the model to bind the TextBox value when "Other" is selected in the DropDownLis, and bind to selected item in DropDownList in all other cases.
Is this achievable without adding an extra property on the Model?
a better solution is not to bind to two fields, instead, copy selected item from a drop-down into bound textbox with some clever javascript:
#Html.DropDownList("ddlTitle", new SelectList(Model.TitleList), "Please select")
#Html.TextBoxFor(m => m.Title, new { maxLength = 10 })
Javascript:
ToggleTitleFields = function () {
var title, txtTitle;
title = $('select#ddlTitle').val();
txtTitle = $('input#Title');
if (title === "Other") {
txtTitle.val("");
txtTitle.show();
return txtTitle.focus();
} else {
txtTitle.hide();
txtTitle.val(title);
return $('span[data-valmsg-for="Title"]').empty();
}
};
$(document).on("change", "select#ddlTitle", function(e) {
return ToggleTitleFields();
});
hope this helps somebody
found a client-side solution: add/remove the "name" attribute from DropDownList. Here's my coffee script:
ToggleTitleFields = () ->
if $('select#Title').val() == "Other"
$('select#Title').removeAttr('name')
else
$('select#Title').attr('name','Title')
Tsar,
Being honest, this isn't a scenario that I've had to deal with before, but is nonetheless a good one. If I were faced with this dilemma and was allowed to use a javascript solution, i'd present a previously 'hidden' textbox when other was chosen. The user would then have to enter the new value into this texbox, which on loosing focus would populate the selectlist and be selected. Then when the form was submitted, you'd have this new value still as part of the exisiting model.
Of course, you could also do a similar logic of showing the textbox when selecting other but this time, do a little logic on the httpost controller action to determine if the 'other' item was selected and then populate the model from the 'textbox' value.
Of course, both scenarios would need a heap of validation, but in principle, either approach would 'work'

knockout js - How to do Conditional Binding on a dropdownlist

I've got a Knockout viewmodel populated from a variety of Mvc actions.
A Category is chosen from the first dropdown (say Fruit, Meat, Drinks etc).
A second dropdown is automatically populated from the first choice. However, there may be 2 matches for fruit (say Apples, Oranges), 2 for meat (say Beef, Lamb) and many choices for drink (several hundred).
My page currently displays a search box depending on the Category chosen.
I was wondering how to automatically bind the second dropdown for Fruit & Meat, or wait and do the bind from the results of the search query.
Sorry this is vague - twitchy client! Very new to KnockoutJs.
Thanks in advance.
If I understood you right, you could create a method in your viewmodel which you bind to the change event of the dropdown.
Example method:
var myViewModel = {
firstDropDownArray: ko.observableArray([]),
secondDropDownArray: ko.observableArray([]),
// Validates Selection
validateSelection: function (item) {
var anotherList;
switch (item.toUpperCase()) {
case "FRUIT":
// Do something...
break;
case "DRINKS":
// Do something else...
break;
default:
}
}
};
Your Dropdown can bind then to the method like this:
<select id="FirstDropDown" data-bind="options: myViewModel.firstDropDownArray, <any other binding options>, event: {change: myViewModel.validateSelection(currentItem)}">
</select>
As stated here: event-binding,
When calling your handler, Knockout will supply the current model
value as the first parameter.
I'm assuming this means the currentItem will be the selected item when you are calling the method.
I know in my sample code I wrote item.toUpperCase() but that is just assuming the item is passed as a string. This syntax obviously has to change depending on how you have declared and populated your dropdown but in essence you still should be able to write a method in your viewmodel you can bind then to the change event,..or any other event you like.

System.Web.MVC.SelectList how to set selected item upon creation

trying to have an item in a DropDownList selected by default from within my viewmodel.
I am creating the select list in my view model using teh following overload..
public SelectList ProgramsSelectList()
{
var ddlist = new SelectList(DiversionPrograms, "DiversionProgramID", "CrimeName", new {value = "1"});
return ddlist;
}
value = 1 is just hard coded for now. I am not sure the Html.DropDownList() respects this selected item.
Razor View:
#Html.DropDownList("programSelect", Model.ProgramsSelectList(), "Choose a Program to Manage")
I must be missing something here...
Figured it out...
var ddlist = new SelectList(DiversionPrograms, "DiversionProgramID", "CrimeName", DiversionProgram.DiversionProgramID);

Resources