birthdaypicker
Version:
i18n birthday picker with a variety of setting options
6 lines (5 loc) • 14.6 kB
JavaScript
/*!
* BirthdayPicker v0.2.2
* https://lemon3.github.io/birthdaypicker
*/
(function(u,c){typeof exports=="object"&&typeof module!="undefined"?module.exports=c():typeof define=="function"&&define.amd?define(c):(u=typeof globalThis!="undefined"?globalThis:u||self,u.BirthdayPicker=c())})(this,function(){"use strict";var G=Object.defineProperty;var H=Object.getOwnPropertySymbols;var J=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var Y=(u,c,d)=>c in u?G(u,c,{enumerable:!0,configurable:!0,writable:!0,value:d}):u[c]=d,y=(u,c)=>{for(var d in c||(c={}))J.call(c,d)&&Y(u,d,c[d]);if(H)for(var d of H(c))B.call(c,d)&&Y(u,d,c[d]);return u};var f=(u,c,d)=>Y(u,typeof c!="symbol"?c+"":c,d);const u={minAge:0,maxAge:100,minYear:null,maxYear:"now",lowerLimit:null,upperLimit:null,monthFormat:"short",placeholder:!0,className:null,defaultDate:null,autoInit:!0,leadingZero:!0,locale:"en",selectFuture:!1,arrange:"ymd",yearEl:null,monthEl:null,dayEl:null,roundDownDay:!0},c={en:{year:"Year",month:"Month",day:"Day"},de:{year:"Jahr",month:"Monat",day:"Tag"},fr:{year:"Année",month:"Mois",day:"Jour"}},d=(h,i,t,e)=>{if(i)for(const s in i)h.setAttribute(s,i[s]);if(t)for(const s in t)h.style[s]=t[s];return e&&(h.innerHTML=e),h},p=(h,i,t,e)=>d(document.createElement(h),i,t,e),W=(h,i,t=null)=>{if(!h)return!1;if(h.dataset[i]===void 0)return h.dataset;let e;try{h.dataset[i]!=="undefined"&&h.dataset[i].indexOf("{")>=0&&(e=JSON.parse(h.dataset[i].replace(/'/g,'"')))}catch(r){console.error(r)}if(typeof e!="object"){e=h.dataset[i];const r={};e=e.replace(/ /g,"");const a=e.split(",");a.length>1?a.forEach(l=>{const[g,z]=l.split(":");r[g.replace(/'/g,"")]=z.replace(/'/g,"")}):r[i]=e,e=r}let s={},n=i.length;return Object.entries(h.dataset).forEach(r=>{if(r[0].toLowerCase().indexOf(i)>=0&&r[0].length>n){let a=r[0][n].toLowerCase()+r[0].substring(n+1);(t===null||t&&t[a]!==void 0)&&(s[a]=r[1])}}),Object.assign(e,s)},v=h=>+h%4===0&&+h%100!==0||+h%400===0,E={_s:new WeakMap,put(h,...i){this._s.has(h)||this._s.set(h,new Map);let t=this._s.get(h);if(i.length>1)return t.set(i[0],i[1]),this;if(typeof i[0]=="object")for(const e in i[0])t.set(e,i[0][e]);else t.set(i[0]);return this},get(h,i){return this._s.has(h)?i?this._s.get(h).get(i):this._s.get(h):!1},has(h,i){return this._s.has(h)&&this._s.get(h).has(i)},remove(h,i){if(!this._s.has(h))return!1;let t=this._s.get(h).delete(i);return this._s.get(h).size===0&&this._s.delete(h),t}},M=(h,i,t)=>{if(h=parseFloat(h,10),isNaN(h))return NaN;if(i=parseFloat(i,10),t=parseFloat(t,10),t<i){let e=t;t=i,i=e}return!isNaN(i)&&h<i?i:!isNaN(t)&&h>t?t:h},D=h=>h===!0||h==="true"||h===1||h==="1",$=(h,i,t)=>{let e=h.getAttribute("on"+i);new Function("e","{"+e+"}").call(h,t)};class Z{constructor(){this._eventCallbacks=this._eventCallbacks||{}}emit(i,t){let e=this._eventCallbacks[i];const s={bubbles:!1,cancelable:!1,detail:t},n=new CustomEvent(i,s);e&&e.forEach(r=>r.call(this,n)),this.element&&(this.element.dispatchEvent(n),$(this.element,i,n))}addEventListener(i,t){return this.allowedEvents&&this.allowedEvents.indexOf(i)<0||typeof t!="function"?!1:(this._eventCallbacks[i]||(this._eventCallbacks[i]=[]),this._eventCallbacks[i].push(t),this)}removeEventListener(i,t){if(!this._eventCallbacks||arguments.length===0)return this._eventCallbacks={},this;let e=this._eventCallbacks[i];return e?arguments.length===1?(delete this._eventCallbacks[i],this):(this._eventCallbacks[i]=e.filter(s=>s!==t),this):this}}let m=[];const S="birthdaypicker",T="data-"+S,j=["short","long","numeric"],q=["ymd","ydm","myd","mdy","dmy","dym"],x="init",N="datechange",A="daychange",I="monthchange",k="yearchange",O="kill",b="option",L={y:"year",m:"month",d:"day"},F=new Date,_={y:F.getFullYear(),m:F.getMonth()+1,d:F.getDate()};let C=!1;const o=class o extends Z{constructor(t,e){if(!t)return{error:!0};if(t=typeof t=="string"?document.querySelector(t):t,t===null||t.length===0)return{error:!0};super();f(this,"_onSelect",t=>{t.target===this._year.el?this._yearWasChanged(+t.target.value):t.target===this._month.el?this._monthWasChanged(+t.target.value):t.target===this._day.el&&this._dayWasChanged(+t.target.value),this._dateChanged()});if(t.dataset.bdpInit)return o.getInstance(t);t.dataset.bdpInit=!0,this.allowedEvents=[x,N,A,I,k,O],m.push(this),E.put(t,"instance",this);const s=W(t,S,o.defaults);this.options=e||{},this.settings=Object.assign({},o.defaults,s,e),this.element=t,this.state=0,this.settings.autoInit&&this.init()}_triggerEvent(t,e){e=y({instance:this,year:+this.currentYear,month:+this.currentMonth,day:+this.currentDay,date:this.getDate()},e),this.emit(t,e)}_parseDate(t){if(t instanceof Date&&!isNaN(t))return{year:t.getFullYear(),month:t.getMonth()+1,day:t.getDate()};if(typeof t!="string"||!t.trim())return!1;const e=new Date(t.replace(/-/g,"/"));return isNaN(e)?!1:{year:e.getFullYear(),month:e.getMonth()+1,day:e.getDate()}}_getIdx(t,e){if(!(t instanceof NodeList)||e===void 0||e===null)return;const s=isNaN(e)?e:+e,n=Array.from(t).findIndex(r=>+r.value===s);return n!==-1?n:void 0}_updateSelectBox(t,e){const s=this[t].el;s.selectedIndex=this._getIdx(s.childNodes,e)}_setYear(t){return t=M(t,this._yearFrom,this._yearTo),this.currentYear===t?!1:(this._updateSelectBox("_year",t),this._yearWasChanged(t,!1),!0)}_setMonth(t){return t=M(t,1,12),this.currentMonth===t?!1:(this._updateSelectBox("_month",t),this._monthWasChanged(t,!1),!0)}_setDay(t){return t=M(t,1,this._getDaysPerMonth()),this.currentDay===t?!1:(this._updateSelectBox("_day",t),this._dayWasChanged(t,!1),!0)}_getDateInRange({year:t=this.currentYear,month:e=this.currentMonth,day:s=this.currentDay}={}){const n=this._lowerLimit,r=this._upperLimit;if(!n||!r)throw new Error("Lower and upper date limits must be defined.");const a=new Date(t,e-1,s),l=new Date(n.year,n.month-1,n.day),g=new Date(r.year,r.month-1,r.day);return a>g?r:a<l?n:{year:t,month:e,day:s}}_setDate(t,e=!1){t=this._getDateInRange(t);let s=this._setYear(t.year),n=this._setMonth(t.month),r=this._setDay(t.day);return(s||n||r)&&this._dateChanged(e),t}_getMonthText(t){return this.settings.monthFormat!=="numeric"?t:this.settings.leadingZero?String(t).padStart(2,"0"):String(t)}_checkArrangement(t){return t=t.toLowerCase(),q.includes(t)?t:"ymd"}_mapSelectBoxes(){const t=this.element.querySelectorAll("select");if(!t.length)return{};const e={},s=this.settings.arrange.split(""),n=s.map(a=>L[a]);n.forEach(a=>{const l=this.settings[`${a}El`]||`[${T}-${a}]`,g=l.nodeName?l:this.element.querySelector(l);g&&g.tagName==="SELECT"&&(e[a]=g,s.splice(s.indexOf(n.indexOf(a).toString()),1))});const r=Array.from(t).filter(a=>!Object.values(e).includes(a));return s.forEach((a,l)=>{const g=L[a];e[g]=r[l]}),e}_create(){const t=this.settings;t.arrange=this._checkArrangement(t.arrange);const e=this._mapSelectBoxes();t.arrange.split("").forEach(n=>{const r=L[n];let a=e[r];(!a||a.dataset.init)&&(a=p("select"),this.element.append(a)),a.setAttribute("aria-label",`select ${r}`),t.className&&a.classList.add(t.className,`${t.className}-${r}`),a.dataset.init=!0;const l=this._onSelect;a.addEventListener("change",l,!1),this._registeredEventListeners.push({element:a,eventName:"change",listener:l,option:!1}),this[`_${r}`]={el:a,name:r,created:!e[r],df:document.createDocumentFragment()},this._date.push(this[`_${r}`])});const s=p(b);t.placeholder&&this._date.forEach(n=>{const r=o.i18n[t.locale][n.name],a=s.cloneNode();a.innerHTML=r,n.df.appendChild(a)});for(let n=this._yearTo;n>=this._yearFrom;n--){const r=s.cloneNode();r.value=n,r.innerHTML=n,this._year.df.append(r)}this.monthFormat[t.monthFormat].forEach((n,r)=>{const a=s.cloneNode();a.value=r+1,a.innerHTML=this._getMonthText(n),this._month.df.append(a)});for(let n=1;n<=31;n++){const r=t.leadingZero&&n<10?`0${n}`:n,a=p(b,{value:n},"",r);this._day.df.append(a)}this._date.forEach(n=>n.el.append(n.df))}_updateDays(t=this.currentMonth){const e=this._getDaysPerMonth(t)||31,s=this.settings.placeholder?1:0,n=this._day.el.children.length-s;if(e===n)return;const r=e-n;if(r>0)for(let a=n+1;a<=e;a++){const l=p(b,{value:a},"",a);this._day.el.append(l)}else{for(let a=0;a<-r;a++)this._day.el.children[n+s-a-1].remove();this.currentDay>e&&(this.settings.roundDownDay?this._setDay(e):this._dayWasChanged())}}_disable(t,e,s){const n=e==="<";this[t].el.childNodes.forEach(r=>{(n&&+r.value<s||!n&&+r.value>s)&&(r.disabled=!0,this._disabled.push(r))})}_noFutureDate(t=this._lowerLimit,e=this._upperLimit){const s=()=>{this.currentYear!==e.year&&this._setYear(e.year),this._disable("_month",">",e.month);let r=this.currentMonth>e.month;r&&this._setMonth(e.month),e.month===this.currentMonth&&(this._disable("_day",">",e.day),(this.currentDay>e.day||r&&this.currentDay<e.day)&&this._setDay(e.day))},n=()=>{this.currentYear!==t.year&&this._setYear(t.year),this._disable("_month","<",t.month);let r=this.currentMonth<t.month;r&&this._setMonth(t.month),t.month===this.currentMonth&&(this._disable("_day","<",t.day),(this.currentDay<t.day||r&&this.currentDay>t.day)&&this._setDay(t.day))};return this._disabled.forEach(r=>{r.disabled=!1}),this._disabled=[],this.currentYear<e.year&&this.currentYear>t.year||!this.currentYear||!this.currentYear&&!this.currentMonth&&!this.currentDay?!1:(this.currentYear>=e.year?s():this.currentYear<=t.year&&n(),!0)}_yearWasChanged(t,e=!0){this.currentYear=t,this._daysPerMonth[1]=v(t)?29:28,e&&this._triggerEvent(k),this.currentMonth===2&&this._updateDays()}_monthWasChanged(t,e=!0){this.currentMonth=t,e&&this._triggerEvent(I),this._updateDays()}_dayWasChanged(t,e=!0){this.currentDay=t,e&&this._triggerEvent(A)}_dateChanged(t=!0){this.settings.selectFuture||this._noFutureDate(this._lowerLimit,this._upperLimit),t&&this._triggerEvent(N),this.element.value=this.getDateString()}_updateDayList(){const t=this.settings.placeholder?1:0,e=this.settings.leadingZero?"0":"";for(let s=t;s<9+t;s++)this._day.el.childNodes[s].innerHTML=e+s}_updateMonthList(){const t=this.settings.placeholder?1:0,e=this.settings.monthFormat;this.monthFormat[e].forEach((s,n)=>{this._month.el.childNodes[n+t].innerHTML=this._getMonthText(s)})}useLeadingZero(t){t=D(t),t!==this.settings.leadingZero&&(this.settings.leadingZero=t,this.settings.monthFormat==="numeric"&&this._updateMonthList(),this._updateDayList())}_getDaysPerMonth(t=this.currentMonth){return this._daysPerMonth[+t-1]}setMonthFormat(t){return!this.monthFormat[t]||t===this.settings.monthFormat?!1:(this.settings.monthFormat=t,this._updateMonthList(),!0)}setLanguage(t){if(t===this.settings.locale||(""+t).length<2||(""+t).length>2)return!1;o.createLocale(t);const e=o.i18n[t];if(this.settings.placeholder&&this._date.forEach(n=>{n.el.childNodes[0].innerHTML=e[n.name]}),this.monthFormat=e.monthFormat,this.settings.locale=t,this.settings.monthFormat==="numeric")return!1;let s=this.settings.placeholder?1:0;this.monthFormat[this.settings.monthFormat].forEach((n,r)=>{this._month.el.childNodes[s+r].innerHTML=n})}setDate(t,e=!1){let s=this._parseDate(t);return s&&(s=this._setDate(s,e)),s}resetDate(t=!1){const e=t&&this.startDate?this.startDate:{year:NaN,month:NaN,day:NaN};this._setDate(e),this.element.value=this.getDateString(),this._triggerEvent(N)}kill(){var t;(t=this._registeredEventListeners)==null||t.forEach(e=>e.element.removeEventListener(e.eventName,e.listener,e.option)),this._date.forEach(e=>{if(e.created)e.el.remove();else{const s=this.settings.className;s&&e.el.classList.remove(s,...Object.values(L).map(n=>`${s}-${n}`))}}),this._triggerEvent(O)}isLeapYear(t=this.currentYear){return t===void 0?void 0:v(t)}getAge(){if(isNaN(this.currentYear)||isNaN(this.currentMonth)||isNaN(this.currentDay))return"";const t=this.currentYear,e=this.currentMonth,s=this.currentDay,n=new Date,r=n.getMonth()+1;return n.getFullYear()-t-(r<e||r===e&&n.getDate()<s?1:0)}getDateString(t){if(!t){const r=this.getDate();return r&&r.toLocaleDateString(this.settings.locale)}if(!this.currentYear||!this.currentMonth||!this.currentDay)return"";const e=this.currentYear,s=String(this.currentMonth).padStart(2,"0"),n=String(this.currentDay).padStart(2,"0");return t.toLowerCase().replace(/yyyy/g,e).replace(/yy/g,e.toString().slice(2)).replace(/mm/g,s).replace(/m/g,this.currentMonth).replace(/dd/g,n).replace(/d/g,this.currentDay)}getDate(){return!this.currentYear||!this.currentMonth||!this.currentDay?"":new Date(Date.UTC(this.currentYear,+this.currentMonth-1,this.currentDay))}_getUpperLimit(){const t=this.settings;if(t.upperLimit)return t.upperLimit;let e;return t.maxYear==="now"?(e=_.y-+t.minAge,{year:e,month:_.m,day:_.d}):(e=t.maxYear,{year:e,month:12,day:31})}_getLowerLimit(){const t=this.settings;if(t.lowerLimit)return t.lowerLimit;let e;return t.minYear!==null?(e=+t.minYear,{year:e,month:1,day:1}):(e=(t.maxYear==="now"?_.y:t.maxYear)-+t.maxAge,{year:e,month:_.m,day:_.d})}init(){if(this.initialized)return!0;this.initialized=!0,this._registeredEventListeners=[],this._daysPerMonth=[31,28,31,30,31,30,31,31,30,31,30,31],this._date=[],this._disabled=[];const t=this.settings;t.placeholder=D(t.placeholder),t.leadingZero=D(t.leadingZero),t.selectFuture=D(t.selectFuture),this._lowerLimit=this._getLowerLimit(),this._upperLimit=this._getUpperLimit(),this._yearFrom=this._lowerLimit.year,this._yearTo=this._upperLimit.year;const[e]=o.createLocale(t.locale);if(t.locale=e,this.monthFormat=o.i18n[t.locale].monthFormat,this.allowedEvents.forEach(s=>{t[s]&&this.addEventListener(s,t[s])}),this._create(),t.defaultDate){const s=this.setDate(t.defaultDate==="now"?new Date().toString():t.defaultDate,!0);this.startDate=s}this.state=1,this._triggerEvent(x)}};f(o,"currentLocale","en"),f(o,"i18n",{}),f(o,"createLocale",(t="en")=>{if(t.length!==2&&(t="en"),o.i18n[t])return[t,o.i18n[t]];const e=new Date("2000-01-15"),s={monthFormat:{}};j.forEach(a=>{s.monthFormat[a]=[];for(let l=0;l<12;l++)e.setMonth(l),s.monthFormat[a].push(e.toLocaleDateString(t,{month:a}))});const n="BirthdayPickerLocale",r=y(y({},c[t]||c.en),window[n]&&window[n][t]);return o.i18n[t]=y(y({},s),r),[t,o.i18n[t]]}),f(o,"getInstance",t=>E.get(t,"instance")),f(o,"setMonthFormat",t=>{m.forEach(e=>{e.setMonthFormat(t)})}),f(o,"setLanguage",t=>{o.currentLocale=t,m.forEach(e=>{e.setLanguage(t)})}),f(o,"killAll",()=>m.length?(m.forEach(t=>{o.kill(t)}),m=[],!0):!1),f(o,"kill",t=>{if(!t||(t.element||(t=o.getInstance(t)),!t))return!1;t.kill();const e=t.element;return e.dataset.bdpInit=!1,delete e.dataset.bdpInit,E.remove(e,"instance"),C=!1,!0}),f(o,"defaults",u),f(o,"init",()=>{if(C)return!1;C=!0,o.createLocale(o.currentLocale);let t=document.querySelectorAll("["+T+"]");return t.length===0?!1:(t.forEach(e=>{new o(e)}),m)});let w=o;return w});