0

I am new to asp.net mvc. I am making an online video store application.

I have this view:

enter image description here

where users can choose which videos their gonna rent. The code for the view:

@model IEnumerable<VideoRentalSystem.Models.VideoMaintenance>

@{
    ViewBag.Title = "Index";
}

<h2>Video Rentals</h2>
<h5 style="color:red">Only available videos is shown.</h5>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Rating)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Quantity)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.UnitsAvailable)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.RentalPrice)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Rating)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Quantity)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.UnitsAvailable)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.RentalPrice)
        </td>
        <td>
            @Html.CheckBox("Rent?", new { id= item.VideoMaintenanceID})
        </td>
    </tr>
}

</table>

<input class="btn btn-primary" type="submit" value="Rent Selected Videos" />

Like you can see at the bottom of the code where I add the checkbox I (hopefully) give the checkbox an ID equal to the video info left of the textbox. What I want to know is how will I, if the user clicks the 'Rent Selected Videos' button, get all the selected videos and add it to a list, inside the controller-hope this makes sense?

My current controller:

using System.Data;
using System.Linq;
using System.Web.Mvc;
using VideoRentalSystem.DAL;

namespace VideoRentalSystem.Controllers
{
    public class VideoRentalsController : Controller
    {
        private VideoRentalContext db = new VideoRentalContext();

        // GET: VideoRentals
        public ActionResult Index()
        {
            var available = from a in db.VideosMaintenance
                            select a;

            available = available.Where(av => av.UnitsAvailable != 0);

            return View(available);
        }
    }
}

My Model for the VideoMaintenance:

//Primary Key
        public int VideoMaintenanceID { get; set; }

        [StringLength(60, MinimumLength = 3, ErrorMessage = "A maximum of 60 and a minimum of 3 characters is allowed")]
        [Required(ErrorMessage = "This field is required")]
        public string Title { get; set; }


        [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "Only letters is allowed")]
        [Required(ErrorMessage = "This field is required")]
        [StringLength(140, ErrorMessage = "A maximum of 140 characters is allowed")]
        public string Description { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "Only letters is allowed")]
        [Required(ErrorMessage = "This field is required")]
        [StringLength(30, ErrorMessage = "A maximum of 30 characters is allowed")]
        public string Genre { get; set; }

        [StringLength(15, ErrorMessage = "A maximum of 15 characters is allowed")]
        public string Rating { get; set; }

        [RegularExpression(@"^[0-9]+$", ErrorMessage = "Only numbers is allowed")]
        [Required(ErrorMessage = "This field is required")]
        public int Quantity { get; set; }

        [Display(Name = "Units Available")]
        [RegularExpression(@"^[0-9]+$", ErrorMessage = "Only numbers is allowed")]
        [Required(ErrorMessage = "This field is required")]
        public int UnitsAvailable { get; set; }

        [Display(Name = "Rental Price")]
        [Range(1, 100, ErrorMessage = "Range between 1,100")]
        [DataType(DataType.Currency)]
        public decimal RentalPrice { get; set; }

        //Foreign Key
        public virtual ICollection<CustomerMaintenance> CustomersMaintenance { get; set; }
    }

...and my model for CustomerMaintenance:

//Primary Key
        [Display(Name = "Identification Number")]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Required(ErrorMessage = "This field is required")]
        [RegularExpression(@"^[0-9]+$", ErrorMessage = "Only numbers is allowed")]
        public string CustomerMaintenanceID { get; set; }

        [StringLength(30, ErrorMessage = "A maximum of 30 characters is allowed")]
        [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "Only letters is allowed")]
        [Required(ErrorMessage = "This field is required")]
        public string Name { get; set; }

        [StringLength(60, ErrorMessage = "A maximum of 60 characters is allowed")]
        [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "Only letters it allowed")]
        [Required(ErrorMessage = "This field is required")]
        public string Surname { get; set; }

        [StringLength(250, ErrorMessage = "A maximum of 250 characters is allowed")]
        //[RegularExpression(@"^[A-Z]+[0-9]+[a-zA-Z''-'\s]*$")]
        [Required(ErrorMessage = "This field is required")]
        [Display(Name = "Physical Address")]
        public string Address { get; set; }

        [StringLength(10, ErrorMessage = "A maximum of 10 characters is allowed")]
        [RegularExpression(@"^[0-9]+$", ErrorMessage = "Only numbers allowed")]
        [Required(ErrorMessage = "This field is required")]
        [Display(Name = "Phone Number")]
        public string PhoneNumber { get; set; }

        //Foreign Key
        public virtual VideoMaintenance VideosMaintenance { get; set; }

