mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
fix(datetime): ionChange event
This commit is contained in:
@ -163,10 +163,7 @@ export class Datetime {
|
||||
* Any additional options that the picker interface can accept.
|
||||
* See the [Picker API docs](../../picker/Picker) for the picker options.
|
||||
*/
|
||||
@Prop() pickerOptions: PickerOptions = {
|
||||
buttons: [],
|
||||
columns: []
|
||||
};
|
||||
@Prop() pickerOptions?: PickerOptions;
|
||||
|
||||
/**
|
||||
* The text to display when there's no date selected yet.
|
||||
@ -186,6 +183,7 @@ export class Datetime {
|
||||
protected valueChanged() {
|
||||
this.updateValue();
|
||||
this.emitStyle();
|
||||
this.ionChange.emit();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,6 +191,11 @@ export class Datetime {
|
||||
*/
|
||||
@Event() ionCancel!: EventEmitter<void>;
|
||||
|
||||
/**
|
||||
* Emitted when the checked property has changed.
|
||||
*/
|
||||
@Event() ionChange!: EventEmitter<void>;
|
||||
|
||||
/**
|
||||
* Emitted when the styles change.
|
||||
*/
|
||||
@ -232,7 +235,23 @@ export class Datetime {
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
private buildPicker(pickerOptions: PickerOptions) {
|
||||
private async open() {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pickerOptions = this.generatePicketOptions();
|
||||
this.picker = await this.pickerCtrl.create(pickerOptions);
|
||||
this.validate();
|
||||
await this.picker!.present();
|
||||
}
|
||||
|
||||
private generatePicketOptions(): PickerOptions {
|
||||
const pickerOptions: PickerOptions = {
|
||||
...this.pickerOptions,
|
||||
columns: this.generateColumns()
|
||||
};
|
||||
|
||||
// If the user has not passed in picker buttons,
|
||||
// add a cancel and ok button to the picker
|
||||
const buttons = pickerOptions.buttons;
|
||||
@ -245,101 +264,77 @@ export class Datetime {
|
||||
},
|
||||
{
|
||||
text: this.doneText,
|
||||
handler: (data: any) => this.value = data,
|
||||
}];
|
||||
}
|
||||
|
||||
pickerOptions.columns = this.generateColumns();
|
||||
|
||||
const picker = this.pickerCtrl.create(pickerOptions);
|
||||
|
||||
return picker;
|
||||
}
|
||||
|
||||
private async open() {
|
||||
// TODO check this.isFocus() || this.disabled
|
||||
if (this.disabled) {
|
||||
return;
|
||||
handler: (data: any) => this.value = data
|
||||
}
|
||||
];
|
||||
}
|
||||
const pickerOptions = { ...this.pickerOptions };
|
||||
this.picker = await this.buildPicker(pickerOptions);
|
||||
this.validate();
|
||||
await this.picker!.present();
|
||||
return pickerOptions;
|
||||
}
|
||||
|
||||
private generateColumns(): PickerColumn[] {
|
||||
let columns: PickerColumn[] = [];
|
||||
|
||||
// if a picker format wasn't provided, then fallback
|
||||
// to use the display format
|
||||
let template = this.pickerFormat || this.displayFormat || DEFAULT_FORMAT;
|
||||
|
||||
if (template) {
|
||||
// make sure we've got up to date sizing information
|
||||
this.calcMinMax();
|
||||
|
||||
// does not support selecting by day name
|
||||
// automaticallly remove any day name formats
|
||||
template = template.replace('DDDD', '{~}').replace('DDD', '{~}');
|
||||
if (template.indexOf('D') === -1) {
|
||||
// there is not a day in the template
|
||||
// replace the day name with a numeric one if it exists
|
||||
template = template.replace('{~}', 'D');
|
||||
}
|
||||
// make sure no day name replacer is left in the string
|
||||
template = template.replace(/{~}/g, '');
|
||||
|
||||
// parse apart the given template into an array of "formats"
|
||||
parseTemplate(template).forEach((format: any) => {
|
||||
// loop through each format in the template
|
||||
// create a new picker column to build up with data
|
||||
const key = convertFormatToKey(format)!;
|
||||
let values: any[];
|
||||
|
||||
// check if they have exact values to use for this date part
|
||||
// otherwise use the default date part values
|
||||
values = this[key + 'Values']
|
||||
? convertToArrayOfNumbers(this[key + 'Values'], key)
|
||||
: dateValueRange(format, this.datetimeMin, this.datetimeMax);
|
||||
|
||||
const column: PickerColumn = {
|
||||
name: key,
|
||||
selectedIndex: 0,
|
||||
options: values.map(val => {
|
||||
return {
|
||||
value: val,
|
||||
text: renderTextFormat(format, val, null, this.locale),
|
||||
};
|
||||
})
|
||||
if (!template) {
|
||||
return [];
|
||||
}
|
||||
// make sure we've got up to date sizing information
|
||||
this.calcMinMax();
|
||||
|
||||
// does not support selecting by day name
|
||||
// automaticallly remove any day name formats
|
||||
template = template.replace('DDDD', '{~}').replace('DDD', '{~}');
|
||||
if (template.indexOf('D') === -1) {
|
||||
// there is not a day in the template
|
||||
// replace the day name with a numeric one if it exists
|
||||
template = template.replace('{~}', 'D');
|
||||
}
|
||||
// make sure no day name replacer is left in the string
|
||||
template = template.replace(/{~}/g, '');
|
||||
|
||||
// parse apart the given template into an array of "formats"
|
||||
const columns = parseTemplate(template).map((format: any) => {
|
||||
// loop through each format in the template
|
||||
// create a new picker column to build up with data
|
||||
const key = convertFormatToKey(format)!;
|
||||
let values: any[];
|
||||
|
||||
// check if they have exact values to use for this date part
|
||||
// otherwise use the default date part values
|
||||
values = this[key + 'Values']
|
||||
? convertToArrayOfNumbers(this[key + 'Values'], key)
|
||||
: dateValueRange(format, this.datetimeMin, this.datetimeMax);
|
||||
|
||||
const colOptions = values.map(val => {
|
||||
return {
|
||||
value: val,
|
||||
text: renderTextFormat(format, val, null, this.locale),
|
||||
};
|
||||
});
|
||||
|
||||
// cool, we've loaded up the columns with options
|
||||
// preselect the option for this column
|
||||
const optValue = getValueFromFormat(this.datetimeValue, format);
|
||||
const selectedIndex = column.options.findIndex(opt => opt.value === optValue);
|
||||
if (selectedIndex >= 0) {
|
||||
// set the select index for this column's options
|
||||
column.selectedIndex = selectedIndex;
|
||||
}
|
||||
// cool, we've loaded up the columns with options
|
||||
// preselect the option for this column
|
||||
const optValue = getValueFromFormat(this.datetimeValue, format);
|
||||
const selectedIndex = colOptions.findIndex(opt => opt.value === optValue);
|
||||
|
||||
// add our newly created column to the picker
|
||||
columns.push(column);
|
||||
});
|
||||
return {
|
||||
name: key,
|
||||
selectedIndex: selectedIndex >= 0 ? selectedIndex : 0,
|
||||
options: colOptions
|
||||
};
|
||||
});
|
||||
|
||||
// Normalize min/max
|
||||
const min = this.datetimeMin;
|
||||
const max = this.datetimeMax;
|
||||
['month', 'day', 'hour', 'minute']
|
||||
.filter(name => !columns.find(column => column.name === name))
|
||||
.forEach(name => {
|
||||
min[name] = 0;
|
||||
max[name] = 0;
|
||||
});
|
||||
|
||||
columns = this.divyColumns(columns);
|
||||
}
|
||||
// Normalize min/max
|
||||
const min = this.datetimeMin;
|
||||
const max = this.datetimeMax;
|
||||
['month', 'day', 'hour', 'minute']
|
||||
.filter(name => !columns.find(column => column.name === name))
|
||||
.forEach(name => {
|
||||
min[name] = 0;
|
||||
max[name] = 0;
|
||||
});
|
||||
|
||||
return columns;
|
||||
return divyColumns(columns);
|
||||
}
|
||||
|
||||
private validate() {
|
||||
@ -484,42 +479,6 @@ export class Datetime {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private divyColumns(columns: PickerColumn[]): PickerColumn[] {
|
||||
const pickerColumns = columns;
|
||||
const columnsWidth: number[] = [];
|
||||
let col: PickerColumn;
|
||||
let width: number;
|
||||
for (let i = 0; i < pickerColumns.length; i++) {
|
||||
col = pickerColumns[i];
|
||||
columnsWidth.push(0);
|
||||
|
||||
for (const option of col.options) {
|
||||
width = option.text!.length;
|
||||
if (width > columnsWidth[i]) {
|
||||
columnsWidth[i] = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (columnsWidth.length === 2) {
|
||||
width = Math.max(columnsWidth[0], columnsWidth[1]);
|
||||
pickerColumns[0].align = 'right';
|
||||
pickerColumns[1].align = 'left';
|
||||
pickerColumns[0].optionsWidth = pickerColumns[1].optionsWidth = `${width * 17}px`;
|
||||
|
||||
} else if (columnsWidth.length === 3) {
|
||||
width = Math.max(columnsWidth[0], columnsWidth[2]);
|
||||
pickerColumns[0].align = 'right';
|
||||
pickerColumns[1].columnWidth = `${columnsWidth[1] * 17}px`;
|
||||
pickerColumns[0].optionsWidth = pickerColumns[2].optionsWidth = `${width * 17}px`;
|
||||
pickerColumns[2].align = 'left';
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private updateText() {
|
||||
// create the text of the formatted data
|
||||
const template = this.displayFormat || this.pickerFormat || DEFAULT_FORMAT;
|
||||
@ -527,8 +486,6 @@ export class Datetime {
|
||||
this.text = renderDatetime(template, this.datetimeValue, this.locale);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
hasValue(): boolean {
|
||||
const val = this.datetimeValue;
|
||||
return val
|
||||
@ -580,6 +537,38 @@ export class Datetime {
|
||||
}
|
||||
}
|
||||
|
||||
function divyColumns(columns: PickerColumn[]): PickerColumn[] {
|
||||
const columnsWidth: number[] = [];
|
||||
let col: PickerColumn;
|
||||
let width: number;
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
col = columns[i];
|
||||
columnsWidth.push(0);
|
||||
|
||||
for (const option of col.options) {
|
||||
width = option.text!.length;
|
||||
if (width > columnsWidth[i]) {
|
||||
columnsWidth[i] = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (columnsWidth.length === 2) {
|
||||
width = Math.max(columnsWidth[0], columnsWidth[1]);
|
||||
columns[0].align = 'right';
|
||||
columns[1].align = 'left';
|
||||
columns[0].optionsWidth = columns[1].optionsWidth = `${width * 17}px`;
|
||||
|
||||
} else if (columnsWidth.length === 3) {
|
||||
width = Math.max(columnsWidth[0], columnsWidth[2]);
|
||||
columns[0].align = 'right';
|
||||
columns[1].columnWidth = `${columnsWidth[1] * 17}px`;
|
||||
columns[0].optionsWidth = columns[2].optionsWidth = `${width * 17}px`;
|
||||
columns[2].align = 'left';
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
let datetimeIds = 0;
|
||||
|
||||
const DEFAULT_FORMAT = 'MMM D, YYYY';
|
||||
|
||||
Reference in New Issue
Block a user