0

I am currently working on an asp.net mvc project which allows users to select only available dates from a calendar in order to book a specific service. I currently have a Datepicker.cs model which holds a DateTime Date field and an int Id field and I have a DbContext class which I use to persist and retrieve this data

namespace Calendar.Models
{
  public class CalendarDb : DbContext
  {
    public DbSet<Datepicker> Dates { get; set; }
  }
}

I am using jQuery UI Datepicker on my Create.cshtml page to show the available dates to users. Currently the calendar shows 2 hardcoded available dates.

a busy cat

Now my question is, is it possible in the asp.net mvc framework to populate this hardcoded array (or even a list etc.) with all of the dates in the Date column in the Datepickers Db? i.e. I need the calendar to show all the available dates in the database

Any help would be greatly appreciated!

My Datepicker model:

namespace Calendar.Models
{
  public class Datepicker
  {
    public DateTime DtmDate { get; set; }
    public int Id { get; set; }
    public int UserId { get; set; }
  }
}

Controller for the view:

    [HttpGet]
    public ActionResult Create()
    {
       var model = _db.Dates.ToList();
       return View(model);
    }

My Create.cshtml view as it stands:

@model Calendar.Models.Datepicker

@{
ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
    <h4>Datepicker</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.DtmDate, htmlAttributes: new { @class 
= "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.DtmDate, new { htmlAttributes = 
new { @class = "form-control1" } })
            @Html.ValidationMessageFor(model => model.DtmDate, "", new { 
@class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.UserId, htmlAttributes: new { @class = 
"control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.UserId, new { htmlAttributes = 
new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.UserId, "", new { 
@class = "text-danger" })
         </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

<link href="~/Content/themes/base/jquery-ui.min.css" rel="stylesheet" />

@section scripts {
<script src="~/Scripts/jquery-ui-1.12.1.min.js"></script>
<script>
    jQuery(function(){
        var enableDays = ["11-07-2019", "12-07-2019"];

        function enableAllTheseDays(date) {
            var sdate = $.datepicker.formatDate('dd-mm-yy', date)
            console.log(sdate)
            if ($.inArray(sdate, enableDays) != -1) {
                return [true];
            }
            return [false];
        }

        $(".form-control1").datepicker({
            dateFormat: "dd/MM/yy",
            beforeShowDay: enableAllTheseDays

        });
    });

</script>

@Scripts.Render("~/bundles/jqueryval")
}

<style>
.my-class a {
     background-color: #07ea69 !important;
     background-image :none !important;
     color: #ffffff !important;
}
</style>
Craig
  • 95
  • 1
  • 2
  • 11
  • 2
    I don't understand which part you're stuck on. You seem to know how to get the data into your application from the database. Did you put it in a model that you passed to the view? Do you know how to grab values from the model in your view and utilize them in JavaScript? Which specific part do you need help with? – mason Jul 09 '19 at 16:48
  • 1
    Yes, you can just pass list from code and use into view. Other wise convert that list to javascript list and use it. – Kalpesh Boghara Jul 09 '19 at 17:00
  • @Craig, "https://stackoverflow.com/questions/9480537/select-only-specific-dates-in-jquery-ui-datepicker-date-list-comes-from-ajax" post might be a help. – NCCSBIM071 Jul 09 '19 at 17:21
  • @mason Hi mate thanks for the reply. Yes I passed in the Datepicker model into the view (@model Calendar.Models.Datepicker). As far as grabbing the values in the view and utilizing them i.e. putting the dates into some sort collection for the Datepicker to use, I am not so sure how to implement. Any help would be appreciated – Craig Jul 09 '19 at 17:27
  • @KalpeshBoghara Thanks for the reply! Could you please provide an example on how to do this to give me an idea? i.e. creating the list of model dates in the view for the enableAllTheseDays function to use – Craig Jul 09 '19 at 17:31
  • 2
    You defined a JSON array that contains the enabled days. Right now that's hardcoded, but you want to use the values from your Model? You could simply use Razor syntax to grab the values from the model and insert them into the markup instead of the hardcoded values. – mason Jul 09 '19 at 17:31
  • @mason thanks again. the hardcoded values were used while I was setting up the jQuery Datepicker just to make sure it was working only showing specific dates. I am very new to c# and .net so not too familiar with the razor syntax. Could you give me a quick example on how to grab the date values from the model and insert them into the markup please? Or something I could work with to get rid of this headache! It would be much appreciated – Craig Jul 09 '19 at 17:42
  • You need to show your model that you're passing to the view in the question. Then someone can assist you with an appropriate answer. You can check our a general guide to Razor syntax [here](https://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx/). – mason Jul 09 '19 at 17:44
  • @mason - https://i.ibb.co/nmnWLdW/dates2.jpg - the simple model class used to store the dates and below it is the controller for the view. On the right is the view with my jQuery UI Datepicker. Thank you for the Razor syntax link! – Craig Jul 09 '19 at 17:57
  • Don't provide us with pictures of your code. Instead, create a [MCVE] and put it in your question (as text). – mason Jul 09 '19 at 17:59
  • @mason Cheers, I have edited my initial post – Craig Jul 09 '19 at 18:06
  • Your action method doesn't make much sense. You're getting the model from the parameters...shouldn't you be retrieving that from the database instead? – mason Jul 09 '19 at 18:09
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/196214/discussion-between-craig-and-mason). – Craig Jul 09 '19 at 18:49
  • @mason Does the above controller look any better mate? Although now I only get raw date data displayed on screen when I go to the view. https://i.ibb.co/XDP6vmj/rawdates.jpg – Craig Jul 09 '19 at 18:49
  • No. I don't know why you'd change it to just return JSON. You still need to return a view with a populated model. – mason Jul 09 '19 at 18:56
  • @mason Are you talking about passing a list of models to the view? i.e. var model = _db.Dates.ToList(); return View(model); – Craig Jul 09 '19 at 19:10
  • Sure, that can work. – mason Jul 09 '19 at 19:12
  • @mason so now that I have a list of models in my view, can you please advise me how to grab the dates from each model and add them to my jQuery markup? – Craig Jul 09 '19 at 19:28

2 Answers2

2

Your model type is a List, because of the line var model = _db.Dates.ToList(); in your controller. You'll need to adjust your view's Model declaration to match.

Change

@model Calendar.Models.Datepicker

to

@model List<Calendar.Models.Datepicker>

Now that your model is of the correct type, you can embed the dates into your JavaScript. We need to select the dates using Linq, and convert them to the proper string format that the JS is expecting, and then use some string methods to concatenate them together. Change this:

var enableDays = ["11-07-2019", "12-07-2019"];

to

var enableDays = [' @Html.Raw(string.Join("','", Model.Select(d => d.DtmDate.ToString("MM-dd-yyyy"))) '];

Then run it all. In the rendered HTML, you should see the dates from your database nicely embedded in the JavaScript, which should enable the correct days in your datepicker. Obviously you'll need to deal with edge cases, such as there being no rows in your table, or the date being null in one of the rows. But that should get you started.

mason
  • 31,774
  • 10
  • 77
  • 121
  • you are a life saver, I will implement this when I get back home. Thank you for your time! – Craig Jul 09 '19 at 20:22
  • I changed the model to type List although now the Html helpers 'LabelFor' and 'EditorFor' will not work because I assume they are expecting a model and not a list. The error is as follows: 'List' does not contain a definition for 'DtmDate' (the same for UserId). Is there a quick fix for this? As I will still need a label and field for the user to select their date. Thanks again for the help Mason! – Craig Jul 10 '19 at 00:48
  • @Craig Sure there's a quick fix. You need to decide whether your view needs a single Datepicker or a List passed to it. If it needs a list, then using the LabelFor and EditorFor directly won't work. Take a minute to sit down and actually plan out what the view is intended for, what input (Model) it should have, and what result (form values) should come out of it. – mason Jul 10 '19 at 00:52
  • The view should allow a user to use the calendar to select an available date, this date will then be stored into a different booking table. I just thought a list of dates had to be passed into the view, in order to populate the calendar with all of the available dates.. Is it possible to pass a Datepicker model into the view and use it to get all the dates from the db? – Craig Jul 10 '19 at 01:08
  • or is there a way to store the date the user selected without using labelFor/editorFor so I can still pass in the List? – Craig Jul 10 '19 at 01:13
  • I tested the code with a test controller and view just to see if I could get it to work after following your instructions passing in a List of Datepicker. Although the calendar does not show the dates from the Db for some reason. No dates at all are available to choose from, not sure why. https://i.ibb.co/09W1yNP/testc.png – Craig Jul 10 '19 at 01:57
  • Have you any idea why the calendar is showing up blank mate? I followed your instructions, passed in the List and embedded the dates into the JavaScript like you said, although I still can not see any dates from the Db: https://i.ibb.co/09W1yNP/testc.png It would be great to get it working so I can accept the answer and move on :) – Craig Jul 10 '19 at 15:03
  • You'd have to debug that. Look in your browser's JavaScript console for errors. Look at the resulting HTML and make sure it matches what you'd expect etc. – mason Jul 10 '19 at 15:37
  • Hi again, I added console.log and got the following returned: Array(1) 0: " 10-10-1990','07-01-2019','07-31-2019','07-15-2019 " length: 1. Can you see why this line of code is giving this output? My JavaScript knowledge isn't the best. I don't know why ''' is coming out – Craig Jul 11 '19 at 11:31
  • @Craig It's encoding it to prevent code injection as a defense against XSS. Since this is known to be just DateTime values, you can override it. See my updated answer where I added Html.Raw. – mason Jul 11 '19 at 12:21
  • works perfect now. I can finally see all the dates from the db! thank you for all your help and time – Craig Jul 11 '19 at 12:29
-1

Here is an idee of how you could do it.

First create a method that return a List<DateTime> example

 [HttpPost]
    public ActionResult GetDates()
    {

        return Json(CalendarDb.Dates.Select(x=> x.DtmDate.ToString("dd-MM-yyyy")));
    }

Now when you create your datepickider you will need this list eg enableDays

var enableDays = [];
 $.ajax({
  url: "/GetDates",
  method: "POST" ,// post or get
  async: false,
  success:function(dates){ enableDays =dates; }
});

// now create your DatePicker.

Now if you want an mvc modol solution you could do it like this.

Create a modol that containe the dates,and simple convert it to json

enableDays  =@Html.Raw(Json.Encode(modol.Dates.ToString("dd-MM-yyyy")))
// now create your DatePicker.
Alen.Toma
  • 4,684
  • 2
  • 14
  • 31
  • Thanks for the reply! I have tried: [HttpGet] public ActionResult Create() { return Json(_db.Dates.Select(x => x.DtmDate), JsonRequestBehavior.AllowGet); }. Although now when I go to the view, raw dates are displayed on the screen. https://i.ibb.co/XDP6vmj/rawdates.jpg – Craig Jul 09 '19 at 18:44
  • Ok i see the format is wrong. i edited my answer, try `x.DtmDate.ToString("dd-MM-yyyy")` this will return the right format for you to use. And also read here about how to format the datetime https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tostring?view=netframework-4.8 – Alen.Toma Jul 09 '19 at 22:49