bulma-extensions
Advanced tools
Comparing version 1.0.28 to 1.0.29
@@ -7,3 +7,277 @@ (function (global, factory) { | ||
var datepicker_langs = { | ||
class EventEmitter { | ||
constructor(listeners = []) { | ||
this._listeners = new Map(listeners); | ||
this._middlewares = new Map(); | ||
} | ||
listenerCount(eventName) { | ||
if (!this._listeners.has(eventName)) { | ||
return 0; | ||
} | ||
const eventListeners = this._listeners.get(eventName); | ||
return eventListeners.length; | ||
} | ||
removeListeners(eventName = null, middleware = false) { | ||
if (eventName !== null) { | ||
if (Array.isArray(eventName)) { | ||
name.forEach(e => this.removeListeners(e, middleware)); | ||
} else { | ||
this._listeners.delete(eventName); | ||
if (middleware) { | ||
this.removeMiddleware(eventName); | ||
} | ||
} | ||
} else { | ||
this._listeners = new Map(); | ||
} | ||
} | ||
middleware(eventName, fn) { | ||
if (Array.isArray(eventName)) { | ||
name.forEach(e => this.middleware(e, fn)); | ||
} else { | ||
if (!Array.isArray(this._middlewares.get(eventName))) { | ||
this._middlewares.set(eventName, []); | ||
} | ||
(this._middlewares.get(eventName)).push(fn); | ||
} | ||
} | ||
removeMiddleware(eventName = null) { | ||
if (eventName !== null) { | ||
if (Array.isArray(eventName)) { | ||
name.forEach(e => this.removeMiddleware(e)); | ||
} else { | ||
this._middlewares.delete(eventName); | ||
} | ||
} else { | ||
this._middlewares = new Map(); | ||
} | ||
} | ||
on(name, callback, once = false) { | ||
if (Array.isArray(name)) { | ||
name.forEach(e => this.on(e, callback)); | ||
} else { | ||
name = name.toString(); | ||
const split = name.split(/,|, | /); | ||
if (split.length > 1) { | ||
split.forEach(e => this.on(e, callback)); | ||
} else { | ||
if (!Array.isArray(this._listeners.get(name))) { | ||
this._listeners.set(name, []); | ||
} | ||
(this._listeners.get(name)).push({once: once, callback: callback}); | ||
} | ||
} | ||
} | ||
once(name, callback) { | ||
this.on(name, callback, true); | ||
} | ||
emit(name, data, silent = false) { | ||
name = name.toString(); | ||
let listeners = this._listeners.get(name); | ||
let middlewares = null; | ||
let doneCount = 0; | ||
let execute = silent; | ||
if (Array.isArray(listeners)) { | ||
listeners.forEach((listener, index) => { | ||
// Start Middleware checks unless we're doing a silent emit | ||
if (!silent) { | ||
middlewares = this._middlewares.get(name); | ||
// Check and execute Middleware | ||
if (Array.isArray(middlewares)) { | ||
middlewares.forEach(middleware => { | ||
middleware(data, (newData = null) => { | ||
if (newData !== null) { | ||
data = newData; | ||
} | ||
doneCount++; | ||
}, name); | ||
}); | ||
if (doneCount >= middlewares.length) { | ||
execute = true; | ||
} | ||
} else { | ||
execute = true; | ||
} | ||
} | ||
// If Middleware checks have been passed, execute | ||
if (execute) { | ||
if (listener.once) { | ||
listeners[index] = null; | ||
} | ||
listener.callback(data); | ||
} | ||
}); | ||
// Dirty way of removing used Events | ||
while (listeners.indexOf(null) !== -1) { | ||
listeners.splice(listeners.indexOf(null), 1); | ||
} | ||
} | ||
} | ||
} | ||
/** | ||
* Get the number of days in month | ||
* @method getDaysInMonth | ||
* @param {Integer} year Year to check if we are facing a leapyear or not | ||
* @param {Integer} month Month for which we want to know the amount of days | ||
* @return {Integer} Days amount | ||
*/ | ||
const getDaysInMonth = (year, month) => { | ||
return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; | ||
}; | ||
/** | ||
* Compare two dates | ||
* @method compareDates | ||
* @param {Date} a First date to compare | ||
* @param {Date} b Second Date to compare with | ||
* @return {Boolean} True if dates are equal then false | ||
*/ | ||
const compareDates = (a, b) => { | ||
// weak date comparison | ||
a.setHours(0, 0, 0, 0); | ||
b.setHours(0, 0, 0, 0); | ||
return a.getTime() === b.getTime(); | ||
}; | ||
/** | ||
* Check if given year is LeapYear or not | ||
* @method isLeapYear | ||
* @param {Integer} year Year to check | ||
* @return {Boolean} True if LeapYear then False | ||
*/ | ||
const isLeapYear = year => { | ||
// solution by Matti Virkkunen: http://stackoverflow.com/a/4881951 | ||
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; | ||
}; | ||
/** | ||
* Parse Date string based on the Date Format given | ||
* @method parseDate | ||
* @param {String} dateString Date string to parse | ||
* @param {[String} [format=undefined] Date Format | ||
* @return {Date} Date Object initialized with Date String based on the Date Format | ||
*/ | ||
const parseDate = (dateString, format = undefined) => { | ||
const date = new Date(); | ||
date.setHours(0, 0, 0, 0); | ||
const formatPattern = /((?:mm?)|(?:dd?)|(?:yyy?y?))[^0-9]((?:mm?)|(?:dd?)|(?:yyy?y?))[^0-9]((?:mm?)|(?:dd?)|(?:yyy?y?))/i; | ||
const datePattern = /(\d+)[^0-9](\d+)[^0-9](\d+)/i; | ||
let matchFormat = formatPattern.exec(format); | ||
if (matchFormat) { | ||
let matchDate = datePattern.exec(dateString); | ||
if (matchDate) { | ||
switch(matchFormat[1][0]) { | ||
case 'd': | ||
date.setDate(matchDate[1]); | ||
break; | ||
case 'm': | ||
date.setMonth(matchDate[1] - 1); | ||
break; | ||
case 'y': | ||
date.setFullYear(matchDate[1]); | ||
break; | ||
} | ||
switch(matchFormat[2][0]) { | ||
case 'd': | ||
date.setDate(matchDate[2]); | ||
break; | ||
case 'm': | ||
date.setMonth(matchDate[2] - 1); | ||
break; | ||
case 'y': | ||
date.setFullYear(matchDate[2]); | ||
break; | ||
} | ||
switch(matchFormat[3][0]) { | ||
case 'd': | ||
date.setDate(matchDate[3]); | ||
break; | ||
case 'm': | ||
date.setMonth(matchDate[3] - 1); | ||
break; | ||
case 'y': | ||
date.setFullYear(matchDate[3]); | ||
break; | ||
} | ||
} | ||
} | ||
return date; | ||
}; | ||
/** | ||
* Returns date according to passed format | ||
* @method getFormatedDate | ||
* @param {Date} dt Date object | ||
* @param {String} format Format string | ||
* d - day of month | ||
* dd - 2-digits day of month | ||
* D - day of week | ||
* m - month number | ||
* mm - 2-digits month number | ||
* M - short month name | ||
* MM - full month name | ||
* yy - 2-digits year number | ||
* yyyy - 4-digits year number | ||
*/ | ||
const getFormatedDate = (dt, format, lang) => { | ||
var items = { | ||
d: dt.getDate(), | ||
dd: dt.getDate(), | ||
D: dt.getDay(), | ||
m: dt.getMonth() + 1, | ||
mm: dt.getMonth() + 1, | ||
M: dt.getMonth(), | ||
MM: dt.getMonth(), | ||
yy: dt.getFullYear().toString().substr(-2), | ||
yyyy: dt.getFullYear() | ||
}; | ||
items.dd < 10 && (items.dd = '0' + items.dd); | ||
items.mm < 10 && (items.mm = '0' + items.mm); | ||
items.D = lang.weekdays[items.D ? items.D - 1 : 6]; | ||
items.M = lang.monthsShort[items.M]; | ||
items.MM = lang.months[items.MM]; | ||
return format.replace(/(?:[dmM]{1,2}|D|yyyy|yy)/g, function(m) { | ||
return typeof items[m] !== 'undefined' ? items[m] : m; | ||
}); | ||
}; | ||
const isString = unknown => (typeof unknown === 'string' || ((!!unknown && typeof unknown === 'object') && Object.prototype.toString.call(unknown) === '[object String]')); | ||
const defaultOptions = { | ||
startDate: new Date(), | ||
minDate: null, | ||
maxDate: null, | ||
disabledDates: null, | ||
dateFormat: 'yyyy-mm-dd', // the default data format `field` value | ||
lang: 'en', // internationalization | ||
overlay: false, | ||
closeOnOverlayClick: true, | ||
closeOnSelect: true | ||
}; | ||
const datepicker_langs = { | ||
ar: { | ||
@@ -84,2 +358,11 @@ weekStart: 0, | ||
}, | ||
hu: { | ||
weekStart: 1, | ||
previousMonth: 'Előző hónap', | ||
nextMonth: 'Következő hónap', | ||
months: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], | ||
monthsShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', 'Júl', 'Aug', 'Szept', 'Okt', 'Nov', 'Dec'], | ||
weekdays: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], | ||
weekdaysShort: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'], | ||
}, | ||
id: { | ||
@@ -190,10 +473,12 @@ weekStart: 1, | ||
class datePicker { | ||
class datePicker extends EventEmitter { | ||
constructor(selector, options = {}) { | ||
super(); | ||
// Determine click event depending on if we are on Touch device or not | ||
this._clickEvent = ['touchstart' , 'click']; | ||
this.element = typeof selector === 'string' ? document.querySelector(selector) : selector; | ||
this.datepicker = typeof selector === 'string' ? document.querySelector(selector) : selector; | ||
// An invalid selector or non-DOM node has been provided. | ||
if (!this.element) { | ||
if (!this.datepicker) { | ||
throw new Error('An invalid selector or non-DOM node has been provided.'); | ||
@@ -203,17 +488,3 @@ } | ||
/// Set default options and merge with instance defined | ||
this.options = Object.assign({}, { | ||
startDate: new Date(), | ||
minDate: null, | ||
maxDate: null, | ||
dateFormat: 'yyyy-mm-dd', // the default data format `field` value | ||
lang: 'en', // internationalization | ||
overlay: false, | ||
closeOnOverlayClick: true, | ||
closeOnSelect: true, | ||
// callback functions | ||
onSelect: null, | ||
onOpen: null, | ||
onClose: null, | ||
onRender: null | ||
}, options); | ||
this.options = Object.assign({}, defaultOptions, options); | ||
@@ -225,2 +496,82 @@ // Initiate plugin | ||
/** | ||
* Initiate all DOM element containing datePicker class | ||
* @method | ||
* @return {Array} Array of all datePicker instances | ||
*/ | ||
static attach(selector = 'input[type="date"]', options = {}) { | ||
let datepickerInstances = new Array(); | ||
const datepickers = document.querySelectorAll(selector); | ||
[].forEach.call(datepickers, datepicker => { | ||
setTimeout(() => { | ||
datepickerInstances.push(new datePicker(datepicker, options)); | ||
}, 100); | ||
}); | ||
return datepickerInstances; | ||
} | ||
get id() { | ||
return this._id; | ||
} | ||
get lang() { | ||
return this.options.lang; | ||
} | ||
set lang(lang = 'en') { | ||
this._lang = typeof datepicker_langs[lang] !== 'undefined' ? lang : 'en'; | ||
} | ||
get date() { | ||
return this._date; | ||
} | ||
set date(date = new Date()) { | ||
if (isString(date)) { | ||
this.options.startDate = parseDate(date, this.dateFormat); | ||
} else { | ||
this.options.startDate = parseDate(getFormatedDate(date, this.dateFormat, datepicker_langs[this.options.lang])); | ||
this._date = { | ||
month: this.options.startDate.getMonth(), | ||
year: this.options.startDate.getFullYear(), | ||
day: this.options.startDate.getDate() | ||
}; | ||
} | ||
} | ||
get minDate() { | ||
return this.options.minDate; | ||
} | ||
set minDate(minDate = '1970-01-01') { | ||
if (isString(minDate)) { | ||
this.options.minDate = parseDate(minDate, this.dateFormat); | ||
} else { | ||
this.options.minDate = parseDate(getFormatedDate(minDate, this.dateFormat, datepicker_langs[this.options.lang])); | ||
} | ||
} | ||
get maxDate() { | ||
return this.options.maxDate; | ||
} | ||
set maxDate(maxDate = '9999-12-31') { | ||
if (isString(maxDate)) { | ||
this.options.maxDate = parseDate(maxDate, this.dateFormat); | ||
} else { | ||
this.options.maxDate = parseDate(getFormatedDate(maxDate, this.dateFormat, datepicker_langs[this.options.lang])); | ||
} | ||
} | ||
get dateFormat() { | ||
return this.options.dateFormat; | ||
} | ||
set dateFormat(dateFormat = 'yyyy-mm-dd') { | ||
this.options.dateFormat = dateFormat; | ||
this._initDates(); | ||
return this; | ||
} | ||
/** | ||
* Initiate plugin instance | ||
@@ -232,28 +583,31 @@ * @method _init | ||
this._id = 'datePicker' + (new Date()).getTime() + Math.floor(Math.random() * Math.floor(9999)); | ||
this.lang = typeof datepicker_langs[this.lang] !== 'undefined' ? this.lang : 'en'; | ||
// Set the startDate to the input value | ||
if (this.element.value) { | ||
this.options.startDate = this._parseDate(this.element.value); | ||
} | ||
// Transform start date according to dateFormat option | ||
this.options.startDate = this._parseDate(this._getFormatedDate(this.options.startDate, this.options.dateFormat)); | ||
this.lang = this.options.lang; | ||
this._open = false; | ||
if (this.options.minDate) { | ||
this.options.minDate = this._parseDate(this._getFormatedDate(this.options.minDate, this.options.dateFormat)); | ||
} | ||
if (this.options.maxDate) { | ||
this.options.maxDate = this._parseDate(this._getFormatedDate(this.options.maxDate, this.options.dateFormat)); | ||
} | ||
this.month = this.options.startDate.getMonth(); | ||
this.year = this.options.startDate.getFullYear(); | ||
this.day = this.options.startDate.getDate(); | ||
this.open = false; | ||
this._initDates(); | ||
this._build(); | ||
this._bindEvents(); | ||
this.emit('datepicker:ready', this._date); | ||
return this; | ||
} | ||
_initDates() { | ||
// Set the startDate to the input value | ||
if (this.datepicker.value) { | ||
this.options.startDate = parseDate(this.datepicker.value); | ||
} | ||
// Transform start date according to dateFormat option | ||
this.date = this.options.startDate; | ||
this.minDate = this.options.minDate ? this.options.minDate : '1970-01-01'; | ||
this.maxDate = this.options.maxDate ? this.options.maxDate : '9999-12-31'; | ||
if (this.options.disabledDates) { | ||
for (var i=0; i < this.options.disabledDates.length; i++) { | ||
this.options.disabledDates[i] = parseDate(getFormatedDate(new Date(this.options.disabledDates[i]), this.dateFormat, datepicker_langs[this.options.lang])); | ||
} | ||
} | ||
} | ||
/** | ||
@@ -266,4 +620,4 @@ * Build datePicker HTML component and append it to the DOM | ||
// Define datePicker Template | ||
const datePicker = ` | ||
<div id='${this._id}' class="datepicker ${this.options.overlay ? 'modal' : ''}"> | ||
const datePickerFragment = document.createRange().createContextualFragment(` | ||
<div id='${this.id}' class="datepicker ${this.options.overlay ? 'modal' : ''}"> | ||
${this.options.overlay ? '<div class="modal-background"></div>' : ''} | ||
@@ -278,3 +632,3 @@ <div class="calendar"> | ||
</button> | ||
<div class="calendar-month">${datepicker_langs[this.options.lang].months[this.month]}</div> | ||
<div class="calendar-month">${datepicker_langs[this.lang].months[this.date.month]}</div> | ||
<button class="calendar-nav-next-month button is-small is-text"> | ||
@@ -286,3 +640,3 @@ <svg viewBox="0 0 50 80" xml:space="preserve"> | ||
<div class="calendar-nav-day"> | ||
<div class="calendar-day">${this.day}</div> | ||
<div class="calendar-day">${this.date.day}</div> | ||
</div> | ||
@@ -295,3 +649,3 @@ <div class="calendar-nav-year"> | ||
</button> | ||
<div class="calendar-year">${this.year}</div> | ||
<div class="calendar-year">${this.date.year}</div> | ||
<button class="calendar-nav-next-year button is-small is-text"> | ||
@@ -317,9 +671,6 @@ <svg viewBox="0 0 50 80" xml:space="preserve"> | ||
</div> | ||
`; | ||
`); | ||
// Add datepicker HTML element to Document Body | ||
document.body.insertAdjacentHTML('beforeend', datePicker); | ||
// Save pointer to each datePicker element for later use | ||
this.datePickerContainer = document.getElementById(this._id); | ||
this.datePickerContainer = datePickerFragment.querySelector('#' + this.id); | ||
this.datePickerCalendar = this.datePickerContainer.querySelector('.calendar'); | ||
@@ -340,2 +691,5 @@ if (this.options.overlay) { | ||
this.datePickerCalendarBody = this.datePickerCalendar.querySelector('.calendar-body'); | ||
// Add datepicker HTML element to Document Body | ||
document.body.appendChild(datePickerFragment); | ||
} | ||
@@ -350,10 +704,6 @@ | ||
// Bind event to element in order to display/hide datePicker on click | ||
this.element.addEventsListener(this._clickEvent, (e) => { | ||
this.datepicker.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
if (this.open) { | ||
this.hide(); | ||
} else { | ||
this.show(); | ||
} | ||
this._open ? this.hide() : this.show(); | ||
}); | ||
@@ -364,3 +714,3 @@ | ||
if (this.datePickerCloseButton) { | ||
this.datePickerCloseButton.addEventsListener(this._clickEvent, (e) => { | ||
this.datePickerCloseButton.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
@@ -371,4 +721,4 @@ this.hide(); | ||
// Bind close event on overlay based on options | ||
if (this.options.closeOnOverlayClick) { | ||
this.datePickerOverlay.addEventsListener(this._clickEvent, (e) => { | ||
if (this.options.closeOnOverlayClick && this.datePickerOverlay) { | ||
this.datePickerOverlay.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
@@ -381,20 +731,28 @@ this.hide(); | ||
// Bind year navigation events | ||
this.datePickerCalendarNavPreviousYear.addEventsListener(this._clickEvent, (e) => { | ||
e.preventDefault(); | ||
this.prevYear(); | ||
}); | ||
this.datePickerCalendarNavNextYear.addEventsListener(this._clickEvent, (e) => { | ||
e.preventDefault(); | ||
this.nextYear(); | ||
}); | ||
if (this.datePickerCalendarNavPreviousYear) { | ||
this.datePickerCalendarNavPreviousYear.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
this.prevYear(); | ||
}); | ||
} | ||
if (this.datePickerCalendarNavNextYear) { | ||
this.datePickerCalendarNavNextYear.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
this.nextYear(); | ||
}); | ||
} | ||
// Bind month navigation events | ||
this.datePickerCalendarNavPreviousMonth.addEventsListener(this._clickEvent, (e) => { | ||
e.preventDefault(); | ||
this.prevMonth(); | ||
}); | ||
this.datePickerCalendarNavNextMonth.addEventsListener(this._clickEvent, (e) => { | ||
e.preventDefault(); | ||
this.nextMonth(); | ||
}); | ||
if (this.datePickerCalendarNavPreviousMonth) { | ||
this.datePickerCalendarNavPreviousMonth.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
this.prevMonth(); | ||
}); | ||
} | ||
if (this.datePickerCalendarNavNextMonth) { | ||
this.datePickerCalendarNavNextMonth.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
this.nextMonth(); | ||
}); | ||
} | ||
} | ||
@@ -409,3 +767,3 @@ | ||
[].forEach.call(this.datePickerCalendarDays, (calendarDay) => { | ||
calendarDay.addEventsListener(this._clickEvent, (e) => { | ||
calendarDay.addEventsListener(this._clickEvent, e => { | ||
e.preventDefault(); | ||
@@ -415,8 +773,11 @@ if (!e.currentTarget.classList.contains('is-disabled')) { | ||
let [year, month, day] = date; | ||
if (typeof this.options.onSelect != 'undefined' && | ||
this.options.onSelect != null && | ||
this.options.onSelect) { | ||
this.options.onSelect(new Date(year, month, day)); | ||
} | ||
this.element.value = this._getFormatedDate((new Date(year, month, day)), this.options.dateFormat); | ||
this._date = { | ||
year: year, | ||
month: month, | ||
day: day | ||
}; | ||
this.emit('datepicker:date:selected', this); | ||
this.datepicker.value = getFormatedDate((new Date(year, month, day)), this.options.dateFormat, datepicker_langs[this.options.lang]); | ||
if (this.options.closeOnSelect) { | ||
@@ -458,11 +819,6 @@ this.hide(); | ||
let numberOfDays = this._getDaysInMonth(this.year, this.month), | ||
before = new Date(this.year, this.month, 1).getDay(); | ||
let numberOfDays = getDaysInMonth(this.date.year, this.date.month), | ||
before = new Date(this.date.year, this.date.month, 1).getDay(); | ||
// Call onRender callback if defined | ||
if (typeof this.options.onRender != 'undefined' && | ||
this.options.onRender != null && | ||
this.options.onRender) { | ||
this.options.onRender(this); | ||
} | ||
this.emit('datepicker:rendered', this); | ||
@@ -485,8 +841,8 @@ // Get start day from options | ||
for (var i = 0; i < cells; i++) { | ||
var day = new Date(this.year, this.month, 1 + (i - before)), | ||
var day = new Date(this.date.year, this.date.month, 1 + (i - before)), | ||
isBetween = false, | ||
isSelected = this._compareDates(day, this.options.startDate), | ||
isSelected = compareDates(day, this.options.startDate), | ||
isSelectedIn = false, | ||
isSelectedOut = false, | ||
isToday = this._compareDates(day, now), | ||
isToday = compareDates(day, now), | ||
isEmpty = i < before || i >= (numberOfDays + before), | ||
@@ -502,8 +858,15 @@ isDisabled = false; | ||
if (day.getMonth() !== this.month || (this.options.minDate && | ||
day.getTime() < this.options.minDate.getTime()) || (this.options.maxDate && day.getTime() > this.options.maxDate.getTime())) { | ||
if (day.getMonth() !== this.date.month || (this.minDate && day.getTime() < this.minDate.getTime()) || (this.maxDate && day.getTime() > this.maxDate.getTime())) { | ||
isDisabled = true; | ||
} | ||
days += this._renderDay(day.getDate(), this.month, this.year, isSelected, isToday, isDisabled, isEmpty, isBetween, isSelectedIn, isSelectedOut); | ||
if (this.options.disabledDates) { | ||
for (var j=0; j < this.options.disabledDates.length; j++) { | ||
if (day.getTime() == this.options.disabledDates[j].getTime()) { | ||
isDisabled = true; | ||
} | ||
} | ||
} | ||
days += this._renderDay(day.getDate(), this.date.month, this.date.year, isSelected, isToday, isDisabled, isEmpty, isBetween, isSelectedIn, isSelectedOut); | ||
} | ||
@@ -522,3 +885,3 @@ | ||
prevMonth() { | ||
this.month -= 1; | ||
this.date.month -= 1; | ||
this._refreshCalendar(); | ||
@@ -541,3 +904,3 @@ } | ||
nextMonth() { | ||
this.month += 1; | ||
this.date.month += 1; | ||
this._refreshCalendar(); | ||
@@ -560,3 +923,3 @@ } | ||
prevYear() { | ||
this.year -= 1; | ||
this.date.year -= 1; | ||
this._refreshCalendar(); | ||
@@ -579,3 +942,3 @@ } | ||
nextYear() { | ||
this.year += 1; | ||
this.date.year += 1; | ||
this._refreshCalendar(); | ||
@@ -599,15 +962,11 @@ } | ||
// Set the startDate to the input value | ||
if (this.element.value) { | ||
this.options.startDate = this._parseDate(this.element.value); | ||
if (this.datepicker.value) { | ||
this.options.startDate = parseDate(this.datepicker.value); | ||
} | ||
this.month = this.options.startDate.getMonth(); | ||
this.year = this.options.startDate.getFullYear(); | ||
this.day = this.options.startDate.getDate(); | ||
this.date.month = this.options.startDate.getMonth(); | ||
this.date.year = this.options.startDate.getFullYear(); | ||
this.date.day = this.options.startDate.getDate(); | ||
this._refreshCalendar(); | ||
if (typeof this.options.onOpen != 'undefined' && | ||
this.options.onOpen != null && | ||
this.options.onOpen) { | ||
this.options.onOpen(this); | ||
} | ||
this.emit('datepicker:show', this); | ||
@@ -618,3 +977,3 @@ this.datePickerContainer.classList.add('is-active'); | ||
} | ||
this.open = true; | ||
this._open = true; | ||
} | ||
@@ -628,8 +987,4 @@ | ||
hide() { | ||
this.open = false; | ||
if (typeof this.options.onClose != 'undefined' && | ||
this.options.onClose != null && | ||
this.options.onClose) { | ||
this.options.onClose(this); | ||
} | ||
this._open = false; | ||
this.emit('datepicker:hide', this); | ||
this.datePickerContainer.classList.remove('is-active'); | ||
@@ -644,13 +999,13 @@ } | ||
_refreshCalendar() { | ||
if (this.month < 0) { | ||
this.year -= Math.ceil(Math.abs(this.month) / 12); | ||
this.month += 12; | ||
if (this.date.month < 0) { | ||
this.date.year -= Math.ceil(Math.abs(this.date.month) / 12); | ||
this.date.month += 12; | ||
} | ||
if (this.month > 11) { | ||
this.year += Math.floor(Math.abs(this.month) / 12); | ||
this.month -= 12; | ||
if (this.date.month > 11) { | ||
this.date.year += Math.floor(Math.abs(this.date.month) / 12); | ||
this.date.month -= 12; | ||
} | ||
this.datePickerCalendarNavMonth.innerHTML = datepicker_langs[this.options.lang].months[this.month]; | ||
this.datePickerCalendarNavYear.innerHTML = this.year; | ||
this.datePickerCalendarNavDay.innerHTML = this.day; | ||
this.datePickerCalendarNavMonth.innerHTML = datepicker_langs[this.options.lang].months[this.date.month]; | ||
this.datePickerCalendarNavYear.innerHTML = this.date.year; | ||
this.datePickerCalendarNavDay.innerHTML = this.date.day; | ||
this.datePickerCalendarBody.innerHTML = ''; | ||
@@ -672,3 +1027,3 @@ | ||
if (this.year <= minYear) { | ||
if (this.date.year <= minYear) { | ||
this._disablePrevYear(); | ||
@@ -679,3 +1034,3 @@ } else { | ||
if (this.year >= maxYear) { | ||
if (this.date.year >= maxYear) { | ||
this._disableNextYear(); | ||
@@ -686,3 +1041,3 @@ } else { | ||
if (this.year <= minYear && this.month <= minMonth) { | ||
if (this.date.year <= minYear && this.date.month <= minMonth) { | ||
this._disablePrevMonth(); | ||
@@ -693,3 +1048,3 @@ } else { | ||
if (this.year >= maxYear && this.month >= maxMonth) { | ||
if (this.date.year >= maxYear && this.date.month >= maxMonth) { | ||
this._disableNextMonth(); | ||
@@ -710,19 +1065,19 @@ } else { | ||
_adjustPosition() { | ||
var width = this.datePickerCalendar.offsetWidth, | ||
height = this.datePickerCalendar.offsetHeight, | ||
viewportWidth = window.innerWidth || document.documentElement.clientWidth, | ||
viewportHeight = window.innerHeight || document.documentElement.clientHeight, | ||
scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop, | ||
left, top, clientRect; | ||
//var width = this.datePickerCalendar.offsetWidth, | ||
// height = this.datePickerCalendar.offsetHeight, | ||
// viewportWidth = window.innerWidth || document.documentElement.clientWidth, | ||
// viewportHeight = window.innerHeight || document.documentElement.clientHeight, | ||
// scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop, | ||
let left, top, clientRect; | ||
if (typeof this.element.getBoundingClientRect === 'function') { | ||
clientRect = this.element.getBoundingClientRect(); | ||
if (typeof this.datepicker.getBoundingClientRect === 'function') { | ||
clientRect = this.datepicker.getBoundingClientRect(); | ||
left = clientRect.left + window.pageXOffset; | ||
top = clientRect.bottom + window.pageYOffset; | ||
} else { | ||
left = this.element.offsetLeft; | ||
top = this.element.offsetTop + this.element.offsetHeight; | ||
while ((this.element = this.element.offsetParent)) { | ||
left += this.element.offsetLeft; | ||
top += this.element.offsetTop; | ||
left = this.datepicker.offsetLeft; | ||
top = this.datepicker.offsetTop + this.datepicker.offsetHeight; | ||
while ((this.datepicker = this.datepicker.offsetParent)) { | ||
left += this.datepicker.offsetLeft; | ||
top += this.datepicker.offsetTop; | ||
} | ||
@@ -744,140 +1099,2 @@ } | ||
} | ||
/** | ||
* Returns date according to passed format | ||
* @method _getFormatedDate | ||
* @param {Date} dt Date object | ||
* @param {String} format Format string | ||
* d - day of month | ||
* dd - 2-digits day of month | ||
* D - day of week | ||
* m - month number | ||
* mm - 2-digits month number | ||
* M - short month name | ||
* MM - full month name | ||
* yy - 2-digits year number | ||
* yyyy - 4-digits year number | ||
*/ | ||
_getFormatedDate(dt, format) { | ||
var items = { | ||
d: dt.getDate(), | ||
dd: dt.getDate(), | ||
D: dt.getDay(), | ||
m: dt.getMonth() + 1, | ||
mm: dt.getMonth() + 1, | ||
M: dt.getMonth(), | ||
MM: dt.getMonth(), | ||
yy: dt.getFullYear().toString().substr(-2), | ||
yyyy: dt.getFullYear() | ||
}; | ||
items.dd < 10 && (items.dd = '0' + items.dd); | ||
items.mm < 10 && (items.mm = '0' + items.mm); | ||
items.D = datepicker_langs[this.options.lang].weekdays[items.D ? items.D - 1 : 6]; | ||
items.M = datepicker_langs[this.options.lang].monthsShort[items.M]; | ||
items.MM = datepicker_langs[this.options.lang].months[items.MM]; | ||
return format.replace(/(?:[dmM]{1,2}|D|yyyy|yy)/g, function(m) { | ||
return typeof items[m] !== 'undefined' ? items[m] : m; | ||
}); | ||
} | ||
/** | ||
* Parse Date string based on the Date Format given | ||
* @method _parseDate | ||
* @param {String} dateString Date string to parse | ||
* @param {[String} [format=undefined] Date Format | ||
* @return {Date} Date Object initialized with Date String based on the Date Format | ||
*/ | ||
_parseDate(dateString, format = undefined) { | ||
const date = new Date(); | ||
date.setHours(0, 0, 0, 0); | ||
if (!format) { | ||
format = this.options.dateFormat; | ||
} | ||
const formatPattern = /((?:mm?)|(?:dd?)|(?:yyy?y?))[^0-9]((?:mm?)|(?:dd?)|(?:yyy?y?))[^0-9]((?:mm?)|(?:dd?)|(?:yyy?y?))/i; | ||
const datePattern = /(\d+)[^0-9](\d+)[^0-9](\d+)/i; | ||
let matchFormat = formatPattern.exec(format); | ||
if (matchFormat) { | ||
let matchDate = datePattern.exec(dateString); | ||
if (matchDate) { | ||
switch(matchFormat[1][0]) { | ||
case 'd': | ||
date.setDate(matchDate[1]); | ||
break; | ||
case 'm': | ||
date.setMonth(matchDate[1] - 1); | ||
break; | ||
case 'y': | ||
date.setFullYear(matchDate[1]); | ||
break; | ||
} | ||
switch(matchFormat[2][0]) { | ||
case 'd': | ||
date.setDate(matchDate[2]); | ||
break; | ||
case 'm': | ||
date.setMonth(matchDate[2] - 1); | ||
break; | ||
case 'y': | ||
date.setFullYear(matchDate[2]); | ||
break; | ||
} | ||
switch(matchFormat[3][0]) { | ||
case 'd': | ||
date.setDate(matchDate[3]); | ||
break; | ||
case 'm': | ||
date.setMonth(matchDate[3] - 1); | ||
break; | ||
case 'y': | ||
date.setFullYear(matchDate[3]); | ||
break; | ||
} | ||
} | ||
} | ||
return date; | ||
} | ||
/** | ||
* Check if given year is LeapYear or not | ||
* @method _isLeapYear | ||
* @param {Integer} year Year to check | ||
* @return {Boolean} True if LeapYear then False | ||
*/ | ||
_isLeapYear(year) { | ||
// solution by Matti Virkkunen: http://stackoverflow.com/a/4881951 | ||
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; | ||
} | ||
/** | ||
* Get the number of days in month | ||
* @method _getDaysInMonth | ||
* @param {Integer} year Year to check if we are facing a leapyear or not | ||
* @param {Integer} month Month for which we want to know the amount of days | ||
* @return {Integer} Days amount | ||
*/ | ||
_getDaysInMonth(year, month) { | ||
return [31, this._isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; | ||
} | ||
/** | ||
* Compare two dates | ||
* @method _compareDates | ||
* @param {Date} a First date to compare | ||
* @param {Date} b Second Date to compare with | ||
* @return {Boolean} True if dates are equal then false | ||
*/ | ||
_compareDates(a, b) { | ||
// weak date comparison | ||
a.setHours(0, 0, 0, 0); | ||
b.setHours(0, 0, 0, 0); | ||
return a.getTime() === b.getTime(); | ||
} | ||
} | ||
@@ -884,0 +1101,0 @@ |
@@ -0,3 +1,13 @@ | ||
<a name="2.0.12"></a> | ||
## [2.0.12](https://github.com/Wikiki/bulma-carousel/compare/2.0.9...2.0.12) (2018-05-13) | ||
### Bug Fixes | ||
* **fade:** Blank image ([2eb732c](https://github.com/Wikiki/bulma-carousel/commit/2eb732c)) | ||
<a name="2.0.11"></a> | ||
## [2.0.11](https://github.com/Wikiki/bulma-carousel/compare/2.0.10...2.0.11) (2018-05-13) | ||
## [2.0.11](https://github.com/Wikiki/bulma-carousel/compare/2.0.9...2.0.11) (2018-05-13) | ||
@@ -15,3 +25,8 @@ | ||
### Bug Fixes | ||
* **fade:** Blank image ([2eb732c](https://github.com/Wikiki/bulma-carousel/commit/2eb732c)) | ||
<a name="2.0.9"></a> | ||
@@ -18,0 +33,0 @@ ## [2.0.9](https://github.com/Wikiki/bulma-carousel/compare/2.0.8...2.0.9) (2018-05-11) |
@@ -414,3 +414,5 @@ (function (global, factory) { | ||
if (Math.abs(this._touch.dist.x) >= this.options.threshold && Math.abs(this._touch.dist.y) <= this.options.restraint) { // 2nd condition for horizontal swipe met | ||
(this._touch.dist.x < 0) ? this._slide('next') : this._slide('previous'); // if dist traveled is negative, it indicates left swipe | ||
(this._touch.dist.x < 0) | ||
? this._slide('next') | ||
: this._slide('previous'); // if dist traveled is negative, it indicates left swipe | ||
} | ||
@@ -426,35 +428,35 @@ } | ||
*/ | ||
_slide(direction = 'next') { | ||
if (this.carouselItems.length) { | ||
this.oldItemNode = this.currentItem.node; | ||
this.emit('carousel:slide:before', this.currentItem); | ||
// initialize direction to change order | ||
if (direction === 'previous') { | ||
this.currentItem.node = this._previous(this.currentItem.node); | ||
// add reverse class | ||
if (!this.carousel.classList.contains('carousel-animate-fade')) { | ||
this.carousel.classList.add('is-reversing'); | ||
this.carouselContainer.style.transform = `translateX(${ - Math.abs(this.offset)}px)`; | ||
} | ||
} else { | ||
// Reorder items | ||
this.currentItem.node = this._next(this.currentItem.node); | ||
// re_slide reverse class | ||
this.carousel.classList.remove('is-reversing'); | ||
this.carouselContainer.style.transform = `translateX(${Math.abs(this.offset)}px)`; | ||
} | ||
this.currentItem.node.classList.add('is-active'); | ||
this.oldItemNode.classList.remove('is-active'); | ||
_slide(direction = 'next') { | ||
if (this.carouselItems.length) { | ||
this.oldItemNode = this.currentItem.node; | ||
this.emit('carousel:slide:before', this.currentItem); | ||
// initialize direction to change order | ||
if (direction === 'previous') { | ||
this.currentItem.node = this._previous(this.currentItem.node); | ||
// add reverse class | ||
if (!this.carousel.classList.contains('carousel-animate-fade')) { | ||
this.carousel.classList.add('is-reversing'); | ||
this.carouselContainer.style.transform = `translateX(${ - Math.abs(this.offset)}px)`; | ||
} | ||
} else { | ||
// Reorder items | ||
this.currentItem.node = this._next(this.currentItem.node); | ||
// re_slide reverse class | ||
this.carousel.classList.remove('is-reversing'); | ||
this.carouselContainer.style.transform = `translateX(${Math.abs(this.offset)}px)`; | ||
} | ||
this.currentItem.node.classList.add('is-active'); | ||
this.oldItemNode.classList.remove('is-active'); | ||
// Disable transition to instant change order | ||
this.carousel.classList.remove('carousel-animated'); | ||
// Enable transition to animate order 1 to order 2 | ||
setTimeout(() => { | ||
this.carousel.classList.add('carousel-animated'); | ||
}, 50); | ||
// Disable transition to instant change order | ||
this.carousel.classList.remove('carousel-animated'); | ||
// Enable transition to animate order 1 to order 2 | ||
setTimeout(() => { | ||
this.carousel.classList.add('carousel-animated'); | ||
}, 50); | ||
this._setOrder(); | ||
this.emit('carousel:slide:after', this.currentItem); | ||
} | ||
} | ||
this._setOrder(); | ||
this.emit('carousel:slide:after', this.currentItem); | ||
} | ||
} | ||
@@ -461,0 +463,0 @@ /** |
{ | ||
"name": "bulma-carousel", | ||
"version": "2.0.11", | ||
"version": "2.0.12", | ||
"description": "Display a Image / Content carousel", | ||
@@ -5,0 +5,0 @@ "main": "dist/bulma-carousel.sass", |
@@ -0,1 +1,6 @@ | ||
<a name="1.0.29"></a> | ||
## [1.0.29](https://github.com/Wikiki/bulma-extensions/compare/1.0.28...1.0.29) (2018-05-14) | ||
<a name="1.0.28"></a> | ||
@@ -2,0 +7,0 @@ ## [1.0.28](https://github.com/Wikiki/bulma-extensions/compare/1.0.27...1.0.28) (2018-05-13) |
{ | ||
"name": "bulma-extensions", | ||
"version": "1.0.28", | ||
"version": "1.0.29", | ||
"description": "Set of extensions for Bulma.io CSS Framework", | ||
@@ -5,0 +5,0 @@ "main": "dist/extensions.sass", |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
735981
2657