I want to create dymanic controls in my ASP.NET MVC Project.
For example
My Model contains an IList<Product> Products. Every product in this list contains a new IList<ProductItem>.
Product item has properties Text and Value.
Now i want to create one DropDownList for every Products and every dropdownlist should contains items for ProductItem.
Is this possible with HtmlHelpers?
This is pretty straight forward.
In your controller
public ActionResult Index()
{
List<Product> model = GetProductList();
View(model);
}
In your View:
#model IList<Products>
... and then later on ...
#Html.DropDownListFor(item => item.Name, new SelectList(Model, "Name", "Value"))
If you don't want to use helpers, you can always do something like this:
<select>
#foreach (var x in Model)
{
<option value="#x.Value">#x.Text</option>
}
</select>
Related
I am currently developing an asp.NET MVC web application as a front end to a database. I have a MySQL database, one of the tables is contact information for employees. I have added a column of 'isOnSite' of datatype TINYINT(1).
I have updated the data model in my application, and added a checkbox control for this in one of my view. This works fine, I edit a contact, check the box to say that they are currently contracted to this particular site, and a '1' is populated in the 'isOnSite' column for that particular record, great!
One of the views is a Dashboard. In this view (using a partial view) I would like to generate a list of the contacts in the table that have the value of 'isOnSite = true'
I am struggling to do this. I should mention that I am pretty new to all of this.
Any help would be greatly appreciated.
Thank you in advance!
-- EDIT --
With the help of #Bunnynut and also my Father-in-Law We managed to solve this,
in large part to the code examples by #Bunnynut.
CONTROLLER ACTION
public ViewResult Index()
{
var tblcontacts = from m in db.tblcontacts.Where(x => x.isOnSite)
select m;
return View(tblcontacts.OrderBy(x => x.LastName).ToList());
}
PARTIAL VIEW
#model IEnumerable<ResourceBase.Models.tblcontact>
#{
ViewBag.Title = "OnSite";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>OnSite</h2>
<div class="container-fluid-viewport jumbotron col-xs-offset-4">
#foreach (var x in Model)
{
#x.FullName <br />
}
</div>
And the Main view just renders the partial view.
Thanks again for your help #Bunnynut
To begin with the Index View uses a model of type ResourceBase.Models.tlbcontact which is it seems a single tblcontcat.
But you are try to pass a List to your partial view so that is not possible.
You Index View should consume a model of which it pass parts of it to your partial views.
IndexViewModel:
public class IndexViewModel
{
public string Title { get; set; }
public List<ResourceBase.Models.tblcontact> Employees { get; set; }
}
Index Action:
public ActionResult Index()
{
var model =
new IndexViewModel
{
Title = "PeopleBase Dashboard",
Employees = GetEmployees()
};
return View(model);
}
Index View:
#model IndexViewModel
<div class="container-fluid-viewport col-md-offset-3 col-md-9">
<h2>#Model.Title</h2>
<div class="partialViewWrapper jumbotron">#{Html.RenderPartial("_peopleBaseDashView", Model.Employees.Where(x => x.isOnSite).ToList());}
</div>
</div>
Your partial View looks ok to me
Use the following SELECT statement
SELECT * FROM yourTable WHERE isOnSite = 1
to fill a property of your ViewModel, which you can then display in your view.
You can easily pass the list of employees directly to your partial view as long as you tell your partial view the model passed is of that type.
So in the master view containing the code that call the partial view you can do this:
#{Html.RenderPartial("NAME_PARTIAL_VIEW", employees.Where(x => x.isOnSite).ToList());}
And in you partial view:
#model List<Employee>
#foreach(var employee in Model)
{
#employee.Name
}
I'm trying to get all the info (column, rows) from a table in SQL and send it as a model to the view.
I also want it to be Distinct.
My controller:
MVCEntities me = new MVCEntities();
List<CarsCategory> arr = me.CarsCategories.ToList();
return View(arr);
My view model:
#model IEnumerable<CarsCategory>
In the view I'm trying to loop through a certain column like this:
<select id="SelectManufacturer">
#foreach (var i in Model)
{
<option value="#i.Manufacturer">#i.Manufacturer</option>
}
</select>
How do I make it Distinct? When I try to add Distinct it gives me system.linq.enumerable+<DistinctIterator> ..
Although it's not a good approach to process data inside the view, your solution might look like this:
<select id="SelectManufacturer">
#{
var manufacturers = Model.Select(x => x.Manufacturer).Distinct().ToList();
foreach (var i in manufacturers)
{
<option value="#i">#i</option>
}
}
</select>
The controller should be responsible to supply the View with the data, the view should not be polutted with a bunch of logic to try to aggregate this data unless you want unmaintainable code. The best approach is to extend your view model to have multiple properties.
Models
public class CategoryModel{
public List<CarsCategory> CarCategories {get;set;}
public List<Manufacturer> Manufacturers {get;set;}
}
public class Manufacturer{
public int Id {get;set;}
public string Name {get;set;}
}
Controller code
// you need to ensure that if you are using EF the context is disposed after you are done using it!
using(MVCEntities me = new MVCEntities()) {
var model = new CategoryModel();
model.CarCategories = me.CarsCategories.ToList();
// you need to supply the correct Id and Name locations in your model as you did not share this
model.Manufacturers = model.CarCategories.Select(x => new Manufacturer(){Id = x.prop.id, Name = x.prop.name}).Distinct();
return View(model);
}
Razor View
#model CategoryModel
<select id="SelectManufacturer">
#foreach (var i in Model.Manufacturers)
{
<option value="#i.Id">#i.Name</option>
}
</select>
I have a news item page and I would like to include a partial view presenting a list of the latest 5 news items. However, I get a
this dictionary requires a model item of type
'System.Collections.Generic.List
error message. I'm assuming the main view is strong typed to present a single item, whereas the partial view is strongly typed with a generic list and the two don't match.
Controller
public ActionResult NewsItem(int newsId, string newsTitle)
{
var q = _ctx.tblNews.Single(x => x.newsID == newsId);
return View(q);
}
public ActionResult NewsLatest()
{
var q = _ctx.tblNews.OrderBy(x => x.newsCreateDate)
.Where(x => x.WebsiteID == 2 && x.newsPublish).Take(5).ToList();
return View(q);
}
View (simplified)
#using MyMVC.Models
#model tblNews
<h2>#Model.newsTitle</h2>
#Html.Raw(Model.newsText)
<p>#Model.newsCreateDate</p>
#Html.RenderPartial("NewsLatest")
Partial View
#using MyMVC.Helpers
#model List<MyMVC.Models.tblNews>
<table>
#foreach (var x in Model)
{
<tr>
<td>
#Html.ActionLink(x.newsTitle, "NewsItem", new { newsId = x.newsID, newsTitle = x.newsTitle.ToSeoUrl() })<br />
<hr />
</td>
</tr>
}
</table>
I tried this in the view:
#{
Html.RenderPartial("NewsLatest", new List<tblNews> { new tblNews()});
}
but it looks like the ActionResult doesn't get fired trying i this way.
There are a few questions on SO relating to this. But I just can't get my head around the solutions. The penny isn't dropping!
Do I really have to create a view model that incorporates the news item data and the list of news items?
I have a class:
public class CarList
{
public int quantity{get;set;}
public List<Car> Cars {get;set;}
}
public class Car {
public string Name {get;set;}
}
I then create a car list with three cars in the list. I then display info on the screen using for loop Model.Cars within a . When I submit the form, quantity field has a valid value but Cars is null.
[HttpPost]
public ActionResult Save(CarList list)
{
//why is list.Cars NULL when i am posting three items in the list
}
View:
Model = Car, added a row
Added new editor template for Car with <tr><td>Name</td><td>Html.TextBoxFor(x=>Model.Name)</td></tr>
And in main view:
Model = CarList, added the forloop
#{foreach (Car item in Model.Cars)
{
#Html.EditorFor(x=>item);
}
Actually you don't need to loop through the cars collection. You just have it like
#Html.EditorFor(x => x.Cars)
Use an EditorTemplate and you will be good.
Create a Folder Called "EditorTemplates" and create a view (the editor template) with the name Car.cshtml
Now Add the below code to this new view.
#model Car
<p>
#Html.TextBoxFor(x => x.Name)
</p>
Now in your Main View, Use the Html.EditorFor HTML helper method to call this editor template
#model SO_MVC.Models.CarList
<h2>CarList</h2>
#using (Html.BeginForm())
{
<p>Quanitty </p>
#Html.TextBoxFor(x => x.quantity)
#Html.EditorFor(x=>x.Cars)
<input type="submit" value="Save" />
}
Now have an HTTPPOst action method to accept the form posting
[HttpPost]
public ActionResult CarList(CarList model)
{
//Check model.Cars property now.
}
You will see the results now
I think this is the issue:
#foreach (Car item in Model.Cars)
{
#Html.EditorFor(x=>item);
}
Change it to
#foreach (Car item in Model.Cars)
{
#Html.EditorFor(x=>item.Name);
}
It might a case of the model binder not being smart enough to bind more than one level down, although I don't remember ever having that issue. it may also help to add Glimpse (http://getglimpse.com/) to your project so that you can see how the request is actually processed.
So I took some advice to create a DropDownListFor element in my view, which meant to create a model view called
MODEL
class StudentModelView.
I have two properties.
StudentID{get;set;}
IEnumerable<SelectListItem> SelectPeopleList { get;set;}
I get the list to populate nicely with this code
VIEW
#Html.DropDownListFor(x => x.StudentID, Model.SelectPeopleList,"--Select Students--", new Dictionary<string,object>{ {"class","dropdowns"},{"id","selectPeopleDDL"}})
//NEED A BUTTON TO SUBMIT
CONTROLLER
public ActionResult Index()
{
return View(new StudentModelView());
}
What kind of button do I need to make it post
After posting, how do I update my view to show the new filtered list? Am I missing a POST controller or just ajax? What's the best approach?
You could do it all using jquery, but here is couple of pointers:
You should wrap your filter in a form:
#using (Html.BeginForm("Home", "Index", FormMethod.Get))
{
#Html.DropDownListFor(x => x.StudentID, Model.SelectPeopleList,"--Select Students--", new Dictionary<string,object>{ {"class","dropdowns"},{"id","selectPeopleDDL"}})
<input type="submit" value="Go" />
}
the submit button is not a must, you could just use jquery to submit whenever the value of the dropdown changes
in your controller:
public ActionMethod Index(int? studentID)
{
var model = new StudentModelView
{
StudentId = studentID,
SelectPeopleList=GetListFiltered(studentId)
}
return(model);
}