简体   繁体   中英

Cascading Drop Down - Invalid Value

I am new to MVC and having great difficulty creating a cascading drop down from database. Upon selecting a practice the opticians who work in that practice populate however it will not save to dataView Model:

public class BookingViewModel
{
    [Display (Name = "Select Patient")]
    public Guid PatientId { get; set; }
    public IEnumerable<SelectListItem> PatientList { get; set; }

    [Display(Name = "Select Practice")]
    public Guid PracticeId { get; set; }
    public IEnumerable<SelectListItem> PracticeList { get; set; }

    [Display(Name = "Select Optician")]
    public Guid OpticianId { get; set; }
    public IEnumerable<SelectListItem> OpticiansList { get; set; }

    [Display(Name = "Select Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime Date { get; set; }

    [Display(Name = "Select Time")]
    public Guid TimeId { get; set; }
    public IEnumerable<SelectListItem> TimeList { get; set; }  
}

}

My Bookings Controller:

  public ActionResult Create()
    {
        // Creates a new booking
        BookingViewModel bookingViewModel = new BookingViewModel();
        // Initilises Select List
        ConfigureCreateViewModel(bookingViewModel);

        return View(bookingViewModel);

    }

    // Initilises Select List 
    public void ConfigureCreateViewModel(BookingViewModel bookingViewModel)
    {
        // Displays Opticians Name 
        bookingViewModel.OpticiansList = db.Opticians.Select(o => new SelectListItem()
        {
            Value = o.OpticianId.ToString(),
            Text = o.User.FirstName
        });

        // Displays Patients name 
        bookingViewModel.PatientList = db.Patients.Select(p => new SelectListItem()
        {
            Value = p.PatientId.ToString(),
            Text = p.User.FirstName
        });

        // Displays Practice Name
        bookingViewModel.PracticeList = db.Practices.Select(p => new SelectListItem()
        {
            Value = p.PracticeId.ToString(),
            Text = p.PracticeName
        });

        // Displays Appointment Times 
        bookingViewModel.TimeList = db.Times.Select(t => new SelectListItem()
        {
            Value = t.TimeId.ToString(),
            Text = t.AppointmentTime
        });


    }


    // Allows Admin to create booking for patient 
    // POST: Bookings1/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(BookingViewModel bookingViewModel)
    {
        // to ensure date is in the future
        if (ModelState.IsValidField("Date") && DateTime.Now > bookingViewModel.Date)
        {
            ModelState.AddModelError("Date", "Please enter a date in the future");
        }



        // if model state is not valid
        if (!ModelState.IsValid)
        {
            // Initilises Select lists
            ConfigureCreateViewModel(bookingViewModel);
            return View(bookingViewModel); // returns user to booking page


        }
        else // if model state is Valid
        {
            Booking booking = new Booking();
            // Sets isAvail to false
            booking.isAvail = false;
            booking.PracticeId = bookingViewModel.PracticeId;
            booking.OpticianId = bookingViewModel.OpticianId;
            booking.PatientId = bookingViewModel.PatientId;
            booking.Date = bookingViewModel.Date;
            booking.TimeId = bookingViewModel.TimeId;

            // Generates a new booking Id
            booking.BookingId = Guid.NewGuid();
            // Adds booking to database
            db.Bookings.Add(booking);
            // Saves changes to Database
            db.SaveChanges();
            // Redirects User to Booking Index
            return RedirectToAction("Index");
        }
    }

 // Json for cascading drop down, to allow the user to select an optician from the selected practice.
    [HttpPost]
    public JsonResult Opticians(Guid Id)
    {
        var opticianList = db.Opticians.Where(a => a.PracticeId == Id).Select(a => a.User.FirstName).ToList();

        return Json(opticianList);
    }

My View:

<script>
$(document).ready(function () {
    $("#OpticianId").prop("disabled", true);
    $("#PracticeId").change(function () {
        $.ajax({
            url : "@Url.Action("Opticians","Bookings")",
            type : "POST",
            data : {Id : $(this).val() }
        }).done(function (opticianList) {
            $("#OpticianId").empty();
            for (var i = 0; i < opticianList.length; i++) {
                $("#OpticianId").append("<option>" + opticianList[i] + "</option>");
            }
            $("#OpticianId").prop("disabled", false);
        });
    });
});

 <div class="form-group">
        @Html.Label("Select Optician :", new { @class = "col-md-2 control-label" })
        <div class="col-md-10">

            @Html.DropDownListFor(model => model.OpticianId, Model.OpticiansList, "-Please Select-", new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.OpticianId, "", new { @class = "text-danger" })
        </div>
    </div>

The cascading drop down works fine but when I try to save it to database I am getting the Validation error -

The value 'Name' is not valid for Select Optician

Any help would be greatly appreciated. Thanks

Because your Opticians(Guid Id) method is only returning the User.FirstName property from your Opticians table, so that the selected value of the dropdownlist for OpticianId posts back the selected FirstName value which cannot be bound to a Guid property. The html your generating is

<option>Some Name</option>

but it needs to be

<option value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">Some Name</option>

Change the method to return both the ID and Name properties

[HttpPost]
public JsonResult Opticians(Guid Id)
{
    var opticianList = db.Opticians.Where(a => a.PracticeId == Id).Select(a => new
    {
      Value = a.OpticianId,
      Text = a.User.FirstName
    }).ToList();
    return Json(opticianList);
}

and then change the script to

var opticians = $("#OpticianId"); // cache elements you repeatedly refer to
opticians.prop("disabled", true);
$("#PracticeId").change(function () {
    $.ajax({
        url : "@Url.Action("Opticians","Bookings")",
        type : "POST",
        data : {Id : $(this).val() }
    }).done(function (opticianList) {
        opticians.empty();
        $.each(opticianList, function(index, item) {
            opticians.append($('<option></option>').val(item.Value).text(item.Text));
        });
        opticians.prop("disabled", false);
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM