Filling an MVC dropdown based on selections from a textbox (datepicker) .NET/Jquery/JS/MVC

Mike Miller
Mike Miller used Ask the Experts™
on
I have the following 2 textboxes and dropdown


   <div class="form-group">
                @Html.LabelFor(model => model.StartDate, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.StartDate, new { htmlAttributes = new { @class = "form-control datepicker", @id = "StartDate", required = "required" } })
                    @Html.ValidationMessageFor(model => model.StartDate, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.EndDate, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.EndDate, new { htmlAttributes = new { @class = "form-control datepicker", @id = "EndDate", required = "required" } })
                    @Html.ValidationMessageFor(model => model.EndDate, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(model => model.Hours, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownListFor(model => model.Hours, (SelectList)ViewBag.hoursddl, "", htmlAttributes: new { @class = "form-control", required = "required" })
                    @Html.ValidationMessageFor(model => model.Hours, "", new { @class = "text-danger" })
                </div>
            </div>

Open in new window


I need to populate the dropdown based on the DateDiff multiplied by 8. Or I guess DateDiff + 1 * 8 minus 1 until it hits 1.
So if 3/1/2016 and 3/4/2016 are selected in the textboxes respectively, the dropdown would fill with 32, 31, 30, 29, 28, 27, 26, 25, 24, and so on until it reaches 1.

Any ideas?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2010

Commented:
Here is a simple example:  https://jsfiddle.net/zephyr_hex/cvmL4o01/

HTML

Start:
<input type="text" class="datepicker start"> End:
<input type="text" class="datepicker end">
<select id="mySelect"></select>

Open in new window


jQuery

$(document).ready(function() {
  $('#mySelect').hide();
  $(".datepicker").datepicker({
    "onClose": function(dateText, inst) {
      var string1 = $('.start').val();
      var string2 = $('.end').val();
      if (string1 !== "" && string2 !== "") {
        //do some validation to make sure they are properly formatted dates
        //then...
        var dateStart = new Date(string1);
        var dateEnd = new Date(string2);
        var days = parseInt((dateEnd - dateStart) / (24 * 3600 * 1000));
        if (days > 0) {
          var ddl = $('#mySelect');
          for (var i = 1; i <= days; i++) {
            var option = new Option(i, i);
            ddl.append(option);
          }
          ddl.show();
        }
      }
    }
  });

});

Open in new window

Top Expert 2010

Commented:
And to explain my example:  Add a listener to the datepickers that triggers when the datepicker closes.  In that event, check to see if both datepickers have values.  If they do, then convert the values to JavaScript Date objects, which can be subtracted from each other and converted to an integer to get the number of days.  If the number of days is greater than 0, do a loop which creates an "option" element and add the options to the select, then show the select element.

Note:  You may want to clear out all existing option elements from the select before appending new ones.

var ddl = $('#mySelect');
ddl.empty();  //add this line
//do the loop that adds the new options

Open in new window

Mike MillerSoftware Engineer

Author

Commented:
Does jquery version matter here? I literally copied your code verbatim to test and the only part that is working is the hiding of the dropdown. Other ideas?
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Top Expert 2010

Commented:
jQuery version should not matter.  There's nothing fancy going on with the code I provided.
Have you checked F12 console for errors?  Or perhaps you need to insert some console.log() lines to see where things are not going as expected.  As you can see from the Fiddle Demo I provided, the code does work.

I added the line where I clear the option from the select to the Fiddle Demo.  Here's that version:  https://jsfiddle.net/zephyr_hex/cvmL4o01/1/
Mike MillerSoftware Engineer

Author

Commented:
Yup, you're right. I just did what you did in notepad with the basic hosted library refs and it worked fine. No errors but I have a bunch of other crap going on. I'll keep playing with it
Mike MillerSoftware Engineer

Author

Commented:
I have some other functionality on the date textboxes that is causing the issue. Really struggling to combine the two.

   <script>
        $(function () {
            var dateFormat = "mm/dd/yy",
                from = $("#StartDate")
                    .datepicker({
                        changeMonth: true,
                        numberOfMonths: 1
                    })
                    .on("change", function () {
                        to.datepicker("option", "minDate", getDate(this));
                    }),
                to = $("#EndDate").datepicker({
                    changeMonth: true,
                    numberOfMonths: 1
                })
                .on("change", function () {
                    from.datepicker("option", "maxDate", getDate(this));
                });

            function getDate(element) {
                var date;
                try {
                    date = $.datepicker.parseDate(dateFormat, element.value);
                } catch (error) {
                    date = null;
                }

                return date;
            }
        });
    </script>  
    <script>
        $(document).ready(function () {
            $(".datepicker").datepicker({
                "onClose": function (dateText, inst) {
                    var string1 = $('.start').val();
                    var string2 = $('.end').val();
                    if (string1 !== "" && string2 !== "") {
                        //do some validation to make sure they are properly formatted dates
                        //then...
                        var dateStart = new Date(string1);
                        var dateEnd = new Date(string2);
                        var days = parseInt((dateEnd - dateStart) / (24 * 3600 * 1000));
                        if (days > 0) {
                            var ddl = $('#mySelect');
                            ddl.empty();
                            for (var i = 1; i <= days; i++) {
                                var option = new Option(i, i);
                                ddl.append(option);
                            }
                        }
                    }
                }
            });

        });
    </script>

Open in new window



So this works fine (but I lose my previous functionality)...
        <input type="text" class="form-control datepicker start" id="fboy"> End:
        <input type="text" class="form-control datepicker end" id="fface">
        <select id="mySelect"></select>

Open in new window


But this doesn't
        <input type="text" class="form-control datepicker start" id="StartDate"> End:
        <input type="text" class="form-control datepicker end" id="StartDate">
        <select id="mySelect"></select>

Open in new window


Anyway, that's where I'm at. Still plugging away over here. Any thoughts are welcome.
Top Expert 2010

Commented:
So, you already are instantiating the datepicker, which is also what my code does.  You'll want to add the OnClose event to your current instantiation.  You instantiate based on element ID, which means you do it once for StartDate and once for EndDate.  That means you need to add the OnClose event to each one.

Also, I noticed on your HTML markup that doesn't work:  you've assigned the same id to both inputs.  One should be End Date.  But the core of the problem is that you need to include the OnClose event in your existing instantiations.  I'll work up a demo.
Top Expert 2010
Commented:
So, I decided that a cleaner way to approach this would be to skip the built-in OnClose event, and go with a "regular" change event handler bound to the datepicker class.  This means you won't have to repeat the same code in two different places.

Also, you have some syntax problems in your code (commas instead of semicolons, for example).

Here's a Fiddle Demo:  https://jsfiddle.net/zephyr_hex/kdqm8he9/

HTML
 Start:
<input type="text" class="form-control datepicker start" id="StartDate"> End:
<input type="text" class="form-control datepicker end" id="EndDate">
<select id="mySelect"></select>

Open in new window


jQuery
$(document).ready(function() {
  $('#mySelect').hide();
  var dateFormat = "mm/dd/yy";
  var from = $("#StartDate").datepicker({
    changeMonth: true,
    numberOfMonths: 1
  }).on("change", function() {
    to.datepicker("option", "minDate", getDate(this));
  });

  var to = $("#EndDate").datepicker({
    changeMonth: true,
    numberOfMonths: 1
  }).on("change", function() {
    from.datepicker("option", "maxDate", getDate(this));
  });

  function getDate(element) {
    var date;
    try {
      date = $.datepicker.parseDate(dateFormat, element.value);
    } catch (error) {
      date = null;
    }

    return date;
  }
  $('.datepicker').on('change', function() {
    var string1 = $('.start').val();
    var string2 = $('.end').val();
    if (string1 !== "" && string2 !== "") {
      //do some validation to make sure they are properly formatted dates
      //then...
      var dateStart = new Date(string1);
      var dateEnd = new Date(string2);
      var days = parseInt((dateEnd - dateStart) / (24 * 3600 * 1000));
      if (days > 0) {
        var ddl = $('#mySelect');
        for (var i = 1; i <= days; i++) {
          var option = new Option(i, i);
          ddl.append(option);
        }
        ddl.show();
      }
    }
  });
});

Open in new window

Mike MillerSoftware Engineer

Author

Commented:
Wow, thank you so much. I was going crazy over here. That worked perfectly!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial