2

ORIGINAL

I have a website where I can manage cars, brands, and car models. Right now I have controllers, models and views, the application is working, everything was auto generated by Visual Studio, and i am using entity framework (database first).

When I try to create a car, the dropdowns with brands and Car models are not cascading like I want.

I have a solution: add a class (or other property/attribute) to each option tag on each select (dropdown). Then, with JS, i'll do the rest. I just want to know how can I do a foreach loop to build my dropdown, even if it's not the best solution, i'm not discussing that. Remember, I need to do a foreach loop to the carmodel Model, inside the Cars View.

EDIT

Car View

@model MyApp.Models.car

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm())

{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>car</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.bodytypeId, "bodytypeId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("bodytypeId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.bodytypeId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.manufacturerId, "manufacturerId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("manufacturerId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.manufacturerId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.modelId, "modelId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">                
                @Html.DropDownList("modelId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.modelId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.versionId, "versionId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("versionId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.versionId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.fuelId, "fuelId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("fuelId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.fuelId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.transmissionId, "transmissionId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("transmissionId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.transmissionId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.colorId, "colorId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("colorId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.colorId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.horsePower, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.horsePower, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.horsePower, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.kw, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.kw, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.kw, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.cc, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.cc, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.cc, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Co2Emissions, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Co2Emissions, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Co2Emissions, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.mileage, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.mileage, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.mileage, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.year, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.year, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.year, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.doors, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.doors, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.doors, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.seats, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.seats, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.seats, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.plate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.plate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.plate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.price, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.price, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.price, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.shortDescription, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.shortDescription, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.shortDescription, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.longDescription, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.longDescription, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.longDescription, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.sold, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.sold)
                    @Html.ValidationMessageFor(model => model.sold, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.active, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.active)
                    @Html.ValidationMessageFor(model => model.active, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.dateAdded, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.dateAdded, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.dateAdded, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.dateSold, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.dateSold, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.dateSold, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Car Model

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace MyApp.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Web.Mvc;
    public partial class car
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public car()
        {
            this.carimages = new HashSet<carimage>();
        }

        public int id { get; set; }
        [Display(Name = "#")]
        public Nullable<int> bodytypeId { get; set; }
        [Display(Name = "Body Type")]
        public Nullable<int> manufacturerId { get; set; }
        [Display(Name = "Model")]
        public Nullable<int> modelId { get; set; }
        [Display(Name = "Version")]
        public Nullable<int> versionId { get; set; }
        [Display(Name = "Fuel")]
        public Nullable<int> fuelId { get; set; }
        [Display(Name = "Transmission")]
        public Nullable<int> transmissionId { get; set; }
        [Display(Name = "Color")]
        public Nullable<int> colorId { get; set; }
        [Display(Name = "HP")]
        public Nullable<int> horsePower { get; set; }
        [Display(Name = "KW")]
        public Nullable<int> kw { get; set; }
        [Display(Name = "CC")]
        public Nullable<int> cc { get; set; }
        [Display(Name = "CO2")]
        public Nullable<double> Co2Emissions { get; set; }
        [Display(Name = "Mileage")]
        public Nullable<int> mileage { get; set; }
        [Display(Name = "Year")]
        public Nullable<int> year { get; set; }
        [Display(Name = "Doors")]
        public Nullable<int> doors { get; set; }
        [Display(Name = "Seats")]
        public Nullable<int> seats { get; set; }
        [Display(Name = "Plate")]
        public string plate { get; set; }
        [Display(Name = "Price")]
        public Nullable<int> price { get; set; }
        [Display(Name = "Short Description")]
        public string shortDescription { get; set; }
        [Display(Name = "Long Description")]
        public string longDescription { get; set; }
        [Display(Name = "Sold")]
        public bool sold { get; set; }
        [Display(Name = "Active")]
        public bool active { get; set; }
        [Display(Name = "Date Added")]
        [DataType(DataType.DateTime)]
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy hh:mm}", ApplyFormatInEditMode = true)]
        public Nullable<System.DateTime> dateAdded { get; set; }
        [Display(Name = "Date Sold")]
        [DataType(DataType.DateTime)]
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy hh:mm}", ApplyFormatInEditMode = true)]
        public Nullable<System.DateTime> dateSold { get; set; }

        public virtual bodytype bodytype { get; set; }
        public virtual color color { get; set; }
        public virtual fuel fuel { get; set; }
        public virtual manufacturer manufacturer { get; set; }
        public virtual model model { get; set; }
        public virtual transmission transmission { get; set; }
        public virtual version version { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<carimage> carimages { get; set; }

    }
}

Car Controller

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using MyApp.Models;

namespace MyApp.Controllers
{
    public class carsController : Controller
    {
        private MyAppEntities db = new MyAppEntities();

        // GET: cars
        public ActionResult Index(string id)
        {
            string searchString = id;
            var cars = db.cars.Include(c => c.bodytype).Include(c => c.color).Include(c => c.fuel).Include(c => c.manufacturer).Include(c => c.model).Include(c => c.transmission).Include(c => c.version);

            if (!String.IsNullOrEmpty(searchString))
            {
                cars = cars.Where(s => s.bodytype.name.Contains(searchString) || 
                    s.cc.ToString().Contains(searchString) ||
                    s.Co2Emissions.ToString().Contains(searchString) ||
                    s.color.name.Contains(searchString) ||
                    s.dateAdded.Value.ToString("dd-mm-yyyy").Contains(searchString) ||
                    s.dateSold.Value.ToString("dd-mm-yyyy").Contains(searchString) ||
                    s.doors.ToString().Contains(searchString) ||
                    s.fuel.name.Contains(searchString) ||
                    s.horsePower.ToString().Contains(searchString) ||
                    s.id.ToString().Contains(searchString) ||
                    s.kw.ToString().Contains(searchString) ||
                    s.longDescription.Contains(searchString) ||
                    s.manufacturer.name.Contains(searchString) ||
                    s.mileage.ToString().Contains(searchString) ||
                    s.model.name.Contains(searchString) ||
                    s.plate.Contains(searchString) ||
                    s.price.ToString().Contains(searchString) ||
                    s.seats.ToString().Contains(searchString) ||
                    s.shortDescription.Contains(searchString) ||
                    s.transmission.name.Contains(searchString) ||
                    s.version.name.Contains(searchString) ||
                    s.year.ToString().Contains(searchString)
                );
            }

            return View(cars.ToList());
        }

        // GET: cars/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            car car = db.cars.Find(id);
            if (car == null)
            {
                return HttpNotFound();
            }
            return View(car);
        }

        // GET: cars/Create
        public ActionResult Create()
        {
            ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name");
            ViewBag.colorId = new SelectList(db.colors, "id", "name");
            ViewBag.fuelId = new SelectList(db.fuels, "id", "name");
            ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name");
            ViewBag.modelId = new SelectList(db.models, "id", "name");
            ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name");
            ViewBag.versionId = new SelectList(db.versions, "id", "name");
            return View();
        }

        // POST: cars/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "id,bodytypeId,manufacturerId,modelId,versionId,fuelId,transmissionId,colorId,horsePower,kw,cc,Co2Emissions,mileage,year,doors,seats,plate,price,shortDescription,longDescription,sold,active,dateAdded,dateSold")] car car)
        {
            if (ModelState.IsValid)
            {
                db.cars.Add(car);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name", car.bodytypeId);
            ViewBag.colorId = new SelectList(db.colors, "id", "name", car.colorId);
            ViewBag.fuelId = new SelectList(db.fuels, "id", "name", car.fuelId);
            ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name", car.manufacturerId);
            ViewBag.modelId = new SelectList(db.models, "id", "name", car.modelId);
            ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name", car.transmissionId);
            ViewBag.versionId = new SelectList(db.versions, "id", "name", car.versionId);
            return View(car);
        }

        // GET: cars/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            car car = db.cars.Find(id);
            if (car == null)
            {
                return HttpNotFound();
            }
            ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name", car.bodytypeId);
            ViewBag.colorId = new SelectList(db.colors, "id", "name", car.colorId);
            ViewBag.fuelId = new SelectList(db.fuels, "id", "name", car.fuelId);
            ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name", car.manufacturerId);
            ViewBag.modelId = new SelectList(db.models, "id", "name", car.modelId);
            ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name", car.transmissionId);
            ViewBag.versionId = new SelectList(db.versions, "id", "name", car.versionId);
            return View(car);
        }

        // POST: cars/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "id,bodytypeId,manufacturerId,modelId,versionId,fuelId,transmissionId,colorId,horsePower,kw,cc,Co2Emissions,mileage,year,doors,seats,plate,price,shortDescription,longDescription,sold,active,dateAdded,dateSold")] car car)
        {
            if (ModelState.IsValid)
            {
                db.Entry(car).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.bodytypeId = new SelectList(db.bodytypes, "id", "name", car.bodytypeId);
            ViewBag.colorId = new SelectList(db.colors, "id", "name", car.colorId);
            ViewBag.fuelId = new SelectList(db.fuels, "id", "name", car.fuelId);
            ViewBag.manufacturerId = new SelectList(db.manufacturers, "id", "name", car.manufacturerId);
            ViewBag.modelId = new SelectList(db.models, "id", "name", car.modelId);
            ViewBag.transmissionId = new SelectList(db.transmissions, "id", "name", car.transmissionId);
            ViewBag.versionId = new SelectList(db.versions, "id", "name", car.versionId);
            return View(car);
        }

        // GET: cars/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            car car = db.cars.Find(id);
            if (car == null)
            {
                return HttpNotFound();
            }
            return View(car);
        }

        // POST: cars/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            car car = db.cars.Find(id);
            db.cars.Remove(car);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
  • You wrote a lot but actually you didn't say what _"...are not cascading like I want"_. What do you want? How they look like? – Adriano Repetti Mar 24 '16 at 11:14
  • Sorry. When i select the brand Peugeot, for example, i want that the other dropdown (car models) only show peugeot models, instead of all models for all brands. But that's not the question, i can do that with JS like i said, i just want to know how to build a dropdown with a for each loop inside the view. Remember, the dropdown is inside Cars View, and must have CarModel data. –  Mar 24 '16 at 11:20
  • I'd do it server-side. When you pick a Brand then a quick AJAX request will obtain items to populate Model dropdown. I think it's much easier than client side filtering (where you need to retrieve all possible models for every brand in advance). – Adriano Repetti Mar 24 '16 at 11:26
  • @DA_Interlog Your idea of making a model dropdown independent to the brand dropdown can be achieved by having a neat DB design – KTOV Mar 24 '16 at 11:31
  • 2 tables, brand table with just the brand and model table with both model and brand as an FK. When the brand is selected, grab the ID send an AJAX request to then do an SQL to retrieve models specific to the brand ID and repopulate data on the dropdown :) – KTOV Mar 24 '16 at 11:34
  • @KTOV can you post an answer showing how to do it step by step? I know i'm asking a lot, but i'm really new to this and i'm not very confortable with ajax too. Maybe I can learn from you... I already have the FK, the database is configured correctly, i'm confortable with that –  Mar 24 '16 at 12:16

4 Answers4

3

Original

With ASP.NET MVC, you use server-side pre-processing to bind servers-side models to the .cshtml. From within the markup you can use tag helpers to build out common controls and user input components, this is where the razor view engine comes into play. Odeto-Code by Scott Allen has a great article on how you use these technologies together to build out a drop-down-list control specifically.

Here is part of that examples, .cshtml:

@Html.LabelFor(m=>m.SelectedFlavorId)
@Html.DropDownListFor(m => m.SelectedFlavorId, Model.FlavorItems)
@Html.ValidationMessageFor(m=>m.SelectedFlavorId)
<input type="submit" value="Submit" />

And here is the corresponding model, ViewModel.cs:

public class ViewModel
{
    private readonly List<IceCreamFlavor> _flavors;

    [Display(Name = "Favorite Flavor")]
    public int SelectedFlavorId { get; set; }

    public IEnumerable<SelectListItem> FlavorItems
    {
        get { return new SelectList(_flavors, "Id", "Name");}
    }
}

As an additional resource there is actually several other stackoverflow Q/A's that cover questions similar to this, here is one that is noteable.

Update 1

I just want to know how can I do a foreach loop to build my dropdown

Again you can use the razor view engine here. It allows for interaction with a server-side C# model and a means to build HTML markup from that. Here is an example:

<select>
    @{
        foreach (var item in Model.ListOfItems)
        {
            <option value="item.Value" customAttribute="item.SomethingSpecial">
                item.Name
            </option>
        }
    }
</select>

Update 2

You car model does not define a list of models. You need to specify what the options are in order to do a foreach. In other words you cannot build a dropdownlist from a property on a C# model that is not a list. Does that help?

Community
  • 1
  • 1
David Pine
  • 23,787
  • 10
  • 79
  • 107
  • That part i understood. I know i can do that, but i want to use data from a model, not static text, and i want to add a third attribute to options inside the dropdown, not hat text and value. –  Mar 24 '16 at 11:28
  • An option can be added within the dropdown from my answer @DA_Interlog – KTOV Mar 24 '16 at 11:38
  • @KTOV, I already called attention to that method. It does not however work as he needs to add a custom attribute to the `option` element. I have covered both cases in my answer. – David Pine Mar 24 '16 at 11:40
  • @DavidPine Where should i put the ViewModel.cs file? I'm sorry, like i said i'm new to MVC –  Mar 24 '16 at 11:43
  • In your Models directory, it's the "M" in `MVC`. Your should have a this type of relationship https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/MVC-Process.svg/200px-MVC-Process.svg.png. – David Pine Mar 24 '16 at 11:45
  • @DavidPine It's showing me a warning 'field _flavors is never assigned to and will always have its default value null –  Mar 24 '16 at 12:14
  • Without any source code of yours to look at, it is hard to say exactly. – David Pine Mar 24 '16 at 12:15
  • @DavidPine I included the original code in my original post, without your code. When i include the code (the one you wrote inside ViewModel class) inside my public partial class car, it gives me the warning i said earlier, and at runtime there is an error too –  Mar 24 '16 at 12:24
  • @DavidPine Thank you for your 3 Updates, yes, they helped very very much. With your help and some hours searching, i found a solution that i posted as answer to help others with the same problem. More important, i learned something more about MVC. Thank you very much! I don't have enough reputation to vote or accept answers, when i do i will upvote you. I have to wait that somebody upvotes my question... –  Mar 24 '16 at 14:49
0

You can do this in C# rather than JS, a quick example here:

public class FindUser 
{

  // Where the items from the DB will be kept
  public Dictionary<int, string> CountryList { get; set; }

  // Used to store the users selected option
  public int SelectedCountry { get; set; }

  // A constructor to be called when the page renders
  public FindUser()
  {
      PopulateCountryDropdown();
  }

  public void PopulateLeaDropdown()
    {
        // 1. Grab your items from the database, store it within a databale
        // 2. Loop through the datatable and add each row to the list

        CountryList = new Dictionary<int, string>();

        foreach(DataRow row in dt.Rows)
        {
            CountryList.Add(Convert.ToInt32(row["ID"]), row["country"].ToString());
        }
    }
}

Then in your frontend add:

@Html.DropDownListFor(u => u.SelectedCountry, new SelectList(Model.CountryList, "Key", "Value"), "Select your country", new { @class = "form-control countries", id = "country_list" })
KTOV
  • 559
  • 3
  • 14
  • 39
  • How can i add a class attribute to each option inside dropdown with that? –  Mar 24 '16 at 13:04
0

Solution found HERE

School database with the following 2 tables.

StateMaster
DistrictMaster

Step 1

Open Visual Studio then select File >> New >> Project then select ASP.Net MVC 4 Web Application.

Step 2

Select Internet Application then click OK.

Step 3

Select the Model folder then create a new Model class.

StudentModel.cs

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  

namespace MvcDemoApplication.Models  
{  
    public class StudentModel  
    {  
        public IList<SelectListItem> StateNames { get; set; }  
        public IList<SelectListItem> DistrictNames { get; set; }  
    }  
}

Step 4

Create a .edmx file and connect with the database.

Step 5

Create a new Controller. In this article I create DropDownListController.cs.

DropDownListController.cs

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  
using MvcDemoApplication.Models;  

namespace MvcDemoApplication.Controllers  
{  
    public class DropDownListController : Controller  
    {  
        //  
        // GET: /DropDownList/  
        SchoolEntities schoolEntity = new SchoolEntities();  
        public ActionResult Index()  
        {  
            List<SelectListItem> stateNames = new List<SelectListItem>();  
            StudentModel stuModel=new StudentModel();  

            List<StateMaster> states = schoolEntity.StateMasters.ToList();  
            states.ForEach(x =>  
                {  
          stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });  
                });  
            stuModel.StateNames = stateNames;  
            return View(stuModel);  
        }  
    }  
}

Index.cshtml

@model MvcDemoApplication.Models.StudentModel  
@{  
    ViewBag.Title = "Index";  
}  

<script src="~/Scripts/jquery-1.7.1.min.js"></script>  

<h2>Cascading Dropdownlist</h2>  
<table>  
    <tr>  
        <td>  
            <label>State</label>  
        </td>  
        <td>  
@Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { @id="ddlState"});  
        </td>  
    </tr>  
</table>

Understand the Code

In Studentmodel we have the following 2 properties:

    public IList<SelectListItem> StateNames { get; set; }  
    public IList<SelectListItem> DistrictNames { get; set; }  

Here we are using the SelectListItem class, this class has the following 3 properties:

Selected: This is a bool type to show in a dropdown (as selected) true or false by default.

Text: This is a string type, for the dropdown text.

Value: This is string type for the value of the dropdown

If you notice in the dropdownlist, we also need the same properties. For this reason we are using SelectListItem in a Ilist.

DropdownlistController.cs

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  
using MvcDemoApplication.Models;  

namespace MvcDemoApplication.Controllers  
{  
    public class DropDownListController : Controller  
    {  
        //  
        // GET: /DropDownList/  
        SchoolEntities schoolEntity = new SchoolEntities();  
        public ActionResult Index()  
        {  
            List<SelectListItem> stateNames = new List<SelectListItem>();  
            StudentModel stuModel=new StudentModel();  

            List<StateMaster> states = schoolEntity.StateMasters.ToList();  
            states.ForEach(x =>  
                {  
                    stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });  
                });  
            stuModel.StateNames = stateNames;  
            return View(stuModel);  
        }  
    }

