How to use flatpickr.js to create a range inputs? - javascript

I am trying to use the flatpickr plugin to create a range like pickers accross two different inputs. One input would be for the From and the other one for To.
I tried the following but the minDate and maxDate are not getting set as expected
document.addEventListener('DOMContentLoaded', function () {
let dateTimeFrom = document.getElementById('From');
let dateTimeTo = document.getElementById('To');
let dateTimeFromPicker = flatpickr(dateTimeFrom, {
enableTime: true,
dateFormat: 'n/j/Y h:i K',
onChange: function (selectedDates, dateStr, instance) {
dateTimeTo.set('minDate', selectedDates[0]);
}
});
let dateTimeToPicker = flatpickr(dateTimeTo, {
enableTime: true,
dateFormat: 'n/j/Y h:i K',
onChange: function (selectedDates, dateStr, instance) {
dateTimeFrom.set('maxDate', selectedDates[0]);
}
});
});
How can I correctly set the range across two inputs?

I was able to get it to work using the following snippet
document.addEventListener('DOMContentLoaded', function () {
let dateTimeFrom = document.getElementById('From');
let dateTimeTo = document.getElementById('To');
let dateTimeToPicker = null;
let dateTimeFromPicker = flatpickr(dateTimeFrom, {
enableTime: true,
dateFormat: 'n/j/Y h:i K',
onChange: function (selectedDates, dateStr, instance) {
dateTimeToPicker.set('minDate', selectedDates[0]);
}
});
dateTimeToPicker = flatpickr(dateTimeTo, {
enableTime: true,
dateFormat: 'n/j/Y h:i K',
onChange: function (selectedDates, dateStr, instance) {
dateTimeFromPicker.set('maxDate', selectedDates[0]);
}
});
});

Related

How to add extra class with easepick

Please Help! How to add "myCss" class for one date before bookedDates? (17 Aug and 17 Sep in my example). The idea is to paint a different color day before booked.
This is example code for which I am trying to do this:
const DateTime = easepick.DateTime;
const bookedDates = [
'18-08-2022', '19-08-2022', '20-08-2022', '18-09-2022', '19-09-2022', '20-09-2022',
].map(d => {
if (d instanceof Array) {
const start = new DateTime(d[0], 'DD-MM-YYYY');
const end = new DateTime(d[1], 'DD-MM-YYYY');
return [start, end];
}
return new DateTime(d, 'DD-MM-YYYY');
});
const picker = new easepick.create({
element: document.getElementById('datepicker'),
css: [
'https://cdn.jsdelivr.net/npm/#easepick/bundle#1.2.0/dist/index.css',
'https://easepick.com/css/demo_hotelcal.css',
],
readonly: true,
zIndex: 10,
format: "DD MMM YYYY",
readonly: false,
plugins: ['RangePlugin', 'LockPlugin'],
RangePlugin: {
tooltipNumber(num) {
return num - 1;
},
locale: {
one: 'night',
other: 'nights',
},
},
LockPlugin: {
minDate: new Date(),
minDays: 2,
inseparable: true,
filter(date, picked) {
if (picked.length === 1) {
const incl = date.isBefore(picked[0]) ? '[)' : '(]';
return !picked[0].isSame(date, 'day') && date.inArray(bookedDates, incl);
}
return date.inArray(bookedDates, '[)');
},
}
});
<script src="https://cdn.jsdelivr.net/npm/#easepick/bundle#1.2.0/dist/index.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/#easepick/bundle#1.2.0/dist/index.umd.min.js"></script>
<input readonly="readonly" id="datepicker"/>
You need to use a setup option in easepick.create({ ... }):
Before date
setup(picker) {
picker.on('view', (event) => {
const { view, target, date } = event.detail;
if (view === 'CalendarDay') {
const dayAfter = date.clone().add(1, 'day');
if (
! picker.options.LockPlugin.filter(date, picker.datePicked)
&& picker.options.LockPlugin.filter(dayAfter, picker.datePicked)
) {
target.classList.add('myCss');
}
}
});
},
After date
setup(picker) {
picker.on('view', (event) => {
const { view, target, date } = event.detail;
if (view === 'CalendarDay') {
const dayBefore = date.clone().subtract(1, 'day');
if (
picker.options.LockPlugin.filter(dayBefore, picker.datePicked)
&& ! picker.options.LockPlugin.filter(date, picker.datePicked)
) {
target.classList.add('myCss');
}
}
});
}

Bootstrap datepicker set dates when creating the datepicker

I've an issue with the bootstrap datepicker: I need to set dates when instantiating the datepicker, without triggering the dateChange event. The reason is that I'm listening to the datechange event to submit a form, so I can't trigger it for setting the selected dates.
I need to be able to set the two days selected from data I store in a div
const $picker = $('.datetimepicker2').datepicker({
inline: true,
multidate: 2,
debug: true,
format: 'dd/mm/yy',
beforeShowDay: function(date) {
if($picker && $picker.datepicker('getDates').length === 2) {
const selectedDates = $picker.datepicker('getDates');
const startDate = moment(selectedDates[0]);
const endDate = moment(selectedDates[1]);
const day = moment(date);
if(day.isAfter(startDate) && day.isBefore(endDate)) {
return {
enabled: true,
classes: 'active'
}
}
}
}
}).on('changeDate', (event) => {
const startDate = moment(event.dates[0]).format('DD/MM/YY');
const $form = $('.main_search').find('form');
const $input = $('<input>', { name: 'start_date', value: startDate , type: 'hidden'});
$form.append($input);
$form.submit();
});
The problem is that if I set dates with this code, it will submit the form
const homeData = $('#home-data').data();
if( homeData.startDate ) {
let dates = [];
dates.push(homeData.startDate);
$picker.datepicker('setDates', dates);
}

