Commit 06b2a84839493c6d82610b8c9fcf5e88faed87d1

Authored by Aresn
Committed by GitHub
2 parents 2ffa16c4 fe5108cd

Merge pull request #1580 from SergioCrisostomo/2.0

Time-Picker new feature: allow steps in lists
src/components/date-picker/base/time-spinner.vue
1 1 <template>
2 2 <div :class="classes">
3 3 <div :class="[prefixCls+ '-list']" ref="hours">
4   - <ul :class="[prefixCls + '-ul']" @click="handleClickHours">
5   - <li :class="getCellCls(item)" v-for="(item, index) in hoursList" v-show="!item.hide" :index="index">{{ formatTime(item.text) }}</li>
  4 + <ul :class="[prefixCls + '-ul']">
  5 + <li :class="getCellCls(item)" v-for="item in hoursList" v-show="!item.hide" @click="handleClick('hours', item)">{{ formatTime(item.text) }}</li>
6 6 </ul>
7 7 </div>
8 8 <div :class="[prefixCls+ '-list']" ref="minutes">
9   - <ul :class="[prefixCls + '-ul']" @click="handleClickMinutes">
10   - <li :class="getCellCls(item)" v-for="(item, index) in minutesList" v-show="!item.hide" :index="index">{{ formatTime(item.text) }}</li>
  9 + <ul :class="[prefixCls + '-ul']">
  10 + <li :class="getCellCls(item)" v-for="item in minutesList" v-show="!item.hide" @click="handleClick('minutes', item)">{{ formatTime(item.text) }}</li>
11 11 </ul>
12 12 </div>
13 13 <div :class="[prefixCls+ '-list']" v-show="showSeconds" ref="seconds">
14   - <ul :class="[prefixCls + '-ul']" @click="handleClickSeconds">
15   - <li :class="getCellCls(item)" v-for="(item, index) in secondsList" v-show="!item.hide" :index="index">{{ formatTime(item.text) }}</li>
  14 + <ul :class="[prefixCls + '-ul']">
  15 + <li :class="getCellCls(item)" v-for="item in secondsList" v-show="!item.hide" @click="handleClick('seconds', item)">{{ formatTime(item.text) }}</li>
