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.
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>
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.
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>
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);
Related
I want to disable dates in flatpicker plugin by a list from the database. this is the code to get them from the database
public List<DateTime> DisablingDates()
{
List<DateTime> dates = new List<DateTime>();
var groups = OrderContext.Collection().GroupBy(o => o.DueDate);
foreach (var g in groups)
{
if (g.Count() == 2)
{
var val = g.Key.Date;
val.ToString("dd/MMM/yyyy");
dates.Add(val);
}
}
return dates;
}
I passed the list through viewbag to the jquery but the plugin stopped working.. the browser debugger showes the DisabledDates array with timestamp dates , so I tried to convert them to readble dates but the alert function doesn't show the values.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.6/flatpickr.min.js"></script>
<script>
$("#datepicker").flatpickr({
enableTime: false,
dateFormat: "d/M/Y",
defaultDate: new Date().fp_incr(2),
minDate: new Date().fp_incr(2),
maxDate: new Date().fp_incr(90),
disable:
function (date) {
var DisabledDates = #Html.Raw(Json.Encode(ViewBag.DisabledDates));
var array = [];
$.each(DisabledDates, function (index, value) {
var date1 = new Date(value * 1000).toDateString();
alert(index + ": " + date1);
array.push(date1);
});
var fulldmy = date.getDate() + "/" + (date.getMonth() + 1) + "/" + date.getFullYear();
if ($.inArray(fulldmy, array) === -1) {
return false;
} else {
return true;
}
},
});
DisabledDates array in the browser debugger
function (date) {
var DisabledDates = ["\/Date(1599166800000)\/","\/Date(1599253200000)\/","\/Date(1599944400000)\/"];
var array = [];
then I tried using JsonResult action with an ajax method and the plugin stopped working again.
$("#datepicker").flatpickr({
enableTime: false,
dateFormat: "d/M/Y",
defaultDate: new Date().fp_incr(2),
minDate: new Date().fp_incr(2),
maxDate: new Date().fp_incr(90),
disable: function (date) {
$.ajax({
url: '#Url.Action("GetReservedDates", "Basket")',
type: "GET",
success: function (result) {
var fulldate = date.getDate() + "/" + (date.getMonth() + 1) + "/" + date.getFullYear();
if ($.inArray(fulldate, result) === -1) {
return false;
} else {
return true;
}
}
});
}
});
the JsonResult action
[HttpGet]
public JsonResult GetReservedDates()
{
var dates = orderService.DisablingDates();
return Json(new { dates }, "text/x-json", JsonRequestBehavior.AllowGet);
}
this is the second plugin I'm currently tring.
What should I do?
Thanks in advance.
I found what made the plugin stop working .. the disable option takes a function between array brackets [].
then to convert the timestamp dates to readable dates I edited the value to contain only milliseconds from /Date(1599166800000)/ to 1599166800000.
finally, the plugin disabled the database-retrieved dates as intended.
$("#datepicker").flatpickr({
enableTime: false,
dateFormat: "d/M/Y",
defaultDate: new Date().fp_incr(2),
minDate: new Date().fp_incr(2),
maxDate: new Date().fp_incr(90),
disable: [Ddates],
onMonthChange: [Ddates],
});
function Ddates (date) {
var DisabledDates = #Html.Raw(Json.Encode(ViewBag.DisabledDates));
var array = [];
$.each(DisabledDates, function (index, value) {
value = value.replace("\\", "")
value = value.replace("/Date(", "")
value = value.replace(")\/", "")
var date1 = new Date(parseInt(value, 10)).toLocaleDateString();
array.push(date1);
});
date = date.toLocaleDateString();
return ($.inArray(date, array) != -1);
}
Below jQuery code working fine. But I want to add enableDays with response of Json like jQuery.each(json.available_dates, function (i, v) {
});
jQuery.ajax({
dataType: 'json',
url: '<?php echo Mage::getUrl('photostudio/index/productsinfo');?>',
data: {
treatment_id:data.treatment_id,
},
success: function (json) {
/*var enableDays = new Array();
jQuery.each(json.available_dates, function (i, v) {
enableDays.push(v);
});*/
var dateToday = new Date();
var enableDays = ["2017-08-31","2017-09-01"];
var dates = jQuery("#sandbox-container div").datepicker({
defaultDate: dateToday,
changeMonth: true,
changeYear: true,
numberOfMonths: 1,
minDate: dateToday,
maxDate: new Date(dateToday.getFullYear() + 1, dateToday.getMonth(), dateToday.getDate()),
beforeShowDay: function(dateToday){
var sdate = jQuery.datepicker.formatDate('yy-mm-dd',dateToday)
if(jQuery.inArray(sdate, enableDays) != -1) {
return [true];
}
return [false];
},
onSelect: function(selectedDate) {
var option = this.id == "from" ? "minDate" : "maxDate",
instance = jQuery(this).data("datepicker"),
date = jQuery.datepicker.parseDate(instance.settings.dateFormat || jQuery.datepicker._defaults.dateFormat, selectedDate, instance.settings);
alert(selectedDate.id);
dates.not(this).datepicker("option", option, date);
}
});
}
});
I have tried with
var enableDays = new Array();
jQuery.each(json.available_dates, function (i, v) {
enableDays.push(v);
});
But I can't get result in created calender.
Full code is added here.
Response Json is 2017-08-31,2017-09-01
See working code is jsfiddle
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "POST",
url: "dates.php",
success: function(data) {
var obj = $.parseJSON(data);
var date = '"'
$.each(obj, function() {
date = date + this['date'] + '","';
});
date = date + '"';
$(document).ready(function() {
$('#datepicker').datepicker({
dateFormat: 'yy-mm-dd',
beforeShowDay: checkAvailability,
});
});
var $myBadDates = new Array(date);
function checkAvailability(mydate){
var $return=true;
var $returnclass ="available";
$checkdate = $.datepicker.formatDate('yy-mm-dd', mydate);
for(var i = 0; i < $myBadDates.length; i++)
{
if($myBadDates[i] == $checkdate)
{
$return = false;
$returnclass= "unavailable";
}
}
return [$return,$returnclass];
}
}
});
});
</script>
This is my existing code. I just want to disable some dates in datepicker coming from database.
$myBadDates takes array of dates like this "2017-05-01", "2017-05-02" which is coming in var date. But for some reason it is not working. When I put hand-written dates in $myBadDates it works well, but with var date it is not working.
I am unable to understand what is happening here as I am new to JavaScript and JSON.
Changing one array into another is done using Array.prototype.map:
var result = input.map(function(e) { return e.date; });
ES6:
var result = input.map(e => e.date);
var input = [{"date":"2017-05-01"},{"date":"2017-04-10"},{"date":"2017-05-02"},{"date":"2017-04-30"},{"date":"2017-04-29"},{"date":"2017-04-28"},{"date":"2017-04-27"},{"date":"2017-04-26"},{"date":"2017-04-25"},{"date":"2017-04-24"},{"date":"2017-04-23"},{"date":"2017-04-14"},{"date":"2017-04-20"},{"date":"2017-05-03"},{"date":"2017-04-22"},{"date":"2017-04-21"},{"date":"2017-05-04"},{"date":"2017-04-19"},{"date":"2017-04-18"},{"date":"2017-04-17"},{"date":"2017-04-16"},{"date":"2017-04-11"},{"date":"2017-04-15"},{"date":"2017-05-05"},{"date":"2017-04-13"},{"date":"2017-04-12"},{"date":"2017-04-09"},{"date":"2017-04-08"},{"date":"2017-04-07"},{"date":"2017-04-06"},{"date":"2017-04-05"},{"date":"2017-04-04"},{"date":"2017-04-03"},{"date":"2017-04-02"},{"date":"2017-04-01"},{"date":"2017-03-31"},{"date":"2017-03-30"},{"date":"2017-02-07"},{"date":"2017-03-29"},{"date":"2017-03-28"},{"date":"2017-03-27"},{"date":"2017-02-08"},{"date":"2017-03-26"},{"date":"2017-03-25"},{"date":"2017-03-24"},{"date":"2017-03-23"},{"date":"2017-03-22"},{"date":"2017-03-21"},{"date":"2017-03-20"},{"date":"2017-02-28"}];
var output = input.map(function(e){ return e.date; });
console.log(output);
I have implemented Angular JS in my Phonegap Application. Where I wish to open a Calendar in the App. But The application is not allowing me to do so.
Following is the code, where I am using with the plugins.
$scope.reminderTimes.selected = returnDate.getHours();
$scope.reminderMins.selected = returnDate.getMinutes();
var newDate = new Date();
$scope.showDatePicker = function($event) {
//console.log('dfdsfsdfsdfdsfsf sdfdsfs');
var options = {
date: new Date(),
mode: 'date'
};
datePicker.show(options, function(date){
if(date != 'Invalid Date') {
console.log("Date came" + date);
} else {
console.log(date);
}
});
$event.stopPropagation();
};
$scope.toogle = function(){
var options = {date: new Date(), mode: 'date'};
var options = {date: new Date(), mode: 'time'}; for time
$cordovaDatePicker.show(options).then(function(date){
alert(date);
});
};
If there is any other way please tell that as well.
I have 2 datepicker for filling checkin text box and checkout text box. I have to enable only checkin+13 days in checkout datepicker.
What I tried is-
$("#Chkin").datepicker({ dateFormat: 'dd/mm/yy', minDate: '+0', onClose: function (dateText, inst) {
if ($("#ctl00_ContentPlaceHolder1_hdnDateformat").val() == "dd/mm/yy") {
var parts = dateText.split("/");
var cin = new Date(Number(parts[2]), Number(parts[1]) - 1, Number(parts[0]));
}
else {
var cin = new Date(dateText);
}
var cout = new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+1);
$("#Chkout").datepicker('option', 'minDate', cout).datepicker('show');
showDays();
}
});
var cin = new Date($("#Chkin").val());
var cout = new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+1);
var maxOut= new Date(cin.getDate()+13);
$("#Chkout").datepicker({ dateFormat: 'dd/mm/yy', minDate: cout, maxDate: maxOut, onSelect: showDays });
Where I went wrong?
I was able to make it work using the following code. Note that I had to deviate a bit from your pasted code since I did not have access to the showDays function. Anyway the issue in your code was that while constructing the maxOut date object, you were using var maxOut = new Date(cin.getDate()+13), which would actually construct a date object using cin.getDate()+13 as the given year. I am also setting the maxdate option on the checkout datepicker in the onclose function. See the date constructor arguments at http://www.w3schools.com/js/js_obj_date.asp
$(function() {
$("#Chkin").datepicker({ dateFormat: 'dd/mm/yy', minDate: '+0', onClose: function (dateText, inst) {
var cin = $(this).datepicker( "getDate" ); // this returns a date object, or null is nothing is selected.
if(cin != null && cin != 'Invalid Date'){ // check for a valid date object, definitely can be done in a better way.
var cout = new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+1);
var maxOut = new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+13);
$("#Chkout").datepicker('option', 'minDate', cout)
.datepicker( "option", "maxDate", maxOut )
.datepicker('show');
}
}
});
var cin = $("#Chkin").datepicker( "getDate" ); //new Date($("#Chkin").val());
if(cin != null && cin != 'Invalid Date'){ // check for a valid date object, definitely can be done in a better way.
var cout = new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+1);
var maxOut= new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+13);
$("#Chkout").datepicker({ dateFormat: 'dd/mm/yy', minDate: cout, maxDate: maxOut});
}else{
$("#Chkout").datepicker({ dateFormat: 'dd/mm/yy'});
}
});
I could sorted it finally.
Here is the code-
$("#Chkin").datepicker({ dateFormat: $("#ctl00_ContentPlaceHolder1_hdnDateformat").val(), minDate: '+0', onClose: function (dateText, inst) {
if ($("#ctl00_ContentPlaceHolder1_hdnDateformat").val() == "dd/mm/yy") {
var parts = dateText.split("/");
var cin = new Date(Number(parts[2]), Number(parts[1]) - 1, Number(parts[0]));
}
else {
var cin = new Date(dateText);
}
var cout = new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+1);
var maxOut= new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+14);
$("#Chkout").datepicker('option', 'minDate', cout);
$("#Chkout").datepicker('option', 'maxDate', maxOut);
showDays();
}
});
var cin = new Date($("#Chkin").val());
var cout = new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+1);
var maxOut= new Date(cin.getFullYear(), cin.getMonth(), cin.getDate()+14);
$("#Chkout").datepicker({ dateFormat: $("#ctl00_ContentPlaceHolder1_hdnDateformat").val(), minDate: cout, maxDate: maxOut, onSelect: showDays });
What I the changes i made are called the function option like this-
$("#Chkout").datepicker('option', 'minDate', cout);
$("#Chkout").datepicker('option', 'maxDate', maxOut);