In the preceding code we create the SchoolEntities object, in this object all the related tables exist.

SchoolEntities schoolEntity = new SchoolEntities();  

List<StateMaster> states = schoolEntity.StateMasters.ToList();  

In the preceding line of code, all the related data of the StateMasters tables comes into the StateMaster list object.

states.ForEach(x =>  
{  
   stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });  
});  

Now it is time to add entity data into the Text and value properties, the all collection will be stored into the stateNames object.

Index.cshtml

@model MvcDemoApplication.Models.StudentModel  
@{  
    ViewBag.Title = "Index";  
}  

<script src="~/Scripts/jquery-1.7.1.min.js"></script>  

<h2>Cascading Dropdownlist</h2>  
<table>  
    <tr>  
        <td>  
            <label>State</label>  
        </td>  
        <td>  
  @Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { @id="ddlState"});  
        </td>  
    </tr>  
</table>

The preceding code shows the model data in View. Now to understand how it works.

@Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { @id="ddlState"});

Look at the preceding code, we used here, @Html helper classes for creating a DropDownList. In the DropDownListFor helper class we used 4 parameters.

x=>x.StateNames: For getting the values of the collection from the entity.

Model.StateNames: Collections of states.

“—Select--”: Default value, when the dropdown list will be populated.

new {@id=”ddlState”}: In this part we can define an id, class and name for the control.

