Question

Based on https://mvcmusicstore.codeplex.com/ trying to get a drop down list of attributes in the Details album before buying. I created a table with a map of attributes and table with attributes. In principle, the product has to refer to the map of attributes, which is to define what akrybuty will appear in the drop-down list. enter image description hereSomeone can help me to implement in the application?

I know that in the view just add

@Html.DropDownList("Name",new SelectList(ViewBag.Names))

, I do not know how to get the data from that map the attributes so that each album had its own set of attributes from all available.

Controller:

namespace MvcMusicStore.Controllers
{
    public class StoreController : Controller
    {
        MusicStoreEntities storeDB = new MusicStoreEntities();

        //
        // GET: /Store/

        public ActionResult Index()
        {
            var genres = storeDB.Genres.ToList();

            return View(genres);
        }


        public ActionResult Browse(string genre)
        {
            // Retrieve Genre and its Associated Albums from database
            var genreModel = storeDB.Genres.Include("Albums")
                .Single(g => g.Name == genre);

            return View(genreModel);
        }


        public ActionResult Details(int id)
        {
            var album = storeDB.Albums.Find(id);

            return View(album);
        }        
    }
}

Models:

1

namespace MvcMusicStore.Models
{
    [Bind(Exclude = "AlbumId")]
    public class Album
    {
        [ScaffoldColumn(false)]
        public int AlbumId { get; set; }

        [DisplayName("Genre")]
        public int GenreId { get; set; }

        [DisplayName("Artist")]
        public int ArtistId { get; set; }

        [Required(ErrorMessage = "An Album Title is required")]
        [StringLength(160)]
        public string Title { get; set; }

        [Required(ErrorMessage = "Price is required")]
        [Range(0.01, 100.00,
            ErrorMessage = "Price must be between 0.01 and 100.00")]
        public decimal Price { get; set; }

        [DisplayName("Album Art URL")]
        [StringLength(1024)]
        public string AlbumArtUrl { get; set; }

        public virtual Genre Genre { get; set; }
        public virtual Artist Artist { get; set; }
        public virtual List<OrderDetail> OrderDetails { get; set; }
    }
}

2

namespace MvcMusicStore.Models
{
    public class Artist
    {
        public int ArtistId { get; set; }
        public string Name { get; set; }
    }
}

3

namespace MvcMusicStore.Models
{
    public partial class Genre
    {
        public int GenreId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public List<Album> Albums { get; set; }
    }
}

View:

@model MvcMusicStore.Models.Album

@{
ViewBag.Title = "Album - " + Model.Title;
}

<h2>@Model.Title</h2>

<p>
<img alt="@Model.Title" src="@Model.AlbumArtUrl" />
</p>

 <div id="album-details">
<p>
    <em>Genre:</em>
    @Model.Genre.Name
</p>
<p>
    <em>Artist:</em>
    @Model.Artist.Name
</p>
<p>
    <em>Price:</em>
    @String.Format("{0:F}", Model.Price)
</p>
<p class="button">
    @Html.ActionLink("Add to cart", "AddToCart", 
    "ShoppingCart", new { id = Model.AlbumId }, "")
</p>
</div>

the code I have currently.

I want to add dropdownlisty given the fact that each product will have different attributes such as one will have 8 types of cover, while the other only two. When you select each item (each with 8 covers) dropdownlist below it will zmianiała its contents

Picture an example of what he wants to achieve.

https://i.stack.imgur.com/IIApj.png

Was it helpful?

Solution

Assuming that you mean to have the second drop-down's values updated each time a different value is selected in the first drop-down, one way to do it is via jQuery, JSON, a view model and some controller actions (note this doesn't implement best practices like not having database calls in controller actions and extracting JS from the view and putting it into a module):

Entities:

namespace DataModel
{
    public class Item
    {
        [Id]
        public int ItemId {get; set;}

        public string ItemText {get; set;} 
    }

    public class Attribute
    {
        [Id]
        public int AttributeId {get; set;}

        public string AttributeText {get; set;}
    }
}

(omitting DbContext code)

Controller actions:

    [HttpGet]
    public ActionResult TestDropdown()
    {
        using(var context = new YourDbContext()) // it's good practice to use the using() statement to dispose of the DbContext's resources right when it's finished, rather than setting a class-level variable
        {
            var model = new Models.TestDropdownViewModel();
            // gets all the items; you might want to filter for items that you want to display 
            model.Items = context.Items.ToList().Select(i => new SelectListItem()
                {
                     Text = i.ItemText,
                     Value = i.ItemId.ToString() // this is probably an ID of the row for the corresponding Item
                });

            model.Attributes = context.Attributes.First().Select(a => new SelectListItem
                {
                    Text = a.AttributeText,
                    Value = a.AttributeId.ToString()
                });

            return View(model);
        }
    }

    [HttpGet]
    public JsonResult GetAttributesForItem(int selectedId)
    {
        using(var context = new YourDbContext())
        {
            var attributes = context.Attributes.Where(a => a.Item.ItemId == selectedId).ToList();

            return Json(addresses.Select(a => new { Value = a.AddressId.ToString(), Text = a.Address1 }), JsonRequestBehavior.AllowGet);
        }
    }

View model:

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

namespace Models
{
    public class TestDropdownViewModel
    {
        public IEnumerable<SelectListItem> Items { get; set; }

        public IEnumerable<SelectListItem> Attributes { get; set; }
    }
}

Partial View:

// make sure jQuery is loaded in your _Layout.cshtml if you're using that pattern

@model Models.TestDropdownViewModel

@{
    ViewBag.Title = "TestDropdown";
}

<div>
    @Html.DropDownList("Items", Model.Items, new { id = "Items" })
</div>
<br />
<div>
    @Html.DropDownList("Attributes", Model.Attributes, new { id = "Attributes" })
</div>

<script type="text/javascript">
    $(document).ready(function () {
        $('#Items').change(function () {
            var selectedId = this.value;
            $.getJSON('/GetAttributesForItem?', { id: selectedId }, function (data) {
                var attributes = $('#Attributes');
                var options;
                $.each(data, function (index, elem) {
                    options += "<option value='" + elem.Value + "'>" + elem.Text + "</option>";
                });
                attributes.html(options);
            });
        });
    });
</script>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top