I am trying to create a dropdonw in my MVC web application.
Model
namespace projectname.Models
{
public class DropDownModel
{
public int id{get; set;}
puclic string value {get; set;}
}
}
Controller
using projectname.Models;
{
public class DropDownController: Controller
{
public ActionResult Index() //where Index is one of the view
{
List <SelectListItem> listItem = new List<SelectListItem>();
DropDownModel drop = new DropDownModel();
drop.id = 1;
drop.value = "First";
listItem.Add(new SelectListItem() {Value = drop.Value, Text = drop.id.toString()});
return view(listitem);
}
}
}
View
#{
ViewBag.Title = "Home Page";
}
<h2>#ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit http://asp.net/mvc.
</p>
However, the drop down is not being displayed on my Index view.
I would suggest reading more about MVC. You have nothing rendering the dropdown on your view and you have a model that more or less does the same-thing your listitem is doing. This could be handled by one object instead of two. That said :
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
List<SelectListItem> listItem = new List<SelectListItem>();
DropDownModel drop = new DropDownModel();
drop.id = 1;
drop.value = "First";
listItem.Add(new SelectListItem() { Value = drop.id.ToString(), Text = drop.value });
return View(listItem);
}
}
View
Note the #Model List at the top of the view. This defines the strongly typed model asigned to the view. This Model is passed from the controller (listitem) to the view.
#model List<SelectListItem>
#{
ViewBag.Title = "title";
}
#Html.DropDownList("name", Model)
<h2>title</h2>
There are a few ways of display DropDownList in MVC. Here is my way.
Note: You need a collection of SelectListItem in model.
Model
public class MyModel
{
public int SelectedId { get; set; }
public IList<SelectListItem> AllItems { get; set; }
public MyModel()
{
AllItems = new List<SelectListItem>();
}
}
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyModel();
model.AllItems = new List<SelectListItem>
{
new SelectListItem { Text = "One", Value = "1"},
new SelectListItem { Text = "Two", Value = "2"},
new SelectListItem { Text = "Three", Value = "3"}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyModel model)
{
// Get the selected value
int id = model.SelectedId;
return View();
}
}
View
#model DemoMvc.Controllers.MyModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.DropDownListFor(x => x.SelectedId, Model.AllItems)
<input type="submit" value="Submit" />
}
You need to give your View the Model which is the listItem.
return View(listItem);
Related
I am following this tutorial which works very fine. But the problem is that it only provides key and without it own value (As shown in the picture below). How to include values to each of these keys?
Inspected Elements (Picture)
Model
[Required( ErrorMessage = "Selection is a MUST" )]
public string SelectedItem { get; set; }
private List<string> _items;
public List<string> Items
{
get
{
_items = new List<string>();
_items.Add("One");
_items.Add("Two");
_items.Add("Three");
return _items;
}
}
Controller
public class HomeController : Controller
{
//Render Action
[HttpGet]
public ViewResult Index()
{
DropdownListModel model = new DropdownListModel();
return View(model);
}
//Process Action
[HttpPost]
public ViewResult Index(DropdownListModel model)
{
//TODO: Validate using if(ModelState.IsValid) and process information
return View(model);
}
}
View
<div>
<!--Render the DropDownListmodel -->
#using (Html.BeginForm())
{
<p>#Html.ValidationSummary()</p>
<p>Select an Item : #Html.DropDownListFor(x => x.SelectedItem, new SelectList(Model.Items), "--Choose any Item--" )</p>
<input type="submit" value="Submit" />
}
<!-- Display Selected Item -->
#if (!String.IsNullOrWhiteSpace(Model.SelectedItem))
{
<span>Selected Item : #Model.SelectedItem</span>
}
</div>
What I Attempted
I replaced the codes in models with the code below. But I have error saying Models.KeyValueModel: : EntityType 'KeyValueModel' has no key defined. Define the key for this EntityType.
KeyValueModels: EntityType: EntitySet 'KeyValueModels' is based on type 'KeyValueModel' that has no keys defined.
public List<KeyValueModel> Items
{
get
{
List<KeyValueModel> item = new List<KeyValueModel>();
var n = new KeyValueModel();
n.Key = "1";
n.Value = "One";
item.Add(n);
n = new KeyValueModel();
n.Key = "2";
n.Value = "Second";
item.Add(n);
n = new KeyValueModel();
n.Key = "3";
n.Value = "Three";
item.Add(n);
return item;
}
}
You need to specify on your HttpGet request your Key Value pair like this one:
DropdownListModel model = new DropdownListModel();
model.ItemList = new List<SelectListItem>()
{
new SelectListItem { Text = "One", Value = "1" },
new SelectListItem { Text = "Two", Value = "2" }
};
Then on your model, add this:
public IEnumerable<SelectListItem> ItemList { get; set; }
And on your View:
#Html.DropDownListFor(x => x.SelectedItem, Model.Items, "--Choose any Item--" )
add the Model as:
public string nameofdropdown{ get; set; }
public IEnumerable<SelectListItem> listyouwanttodisplay{ get; set; }
In get method:
Model model=new Model;
List<SelectListItem> cd = Get() //call here----
var additionaldata= new SelectListItem()
{
Value = null,
Text = "--- place holder---"
};
cd.Insert(0, additionaldata);
model.listyouwanttodisplay=cd;
return View (model);
In View:
<div>
#Html.DropDownListFor(model => model.nameofdropdown, new
SelectList(Model.listyouwanttodisplay, "Value","Text"),htmlAttributes: new { #class = "form-control" })
</div>
I am trying to pull the data from a table stored in SQL 2008 into my MVC4
In My Controller :
public ActionResult Test()
{
SurveyEntities survey = new SurveyEntities();
var doctorList = survey.Doctors.ToList();
return View(doctorList);
}
and in my View:
#model IEnumerable<Survey.DataAccess.Doctor>
#{
ViewBag.Title = "Test";
}
<h2>Test</h2>
#using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
#Html.DropDownListFor(m => m.)
}
But I am not able to access the field name in m, say for eg., the doctor's name, to bind it to the dropdownlist.
Where am i going wrong ?
If you dont need to bind to the result value you can also use Html.DropDownList('name', new SelectList(Model)) If you have to use DropDownListFor you would have to change your model and add a property to bind the select result like Html.DropDownListFor(m=>m.DoctorId, new SelectList(Model.Doctors).....
Normally, you want to use ViewModel, so that you can retrieve the selected doctorId when the form is posted back to server.
For example,
Model
public class SurveyModel
{
public string SelectedDoctorId { get; set; }
public IList<SelectListItem> AvailableDoctors { get; set; }
public SurveyModel()
{
AvailableDoctors = new List<SelectListItem>();
}
}
View
#model DemoMvc.Models.SurveyModel
#using (Html.BeginForm("Index", "Home"))
{
#Html.DropDownListFor(m => m.SelectedDoctorId, Model.AvailableDoctors)
<input type="submit" value="Submit" />
}
Controller
public ActionResult Index()
{
var model = new SurveyModel
{
AvailableDoctors = GetDoctorListItems()
};
return View(model);
}
[HttpPost]
public ActionResult Index(SurveyModel model)
{
if (ModelState.IsValid)
{
var doctorId = model.SelectedDoctorId;
// Do something
return View("Success");
}
// If we got this far, something failed, redisplay form
// Fill AvailableDoctors again; otherwise, DropDownList will be blank.
model.AvailableDoctors = GetDoctorListItems();
return View(model);
}
private IList<SelectListItem> GetDoctorListItems()
{
/*
SurveyEntities survey = new SurveyEntities();
return survey.Doctors
.Select(d => new SelectListItem {Text = d, Value = d.ToString()})
.ToList();
*/
// Simulate doctors return from database.
return new List<SelectListItem>
{
new SelectListItem {Text = "John Doe", Value = "1"},
new SelectListItem {Text = "Eric Newton", Value = "2"}
};
}
you can put this code in the Test method:
> ViewData["doctors"] = new SelectList(doctorList,"value", "text");
and then in a view:
#using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
#Html.DropDownList("name", ViewData["doctors"] as SelectList)
input type="submit" value="Submit" />
}
i have a model :
public class studentmodel
{
public int id { get; set; }
public string name { get; set; }
}
i populate my dropdown :
// GET: dropdown/Test
public ActionResult Index()
{
List<SelectListItem> list = new List<SelectListItem>();
{
list.Add(new SelectListItem { Text = "saurav", Value = "1"});
list.Add(new SelectListItem {Text = "Rj", Value = "2" });
list.Add(new SelectListItem {Text = "rahul", Value = "3" });
ViewBag.studentlist = list;
}
return View();
}
[HttpPost]
public ActionResult Index(studentmodel s)
{
return View();
}
i have a controller action which is postback:
#using (Html.BeginForm("Index", "Test", FormMethod.Post))
{
#Html.DropDownListFor(m => m.name, (IEnumerable<SelectListItem>)ViewBag.studentlist, "select student");
<div>
<input type="submit" value="submit" />
</div>
<div> you have selected : #ViewBag.selected </div>
}
How do i get the text from my drop down list? Thanks
You need to use client side javascript as the change happens at the browser.
First change the markup a little bit to wrap the selection in a span.
<div> you have selected : <span id="selectedItem">#ViewBag.selected</span> </div>
Remove the #ViewBag.selected from the above line if your GET action is not really setting anything to that.
Now the script
$(function(){
$("#name").change(function(){
var selected = $(this).find("option:selected").text();
$("#selectedItem").text(selected);
});
});
This will read the selected option's Text and set that on our span.
If you want this text in the HttpPost action, you can add a new property to your view model
public class studentmodel
{
public int id { get; set; }
public string name { get; set; }
public string SelectedText{ get; set; }
}
And keep a hidden field inside the form
#Html.HiddenFor(s=>s.SelectedText)
Now, set the value of this using javascript set the value of this hidden field.
$(function(){
$("#name").change(function(){
var selected = $(this).find("option:selected").text();
//var selected = $("#name option:selected").text(); // another option
$("#selectedItem").text(selected);
$("#SelectedText").val(selected);
});
});
Now when you submit the form, the value of the hidden field SelectedText will also be submitted.
Model add one viewmodel as below
public class studentmodel
{
public int id { get; set; }
public string name { get; set; }
}
public class SomeViewModel
{
public string studentname {get; set;}
public SelectList studentlist {get; set;}
}
Updated
public ActionResult Index()
{
SomeViewModel Model = new SomeViewModel();
var studentlist = new List<SelectListItem>();
studentlist.Add(new SelectListItem() { Value = "1", Text = "saurav" });
studentlist.Add(new SelectListItem() { Value = "2", Text = "Rj" });
studentlist.Add(new SelectListItem() { Value = "3", Text = "rahul" });
Model.studentlist = new SelectList(studentlist, nameof(SelectListItem.Value), nameof(SelectListItem.Text));
return View(Model);
}
[HttpPost]
public ActionResult Index(SomeViewModel s)
{
return View();
}
and change your view as below
Updated
#model somenamespace.SomeViewModel
#Html.DropDownListFor(m => m.studentname , Model.studentlist , "select student");
I am trying to pass the Model data from a View (and PartialView within the View) back to the Controller upon HttpPost. (Adapted from Pass SelectedValue of DropDownList in Html.BeginForm() in ASP.NEt MVC 3)
Why? I want to show a list of assets each with a DropDownList and number of options. Upon submission of form to read the selected items from DropDownList.
My 2 (simplified) models:
public class Booking
{
public int BookingID { get; set; }
public int StoreID { get; set; }
...
public IEnumerable<AssetShort> Assets { get; set; }
}
and
public class AssetShort
{
public int AssetID { get; set; }
....
public int SelectedAction { get; set; }
public IEnumerable<SelectListItem> ActionList { get; set; }
}
In my Booking Controller > Create I build the List:
public ActionResult Booking(int id)
{
// get myBag which contains a List<Asset>
// booking corresponds to 'id'
var myAssets = new List<AssetShort>();
foreach (var a in myBag.Assets)
{
var b = new AssetShort();
b.AssetID = a.ID;
b.SelectedAction = 0;
b.ActionList = new[]
{
new SelectListItem { Selected = true, Value = "0", Text = "Select..."},
new SelectListItem { Selected = false, Value = "1", Text = "Add"},
new SelectListItem { Selected = false, Value = "2", Text = "Remove"},
new SelectListItem { Selected = false, Value = "3", Text = "Relocate"},
new SelectListItem { Selected = false, Value = "4", Text = "Upgrade"},
new SelectListItem { Selected = false, Value = "5", Text = "Downgrade"}
};
myAssets.Add(b);
};
var model = new BookingRequirementsViewModel
{
BookingID = booking.ID,
StoreID = booking.StoreID,
Assets = myAssets.ToList(),
};
return View(model);
My View:
#model uatlab.ViewModels.BookingRequirementsViewModel
#{
ViewBag.Title = "Booking step 2";
}
<h4>Your booking ref. #Model.BookingID</h4>
#using (Html.BeginForm("Booking2", "Booking", FormMethod.Post))
{
<fieldset>
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.StoreID)
#Html.Partial("_Assets", Model.StoreAssets)
<input type="submit" value="Cancel" class="btn btn-default" />
<input type="submit" value="Next" class="btn btn-default" />
</fieldset>
}
The Partial View includes
#foreach (var item in Model)
{
<tr>
<td>#item.Name</td>
<td>#item.Number</td>
<td>#Html.DropDownListFor(modelItem=>item.SelectedAction, item.ActionList)</td>
</tr>
}
So, all this works fine in the browser and I can select dropdowns for each asset listed but when I submit the only value posted back is the StoreID as it is in a "HiddenFor".
The booking2 controller has the model for a parameter:
public ActionResult Booking2(BookingRequirementsViewModel model)
{
//loop through model.Assets and display SelectedActions
}
Let me make it clear what the problems is - in Booking2 controller the Model is null when viewed in Debug mode and I get error "Object reference not set to an instance of an object."
Any ideas please how to pass back the Model to controller from view?
Regards
Craig
You need to create an EditorTemplate for AssetShort. I also suggest moving ActionList to the BookingRequirementsViewModel so your not regenerating a new SelectList for each AssetShort
The models you have posted aren't making sense. Your controller has var model = new BookingRequirementsViewModel { ..., Assets = myAssets.ToList() }; but in the view you refer to #Html.Partial("_Assets", Model.StoreAssets)? Are these 2 different properties. I will assume that StoreAssets is IEnumerable<AssetShort>
/Views/Shared/EditorTemplates/AssetShort.cshtml
#model AssetShort
<tr>
<td>#Html.DispayFor(m => m.Name)</td>
....
<td>
#Html.DropDownListFor(m => m.SelectedAction, (IEnumerable<SelectListItem>)ViewData["actionList"], "--Please select--")
#Html.ValidationMessageFor(m => m.SelectedAction)
</td>
</tr>
In the main view
#model uatlab.ViewModels.BookingRequirementsViewModel
....
#using (Html.BeginForm()) // Not sure why you post to a method with a different name
{
....
#Html.HiddenFor(m => m.StoreID)
#Html.EditorFor(m => m.StoreAssets, new { actionList = Model.ActionList })
....
}
In the controller
public ActionResult Booking(int id)
{
....
var model = new BookingRequirementsViewModel
{
BookingID = booking.ID,
StoreID = booking.StoreID,
Assets = myBag.Assets.Select(a => new AssetShort()
{
AssetID = a.ID,
SelectedAction = a.SelectedAction, // assign this if you want a selected option, otherwise the "--Please select--" option will be selected
....
})
};
ConfigureViewModel(model); // Assign select list
return View(model);
}
And a separate method to generate the SelectList because it needs to be called in the GET method and again in the POST method if you return the view. Note use the overload of DropDownListFor() to generate the option label (null value) as above, and there is no point setting the Selected property (the value of SelectedAction determines what is selected, not this)
private ConfigureViewModel(BookingRequirementsViewModel model)
{
model.ActionList = new[]
{
new SelectListItem { Value = "1", Text = "Add"},
....
new SelectListItem { Value = "5", Text = "Downgrade"}
};
}
and the POST
public ActionResult Booking(BookingRequirementsViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model); // Re-assign select list
return View(model);
}
// save and redirect
}
I recommend also making SelectedAction nullable with the [Required] attribute so you get client and server side validation
public class AssetShort
{
public int AssetID { get; set; }
....
[Required]
public int? SelectedAction { get; set; }
}
I have a DropDownListFor that is on my Index page and one in my Create page. Both dropdownlists serve the same purpose.
What I want is when the user selects an item in the Index dropdownlist in the index page, it saves that selected item's value which is a GUID to the session and when the Create page loads, I want the dropdownlist in there to select the item based on the GUID in the session.
At the moment when the user clicks on "Create" and goes to the create page, I am merely setting up an object and sending that object to the Create View.
Edit:
I am sending the user over to the Create page by doing this:
Html.ActionLink("Create New Listing", "Create", null, new { #class = "btn btn-primary" }))
How do I send the GUID of the selecteditem over to the view?
I guess you have a situation like this. Here is the Index view:
#model Models.IndexViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("SaveGuid", "Flow"))
{
Html.DropDownListFor(x => x.SelectedGuid, Model.Guids, new { onchange = "this.form.submit();" });
}
Here is the Index model:
public class IndexViewModel
{
public Guid SelectedGuid { get; set; }
public SelectList Guids { get; set; }
}
The Index and SaveGuid Action look like this:
private List<Guid> Guids = new List<Guid> { Guid.NewGuid(), Guid.NewGuid() }; // for testing only
public ActionResult Index()
{
var model = new IndexViewModel { Guids = new SelectList(Guids, Guids.First()) };
return View(model);
}
public ActionResult SaveGuid(IndexViewModel model)
{
Session["SelectedGuid"] = model.SelectedGuid;
return new RedirectResult("Create");
}
The Create View looks like this...
#model MvcBootStrapApp.Models.CreateViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("SaveGuid", "Flow"))
{
#Html.DropDownListFor(x => x.SelectedGuid, Model.Guids, new { onchange = "this.form.submit();" });
}
#using (Html.BeginForm("SaveCreate", "Flow"))
{
// setup other controls
<input type="submit" value="Submit" />
}
Using a CreateViewModel like this...
public class CreateViewModel
{
public Guid SelectedGuid { get; set; }
public SelectList Guids { get; set; }
// include other model properties
}
The Create and CreateSave ActionResults look like this...
public ActionResult Create()
{
Guid selectedGuid = Guids.First();
if (Session["SelectedGuid"] != null)
selectedGuid = (Guid)Session["SelectedGuid"];
return View(new CreateViewModel
{
Guids = new SelectList(Guids, selectedGuid),
SelectedGuid = selectedGuid
});
}
public ActionResult SaveCreate(CreateViewModel model)
{
// save properties
return new RedirectResult("Index");
}
I used two forms to allow both the change of selected Guid and to postback all the Create properties.
If you want to use Session, what I think you need is to use a form to post to an ActionResult to save the dropdownlist's value and then redirect to the Create page.
public ActionResult SaveGuid(Guid value)
{
Session["SelectedGuid"] = value;
return new RedirectResult("Create");
}
Then in your Create ActionResult, pass the Session value to the Create View's Model.
public ActionResult Create()
{
var selectedGuid = (Guid)Session["SelectedGuid"];
return View(new CreateViewModel { SelectedGuid = selectedGuid, /* include other properties */ };
}
In your view you can set the selected option on the SelectList passed to your DropDownListFor...
#Html.DropDownListFor(
x => x.SelectedGuid,
new SelectList(Model.ListOfStuff, "Key", "Value", Model.SelectedGuid)
)