Pikaday bug with a disableDayFn array to remove specific days - javascript

I am using Pikaday datepicker. All works well but for some complicated date manipulation I need to add/remove multiple dates.
<code>
var start_date = new Pikaday({
disableDayFn: function(date) {
var enabled_dates = ["06/11/2019","06/17/2019","06/24/2019"]; // dates I want to enable.
var disabled_dates = ["06/15/2019", "06/22/2019"]; // dates I want to disable.
if ((date.getDay() === 1 || date.getDay() === 2 || ($.inArray(moment(date).format("MM/DD/YYYY"), disabled_dates) === 0)) && $.inArray(moment(date).format("MM/DD/YYYY"), enabled_dates) === -1) {
return date;
}
},
format: 'MM/DD/YYYY',
field: document.getElementById('start_date'),
});
</code>
In this example above:
[this works fine] I am using an enabled_dates array to enable multiple dates I need to display on calendar.
[this works fine] I am removing ALL mondays and tuesdays using the actual day value '1' and '2' example: date.getDay() === x
[not working] when I try pass multiple dates in an array the first date is removed but the subsequent dates are not actioned.
In this example all good except for the date "06/22/2019" not removed as appears only removes the first date in array not subsequent
Fiddle demo:
http://jsfiddle.net/netfast/k36nhacz/18/

Related

Enable and disable dates jquery using datepicker [duplicate]

This question already has answers here:
Enable one specific date in jquery datepicker
(2 answers)
Closed 4 years ago.
I am using the jquery datepicker. I have set an array of dates which should be disabled, this is working fine:
var vakantie = ["25-12-2018", "26-12-2018", "27-12-2018", "28-12-2018", "29-12-2018", "30-12-2018", "31-12-2018"];
function nietBeschikbaar(dt){
var datestring = jQuery.datepicker.formatDate('dd-mm-yy', dt);
return [dt.getDay() == 1 || dt.getDay() == 2 ? false : true && vakantie.indexOf(datestring) == -1 ];
};
jQuery("#datepicker").datepicker("option", "beforeShowDay", nietBeschikbaar);
Now I would also want one date to be enabled (every monday and tuesday is also disabled, but this date is on a monday). With this code I can disable everything except this one date:
var enableDays = ["24-12-2018"];
function enableAllTheseDays(date) {
var sdate = $.datepicker.formatDate( 'dd-mm-yy', date)
if($.inArray(sdate, enableDays) != -1) {
return [true];
}
return [false];
}
jQuery("#datepicker").datepicker("option", "beforeShowDay", enableAllTheseDays);
But now I would like to combine these two scripts, so I would like to disable the 'vakantie' array, and also enable the 'enableDays' array. I can't get them working togheter, could anyone help me out?
This might work, test it please:
function enableAllTheseDays() {
var sdate = $.datepicker.formatDate( 'dd-mm-yy', date);
var evaluateArray = vakantie.some(function(item){
return item == sdate;
});
var arrayWithResult = [];
arrayWithResult.push(evaluateArray);
return arrayWithResult;
}
Just make sure that sdate is a string variable in this format:
"dd-mm-yy"
Hope it helps!

How to change the filtering pattern of the Webix dateFilter?

How to specify the format of the dateFilter in Webix datatable?
I have a grid where dates are formatted to "%d.%m.%Y":
columns:[
{ id:"date", header:[{ content:"dateFilter" }], width:160, format:myFormat }
]
where myFormat is webix.Date.dateToStr("%d.%m.%Y"); The result is dd.mm.yyyy
Here's a snippet with the similar grid: http://webix.com/snippet/1ec86aa8
The point is that the dateFilter still requires the full dates as %m-%d-%Y (mm-dd-yyyy)
So I'm looking for a way to change this predefined pattern. Any suggestion are appreciated.
dateFilter convert user entered date from str to date using webix.i18n.dateFormatDate
By the way, it does more thing. For exemple you can enter "<1996" and so it will not convert using the above method date but extract the year.
Then it convert the guessed date to an interger and perform an interger comparison with data's dates
Sadly "webix.i18n.dateFormatDate" use the webix.i18n.dateFormat which depend the locale to convert string to date. and there is no way to customize the format used by dateFilter.
A solution for you is to create a custom filter which do the same job as dateFilter but using your own date convertion :
Here is a modified webix code of dateFilter :
webix.ui.datafilter.myDateFilter = webix.extend({
format:function(value){
if (value === "") return "";
var date = new Date();
if (value.indexOf("today") != -1){
date = webix.Date.dayStart(date);
} else if (value.indexOf("now") == -1){
var parts = value.match(/[0-9]+/g);
if (!parts||!parts.length) return "";
if (parts.length < 3){
parts.reverse();
date = new Date(parts[0], (parts[1]||1)-1, 1);
} else
// Change here
date = webix.Date.strToDate("%d.%m.%Y")(value.replace(/^[>< =]+/,""));
}
return date.valueOf();
}
}, webix.ui.datafilter.numberFilter);
Updated snippet : http://webix.com/snippet/20c0175a

