In our VS solution project, there are about 50 different JS files. What I am doing is moving the code out of these files (Require.js was used in these separated files) and combining all the code into one larger single JS file. Reason for this is to reduce the requests from the website.
Nonetheless, I am receiving 1 of 2 errors, depending on if I wrap the JS functions/prototypes w/ a self-containing function.
The code uses jQuery and jQuery.UI
First error (if wrapped) is FormBuilderDatePicker is not a constructor
Second error (if not wrapped) is this.registerSelectors is not a function
Calling JS code:
var quoteModuleObjArr = [
{ formId: "quote-module-form-moving", className: '.zipcode-moving', moveType: 'moving' },
{ formId: "quote-module-form-storage", className: '.zipcode-storage', moveType: 'storage' },
{ formId: "quote-module-form-moving-storage", className: '.zipcode-moving-storage', moveType: 'moving-storage' }
];
for (var i = 0; i < quoteModuleObjArr.length; i++) {
var formBuilder = null;
formBuilder = new FormBuilderDatePicker({
datepicker: '#' + quoteModuleObjArr[i].formId + ' input.isDatePicker',
formId: '#' + quoteModuleObjArr[i].formId
});
}
FormBuilderDatePicker function/prototype (wrapped):
var FormBuilderDatePicker = (function () { // remove for the 2nd error (unwrapped)
function FormBuilderDatePicker(options) {
this.options = options;
this.options = $.extend(true, {}, this.defaults, this.options);
this.registerSelectors();
this.delegateEvents()
};
FormBuilderDatePicker.prototype.defaults = {
datepicker: ".hasDatePicker",
disabledDays: [],
datepickerOptions: {
minDate: 0,
maxDate: "+12M"
},
formId: ''
};
FormBuilderDatePicker.prototype.registerSelectors = function () {
this.options.$datepicker = $(this.options.datepicker);
};
FormBuilderDatePicker.prototype.delegateEvents = function () {
var _self = this;
this.options.$datepicker.on("error", function () {
var selectedDate = _self.options.$datepicker.val();
_self.options.disabledDays.push(selectedDate)
});
this.options.$datepicker.on("change", function () {
$(this).valid()
});
this.options.datepickerOptions.beforeShowDay = function (date) {
var today = new Date;
var todayDate = $.datepicker.formatDate("mm/dd/yy", today);
var selectedDate = $.datepicker.formatDate("mm/dd/yy", date);
var notToday = todayDate != selectedDate;
var isDisabledDay = $.inArray($.datepicker.formatDate("m/d/yy", date), _self.options.disabledDays) == -1;
var result = notToday && isDisabledDay;
if (notToday == false) {
setTimeout(function () {
$(".ui-datepicker-today").removeClass("ui-state-disabled");
}, 0);
return [result, "ui-datepicker-current-day"];
}
return [result];
};
this.options.datepickerOptions.onChangeMonthYear = function (year, month, datepicker) {
}
this.options.$datepicker.datepicker(this.options.datepickerOptions);
};
return FormBuilderDatePicker; // remove for the 2nd error (unwrapped)
})(); // remove for the 2nd error (unwrapped)
I have also tried creating an init function, that calls FormBuilderDatePicker.registerSelectors() and FormBuilderDatePicker.delegateEvents(), and removed the last (2) lines within the constructor, but I get the same error, that registerSelectors() is not a function (same w/ delagateEvents().
I've also read that for prototypes to have the ability to be called, they need a return within the function. Hence, during testing, I added a return true; to the delegateEvents and registerSelectors functions, but this did not work either.
All code above is inside a $(function() {});
Updated Code/Solution:
setupFormBuilderDatePicker();
setupQuoteModuleDatePicker();
// ***********************************************
// Quote Module Date Picker
// ***********************************************
var FormBuilderDatePicker;
function setupFormBuilderDatePicker() {
FormBuilderDatePicker = (function () {
function FormBuilderDatePicker(options) {
this.options = options;
this.options = $.extend(true, {}, this.defaults, this.options);
this.registerSelectors();
this.delegateEvents()
};
FormBuilderDatePicker.prototype.defaults = {
datepicker: ".hasDatePicker",
disabledDays: [],
datepickerOptions: {
minDate: 0,
maxDate: "+12M"
},
formId: ''
};
FormBuilderDatePicker.prototype.registerSelectors = function () {
this.options.$datepicker = $(this.options.datepicker);
};
FormBuilderDatePicker.prototype.delegateEvents = function () {
var _self = this;
this.options.$datepicker.on("error", function () {
var selectedDate = _self.options.$datepicker.val();
_self.options.disabledDays.push(selectedDate)
});
this.options.$datepicker.on("change", function () {
$(this).valid()
});
this.options.datepickerOptions.beforeShowDay = function (date) {
var today = new Date;
var todayDate = $.datepicker.formatDate("mm/dd/yy", today);
var selectedDate = $.datepicker.formatDate("mm/dd/yy", date);
var notToday = todayDate != selectedDate;
var isDisabledDay = $.inArray($.datepicker.formatDate("m/d/yy", date), _self.options.disabledDays) == -1;
var result = notToday && isDisabledDay;
if (notToday == false) {
setTimeout(function () {
$(".ui-datepicker-today").removeClass("ui-state-disabled");
}, 0);
return [result, "ui-datepicker-current-day"];
}
return [result];
};
this.options.datepickerOptions.onChangeMonthYear = function (year, month, datepicker) {
}
this.options.$datepicker.datepicker(this.options.datepickerOptions);
};
return FormBuilderDatePicker;
})();
}
function setupQuoteModuleDatePicker() {
var quoteModuleObjArr = [
{ formId: "quote-module-form-moving", className: '.zipcode-moving', moveType: 'moving' },
{ formId: "quote-module-form-storage", className: '.zipcode-storage', moveType: 'storage' },
{ formId: "quote-module-form-moving-storage", className: '.zipcode-moving-storage', moveType: 'moving-storage' }
];
for (var i = 0; i < quoteModuleObjArr.length; i++) {
var formBuilder = null;
formBuilder = new FormBuilderDatePicker({
datepicker: '#' + quoteModuleObjArr[i].formId + ' input.isDatePicker',
formId: '#' + quoteModuleObjArr[i].formId
});
greyOutFacilityClosedDates(quoteModuleObjArr[i].formId, quoteModuleObjArr[i].className, formBuilder, quoteModuleObjArr[i].moveType);
//return formBuilder;
}
}
Just for testing purposes the OP's above posted code was taken as is ... results/conclusion ...
FormBuilderDatePicker exists as constructor function.
registerSelectors exists as prototypal method.
There was another error within the code of the prototypal delegateEvents methods though ... this.options.$datepicker.datepicker ... of cause is not provided with the current environment (settings).
The OP's script got sanitized and (re)formatted into the next provided example code in order to provide proof that the OP's code actually does work. Thus there must be some other reasons for the OP's script failures.
const dp = new FormBuilderDatePicker;
console.log({ registerSelectors: dp.registerSelectors });
console.log({ dp });
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var FormBuilderDatePicker = (function () {
function FormBuilderDatePicker(options) {
this.options = options;
this.options = $.extend(true, {}, this.defaults, this.options);
this.registerSelectors();
this.delegateEvents();
};
FormBuilderDatePicker.prototype.defaults = {
datepicker: ".hasDatePicker",
disabledDays: [],
datepickerOptions: {
minDate: 0,
maxDate: "+12M",
},
formId: '',
};
FormBuilderDatePicker.prototype.registerSelectors = function () {
this.options.$datepicker = $(this.options.datepicker);
};
FormBuilderDatePicker.prototype.delegateEvents = function () {
var _self = this;
this.options.$datepicker.on("error", function () {
var selectedDate = _self.options.$datepicker.val();
_self.options.disabledDays.push(selectedDate);
});
this.options.$datepicker.on("change", function () {
$(this).valid();
});
this.options.datepickerOptions.beforeShowDay = function (date) {
var today = new Date;
var todayDate = $.datepicker.formatDate("mm/dd/yy", today);
var selectedDate = $.datepicker.formatDate("mm/dd/yy", date);
var notToday = todayDate != selectedDate;
var isDisabledDay = $.inArray($.datepicker.formatDate("m/d/yy", date), _self.options.disabledDays) == -1;
var result = notToday && isDisabledDay;
if (notToday == false) {
setTimeout(function () {
$(".ui-datepicker-today").removeClass("ui-state-disabled");
}, 0);
return [result, "ui-datepicker-current-day"];
}
return [result];
};
this.options.datepickerOptions.onChangeMonthYear = function (year, month, datepicker) {
};
// this.options.$datepicker.datepicker(this.options.datepickerOptions);
};
return FormBuilderDatePicker;
}());
</script>
I have function that works with datepickers
Here it is
$(".multi_datepicker").each((key, elem) => {
$(elem)
.datepicker({
language: gon.locale,
minDate: new Date($(elem).attr("data-mindate")),
maxDate: new Date($(elem).attr("data-maxdate")),
autoClose: true,
onShow: (inst, animationCompleted) => {
if (animationCompleted) return true;
var id = Number(inst.$el.attr("id").split("_")[2]);
if (id < 0) return true;
var previous = $(`#search_legs_${id - 1}_date`);
if (previous.length == 0) return true;
var date = previous.datepicker().data("datepicker")
.selectedDates[0];
if (inst.selectedDates[0] < date) inst.selectedDates = [date];
inst.update("minDate", date);
},
onSelect: (dateText, inst) => {
var no_count = Number($("#search_no_legs").val());
var p = $("#search_legs_0_date").val();
for (let i = 1; i < no_count; i++) {
var leg_id = `#search_legs_${i}_date`;
if ($(leg_id).val() < p) $(leg_id).val(p);
p = $(leg_id).val();
}
}
})
.data("datepicker")
.selectDate(new Date($(elem).attr("data-defaultDate")));
});
}
But last row cause error
$(...).datepicker(...).data(...).selectDate is not a function
I cannot unserstood why?
How I can solve it?
Have you tried using .selectDate() after creating the date picker?
It would end up something like this:
$(elem).datepicker(..).data(..);
$(elem).selectDate(..);
I need to get visible dates from the Datepicker if mode is day.
Example:
In this case I need to get these 42 days. Also if user change month, I should refresh the Datepicker controller view and get new 42 days.
So i managed to fix this.
We need to extend uibDatepickerDirective
angular.module('ui.bootstrap.datepicker')
.config(function ($provide) {
$provide.decorator('uibDatepickerDirective', function ($delegate, $timeout) {
var directive = $delegate[0];
var link = directive.link;
angular.extend(directive.scope, {
visibleDates: '=?'
});
directive.compile = function () {
return function (scope, element, attrs, ctrls) {
link.apply(this, arguments);
var datepickerCtrl = ctrls[0];
datepickerCtrl.getVisibleDates = function () {
var year = this.activeDate.getFullYear(),
month = this.activeDate.getMonth(),
firstDayOfMonth = new Date(this.activeDate);
firstDayOfMonth.setFullYear(year, month, 1);
var difference = this.startingDay - firstDayOfMonth.getDay(),
numDisplayedFromPreviousMonth = difference > 0 ?
7 - difference : -difference,
firstDate = new Date(firstDayOfMonth);
if (numDisplayedFromPreviousMonth > 0) {
firstDate.setDate(-numDisplayedFromPreviousMonth + 1);
}
return this.getDates(firstDate, 42);;
}
var firstTime = true;
$timeout(function () {
scope.$watch("activeDt", function () {
var newValues = datepickerCtrl.getVisibleDates();
if (firstTime) {
scope.visibleDates = newValues;
firstTime = false;
return;
}
if (newValues[0].getYear() !== scope.visibleDates[0].getYear() ||
newValues[0].getMonth() !== scope.visibleDates[0].getMonth() ||
newValues[0].getDate() !== scope.visibleDates[0].getDate()) {
scope.visibleDates = newValues;
}
});
});
}
};
return $delegate;
});
});
And in directive itself we need to pass atribute visible-dates and point to the variable where we want to save these 42 days.
<span uib-datepicker visible-dates="visibleDates" datepicker- ng-model="datePicked"></span>
This way we will update visibleDates (42 of them) if we change month in datepicker, but if we change activeDate (scope.activeDt) on the same month (same visible dates), it will stay unchanged.
How can I check and see if a given date, let’s call it (dateX) is within the (Present dates) work week (Monday-Friday)
Logic:
If (dateX is within the present work week of Monday-Friday) { return true }
Else { return false }
Ie.
//Date Format is: yyyy-mm-dd
//dateX = 2016-10-11
If (2016-10-11 is within 2016-10-10 to 2016-10-14) { then return true }
Else { return false }
You can try this one
if(datebetweenCheck("10/09/2016","10/10/2016","12/09/2016"))
{
alert("Yes");
}
else
{
alert("No");
}
function datebetweenCheck(from,to,current) {
var fromDate,toDate,currentDate;
fromDate = Date.parse(from);
toDate = Date.parse(to);
currentDate = Date.parse(current);
if((currentDate <= toDate && currentDate >= fromDate)) {
return true;
}
return false;
}
I ran into a deadly chaos on datepicker issues.
Who can solve my problem I can give 100 point as a return.
When I click the calendar on 2016-08-23 it will show me the 2016-08-22 as the date value.
Furthermore, the date value in angular model is also not correct.
I want to make the output can be consistent.
To reproduce the buggy issue, change your timezone between LA and TOKYO
DEMO site: https://test.jiyubi.com/tour_package/home
controller js
app.controller('tourPackageStartDatePickerCtrl',
function ($scope) {
$scope.initStartDate = function () {
$scope.startDate = $scope.startDate || null;
};
$scope.initStartDate();
$scope.dateOptions = {
baseDate: $scope.startDate,
minDate: $scope.startDate || moment.utc().toDate(),
};
$scope.openStartDateClick = function () {
$scope.startDatePopup.opened = true;
};
});
app.controller('tourPackageEndDatePickerCtrl',
function ($scope, $rootScope) {
$scope.clear = function () {
$scope.endDate = null;
};
$scope.endDateOptions = {
dateDisabled: disabledDays,
baseDate: new Date(),
};
$scope.openEndDateClick = function () {
$scope.endDatePopup.opened = true;
};
$scope.$watch("endDate", function (new_val, old_val) {
if (new_val && moment(new_val).isValid()) {
setTravelDateRange($scope.startDate, $scope.endDate);
}
}, true)
function setTravelDateRange(startDate, endDate) {
var start_date = moment_with_TAIPEI_TZ(startDate).format("YYYY/MM/DD");
var end_date = moment_with_TAIPEI_TZ(endDate).format("YYYY/MM/DD");
moment(startDate.toDateString()).tz("Asia/Taipei").format("YYYY/MM/DD");
$scope.q_param.startDate = start_date;
$scope.q_param.date_range = start_date + "-" + end_date;
}
});
helper.js
function moment_with_TAIPEI_TZ(time){
return moment(time).tz("Asia/Taipei");
}
function MOMENT_WITH_LOCAL(time){
return moment(time).local();
}
function discard_timezone(value) {
return moment.utc(value).format(DEFAULT_MOMENT_TIME_FORMAT);
}
function getYYYYMMDD(value) {
return moment.utc(value).format("YYYY/MM/DD");
}
function date_without_timezone(value) {
return moment.utc(value).toDate();
}
It's may be because of a timezone issue.
Could you please try to convert to date without considering the timezone?
this.convertToDateWithoutTimezone = function(date) {
if (date.toString().match(/(\d\d\d\d)-(\d\d)-(\d\d)/)) {
var year = $filter('date')(date.slice(0, 10), 'yyyy'),
month = $filter('date')(date.slice(0, 10), 'MM'),
day = $filter('date')(date.slice(0, 10), 'dd');
return new Date(year, month - 1, day);
} else {
return new Date(date);
}
};