My DbContext:

using System.Data.Entity;
using VideoRentalSystem.Models;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace VideoRentalSystem.DAL
{
    public class VideoRentalContext : DbContext
    {
        //Passes name of the connnection string to the constructor
        public VideoRentalContext() : base("VideoRentalContext")
        {

        }

        public DbSet<CustomerMaintenance> CustomersMaintenance { get; set; }
        public DbSet<VideoMaintenance> VideosMaintenance { get; set; }

        //Override entity naming convention- disable pluralisation 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>();
        }
    }
}

I apologize for this long question! Any help will be appreciated!

naheiwProg
  • 99
  • 2
  • 11
  • 1
    Refer [this answer](http://stackoverflow.com/questions/29542107/pass-list-of-checkboxes-into-view-and-pull-out-ienumerable/29554416#29554416) for an example of using checkboxes in a collection –  Nov 11 '15 at 20:27

2 Answers2

3

Looks like a great use case to make use of Editor Templates.

Create a view model like this for your view.

public class RentVideoVM
{       
    public List<VideoSelection> Videos { set; get; } 
    //Add other properties needed for your view.
}

public class VideoSelection
{
    public int VideoId { set; get; }
    public string Name { set; get; }   

    public bool IsSelected { set; get; }
   //Add other properties needed for your view.
}

The IsSelected property of VideoSelection class is used to store users selection on the check box from the UI.

Now in your GET action method, create an instance of the RentVideoVM viewmodel, Load the Videos collection and send it to the view,

public ActionResult Register()
{
    var vm = new RentVideoVM();
    vm.Videos = db.Videos.Select(s => new VideoSelection
    {
        VideoId = s.VideoId,
        Name = s.VideoName
    }).ToList();
    return View(vm);
}

Change it db.YourWhateverDBSet instead of db.Videos

Now we need to create an editor template. Go to Views folder and go inside the folder for your current controller and create a sub folder called "EditorTemplates". Add a new view there with the name VideoSelection.cshtml and have the below code there.

@model YourNamespace.VideoSelection
<div>
    @Model.Name

    @Html.CheckBoxFor(d=>d.IsSelected)

    @Html.HiddenFor(s => s.VideoId)
</div>

You may change the html markup however you want. Make it fancy !

enter image description here

Now in your main view, which is bound to our RentVideoVM view model , call the Html.EditorFor helper method to render the Videos with checkboxes.

@model YourNamespace.RentVideoVM
@using (Html.BeginForm())
{
    @Html.EditorFor(s=>s.Videos)
    <input type="submit"/>
}

And your HttpPost action to handle the form posting would be

[HttpPost]
public ActionResult Register(RentVideoVM model)
{
   //check model.Videos collection
   // to do : Save and redirect
   // If something wrong happened, reload Videos collection 
    return View(model);
}

When user posts the form, you can inspect the Videos collection of the posted model. IsSelected property will be true for those videos which user checked.

enter image description here

Shyju
  • 214,206
  • 104
  • 411
  • 497
0

you may want to build a view model

public class YourDBContext
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class YourDBContextView
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

and use @using (Html.BeginForm()) on the view

[HttpPost]
public ActionResult Index(IEnumerable<YourDBContextView> obj)
{
    //You can get your checkbox here
    foreach(YourDBContextView view in obj)
    {
        bool test = view.IsSelected;
    }
}
sammy
  • 1
  • 1