get default value in a checkbox

I have a checkbox dropdown in a function. So the user can select one, more than one or zero. When the user select one or more than one, everything is correct. But when the user dont select any I have a null pointer exception. To handle this exception I want to make by default that if he doesnt select anything to show the results of all (like if he is selecting all). How can I do that?
Here is the JS function
$(function () {
$("#datepicker").datepicker({
//defaultDate: "+1w",
changeMonth: true,
changeYear: true,
numberOfMonths: 1,
minDate: "01/01/2008"
})
.datepicker('setDate', new Date());
$("button.action").click(function () {
//var users = new Array();
var date = $('#datepicker').val().toString();
var selected_values = new Array();
//var userName = $(' .checked:checked').val();
$(document).ready(function () {
selected_values = []; // initialize empty array
$(".checked:checked").each(function () {
selected_values.push($(this).val());
});
});
$.ajax({
url: 'EmployeeDate',
datatype: "application/json",
traditional:true,
data: {
lstUserName: selected_values,
strDate: date
},
success: function (data, textStatus, jqXHR) {
$('#DataUser').html(data);
},
error: function () {
console.log("error handler when ajax request fails... ");
},
});
});
});
and this is the controller:
public IEnumerable<DateTime> getInfoByDate(string strDate, string[] lstUserName)
{
CareDB context = new CareDB();
IEnumerable<DateTime> lst = null;
List<DateTime> model = new List<DateTime>();
if (lstUserName != null)
{
foreach (string user in lstUserName)
{
SqlParameter userName = new SqlParameter("#EmployeeName", user);
SqlParameter Date = new SqlParameter("#Date", strDate);
object[] parameters = new object[] { Date, userName };
model.Add(context.ReleaseDate.SqlQuery("_UserInformationByDate #Date, #EmployeeName", parameters).ToList().FirstOrDefault());
}
}
else
{
SqlParameter Date = new SqlParameter("#Date", strDate);
SqlParameter userName = new SqlParameter("#EmployeeName", lstUserName);
object[] parameters = new object[] { Date, userName };
model = context.ReleaseDate.SqlQuery("_UserInformationByDate #Date, #EmployeeName", parameters).ToList();
}
context.Dispose();
context = null;
return model;
}
Try this
$(document).ready(function () {
selected_values = []; // initialize empty array
// nothing selected so push all value regadless
if( $(".checked:checked").length == 0)
{
$(".checked").each(function () {
selected_values.push($(this).val());
});
}
else
{
$(".checked:checked").each(function () {
selected_values.push($(this).val());
});
});
}

ReactJS: Calling 'this' within a JQuery event listener function

I am trying to refer to this (i.e. the ReactJS component) within a JQuery event callback:
var Component = React.createClass({
func1: function(){
$("#multi").multiselect({
onChange: function(a, b){
this.test();
},
});
},
test: function(){
console.log("Calling a react component function");
}
...
});
However it says:
TypeError: this.test is not a function
How to I refer to this within a JQuery event callback function?
You'll need to bind the onChange callback to the context:
onChange: function(a, b) {
this.test();
}.bind(this)
You could also use an arrow function:
onChange: (a, b) => {
this.test()
}
Here is a solution
var Search = React.createClass({
componentDidMount: function() {
var that = this;
$('#searchindexcheckinout').datepicker({
language: 'fr',
minDate: new Date(),
firstDay: 0,
onSelect: function(formattedDate, date, inst) {
that.GetResult();
}
});
},
GetResult: function() {
alert();
},
render: function() {
...
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>
$('#searchindexcheckinout').datepicker({
language: 'fr',
minDate: new Date(),
firstDay: 0
});

Pikaday.js: How to disbale days in calendar?

I have a calendar and I want to set a few days to disable. Does anyone have experience with this? On github it says:
disableDayFn: callback function that gets passed a Date object for each day in view. Should return true to disable selection of that day.
But how can I use this?
var bookingPicker = new Pikaday(
{
field: $(self.options.calendarInput, container)[0],
container: $(self.options.calendarContainer, container)[0],
minDate: new Date(),
bound: false,
firstDay: 1,
onOpen: function () {
this.disableDayFn(23); //<--- ???
},
onSelect: function (date) {
},
onDraw: function (date) {
console.log("NEW MONTH")
}
}
);
var bookingPicker = new Pikaday(
{
field: $(self.options.calendarInput, container)[0],
container: $(self.options.calendarContainer, container)[0],
minDate: new Date(),
bound: false,
firstDay: 1,
onOpen: function () {
this.disableDayFn(23); //<--- ???
},
onSelect: function (date) {
},
onDraw: function (date) {
console.log("NEW MONTH")
},
disableDayFn: function(dateTime){
/* here you can access each day shown and disable those in your range. To disable just return true*/
}
}
);
So every date you can see on the picker is passed, just do whatever checks you want in the function against that date. Here's an example using a string array of dates that uses moment.js to qualify equality.
var validDateArray = ["2017-JAN-01", "2017-JAN-02", "2017-JAN-03"]
in the picker:
disableDayFn: (dateToCheck: Date) => {
if (validDateArray == undefined) {
console.log("...validDateArray == undefined");
return true;
}
let d1 = Moment(dateToCheck).format("YYYY-MMM-DD");
for (let d2 of validDateArray) {
if (d1 == d2) {
console.log("...date is valid");
return false;
}
}
console.log("...date is not valid");
return true;
}

Categories