-2

I am trying to create a "Create" form to insert new Results into a table. I have one model which is mapped to this table, first of the three shown below, and another two that I want to use to display data for dropdowns, but bind the result to APLayerID, BPlayerID and CourseID.

In other words, I want a list of A PlayerNames, B PlayersNames and Courses which map to the APLayerID, BPlayerID and COurseID within EditSingles.

I have tried creating a ViewModel, also below, which contains all three of these models, and passing that to the View but i'm really not sure what i'm doing!

In my controller I have a _model.SaveResults(EditSingles) which works well if i'm simply using EditSingles in the View, however I want to display the names of the players and Course so it's easier for adding rows, rather than having to remember the ID numbers.

public class EditSingles
    {
        [Key]
        public int GameID { get; set; }
        public int APlayerID { get; set; }
        public int BPlayerID { get; set; }
        public int Score { get; set; }
        public int Winner { get; set; }
        public int GYear { get; set; }
        public int CourseID { get; set; }

    }

Golfer:

public class Golfer
{
    [Key]
    public int PlayerID { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
    public string ImageURL { get; set; }
}

Course

 public class Courses
{
     [Key]
    public int CourseID { get; set; }
    public string CourseName { get; set; }
    public int CoursePar { get; set; }
    public string CourseAddress { get; set; }
     [DataType(DataType.Date)]
    public DateTime DatePlayed { get; set; }
    public string CourseInformation { get; set; }

}

ViewModel

    public class AdminModel
{
    public IEnumerable<EditSingles> EditSingleResults { get; set; }
    public IEnumerable<GolferDetails> GolferDetails { get; set; }
    public IEnumerable<Courses> CourseDetails { get; set; }
}
tereško
  • 58,060
  • 25
  • 98
  • 150
iandavidson1982
  • 190
  • 3
  • 17

1 Answers1

1

You need a view model that contains the relevant properties of EditSingles plus properties for the collections of Golfers and Courses

public class EditSinglesVM
{
  [Required(ErrorMessage = "Please select player A")]
  [Display(Name = "Player A")]
  public int APlayerID { get; set; }
  ....
  [Required(ErrorMessage = "Please select a course")]
  [Display(Name = "Course")]
  public int CourseID { get; set; }
  public IEnumerable<SelectListItem> PlayerList { get; set; }
  public IEnumerable<SelectListItem> CourseList { get; set }
}

Then in the GET method (assumes you creating a new record)

public ActionResult EditSingles(int ID)
{
  // Initialize your view model
  EditSinglesVM model = new EditSinglesVM();
  // Populate the SelectList's
  ConfigureViewModel(model);
  return View(model);
}

private void ConfigureViewModel(EditSinglesVM model)
{
  model.PlayerList = db.Golfers().Select(g => new SelectListItem
  {
    Value = g.PlayerID.ToString(),
    Text = string.Format("{0} {1}", g.FirstName, g.Surname)
  });
  model.CourseList = db.Courses().Select(c => new SelectListItem
  {
    Value = g.CourseID.ToString(),
    Text = g.CourseName
  });
}

and in the view

@model EditSinglesVM
@using(Html.BeginForm())
{
  @Html.LabelFor(m => m.APlayerID)
  @Html.DropDownListFor(m => m.APlayerID, Model.PlayerList, "-Please select-")
  @Html.ValidationMessageFor(m => m.APlayerID)
  ....
  @Html.LabelFor(m => m.CourseID)
  @Html.DropDownListFor(m => m.CourseID, Model.CourseList, "-Please select-")
  @Html.ValidationMessageFor(m => m.CourseID)
  <input type="submit" ... />
}

and in the POST method

public ActionResult EditSingles(EditSinglesVM model)
{
  if (!ModelState.IsValid)
  {
    ConfigureViewModel(model); // repopulate SelectList's
    return View(model(;
  }
  // Initialize a new data model
  // Map the view model properties to it
  // Save and redirect
}
  • Great thanks...I fought with this for a few days and there are loads of questions around it and couldn't get it to work the way I wanted. Looks to be working a charm! – iandavidson1982 Sep 18 '15 at 07:50
  • Just a side note: You will probably want a `[NotEqualTo]` or similar validation attribute on the `BPlayerID` property so the user cannot select the same player as for `APlayerID` –  Sep 18 '15 at 07:52
  • 1
    I have modified what you have and created two player lists, one with X team and the other with Y team players, filtered by the Teams table (which is basically PlayerID, Team) based on Team. But that is a useful bit of information for anything else I want to add. – iandavidson1982 Sep 18 '15 at 07:56