UNPKG

ionic-framework

Version:

An advanced HTML5 mobile app framework built on Angular2

395 lines (394 loc) 13.9 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var core_1 = require('angular2/core'); var common_1 = require('angular2/common'); var alert_1 = require('../alert/alert'); var form_1 = require('../../util/form'); var item_1 = require('../item/item'); var util_1 = require('../../util/util'); var nav_controller_1 = require('../nav/nav-controller'); var option_1 = require('../option/option'); var SELECT_VALUE_ACCESSOR = new core_1.Provider(common_1.NG_VALUE_ACCESSOR, { useExisting: core_1.forwardRef(function () { return Select; }), multi: true }); /** * @name Select * @description * The `ion-select` component is similar to an HTML `<select>` element, however, * Ionic's select component makes it easier for users to sort through and select * the preferred option or options. When users tap the select component, a * dialog will appear with all of the options in a large, easy to select list * for users. * * Under-the-hood the `ion-select` actually uses the * {@link ../../alert/Alert Alert API} to open up the overlay of options * which the user is presented with. Select can take numerous child * `ion-option` components. If `ion-option` is not given a `value` attribute * then it will use its text as the value. * * ### Single Value: Radio Buttons * * The standard `ion-select` component allows the user to select only one * option. When selecting only one option the alert overlay presents users with * a radio button styled list of options. The `ion-select` component's value * receives the value of the selected option's value. * * ```html * <ion-item> * <ion-label>Gender</ion-label> * <ion-select [(ngModel)]="gender"> * <ion-option value="f" checked="true">Female</ion-option> * <ion-option value="m">Male</ion-option> * </ion-select> * </ion-item> * ``` * * ### Multiple Value: Checkboxes * * By adding the `multiple="true"` attribute to `ion-select`, users are able * to select multiple options. When multiple options can be selected, the alert * overlay presents users with a checkbox styled list of options. The * `ion-select multiple="true"` component's value receives an array of all the * selected option values. In the example below, because each option is not given * a `value`, then it'll use its text as the value instead. * * ```html * <ion-item> * <ion-label>Toppings</ion-label> * <ion-select [(ngModel)]="toppings" multiple="true"> * <ion-option>Bacon</ion-option> * <ion-option>Black Olives</ion-option> * <ion-option>Extra Cheese</ion-option> * <ion-option>Mushrooms</ion-option> * <ion-option>Pepperoni</ion-option> * <ion-option>Sausage</ion-option> * </ion-select> * <ion-item> * ``` * * ### Alert Buttons * By default, the two buttons read `Cancel` and `OK`. The each button's text * can be customized using the `cancelText` and `okText` attributes: * * ```html * <ion-select okText="Okay" cancelText="Dismiss"> * ... * </ion-select> * ``` * * ### Alert Options * * Remember how `ion-select` is really just a wrapper to `Alert`? By using * the `alertOptions` property you can pass custom options to the alert * overlay. This would be useful if there is a custom alert title, * subtitle or message. {@link ../../alert/Alert Alert API} * * ```html * <ion-select [alertOptions]="alertOptions"> * ... * </ion-select> * ``` * * ```ts * this.alertOptions = { * title: 'Pizza Toppings', * subTitle: 'Select your toppings' * }; * ``` * * @demo /docs/v2/demos/select/ */ var Select = (function () { function Select(_form, _elementRef, _renderer, _item, _nav) { this._form = _form; this._elementRef = _elementRef; this._renderer = _renderer; this._item = _item; this._nav = _nav; this._disabled = false; this._multi = false; this._values = []; this._texts = []; this._text = ''; /** * @private * @input {string} The text of the cancel button. Defatuls to `Cancel` */ this.cancelText = 'Cancel'; /** * @private * @input {string} The text of the ok button. Defatuls to `OK` */ this.okText = 'OK'; /** * @private * @input {any} Any addition options that an alert can take. Title, Subtitle, etc. */ this.alertOptions = {}; /** * @private */ this.checked = false; /** * @output {any} Any expression you want to evaluate when the selection has changed */ this.change = new core_1.EventEmitter(); /** * @output {any} Any expression you want to evaluate when the selection was cancelled */ this.cancel = new core_1.EventEmitter(); this._form.register(this); if (_item) { this.id = 'sel-' + _item.registerInput('select'); this._labelId = 'lbl-' + _item.id; this._item.setCssClass('item-select', true); } if (!_nav) { void 0; } } /** * @private */ Select.prototype._click = function (ev) { var _this = this; ev.preventDefault(); ev.stopPropagation(); if (this._disabled) return; void 0; // the user may have assigned some options specifically for the alert var alertOptions = util_1.merge({}, this.alertOptions); // make sure their buttons array is removed from the options // and we create a new array for the alert's two buttons alertOptions.buttons = [{ text: this.cancelText, handler: function () { _this.cancel.emit(null); } }]; // if the alertOptions didn't provide an title then use the label's text if (!alertOptions.title && this._item) { alertOptions.title = this._item.getLabelText(); } // user cannot provide inputs from alertOptions // alert inputs must be created by ionic from ion-options alertOptions.inputs = this._options.toArray().map(function (input) { return { type: (_this._multi ? 'checkbox' : 'radio'), label: input.text, value: input.value, checked: input.checked }; }); // create the alert instance from our built up alertOptions var alert = alert_1.Alert.create(alertOptions); if (this._multi) { // use checkboxes alert.setCssClass('select-alert multiple-select-alert'); } else { // use radio buttons alert.setCssClass('select-alert single-select-alert'); } alert.addButton({ text: this.okText, handler: function (selectedValues) { _this.onChange(selectedValues); _this.change.emit(selectedValues); } }); this._nav.present(alert, alertOptions); }; Object.defineProperty(Select.prototype, "multiple", { /** * @input {boolean} Whether or not the select component can accept multipl selections */ get: function () { return this._multi; }, set: function (val) { this._multi = util_1.isTrueProperty(val); }, enumerable: true, configurable: true }); Object.defineProperty(Select.prototype, "text", { /** * @private */ get: function () { return (this._multi ? this._texts : this._texts.join()); }, enumerable: true, configurable: true }); Object.defineProperty(Select.prototype, "options", { /** * @private */ set: function (val) { this._options = val; if (!this._values.length) { // there are no values set at this point // so check to see who should be checked this._values = val.toArray().filter(function (o) { return o.checked; }).map(function (o) { return o.value; }); } this._updOpts(); }, enumerable: true, configurable: true }); /** * @private */ Select.prototype._updOpts = function () { var _this = this; this._texts = []; if (this._options) { this._options.toArray().forEach(function (option) { // check this option if the option's value is in the values array option.checked = (_this._values.indexOf(option.value) > -1); if (option.checked) { _this._texts.push(option.text); } }); } this._text = this._texts.join(', '); }; Object.defineProperty(Select.prototype, "disabled", { /** * @input {boolean} Whether or not the select component is disabled or not */ get: function () { return this._disabled; }, set: function (val) { this._disabled = util_1.isTrueProperty(val); this._item && this._item.setCssClass('item-select-disabled', this._disabled); }, enumerable: true, configurable: true }); /** * @private */ Select.prototype.writeValue = function (val) { void 0; this._values = (Array.isArray(val) ? val : util_1.isBlank(val) ? [] : [val]); this._updOpts(); }; /** * @private */ Select.prototype.ngAfterContentInit = function () { this._updOpts(); }; /** * @private */ Select.prototype.registerOnChange = function (fn) { var _this = this; this._fn = fn; this.onChange = function (val) { void 0; fn(val); _this._values = (Array.isArray(val) ? val : util_1.isBlank(val) ? [] : [val]); _this._updOpts(); _this.onTouched(); }; }; /** * @private */ Select.prototype.registerOnTouched = function (fn) { this.onTouched = fn; }; /** * @private */ Select.prototype.onChange = function (_) { }; /** * @private */ Select.prototype.onTouched = function () { }; /** * @private */ Select.prototype.ngOnDestroy = function () { this._form.deregister(this); }; __decorate([ core_1.Input(), __metadata('design:type', String) ], Select.prototype, "cancelText", void 0); __decorate([ core_1.Input(), __metadata('design:type', String) ], Select.prototype, "okText", void 0); __decorate([ core_1.Input(), __metadata('design:type', Object) ], Select.prototype, "alertOptions", void 0); __decorate([ core_1.Input(), __metadata('design:type', Object) ], Select.prototype, "checked", void 0); __decorate([ core_1.Output(), __metadata('design:type', core_1.EventEmitter) ], Select.prototype, "change", void 0); __decorate([ core_1.Output(), __metadata('design:type', core_1.EventEmitter) ], Select.prototype, "cancel", void 0); __decorate([ core_1.HostListener('click', ['$event']), __metadata('design:type', Function), __metadata('design:paramtypes', [Object]), __metadata('design:returntype', void 0) ], Select.prototype, "_click", null); __decorate([ core_1.Input(), __metadata('design:type', Object) ], Select.prototype, "multiple", null); __decorate([ core_1.ContentChildren(option_1.Option), __metadata('design:type', core_1.QueryList), __metadata('design:paramtypes', [core_1.QueryList]) ], Select.prototype, "options", null); __decorate([ core_1.Input(), __metadata('design:type', Object) ], Select.prototype, "disabled", null); Select = __decorate([ core_1.Component({ selector: 'ion-select', template: '<div class="select-text">{{_text}}</div>' + '<div class="select-icon">' + '<div class="select-icon-inner"></div>' + '</div>' + '<button aria-haspopup="true" ' + '[id]="id" ' + '[attr.aria-labelledby]="_labelId" ' + '[attr.aria-disabled]="_disabled" ' + 'class="item-cover">' + '</button>', host: { '[class.select-disabled]': '_disabled' }, providers: [SELECT_VALUE_ACCESSOR] }), __param(3, core_1.Optional()), __param(4, core_1.Optional()), __metadata('design:paramtypes', [form_1.Form, core_1.ElementRef, core_1.Renderer, item_1.Item, nav_controller_1.NavController]) ], Select); return Select; })(); exports.Select = Select;