Bootstrap datepicker set dates when creating the datepicker - javascript

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);
}

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');
}
}
});
}

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

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]);
}
});
});

How to handle an error for validating between two dates?

I have an jsp page where the user select between two dates. I need validation to ensure that the limit of the range is a month. I need to display message for error handling about that issue.
I tried making a function with return true and false. When the return is false, the message is already appears but system is still running to the next step. Here is my jsp page: (I use netbeans editor)
var fromDate = new Date(document.getElementById("fromTgl").value);
var toDate = new Date(document.getElementById("toTgl").value);
//call the function
var validateDate;
validateDate = rangeWithinDates(toDate,fromDate);
//funtion for validation within two dates
function rangeWithinDates(toDate,fromDate){
var diff = Math.abs(toDate.getTime() - fromDate.getTime());
var daysDiff = diff / (1000 * 60 * 60 * 24);
if (daysDiff>30){
window.alert("Please limit the date range to 1 month!");
return false;
} else {
return true;
}
}
it's my full script
<script>
var officeCode;
var fdsReport;
var rows;
$(document).ready(function() {
esLoadingAnimWindow("wndLoading");
/** Get the userId from session scope **/
var userId = "${sessionScope.UserSession.getUserId()}";
var CurrOfficeCode = "${sessionScope.UserSession.getUserOfficeCode()}";
if ($("#officeCode").data("kendoDropDownList") == null) {
$('#officeCode').kendoDropDownList({
dataTextField: "nameShort",
dataValueField: "officeCode",
dataSource: {
transport: {
read: {
dataType: "json",
url: getFormRestUrl() + "/getListOffice?officeCode=" + CurrOfficeCode
}
}
},
optionLabel: "Select Office Code"
});
}
if($("#fromTgl").data("kendoDatePicker")==null) {
$("#fromTgl").kendoDatePicker({value: new Date(), format: "dd MMMM yyyy"});
}
if($("#toTgl").data("kendoDatePicker")==null) {
$("#toTgl").kendoDatePicker({value: new Date(), format: "dd MMMM yyyy"});
}
$("#wndLoading").kendoWindow({
actions: ["Close"],
modal: true,
width: "350px",
resizable: false,
title: false,
draggable: false,
open: function(e) { $("html, body").css("overflow", "hidden"); },
close: function(e) {
$("html, body").css("overflow", "");
}
}).data("kendoWindow");
// Call the function to stop scrolling main window when scrolling the content of kendo dropdownlist.
stopScroll($("#officeCode").data("kendoDropDownList").ul.parent());
});
$("#btnProcess").click(function(e){
e.preventDefault();
$("#wndLoading").data("kendoWindow").center().open();
var fromDate = new Date(document.getElementById("fromTgl").value);
var toDate = new Date(document.getElementById("toTgl").value);
var validateDate;
validateDate = rangeWithinDates(toDate,fromDate);
fdsReport = new kendo.data.DataSource({
transport: {
read: {
url: getFormRestUrl() + "/getReportFidusia?officeCode=" + $("#officeCode").val().trim()
+ '&beginDate=' + dateToString($("#fromTgl").data("kendoDatePicker").value())
+ '&endDate=' + dateToString($("#toTgl").data("kendoDatePicker").value()),
dataType: "json",
contentType: "application/json"
}
}
});
rows = [{
cells:[
{ value: "TN NY NN" },
{ value: "Pemberi Fidusia" },
{ value: "Pekerjaan" },
{ value: "Kota Lahir" },
{ value: "Tanggal Lahir" }
]
}];
fdsReport.read().then(function(){
var data = fdsReport.data();
for (var i = 0; i < data.length; i++){
rows.push({
cells: [
{ value: data[i].tNnYnN},
{ value: data[i].pemberiFidusia},
{ value: data[i].jobCust},
{ value: data[i].kotaLahir},
{ value: data[i].tglLahir.slice(0,4) + "-" + data[i].tglLahir.slice(5,7) + "-" + data[i].tglLahir.slice(8,10)}
]
});
};
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
columns: [
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true }
],
title: "Laporan Fidusia",
rows: rows
}
]
});
$("#wndLoading").data("kendoWindow").close();
// Save the file as Excel file with extension xlsx
kendo.saveAs({
dataURI: workbook.toDataURL(),
fileName: "erpt_laporan_fidusia.xlsx"
});
});
});
//Ajax error listener
$(document).ajaxError(function (event, jqxhr, settings, thrownError){
//Close the loading window if it is opened
$("#wndLoading").data("kendoWindow").close();
//Open the alert window.
var wndAlert = registerAlertModalWindow("wndAlert", jqxhr.responseText);
wndAlert.center().open();
});
function getGLobalRestUrl() {
return "/easy/api";
}
function getFormRestUrl() {
return getGLobalRestUrl() + "/OMTRNF661";
}
function dateToString(pDate) {
return kendo.toString(pDate, 'yyyy-MM-dd').trim();
}
function rangeWithinDates(toDate,fromDate){
var diff = Math.abs(toDate.getTime() - fromDate.getTime());
var daysDiff = diff / (1000 * 60 * 60 * 24);
if (daysDiff>30){
window.alert("Please limit the date range to 1 month!");
document.getElementById("toTgl").value = "";
return false;
}
return true;
}
</script>
the result of this code
I expect if return false will display an error message and stop the running. so, the users must choose the date according to predetermined range. And if return true will be continue to the next step. Please help me to resolve this..
Your validateDate doesn't prevent you from downloading: it's just an unused boolean.
If you want to, you'll have to do something like this:
if (validateDate){<the rest of your download code section>}
You can reset textbox value to empty and ask user to enter the value again. You can reset only last date value or both.
if (daysDiff>30){
window.alert("Please limit the date range to 1 month!");
document.getElementById("toTgl").value = "";
return false;
}
return true;
In file downloading function check the value true or false
if (validateDate == true){
// your code
}

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());
});
});
}

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