16 16 </ul>
17 17 </div>
18 18 </div>
... ... @@ -41,10 +41,15 @@
41 41 showSeconds: {
42 42 type: Boolean,
43 43 default: true
  44 + },
  45 + steps: {
  46 + type: Array,
  47 + default: () => []
44 48 }
45 49 },
46 50 data () {
47 51 return {
  52 + spinerSteps: [1, 1, 1].map((one, i) => Math.abs(this.steps[i]) || one),
48 53 prefixCls: prefixCls,
49 54 compiled: false
50 55 };
... ... @@ -60,6 +65,7 @@
60 65 },
61 66 hoursList () {
62 67 let hours = [];
  68 + const step = this.spinerSteps[0];
63 69 const hour_tmpl = {
64 70 text: 0,
65 71 selected: false,
... ... @@ -67,7 +73,7 @@
67 73 hide: false
68 74 };
69 75  
70   - for (let i = 0; i < 24; i++) {
  76 + for (let i = 0; i < 24; i += step) {
71 77 const hour = deepCopy(hour_tmpl);
72 78 hour.text = i;
73 79  
... ... @@ -83,6 +89,7 @@
83 89 },
84 90 minutesList () {
85 91 let minutes = [];
  92 + const step = this.spinerSteps[1];
86 93 const minute_tmpl = {
87 94 text: 0,
88 95 selected: false,
... ... @@ -90,7 +97,7 @@
90 97 hide: false
91 98 };
92 99  
93   - for (let i = 0; i < 60; i++) {
  100 + for (let i = 0; i < 60; i += step) {
94 101 const minute = deepCopy(minute_tmpl);
95 102 minute.text = i;
96 103  
... ... @@ -101,11 +108,11 @@
101 108 if (this.minutes === i) minute.selected = true;
102 109 minutes.push(minute);
103 110 }
104   -
105 111 return minutes;
106 112 },
107 113 secondsList () {
108 114 let seconds = [];
  115 + const step = this.spinerSteps[2];
109 116 const second_tmpl = {
110 117 text: 0,
111 118 selected: false,
... ... @@ -113,7 +120,7 @@
113 120 hide: false
114 121 };
115 122  
116   - for (let i = 0; i < 60; i++) {
  123 + for (let i = 0; i < 60; i += step) {
117 124 const second = deepCopy(second_tmpl);
118 125 second.text = i;
119 126  
... ... @@ -138,24 +145,11 @@
138 145 }
139 146 ];
140 147 },
141   - handleClickHours (event) {
142   - this.handleClick('hours', event);
143   - },
144   - handleClickMinutes (event) {
145   - this.handleClick('minutes', event);
146   - },
147   - handleClickSeconds (event) {
148   - this.handleClick('seconds', event);
149   - },
150   - handleClick (type, event) {
151   - const target = event.target;
152   - if (target.tagName === 'LI') {
153   - const cell = this[`${type}List`][parseInt(event.target.getAttribute('index'))];
154   - if (cell.disabled) return;
155   - const data = {};
156   - data[type] = cell.text;
157   - this.$emit('on-change', data);
158   - }
  148 + handleClick (type, cell) {
  149 + if (cell.disabled) return;
  150 + const data = {};
  151 + data[type] = cell.text;
  152 + this.$emit('on-change', data);
159 153 this.$emit('on-pick-click');
160 154 },
161 155 scroll (type, index) {
... ... @@ -183,20 +177,24 @@
183 177 },
184 178 formatTime (text) {
185 179 return text < 10 ? '0' + text : text;
  180 + },
  181 + getItemIndex(type, val){
  182 + const item = this[`${type}List`].find(obj => obj.text == val);
  183 + return this[`${type}List`].indexOf(item);
186 184 }
187 185 },
188 186 watch: {
189 187 hours (val) {
190 188 if (!this.compiled) return;
191   - this.scroll('hours', val);
  189 + this.scroll('hours', this.getItemIndex('hours', val));
192 190 },
193 191 minutes (val) {
194 192 if (!this.compiled) return;
195   - this.scroll('minutes', val);
  193 + this.scroll('minutes', this.getItemIndex('minutes', val));
196 194 },
197 195 seconds (val) {
198 196 if (!this.compiled) return;
199   - this.scroll('seconds', val);
  197 + this.scroll('seconds', this.getItemIndex('seconds', val));
200 198 }
201 199 },
202 200 mounted () {
... ... @@ -204,4 +202,4 @@
204 202 this.$nextTick(() => this.compiled = true);
205 203 }
206 204 };
207   -</script>
208 205 \ No newline at end of file
  206 +</script>
... ...
src/components/date-picker/panel/time.vue
... ... @@ -6,6 +6,7 @@
6 6 <time-spinner
7 7 ref="timeSpinner"
8 8 :show-seconds="showSeconds"
  9 + :steps="steps"
9 10 :hours="hours"
10 11 :minutes="minutes"
11 12 :seconds="seconds"
... ... @@ -39,6 +40,12 @@
39 40 name: 'TimePicker',
40 41 mixins: [ Mixin, Locale ],
41 42 components: { TimeSpinner, Confirm },
  43 + props: {
  44 + steps: {
  45 + type: Array,
  46 + default: () => []
  47 + }
  48 + },
42 49 data () {
43 50 return {
44 51 prefixCls: prefixCls,
... ... @@ -113,4 +120,4 @@
113 120 if (this.$parent && this.$parent.$options.name === 'DatePicker') this.showDate = true;
114 121 }
115 122 };
116   -</script>
117 123 \ No newline at end of file
  124 +</script>
... ...
src/components/date-picker/picker.vue
... ... @@ -32,7 +32,6 @@
32 32 </div>
33 33 </template>
34 34 <script>
35   - import Vue from 'vue';
36 35 import iInput from '../../components/input/input.vue';
37 36 import Drop from '../../components/select/dropdown.vue';
38 37 import clickoutside from '../../directives/clickoutside';
... ... @@ -397,7 +396,7 @@
397 396 let isConfirm = this.confirm;
398 397 const type = this.type;
399 398  
400   - this.picker = new Vue(this.panel).$mount(this.$refs.picker);
  399 + this.picker = this.Panel.$mount(this.$refs.picker);
401 400 if (type === 'datetime' || type === 'datetimerange') {
402 401 isConfirm = true;
403 402 this.picker.showTime = true;
... ...
src/components/date-picker/picker/date-picker.js
  1 +import Vue from 'vue';
1 2 import Picker from '../picker.vue';
2 3 import DatePanel from '../panel/date.vue';
3 4 import DateRangePanel from '../panel/date-range.vue';
... ... @@ -31,6 +32,7 @@ export default {
31 32 }
32 33 }
33 34  
34   - this.panel = getPanel(this.type);
  35 + const panel = getPanel(this.type);
  36 + this.Panel = new Vue(panel);
35 37 }
36 38 };
... ...
src/components/date-picker/picker/time-picker.js
  1 +import Vue from 'vue';