MomentJS range not always including current month in date range

For some odd reason, MomentJS range does not always display the current month. I am wondering if there is an option that needs to be set so that it includes the current month in it's date range.
This is the code used to generate the date range. I've also attached a codepen so you can see it in action.
http://codepen.io/anon/pen/rORmxY
//momentJs creates the ranges
//Only shows April 2015
var end = moment("2015-05-01","YYYY-MM-DD");
//where the day is > 18 it Shows May 2015
var end2 = moment("2015-05-19","YYYY-MM-DD");
var start = moment().subtract(1.5, "year");
var range = moment.range(start, end);
var range2 = moment.range(start, end2);
//iterate through the months, and populate the SELECT box
range.by('months', function(date) {
//add those values to a SELECT box
$('#month-range').prepend($('<option>', {
value: date.format("MMM YYYY"),
text: date.format("MMM YYYY")
}));
});
//iterate through the months, and populate the SELECT box
range2.by('months', function(date) {
//add those values to a SELECT box
$('#month-range2').prepend($('<option>', {
value: date.format("MMM YYYY"),
text: date.format("MMM YYYY")
}));
});
Thanks a lot
The work around I've found is to simply tell momentJs to use the end of the month for the range. Which makes sense in this context. This is done by adding .endOf("month") to the end range.
See this code for clarification:
//momentJs creates the ranges
//adding .endOf("month") will Include the month of May in the month ranges
var end = moment("2015-05-01","YYYY-MM-DD").endOf("month");
var start = moment().subtract(1.5, "year");
var range = moment.range(start, end);
//iterate through the months, and populate the SELECT box
range.by('months', function(date) {
//add those values to a SELECT box
$('#month-range').prepend($('<option>', {
value: date.format("MMM YYYY"),
text: date.format("MMM YYYY")
}));
});
Thanks a lot for the help
Please take a look at the source code of month-range (https://github.com/gf3/moment-range/blob/master/lib/moment-range.js).
The reason that setting end date to 2015-05-18 will include one less month as 2015-05-19 is nothing special. It is because today is 2015-11-18 and you set the start date to be 2014-05-18.
Now look at _byString function in moment-range (which is called by 'by' function).
function _byString(interval, hollaback, exclusive) {
var current = moment(this.start);
while (this.contains(current, exclusive)) {
hollaback.call(this, current.clone());
current.add(1, interval);
}
}
'current' variable starts from '2014-05-18' and increases one month at a time.
If the end date is 2015-05-19, 'this.contains()' simply returns true when 'current' = '2015-05-18'. And if end date is 2015-05-19, 'this.contains' will return false. This is the reason for the behavior of your code.
Now, if you wanna always include the current month, I think you always add 1 day to the end date. However, I image this method might cause some problem for the last day of a month. Or you can always set the end date to the first day of the next month, but exclude that month. You can do some experimentation.
Hope this helps!

XPages DateTextBox - setting constraints

I am working with the date text box and had a few questions. This is with designer 9, so its using dojo 1.8 not that it should make too much difference.
Setting Min / Max dates
I don't see a way to do this in designer. There isn't anything in xe:djDateTimeConstraints that matches, so is this something I need to do via javascript?
I have an example below that changes the EndDate control once StartDate is selected, but didn't see a way to set StartDate other then beforeRenderResponse or some such.
Selectable Dates
http://dojotoolkit.org/reference-guide/1.8/dijit/form/DateTextBox.html
"also validates against developer-provided constraints like min, max, valid days of the week, etc."
Valid days of the week - I'd love to set it to just weekdays that are selectable, but there is no example, and the link does not go to a page with a dayofweek constraint. What term should I be searching for? In the example below I have a validator, but I didn't know if the date text box could just have the weekends be unselectable.
Here is my example control - when start date is set, it changes constraints of end date
<xp:label value="Start Date" id="lblStartDate"></xp:label>
<xe:djDateTextBox id="djDateStart">
<xe:this.constraints>
<xe:djDateTimeConstraints datePattern="M/dd/yyyy"></xe:djDateTimeConstraints>
</xe:this.constraints>
<xp:eventHandler event="onChange" submit="false">
<xe:this.script><![CDATA[
var startDateID = "#{id:djDateStart}";
var endDateID = "#{id:djDateEnd}";
var hiddenEndDateID = "#{id:hiddenEndDate}";
require(["dojo/date/locale"], function(locale){
var x = new Date (dojo.byId(startDateID).value);
// Fails if current date is the weekend or empty
if(locale.isWeekend(x) || dojo.byId(startDateID).value == "") {
dojo.style(hiddenEndDateID, "display", "none");
dojo.byId(endDateID).value = "";
dojo.byId(startDateID).value = "";
dijit.byId(startDateID).displayMessage("dates must be weekdays");
} else {
// Set display value and constraint for End Date
dojo.byId(endDateID).value = dojo.byId(startDateID).value;
dijit.byId(endDateID).constraints.min = arguments[0];
dijit.byId(endDateID).constraints.max = dojo.date.add(arguments[0], "week", 3);
// Make End Date and Comment visible.
dojo.style(hiddenEndDateID, "display", "inline");
}
})
]]></xe:this.script>
</xp:eventHandler>
</xe:djDateTextBox>
the solution I came up with was to use the Range check - not constraints. So in the script block below, it returns false when the day is sunday/saturday (0, 6) and if its not within the range.
Perhaps this will help someone else.
fyStart = new Date ("#{applicationScope.fyStart}");
fyEnd = new Date ("#{applicationScope.fyEnd}");
calendarEnd = new Date ("#{applicationScope.calendarEnd}");
require(["dojo/ready", "dojo/parser", "dijit/registry", "dijit/Dialog"], function(ready, parser, registry){
ready(function(){
dijit.byId('#{id:djDateStart}').rangeCheck = function(date,constraints) {
var day=date.getDay();
return day !==0 && day !== 6 && date >= fyStart && date <= calendarEnd;
}
dijit.byId('#{id:djDateEnd}').rangeCheck = function(date,constraints) {
var day=date.getDay();
return day !==0 && day !== 6 && date >= fyStart && date <= calendarEnd;
}
});
});

JavaScript - Validate Date

I have an HTML text field. I want to validate via JavaScript that the value entered is a valid date in the form of "MM/DD/YY" or "MM/D/YY" or "MM/DD/YYYY" or "MM/D/YYYY". Is there a function that does this?
I sort of assumed there was something like isNaN but I don't see anything. Is it true that JavaScript can't validate dates?
You could use javascript's own Date object to check the date. Since the date object allows some mucking around with the month and day values (for example March 32 would be corrected to April 1), you can just check that the date you create matches the one you put in. You could shorten this if you want, but it's longer for clarity.
function checkDate(m,d,y)
{
try {
// create the date object with the values sent in (month is zero based)
var dt = new Date(y,m-1,d,0,0,0,0);
// get the month, day, and year from the object we just created
var mon = dt.getMonth() + 1;
var day = dt.getDate();
var yr = dt.getYear() + 1900;
// if they match then the date is valid
if ( mon == m && yr == y && day == d )
return true;
else
return false;
}
catch(e) {
return false;
}
}
Is it true that JavaScript can't validate dates?
No.
Is there a function that does this?
No.
You will need to write your own validation function to parse the date format (regex comes to mind) and then determine if it is valid within your specific criteria.
Check out http://momentjs.com/. Using it, this snippet
moment(yourCandidateString, 'MM-DD-YYYY').isValid()
should do the job.
This is what I use to validate a date.
Date.parse returns NaN for invalid dates.
This supports both date-only and date+time formats.
Hope this helps.
var msg;
var str = "2013-12-04 23:10:59";
str = "2012/12/42";
var resp = Date.parse(str);
if(!isNaN(resp)) { msg='valid date'; } else { msg='invalid date'; }
console.log(msg);
If you want to venture into the realms of JQuery there are plenty of validation plugins that include date validation. This plugin is one I've used a few times and has served me well.
I use Bootstrap Datepicker. One of the options with the text box disabled should do the trick.
http://www.eyecon.ro/bootstrap-datepicker/
<input type="text" id="dateinput"/>
<script type="text/javascript">
$(#"dateinput").datepicker({
buttonImage: "images/calendar.png",
dateFormat: "yyyy-MMM-dd"
});
function validateDate() {
if ($(#"dateinput").val().trim() == "") {
// Is a blank date allowed?
return true;
}
var oldVal = $(#"dateinput").val(); // Current value in textbox
// Now use jQueryUI datepicker to try and set the date with the current textbox value
$(#"dateinput").datepicker("setDate",$(#"dateinput").val());
// Check if the textbox value has changed
if (oldVal != $(#"dateinput").val()) {
// The datepicker will set something different if the date is invalid
$(#"dateinput").val(oldVal); // Set the textbox back to the invalid date
alert ("date was invalid");
return false;
} else {
// If nothing changed, the date must be good.
return true;
}
}
</script>
There does not appear to be a build-in function which does that. However, this code is probably what you're looking for:
<script type="text/javascript">
/**--------------------------
//* Validate Date Field script- By JavaScriptKit.com
//* For this script and 100s more, visit http://www.javascriptkit.com
//* This notice must stay intact for usage
---------------------------**/
function checkdate(input){
var validformat=/^\d{2}\/\d{2}\/\d{4}$/ //Basic check for format validity
var returnval=false
if (!validformat.test(input.value))
alert("Invalid Date Format. Please correct and submit again.")
else{ //Detailed check for valid date ranges
var monthfield=input.value.split("/")[0]
var dayfield=input.value.split("/")[1]
var yearfield=input.value.split("/")[2]
var dayobj = new Date(yearfield, monthfield-1, dayfield)
if ((dayobj.getMonth()+1!=monthfield)||(dayobj.getDate()!=dayfield)||(dayobj.getFullYear()!=yearfield))
alert("Invalid Day, Month, or Year range detected. Please correct and submit again.")
else
returnval=true
}
if (returnval==false) input.select()
return returnval
}
</script>
Source: http://www.javascriptkit.com/script/script2/validatedate.shtml
Have you googled for something like javascript date validation? It shows up some good information, and a working code example here.
I suggest you a couple of solutions.
guide the user input with a date picker. This way you can control the input format. jQueryui datepicker is a popular implementation.
use a js library to manage datetime data type (not an actual datatype in Javascript!!). I suggest you date.js.
Similar to this answer, Date can be used to check if the parsed version of the string corresponds to the original date string.
> datestring_valid = "2020-02-29";
> parsed_Date = new Date(datestring_valid);
> parsed_Date.toISOString().slice(0,10) == datestring_valid;
true
> datestring_invalid = "2021-02-29";
> parsed_Date = new Date(datestring_invalid);
> parsed_Date.toISOString().slice(0,10) == datestring_invalid;
false
NB: This requires the date string to be ISO formatted.
The reason this works is, that Date parses some invalid dates into something valid as in the example above. However, supplying "2020-01-32" into Date will result in the result being "Invalid Date" that isNaN.
A function that handles all of this is the following:
function isValidDateString(datestring) {
parsed_Date = new Date(datestring);
return (parsed_Date.toISOString().slice(0,10) == datestring) && !isNaN(parsed_Date)
};
> isValidDateString(datestring_valid)
true
> isValidDateString(datestring_invalid)
false

Categories

Resources