How to do cascading between two dropdownlists.

DropdownlistController.cs

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  
using MvcDemoApplication.Models;  

namespace MvcDemoApplication.Controllers  
{  
    public class DropDownListController : Controller  
    {  
        //  
        // GET: /DropDownList/  
        SchoolEntities1 schoolEntity = new SchoolEntities1();  
        public ActionResult Index()  
        {  
            List<SelectListItem> stateNames = new List<SelectListItem>();  
            StudentModel stuModel=new StudentModel();  

            List<StateMaster> states = schoolEntity.StateMasters.ToList();  
            states.ForEach(x =>  
                {  
stateNames.Add(new SelectListItem { Text = x.StateName , Value = x.StateId.ToString() });  
                });  
            stuModel.StateNames = stateNames;  
            return View(stuModel);  
        }  

        [HttpPost]  
        public ActionResult GetDistrict(string stateId)  
        {  
            int statId;  
            List<SelectListItem> districtNames = new List<SelectListItem>();  
            if (!string.IsNullOrEmpty(stateId))  
            {  
                statId = Convert.ToInt32(stateId);  
List<DistrictMaster> districts = schoolEntity.DistrictMasters.Where(x => x.StateId == statId).ToList();  
                districts.ForEach(x =>  
                {  
districtNames.Add(new SelectListItem { Text = x.DistrictName, Value = x.DistrictId.ToString() });  
                });  
            }  
            return Json(districtNames, JsonRequestBehavior.AllowGet);  
        }  

    }  
}

