5

I need to pass list/json/array of dates information to a Jquery UI Datepicker dynamically through a jsonresult in a MVC controller.

Following the link below, I am able to highlight selected dates in the datepicker control. http://jquerybyexample.blogspot.com/2012/05/highlight-specific-dates-in-jquery-ui.html

    < script type ="text/javascript">
    $(document).ready( function () {

    var SelectedDates = {};
    SelectedDates[ new Date('05/28/2012' )] = new Date( '05/28/2012' );
    SelectedDates[ new Date('05/29/2012' )] = new Date( '05/29/2012' );
    SelectedDates[ new Date('05/30/2012' )] = new Date( '05/30/2012' );
    //want to replace the above three lines with code to get dates dynamically
    //from controller

    $( '#releasedate' ).datepicker({
        dateFormat: "mm/dd/yy" ,
        numberOfMonths: 3,
        duration: "fast" ,           
        minDate: new Date(),
        maxDate: "+90" ,
    beforeShowDay: function (date) {
        var Highlight = SelectedDates[date];
        if (Highlight) {
            return [true , "Highlighted", Highlight];
        }
        else {
            return [true , '', '' ];
        }
    }
});

The above code will highlight those specific three dates on the calendar control(UIDatepicker).Instead of hard coding dates like above... My challenge is to get these dates dynamically from a controller and pass it on to the var SelectedDates in javascript above.

Controller jsonresult code:

  public JsonResult GetReleasedDates(string Genre)
{

    var relDates = service.GetDates(Genre)//code to get the dates here

    return Json(relDates, JsonRequestBehavior .AllowGet);

    //relDates will have the dates needed to pass to the datepicker control.

}

Thanks for the help.

2
  • I havent done anything.. yet. I know I have the dates coming from the controller and I have the uidatepicker code... I did make ajax call to pass values from the ui to controller before.. now I want the other way from controller to ui Commented May 21, 2012 at 19:08
  • the ui will always have to pull the controller. thats the way http works today. Commented May 21, 2012 at 19:16

4 Answers 4

11

The first possibility is to use a model that will be directly serialized into JSON:

public ActionResult Index()
{
    // TODO: obviously those will come from your service layer
    var selectedDates = new Dictionary<string, DateTime> 
    { 
        { new DateTime(2012, 5, 28).ToString("yyyy-M-dd"), new DateTime(2012, 5, 28) },
        { new DateTime(2012, 5, 29).ToString("yyyy-M-dd"), new DateTime(2012, 5, 29) },
        { new DateTime(2012, 5, 30).ToString("yyyy-M-dd"), new DateTime(2012, 5, 30) },
    };
    return View(selectedDates);
}

and in the view:

@model IDictionary<string, DateTime>

<script type ="text/javascript">
    $(document).ready(function () {

        var selectedDates = @Html.Raw(Json.Encode(Model));

        $('#releasedate').datepicker({
            dateFormat: "mm/dd/yy",
            numberOfMonths: 3,
            duration: "fast",
            minDate: new Date(),
            maxDate: "+90",
            beforeShowDay: function (date) {
                var key = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
                var highlight = selectedDates[key];
                if (highlight) {
                    return [true, "Highlighted", highlight];
                }
                else {
                    return [true, '', ''];
                }
            }
        });
    });
</script>

The other possibility is to use AJAX to retrieve the selectedDates later:

public ActionResult Index()
{
    return View();
}

public ActionResult GetSelectedDates()
{
    // TODO: obviously those will come from your service layer
    var selectedDates = new Dictionary<string, DateTime> 
    { 
        { new DateTime(2012, 5, 28).ToString("yyyy-M-dd"), new DateTime(2012, 5, 28) },
        { new DateTime(2012, 5, 29).ToString("yyyy-M-dd"), new DateTime(2012, 5, 29) },
        { new DateTime(2012, 5, 30).ToString("yyyy-M-dd"), new DateTime(2012, 5, 30) },
    };
    return Json(selectedDates, JsonRequestBehavior.AllowGet);
}

and then:

<script type ="text/javascript">
    $(document).ready(function () {
        $.getJSON('@Url.Action("GetSelectedDates")', function(selectedDates) {
            // Only inside the success callback of the AJAX request you have
            // the selected dates returned by the server, so it is only here
            // that you could wire up your date picker:
            $('#releasedate').datepicker({
                dateFormat: "mm/dd/yy",
                numberOfMonths: 3,
                duration: "fast",
                minDate: new Date(),
                maxDate: "+90",
                beforeShowDay: function (date) {
                    var key = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
                    var highlight = selectedDates[key];
                    if (highlight) {
                        return [true, "Highlighted", highlight];
                    }
                    else {
                        return [true, '', ''];
                    }
                }
            });
        });
    });
</script>
Sign up to request clarification or add additional context in comments.

7 Comments

after making these changes (ajax method).. I cant get the calendar control pop up on click any more... the uidatepicker does not show up
The code works for me, I have tested both cases. There must be something else going on with some other portion of your code. Are you getting javascript errors? Is the AJAX request being sent? Is the controller action being hit? When you inspect the AJAX request in FireBug what do you see?
In the console I have a Network error 500 .. localhost/..../[email protected](%22GetSelectedDates%22)
When you expand the request you can see more details about the exact request being sent, the response and of course the error.
Why is there @Url.Action in the final url? Aren't you using Razor? Is this in a separate javascript file? If it is in a separate javascript file you obviously cannot use server side helpers.
|
2

There is a library to exchange data from controller to javascript without the need of a further ajax call or inline javascript. If you need the data on every page, you could use it in a filter.

http://jsm.codeplex.com

With the library you could just write the following code in your MVC Controller Action:

// Add the dates as objects to javascript - The object should only contain data
// which should be exposed to the public.
this.AddJavaScriptVariable("DatePickerController.Dates", service.GetDates(Genre));
// Execute the initialization function when the DOM has been loaded
// The function can be in a javascript file
this.AddJavaScriptFunction("DatePickerController.Ready");

Your javascript file could look like this:

var DatePickerController = {
    Dates: null,
    Ready: function() {
        $("#releasedate").datepicker({
            dateFormat: "mm/dd/yy" ,
            numberOfMonths: 3,
            duration: "fast" ,           
            minDate: new Date(),
            maxDate: "+90" ,
            beforeShowDay: function (date) {
                var Highlight = DatePickerController.Dates[date];
                if (Highlight) {
                    return [true , "Highlighted", Highlight];
                }
                else {
                    return [true , '', '' ];
                }
            }
        });
    }
};

Note: You maybe have to create a special model for the dates you pass with this.AddJavaScriptVariable which is compatible to the datepicker.

Comments

1

Make an ajax call:

<script type ="text/javascript">
    $(document).ready( function () {

    var SelectedDates = {};
    //SelectedDates[ new Date('05/28/2012' )] = new Date( '05/28/2012' );
    //SelectedDates[ new Date('05/29/2012' )] = new Date( '05/29/2012' );
    //SelectedDates[ new Date('05/30/2012' )] = new Date( '05/30/2012' );

    $.ajax({
        url:'url'
        ,data:{}
        ,type:'get'
        ,success:function(data) {

        for(var i = 0, i < data.length; i++) {
            SelectedDates.push(new Date(data[i]));
        }

        $( '#releasedate' ).datepicker({
            dateFormat: "mm/dd/yy" ,
            numberOfMonths: 3,
            duration: "fast" ,           
            minDate: new Date(),
            maxDate: "+90" ,
            beforeShowDay: function (date) {
            var Highlight = SelectedDates[date];
                if (Highlight) {
                    return [true , "Highlighted", Highlight];
                }
                else {
                    return [true , '', '' ];
                }
            }
        });
    });
});
</script>

Comments

1

make an ajax call to get the dates. upon success of the ajax request, configure the datapickers with the results.

var configureDatePickers = function(dates){
    //setup datepicker in here...
};
$.get('url to get dates', {Genre: smoething}).success(configureDatePickers);

One other recomendation. the default json serializer doesn't play well with the datetime object. therefore I would suggest returning the dates as strings before serializing. example:

var dates = Data.GetDates(genre).Select(x=>x.ToString("MM-dd-yyyy")).ToArray();
return Json(dates);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.