1 2 import Picker from '../picker.vue';
2 3 import TimePanel from '../panel/time.vue';
3 4 import TimeRangePanel from '../panel/time-range.vue';
... ... @@ -21,6 +22,10 @@ export default {
21 22 },
22 23 default: 'time'
23 24 },
  25 + steps: {
  26 + type: Array,
  27 + default: () => []
  28 + },
24 29 value: {}
25 30 },
26 31 created () {
... ... @@ -31,6 +36,11 @@ export default {
31 36 this.currentValue = '';
32 37 }
33 38 }
34   - this.panel = getPanel(this.type);
  39 + const Panel = Vue.extend(getPanel(this.type));
  40 + this.Panel = new Panel({
  41 + propsData: {
  42 + steps: this.steps
  43 + }
  44 + });
35 45 }
36   -};
37 46 \ No newline at end of file
  47 +};
... ...
test/unit/specs/time-spinner.spec.js 0 → 100644
  1 +import { createVue, destroyVM } from '../util';
  2 +
  3 +describe('TimePicker.vue', () => {
  4 + let vm;
  5 + afterEach(() => {
  6 + destroyVM(vm);
  7 + });
  8 +
  9 + it('should create a TimePicker component with hours, minutes and seconds', done => {
  10 + vm = createVue(`
  11 + <Time-Picker></Time-Picker>
  12 + `);
  13 + const picker = vm.$children[0];
  14 + picker.handleIconClick(); // open the picker panels
  15 +
  16 + vm.$nextTick(() => {
  17 + const spiners = picker.$el.querySelectorAll('.ivu-time-picker-cells-list');
  18 + expect(spiners.length).to.equal(3); // hh:mm:ss
  19 + expect(spiners[0].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(24);
  20 + expect(spiners[1].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(60);
  21 + expect(spiners[2].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(60);
  22 + done();
  23 + });
  24 + });
  25 +
  26 + it('should create a TimePicker component with only hours and minutes', done => {
  27 + vm = createVue(`
  28 + <Time-Picker format="HH:mm"></Time-Picker>
  29 + `);
  30 + const picker = vm.$children[0];
  31 + picker.handleIconClick(); // open the picker panels
  32 +
  33 + vm.$nextTick(() => {
  34 + const spiners = picker.$el.querySelectorAll('.ivu-time-picker-cells-list');
  35 + expect([...spiners].filter(el => el.style.display != 'none').length).to.equal(2); // hh:mm
  36 + expect(spiners[0].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(24);
  37 + expect(spiners[1].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(60);
  38 + done();
  39 + });
  40 + });
  41 +
  42 + it('should create a TimePicker component with steps of 15 minutes', done => {
  43 + vm = createVue(`
  44 + <Time-Picker :steps="[1, 15]"></Time-Picker>
  45 + `);
  46 + const picker = vm.$children[0];
  47 + picker.handleIconClick(); // open the picker panels
  48 +
  49 + vm.$nextTick(() => {
  50 + const spiners = picker.$el.querySelectorAll('.ivu-time-picker-cells-list');
  51 + const minutesList = [...spiners[1].querySelectorAll('.ivu-time-picker-cells-cell')];
  52 +
  53 + expect(spiners[0].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(24);
  54 + expect(minutesList.map(el => el.textContent).join(',')).to.equal('00,15,30,45');
  55 + expect(spiners[1].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(4);
  56 + expect(spiners[2].querySelectorAll('.ivu-time-picker-cells-cell').length).to.equal(60);
  57 + done();
  58 + });
  59 + });
  60 +});
... ...