Index.cshtml

@model MvcDemoApplication.Models.StudentModel  
@{  
    ViewBag.Title = "Index";  
}  

<script src="~/Scripts/jquery-1.7.1.min.js"></script>  

<h2>Cascading Dropdownlist</h2>  
<table>  
    <tr>  
        <td>  
            <label>State</label>  
        </td>  
        <td>  
@Html.DropDownListFor(x => x.StateNames, Model.StateNames, "--Select--", new { @id="ddlState"});  
        </td>  
    </tr>  
    <tr>  
        <td>  
            <label>District</label>  
        </td>  
        <td id="District">  
@Html.DropDownListFor(x => x.DistrictNames, new List<SelectListItem>(), "--Select--", new { @id="ddlDistrict"});  
        </td>  
    </tr>  
</table>  

<script type="text/javascript">  
    $(document).ready(function () {  
        $('#ddlState').change(function () {  
            $.ajax({  
                type: "post",  
                url: "/DropDownList/GetDistrict",  
                data: { stateId: $('#ddlState').val() },  
                datatype: "json",  
                traditional: true,  
                success: function (data) {  
                    var district = "<select id='ddlDistrict'>";  
                    district = district + '<option value="">--Select--</option>';  
                    for (var i = 0; i < data.length; i++)  
                    {  
                        district = district + '<option value=' + data[i].Value + '>' + data[i].Text + '</option>';  
                    }  
                    district = district + '</select>';  
                    $('#District').html(district);  
                }  
            });  
        });  
    });  
