Azdine Jattari

Azdine Jattari

  • NA
  • 2
  • 522

DropDownListFor List Values not being updated after AJAX POST

Aug 1 2021 1:55 AM

Hi there,

I have the following problem, in my view I have a JQuery DatePicker and a DropDownListFor that contains a list populated with times of datatype string in HH:MM format that comes from my model. Now, when I select a date from the DatePicker, I will send it from my view to my controller using an AJAX POST call. In my Controller I finally found out through debugging that my model does receive the correct values ??from my view and that the list in my model with times is also adjusted.

However, in my view the DropDownListFor with list of hours is not adjusted. I've tried all sorts of things like adding ModelState.Clear() to my ActionMethod and so on but no luck. Could you maybe help me with this? Thank you very much!

DATETIMEMODEL

public class DateTimeModel
    {

        private static List<System.Web.Mvc.SelectListItem> times = new List<System.Web.Mvc.SelectListItem>
        {
            new System.Web.Mvc.SelectListItem() { Value =  "11:00", Text = "11:00", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "11:30", Text = "11:30", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "12:00", Text = "12:00", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "12:30", Text = "12:30", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "13:00", Text = "13:00", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "13:30", Text = "13:30", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "14:00", Text = "14:00", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "14:30", Text = "14:30", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "15:00", Text = "15:00", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "15:30", Text = "15:30", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "16:00", Text = "16:00", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "16:30", Text = "16:30", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "17:00", Text = "17:00", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "17:30", Text = "17:30", Disabled = false },
            new System.Web.Mvc.SelectListItem() { Value =  "18:00", Text = "18:00", Disabled = false }
        };
        public IEnumerable<System.Web.Mvc.SelectListItem> Times
        {
            get
            {
                return times;
            }
        }
        public void FindTimesAndRemove(List<string> listToCheck, string dateToInspect) ---> Here I am checking the list with all the dates that came from the DB and the second parameter is the active date value from the DatePicker in the View.
        {
            var listOfSelectedDateWithTime = listToCheck.Where(x => x.Contains(dateToInspect)).ToList();

            for (int i = 0; i < listOfSelectedDateWithTime.Count; i++)
            {
                times.RemoveAll(x => x.Text == listOfSelectedDateWithTime[i].Substring(13, 5)); ---> removing the timeslots from the static list that are already taken.
            }
        }
        public void ResetTimeList() ---> Here I am filling the list up again.
        {
            times = new List<System.Web.Mvc.SelectListItem>
            {
                new System.Web.Mvc.SelectListItem() { Value =  "11:00", Text = "11:00", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "11:30", Text = "11:30", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "12:00", Text = "12:00", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "12:30", Text = "12:30", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "13:00", Text = "13:00", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "13:30", Text = "13:30", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "14:00", Text = "14:00", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "14:30", Text = "14:30", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "15:00", Text = "15:00", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "15:30", Text = "15:30", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "16:00", Text = "16:00", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "16:30", Text = "16:30", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "17:00", Text = "17:00", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "17:30", Text = "17:30", Disabled = false },
                new System.Web.Mvc.SelectListItem() { Value =  "18:00", Text = "18:00", Disabled = false }
            };
        }

VIEWMODEL

 public class ViewModel
    {
        public AppointmentModel AppointmentModel { get; set; } = new AppointmentModel();
        public DateTimeModel DateTimeModel { get; set; } = new DateTimeModel(); --> HOLDS THE LIST OF TIMES
        public string ChosenAppointmentTime { get; set; }
    }

CONTROLLER

//PROPERTIES
        private static List<string> ListOfAppointmentDates { get; set; }
        private static string SelectedDate { get; set; }
        private ViewModel VM { get; set; } = new ViewModel();
        private string DateOfToday { get; set; } = DateTime.Now.ToString("yyyy/MM/dd");

        public async Task<ActionResult> Index()
        {
            using (var dbContext = new ProjectContext())
            {
                await Task.Run(() => ListOfAppointmentDates = AppointmentBAL.GetAppointments().Select(x => x.AppointmentDate).ToList()); 
--> GET ALL THE RECORDS FROM DB AND ONLY SELECT THE DATES PROPERTY FROM THE MODEL (APPOINTMENTDATE = yyyy/mm/dd - HH:MM FORMAT)
            }

            if (SelectedDate == null)
            {
                VM.DateTimeModel.FindTimesAndRemove(ListOfAppointmentDates, DateOfToday);
                SelectedDate = DateOfToday;
            }
            else if (SelectedDate == DateOfToday)
            {
                VM.DateTimeModel.FindTimesAndRemove(ListOfAppointmentDates, DateOfToday);
            }
            else if (SelectedDate != null && SelectedDate != DateOfToday)
            {
                VM.DateTimeModel.FindTimesAndRemove(ListOfAppointmentDates, SelectedDate);
            }
            return View(VM);
        }

        public ActionResult SetSelectedDate(string date) --> Selected date in DatePicker from View
        {
            string formattedDate = date.Replace("-", "/"); --> Format incoming date from View

            if (SelectedDate != formattedDate)
            {
                VM.DateTimeModel.ResetTimeList();
                VM.DateTimeModel.FindTimesAndRemove(ListOfAppointmentDates, formattedDate);
                SelectedDate = date;
            }
            else
            {
                VM.DateTimeModel.FindTimesAndRemove(ListOfAppointmentDates, formattedDate);
            }
            _ = VM;  --> HERE I DUBBLE CHECKED THE VIEWMODEL OBJECT THAT CONTAINS THE DATETIMEMODEL THAT HOLDS THE LIST OF AVAILABLE TIMESLOTS. IT SHOWS ME THE LIST WITH THE VALUES THAT SHUD BE IN THERE

            ModelState.Clear();
            return View("Index");
        }

VIEW (JQuery)

 

$('#appointmentdate').change(function () { /* WHEN I SELECT A NEW DATE FROM THE DATEPICKER, I GET THE SELECTED VALUE AND I SEND IT TO THE VIEW */
        var selectedDate = $("#appointmentdate").val();

        $.ajax({
            url: "/Appointment/SetSelectedDate",
            data: { date: selectedDate },
            type: "POST",
            dataType: "text",
            success: function (data) {
                console.log(data);
            },
            error: function (passParams) {
                console.log(passParams);
            }
        });
        //location.reload();
    });

VIEW (HTML)

@using (Html.BeginForm("Create", "Appointment", FormMethod.Post, new { @class = "bg-white rounded" }))
        {
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-row border-bottom">
                <div class="p-4 left border-right w-50">
                    <label class="text-inverse font-12 text-uppercase">Voornaam*</label>
                    @Html.TextBoxFor(m => m.AppointmentModel.CustomerName, new { @class = "border-0 p-0 font-14 text-dark form-control", id = "customername", type = "text", placeholder = "Uw voornaam" })
                    @Html.ValidationMessageFor(model => model.AppointmentModel.CustomerName, "", new { @class = "text-danger" })
                </div>
                <div class="p-4 right w-50">
                    <label class="text-inverse font-12 text-uppercase">Achternaam*</label>
                    @Html.TextBoxFor(m => m.AppointmentModel.CustomerLastName, new { @class = "border-0 p-0 font-14 text-dark form-control", id = "customerlastname", type = "text", placeholder = "Uw achternaam" })
                    @Html.ValidationMessageFor(model => model.AppointmentModel.CustomerLastName, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-row border-bottom p-4">
                <label class="text-inverse font-12 text-uppercase">E-mail*</label>
                @Html.TextBoxFor(m => m.AppointmentModel.Email, new { @class = "border-0 p-0 font-14 text-dark form-control", id = "email", type = "text", placeholder = "Uw e-mailadres" })
                @Html.ValidationMessageFor(model => model.AppointmentModel.Email, "", new { @class = "text-danger" })
            </div>
            <div class="form-row border-bottom p-4">
                <label class="text-inverse font-12 text-uppercase">Mobiele nummer*</label>
                @Html.TextBoxFor(m => m.AppointmentModel.MobileNumber, new { @class = "border-0 p-0 font-14 text-dark form-control", id = "mobilenumber", type = "text", placeholder = "Uw mobiele nr." })
                @Html.ValidationMessageFor(model => model.AppointmentModel.MobileNumber, "", new { @class = "text-danger" })
            </div>
            <div class="form-row border-bottom p-4 position-relative">
                <label class="text-inverse font-12 text-uppercase">Datum afspraak*</label>
                <div class="input-group date">
                    @Html.EditorFor(m => m.AppointmentModel.AppointmentDate, new
               {
                   htmlAttributes = new { @class = "border-0 p-0 font-14 text-dark form-control", @style = "text-align: left; width: 50%", type = "text", id = "appointmentdate" }
               })
                    @Html.ValidationMessageFor(model => model.AppointmentModel.AppointmentDate, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-row border-bottom p-4 position-relative">
                <label class="text-inverse font-12 text-uppercase">Tijdstip afspraak*</label>
                <div class="input-group date">
                    @Html.DropDownListFor(m => m.ChosenAppointmentTime, new SelectList(Model.DateTimeModel.Times, "Value", "Text"), new { @class = "border-0 p-0 font-14 text-dark form-control", @style = "text-align: center; width: 65px", @id = "appointmenttime" })
                </div>  ---> THIS IS THE DROPDOWNLISTFOR I AM TALKING ABOUT
            </div>
            <div class="form-row border-bottom p-4">
                <label class="text-inverse font-12 text-uppercase">Bericht</label>
                @Html.TextAreaFor(m => m.AppointmentModel.Message, new { @class = "border-0 p-0 font-14 text-dark form-control", id = "message", @style = "max-height: 100px;", placeholder = "Typ hier uw bericht", col = "1", row = "1" })
            </div>
            <div class="row d-flex justify-content-center mobile-appointment-card-button">
                <div class="mb-md-2">
                    <button type="submit" class="btn btn-warning w-100" id="submit-button" data-toggle="modal" data-target="#exampleModal"><i class="fas fa-check ml-md-1"></i> Maak afspraak</button>
                    <button class="btn btn-warning w-100" id="resultLoading" type="submit" disabled>
                        <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                        Loading...
                    </button>
                </div>
            </div>
        }

Answers (1)