mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-23 05:58:26 +08:00
Merge branch 'master' of github.com:driftyco/ionic
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
import { Component, Renderer, ElementRef, HostListener, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { Config } from '../../config/config';
|
||||
import { Form } from '../../util/form';
|
||||
import { focusOutActiveElement } from '../../util/dom';
|
||||
import { Key } from '../../util/key';
|
||||
import { NavParams } from '../../navigation/nav-params';
|
||||
import { ViewController } from '../../navigation/view-controller';
|
||||
@ -58,16 +58,15 @@ export class ActionSheetCmp {
|
||||
|
||||
constructor(
|
||||
private _viewCtrl: ViewController,
|
||||
private _config: Config,
|
||||
config: Config,
|
||||
private _elementRef: ElementRef,
|
||||
private _form: Form,
|
||||
gestureCtrl: GestureController,
|
||||
params: NavParams,
|
||||
renderer: Renderer
|
||||
) {
|
||||
this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
|
||||
this.d = params.data;
|
||||
this.mode = _config.get('mode');
|
||||
this.mode = config.get('mode');
|
||||
renderer.setElementClass(_elementRef.nativeElement, `action-sheet-${this.mode}`, true);
|
||||
|
||||
if (this.d.cssClass) {
|
||||
@ -123,7 +122,7 @@ export class ActionSheetCmp {
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this._form.focusOut();
|
||||
focusOutActiveElement();
|
||||
|
||||
let focusableEle = this._elementRef.nativeElement.querySelector('button');
|
||||
if (focusableEle) {
|
||||
@ -142,7 +141,7 @@ export class ActionSheetCmp {
|
||||
}
|
||||
}
|
||||
|
||||
click(button: any, dismissDelay?: number) {
|
||||
click(button: any) {
|
||||
if (! this.enabled ) {
|
||||
return;
|
||||
}
|
||||
@ -158,16 +157,14 @@ export class ActionSheetCmp {
|
||||
}
|
||||
|
||||
if (shouldDismiss) {
|
||||
setTimeout(() => {
|
||||
this.dismiss(button.role);
|
||||
}, dismissDelay || this._config.get('pageTransitionDelay'));
|
||||
this.dismiss(button.role);
|
||||
}
|
||||
}
|
||||
|
||||
bdClick() {
|
||||
if (this.enabled && this.d.enableBackdropDismiss) {
|
||||
if (this.d.cancelButton) {
|
||||
this.click(this.d.cancelButton, 1);
|
||||
this.click(this.d.cancelButton);
|
||||
|
||||
} else {
|
||||
this.dismiss('backdrop');
|
||||
|
@ -1,11 +1,14 @@
|
||||
import { Component, ElementRef, HostListener, Renderer, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { Config } from '../../config/config';
|
||||
import { focusOutActiveElement, NON_TEXT_INPUT_REGEX } from '../../util/dom';
|
||||
import { GestureController, BlockerDelegate, BLOCK_ALL } from '../../gestures/gesture-controller';
|
||||
import { isPresent, assert } from '../../util/util';
|
||||
import { Key } from '../../util/key';
|
||||
import { NavParams } from '../../navigation/nav-params';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import { ViewController } from '../../navigation/view-controller';
|
||||
import { GestureController, BlockerDelegate, BLOCK_ALL } from '../../gestures/gesture-controller';
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -91,21 +94,22 @@ export class AlertCmp {
|
||||
constructor(
|
||||
public _viewCtrl: ViewController,
|
||||
public _elementRef: ElementRef,
|
||||
public _config: Config,
|
||||
config: Config,
|
||||
gestureCtrl: GestureController,
|
||||
params: NavParams,
|
||||
renderer: Renderer
|
||||
private _renderer: Renderer,
|
||||
private _platform: Platform
|
||||
) {
|
||||
// gesture blocker is used to disable gestures dynamically
|
||||
this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
|
||||
this.d = params.data;
|
||||
this.mode = _config.get('mode');
|
||||
renderer.setElementClass(_elementRef.nativeElement, `alert-${this.mode}`, true);
|
||||
this.mode = config.get('mode');
|
||||
_renderer.setElementClass(_elementRef.nativeElement, `alert-${this.mode}`, true);
|
||||
|
||||
if (this.d.cssClass) {
|
||||
this.d.cssClass.split(' ').forEach(cssClass => {
|
||||
// Make sure the class isn't whitespace, otherwise it throws exceptions
|
||||
if (cssClass.trim() !== '') renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
|
||||
if (cssClass.trim() !== '') _renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
|
||||
});
|
||||
}
|
||||
|
||||
@ -131,7 +135,7 @@ export class AlertCmp {
|
||||
|
||||
ionViewDidLoad() {
|
||||
// normalize the data
|
||||
let data = this.d;
|
||||
const data = this.d;
|
||||
|
||||
data.buttons = data.buttons.map(button => {
|
||||
if (typeof button === 'string') {
|
||||
@ -149,7 +153,7 @@ export class AlertCmp {
|
||||
label: input.label,
|
||||
checked: !!input.checked,
|
||||
disabled: !!input.disabled,
|
||||
id: 'alert-input-' + this.id + '-' + index,
|
||||
id: `alert-input-${this.id}-${index}`,
|
||||
handler: isPresent(input.handler) ? input.handler : null,
|
||||
};
|
||||
});
|
||||
@ -157,7 +161,7 @@ export class AlertCmp {
|
||||
|
||||
// An alert can be created with several different inputs. Radios,
|
||||
// checkboxes and inputs are all accepted, but they cannot be mixed.
|
||||
let inputTypes: any[] = [];
|
||||
const inputTypes: string[] = [];
|
||||
data.inputs.forEach(input => {
|
||||
if (inputTypes.indexOf(input.type) < 0) {
|
||||
inputTypes.push(input.type);
|
||||
@ -165,15 +169,24 @@ export class AlertCmp {
|
||||
});
|
||||
|
||||
if (inputTypes.length > 1 && (inputTypes.indexOf('checkbox') > -1 || inputTypes.indexOf('radio') > -1)) {
|
||||
console.warn('Alert cannot mix input types: ' + (inputTypes.join('/')) + '. Please see alert docs for more info.');
|
||||
console.warn(`Alert cannot mix input types: ${(inputTypes.join('/'))}. Please see alert docs for more info.`);
|
||||
}
|
||||
|
||||
this.inputType = inputTypes.length ? inputTypes[0] : null;
|
||||
|
||||
let checkedInput = this.d.inputs.find(input => input.checked);
|
||||
const checkedInput = this.d.inputs.find(input => input.checked);
|
||||
if (checkedInput) {
|
||||
this.activeId = checkedInput.id;
|
||||
}
|
||||
|
||||
const hasTextInput = (this.d.inputs.length && this.d.inputs.some(i => !(NON_TEXT_INPUT_REGEX.test(i.type))));
|
||||
if (hasTextInput && this._platform.is('mobile')) {
|
||||
// this alert has a text input and it's on a mobile device so we should align
|
||||
// the alert up high because we need to leave space for the virtual keboard
|
||||
// this also helps prevent the layout getting all messed up from
|
||||
// the browser trying to scroll the input into a safe area
|
||||
this._renderer.setElementClass(this._elementRef.nativeElement, 'alert-top', true);
|
||||
}
|
||||
}
|
||||
|
||||
ionViewWillEnter() {
|
||||
@ -185,12 +198,14 @@ export class AlertCmp {
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
let activeElement: any = document.activeElement;
|
||||
if (document.activeElement) {
|
||||
activeElement.blur();
|
||||
}
|
||||
// focus out of the active element
|
||||
focusOutActiveElement();
|
||||
|
||||
let focusableEle = this._elementRef.nativeElement.querySelector('input,button');
|
||||
// set focus on the first input or button in the alert
|
||||
// note that this does not always work and bring up the keyboard on
|
||||
// devices since the focus command must come from the user's touch event
|
||||
// and ionViewDidEnter is not in the same callstack as the touch event :(
|
||||
const focusableEle = this._elementRef.nativeElement.querySelector('input,button');
|
||||
if (focusableEle) {
|
||||
focusableEle.focus();
|
||||
}
|
||||
@ -206,19 +221,19 @@ export class AlertCmp {
|
||||
// this can happen when the button has focus and used the enter
|
||||
// key to click the button. However, both the click handler and
|
||||
// this keyup event will fire, so only allow one of them to go.
|
||||
console.debug('alert, enter button');
|
||||
console.debug(`alert, enter button`);
|
||||
let button = this.d.buttons[this.d.buttons.length - 1];
|
||||
this.btnClick(button);
|
||||
}
|
||||
|
||||
} else if (ev.keyCode === Key.ESCAPE) {
|
||||
console.debug('alert, escape button');
|
||||
console.debug(`alert, escape button`);
|
||||
this.bdClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
btnClick(button: any, dismissDelay?: number) {
|
||||
btnClick(button: any) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
@ -238,9 +253,8 @@ export class AlertCmp {
|
||||
}
|
||||
|
||||
if (shouldDismiss) {
|
||||
setTimeout(() => {
|
||||
this.dismiss(button.role);
|
||||
}, dismissDelay || this._config.get('pageTransitionDelay'));
|
||||
this.dismiss(button.role);
|
||||
focusOutActiveElement();
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,7 +285,7 @@ export class AlertCmp {
|
||||
if (this.enabled && this.d.enableBackdropDismiss) {
|
||||
let cancelBtn = this.d.buttons.find(b => b.role === 'cancel');
|
||||
if (cancelBtn) {
|
||||
this.btnClick(cancelBtn, 1);
|
||||
this.btnClick(cancelBtn);
|
||||
|
||||
} else {
|
||||
this.dismiss('backdrop');
|
||||
@ -280,14 +294,15 @@ export class AlertCmp {
|
||||
}
|
||||
|
||||
dismiss(role: any): Promise<any> {
|
||||
focusOutActiveElement();
|
||||
return this._viewCtrl.dismiss(this.getValues(), role);
|
||||
}
|
||||
|
||||
getValues() {
|
||||
getValues(): any {
|
||||
if (this.inputType === 'radio') {
|
||||
// this is an alert with radio buttons (single value select)
|
||||
// return the one value which is checked, otherwise undefined
|
||||
let checkedInput = this.d.inputs.find(i => i.checked);
|
||||
const checkedInput = this.d.inputs.find(i => i.checked);
|
||||
return checkedInput ? checkedInput.value : undefined;
|
||||
}
|
||||
|
||||
@ -299,7 +314,7 @@ export class AlertCmp {
|
||||
|
||||
// this is an alert with text inputs
|
||||
// return an object of all the values with the input name as the key
|
||||
let values: {[k: string]: string} = {};
|
||||
const values: {[k: string]: string} = {};
|
||||
this.d.inputs.forEach(i => {
|
||||
values[i.name] = i.value;
|
||||
});
|
||||
|
@ -24,6 +24,12 @@ ion-alert {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
ion-alert.alert-top {
|
||||
align-items: flex-start;
|
||||
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
ion-alert input {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import { Content } from '../content/content';
|
||||
* items = [];
|
||||
*
|
||||
* constructor() {
|
||||
* for (var i = 0; i < 30; i++) {
|
||||
* for (let i = 0; i < 30; i++) {
|
||||
* this.items.push( this.items.length );
|
||||
* }
|
||||
* }
|
||||
@ -44,7 +44,7 @@ import { Content } from '../content/content';
|
||||
* console.log('Begin async operation');
|
||||
*
|
||||
* setTimeout(() => {
|
||||
* for (var i = 0; i < 30; i++) {
|
||||
* for (let i = 0; i < 30; i++) {
|
||||
* this.items.push( this.items.length );
|
||||
* }
|
||||
*
|
||||
|
@ -461,14 +461,14 @@ export class PickerCmp {
|
||||
constructor(
|
||||
private _viewCtrl: ViewController,
|
||||
private _elementRef: ElementRef,
|
||||
private _config: Config,
|
||||
config: Config,
|
||||
gestureCtrl: GestureController,
|
||||
params: NavParams,
|
||||
renderer: Renderer
|
||||
) {
|
||||
this._gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
|
||||
this.d = params.data;
|
||||
this.mode = _config.get('mode');
|
||||
this.mode = config.get('mode');
|
||||
renderer.setElementClass(_elementRef.nativeElement, `picker-${this.mode}`, true);
|
||||
|
||||
if (this.d.cssClass) {
|
||||
@ -579,7 +579,7 @@ export class PickerCmp {
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
btnClick(button: any, dismissDelay?: number) {
|
||||
btnClick(button: any) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
@ -599,9 +599,7 @@ export class PickerCmp {
|
||||
}
|
||||
|
||||
if (shouldDismiss) {
|
||||
setTimeout(() => {
|
||||
this.dismiss(button.role);
|
||||
}, dismissDelay || this._config.get('pageTransitionDelay'));
|
||||
this.dismiss(button.role);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ import { ViewController } from '../../navigation/view-controller';
|
||||
*
|
||||
*```ts
|
||||
* switchTabs() {
|
||||
* this.navCtrl.parent.switch(2);
|
||||
* this.navCtrl.parent.select(2);
|
||||
* }
|
||||
*```
|
||||
* @demo /docs/v2/demos/src/tabs/
|
||||
|
Reference in New Issue
Block a user