add date panel label format logic

This commit is contained in:
Sergio Crisostomo 2017-10-17 13:09:04 +02:00
parent 3d50db5bb2
commit b27858ddb5
4 changed files with 143 additions and 78 deletions

View file

@ -0,0 +1,25 @@
<template>
<span>
<span
v-if="datePanelLabel"
v-show="datePanelLabel.labels[0].type === 'year' || currentView === 'date'"
:class="[datePrefixCls + '-header-label']"
@click="datePanelLabel.labels[0].handler">{{ datePanelLabel.labels[0].label }}</span>
<template v-if="datePanelLabel && currentView === 'date'">{{ datePanelLabel.separator }}</template>
<span
v-if="datePanelLabel"
v-show="datePanelLabel.labels[1].type === 'year' || currentView === 'date'"
:class="[datePrefixCls + '-header-label']"
@click="datePanelLabel.labels[1].handler">{{ datePanelLabel.labels[1].label }}</span>
</span>
</template>
<script>
export default {
props: {
datePanelLabel: Object,
currentView: String,
datePrefixCls: String
}
};
</script>

View file

@ -16,13 +16,10 @@
:class="iconBtnCls('prev')"
@click="prevMonth"
v-show="leftCurrentView === 'date'"><Icon type="ios-arrow-left"></Icon></span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showYearPicker('left')">{{ leftYearLabel }}</span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showMonthPicker('left')"
v-show="leftCurrentView === 'date'">{{ leftMonthLabel }}</span>
<date-panel-label
:date-panel-label="leftDatePanelLabel"
:current-view="leftCurrentView"
:date-prefix-cls="datePrefixCls"/>
<span
:class="iconBtnCls('next', '-double')"
@click="nextYear('left')"
@ -66,13 +63,10 @@
:class="iconBtnCls('prev', '-double')"
@click="prevYear('right')"
v-show="rightCurrentView === 'year' || rightCurrentView === 'month'"><Icon type="ios-arrow-left"></Icon></span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showYearPicker('right')">{{ rightYearLabel }}</span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showMonthPicker('right')"
v-show="rightCurrentView === 'date'">{{ rightMonthLabel }}</span>
<date-panel-label
:date-panel-label="rightDatePanelLabel"
:current-view="rightCurrentView"
:date-prefix-cls="datePrefixCls"/>
<span
:class="iconBtnCls('next', '-double')"
@click="nextYear('right')"><Icon type="ios-arrow-right"></Icon></span>
@ -138,7 +132,8 @@
import MonthTable from '../base/month-table.vue';
import TimePicker from './time-range.vue';
import Confirm from '../base/confirm.vue';
import { toDate, prevMonth, nextMonth, initTimeDate } from '../util';
import { toDate, prevMonth, nextMonth, initTimeDate, formatDateLabels } from '../util';
import datePanelLabel from './date-panel-label.vue';
import Mixin from './mixin';
import Locale from '../../../mixins/locale';
@ -149,7 +144,7 @@
export default {
name: 'DatePicker',
mixins: [ Mixin, Locale ],
components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm },
components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm, datePanelLabel },
data () {
return {
prefixCls: prefixCls,
@ -195,26 +190,9 @@
return this.date;
}
},
leftYearLabel () {
const tYear = this.t('i.datepicker.year');
if (this.leftCurrentView === 'year') {
const year = this.leftTableYear;
if (!year) return '';
const startYear = Math.floor(year / 10) * 10;
return `${startYear}${tYear} - ${startYear + 9}${tYear}`;
} else {
const year = this.leftCurrentView === 'month' ? this.leftTableYear : this.leftYear;
if (!year) return '';
return `${year}${tYear}`;
}
},
leftMonth () {
return this.date.getMonth();
},
leftMonthLabel () {
const month = this.leftMonth + 1;
return this.t(`i.datepicker.month${month}`);
},
rightYear () {
return this.rightDate.getFullYear();
},
@ -225,26 +203,9 @@
return this.date;
}
},
rightYearLabel () {
const tYear = this.t('i.datepicker.year');
if (this.rightCurrentView === 'year') {
const year = this.rightTableYear;
if (!year) return '';
const startYear = Math.floor(year / 10) * 10;
return `${startYear}${tYear} - ${startYear + 9}${tYear}`;
} else {
const year = this.rightCurrentView === 'month' ? this.rightTableYear : this.rightYear;
if (!year) return '';
return `${year}${tYear}`;
}
},
rightMonth () {
return this.rightDate.getMonth();
},
rightMonthLabel () {
const month = this.rightMonth + 1;
return this.t(`i.datepicker.month${month}`);
},
rightDate () {
const newDate = new Date(this.date);
const month = newDate.getMonth();
@ -258,6 +219,14 @@
}
return newDate;
},
leftDatePanelLabel () {
if (!this.leftYear) return null; // not ready yet
return this.panelLabelConfig('left');
},
rightDatePanelLabel () {
if (!this.leftYear) return null; // not ready yet
return this.panelLabelConfig('right');
},
timeDisabled () {
return !(this.minDate && this.maxDate);
}
@ -288,6 +257,22 @@
}
},
methods: {
panelLabelConfig (direction) {
const locale = this.t('i.locale');
const datePanelLabel = this.t('i.datepicker.datePanelLabel');
const handler = type => {
const fn = type == 'month' ? this.showMonthPicker : this.showYearPicker;
return () => fn(direction);
};
const date = new Date(this[`${direction}Year`], this[`${direction}Month`]);
const { labels, separator } = formatDateLabels(locale, datePanelLabel, date);
return {
separator: separator,
labels: labels.map(obj => ((obj.handler = handler(obj.type)), obj))
};
},
resetDate () {
this.date = new Date(this.date);
this.leftTableYear = this.date.getFullYear();

View file

@ -15,13 +15,10 @@
:class="iconBtnCls('prev')"
@click="changeMonth(-1)"
v-show="currentView === 'date'"><Icon type="ios-arrow-left"></Icon></span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showYearPicker">{{ yearLabel }}</span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showMonthPicker"
v-show="currentView === 'date'">{{ monthLabel }}</span>
<date-panel-label
:date-panel-label="datePanelLabel"
:current-view="currentView"
:date-prefix-cls="datePrefixCls"/>
<span
:class="iconBtnCls('next', '-double')"
@click="changeYear(+1)"><Icon type="ios-arrow-right"></Icon></span>
@ -83,11 +80,12 @@
import MonthTable from '../base/month-table.vue';
import TimePicker from './time.vue';
import Confirm from '../base/confirm.vue';
import datePanelLabel from './date-panel-label.vue';
import Mixin from './mixin';
import Locale from '../../../mixins/locale';
import { initTimeDate, siblingMonth } from '../util';
import { initTimeDate, siblingMonth, formatDateLabels } from '../util';
const prefixCls = 'ivu-picker-panel';
const datePrefixCls = 'ivu-date-picker';
@ -95,7 +93,7 @@
export default {
name: 'DatePicker',
mixins: [ Mixin, Locale ],
components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm },
components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm, datePanelLabel },
data () {
return {
prefixCls: prefixCls,
@ -123,19 +121,21 @@
}
];
},
yearLabel () {
const tYear = this.t('i.datepicker.year');
const year = this.year;
if (!year) return '';
if (this.currentView === 'year') {
const startYear = Math.floor(year / 10) * 10;
return `${startYear}${tYear} - ${startYear + 9}${tYear}`;
}
return `${year}${tYear}`;
},
monthLabel () {
const month = this.month + 1;
return this.t(`i.datepicker.month${month}`);
datePanelLabel () {
if (!this.year) return null; // not ready yet
const locale = this.t('i.locale');
const datePanelLabel = this.t('i.datepicker.datePanelLabel');
const date = new Date(this.year, this.month);
const { labels, separator } = formatDateLabels(locale, datePanelLabel, date);
const handler = type => {
return () => (this.currentView = type);
};
return {
separator: separator,
labels: labels.map(obj => ((obj.handler = handler(obj.type)), obj))
};
}
},
watch: {
@ -196,12 +196,6 @@
this.date = siblingMonth(this.date, dir);
this.setMonthYear(this.date);
},
showYearPicker () {
this.currentView = 'year';
},
showMonthPicker () {
this.currentView = 'month';
},
handleToggleTime () {
if (this.currentView === 'date') {
this.currentView = 'time';

View file

@ -61,3 +61,64 @@ export const initTimeDate = function() {
date.setSeconds(0);
return date;
};
export const formatDateLabels = (function() {
/*
Formats:
yyyy - 4 digit year
m - month, numeric, 1 - 12
m - month, numeric, 01 - 12
mmm - month, 3 letters, as in `toLocaleDateString`
Mmm - month, 3 letters, capitalize the return from `toLocaleDateString`
mmmm - month, full name, as in `toLocaleDateString`
Mmmm - month, full name, capitalize the return from `toLocaleDateString`
*/
const formats = {
yyyy: date => date.getFullYear(),
m: date => date.getMonth(),
mm: date => ('0' + date.getMonth()).slice(-2),
mmm: (date, locale) => {
const monthName = date.toLocaleDateString(locale, {
month: 'long'
});
return monthName.slice(0, 3);
},
Mmm: (date, locale) => {
const monthName = date.toLocaleDateString(locale, {
month: 'long'
});
return (monthName[0].toUpperCase() + monthName.slice(1).toLowerCase()).slice(0, 3);
},
mmmm: (date, locale) =>
date.toLocaleDateString(locale, {
month: 'long'
}),
Mmmm: (date, locale) => {
const monthName = date.toLocaleDateString(locale, {
month: 'long'
});
return monthName[0].toUpperCase() + monthName.slice(1).toLowerCase();
}
};
const formatRegex = new RegExp(['yyyy', 'Mmmm', 'mmmm', 'Mmm', 'mmm', 'mm', 'm'].join('|'), 'g');
return function(locale, format, date) {
const componetsRegex = /(\[[^\]]+\])([^\[\]]+)(\[[^\]]+\])/;
const components = format.match(componetsRegex).slice(1);
const separator = components[1];
const labels = [components[0], components[2]].map(component => {
const label = component.replace(/\[[^\]]+\]/, str => {
return str.slice(1, -1).replace(formatRegex, match => formats[match](date, locale));
});
return {
label: label,
type: component.includes('yy') ? 'year' : 'month'
};
});
return {
separator: separator,
labels: labels
};
};
})();