</script>

That's it. Press F5 and run your code.

-1

Look at Nuget package Mvc.CascadeDropDown:
https://www.nuget.org/packages/Mvc.CascadeDropDown/

Here is how I am using it:

@Html.CascadingDropDownListFor(m => m.ArticleGroup_Nr, "Department_Nr",
    Url.Action("GetArticleGroups"), "DepartmentNr", "-- Select item --", true,
    new { @class = "form-control", style = "width: 450px" })

Here Department_Nr specifies the parent dropdown elsewhere in the View - either a regular dropdownlist or another cascaded dropdownlist.

I then created a JSON Action GetArticleGroups on the same Controller that accepts a DepartmentNr parameter, which is passed the current value of the parent dropdown.

The JSON Action will be called everytime the value of the parent dropdown is changed because @Html.Cascading... also attaches an onchange-eventhandler to the parent object.

public virtual JsonResult GetArticleGroups(int DepartmentNr)
{
    var items = provider.ArticleGroups.Where(m => m.Parent_Nr == DepartmentNr);
    return GetJson(items); // convert items to JSON [ { "Value":"xx", "Text":"yy" } ]
}

private JsonResult GetJson(IQueryable<ICatalogueItem> items)
{
    var data = items
        .Select(x => new { Value = x.Number, Text = x.Text })
        .OrderBy(o => o.Text);
    return Json(data, JsonRequestBehavior.AllowGet);
}



... Or see this article on how to build it yourself:
http://www.c-sharpcorner.com/UploadFile/4d9083/creating-simple-cascading-dropdownlist-in-mvc-4-using-razor/
Peter B
  • 22,460
  • 5
  • 32
  • 69
  • whoever downvoted you is probably concerned about the "answer in another castle" problem that you get just posting links to external resources. http://meta.stackexchange.com/questions/225370/your-answer-is-in-another-castle-when-is-an-answer-not-an-answer – Loofer Mar 24 '16 at 11:26
  • @Loofer Tried the nuget, but when put '@using Mvc.CascadeDropDown' in the top of my .cshtml view it doesn't accept, says 'mvc.' doesn't exist. Tried the web.config way, doens't work too. I checked andthe pacckage is installed and the reference to 'Mvc.CascadeDropDown' is in the project. –  Mar 24 '16 at 12:37
  • ask Peter B... I was just moaning about his stack overflow etiquette. – Loofer Mar 24 '16 at 14:18