How to avoid ok/cancel button in ion-option/ion-select

放肆的年华 提交于 2019-12-12 15:11:55

问题


Hi how to avoid the ok and cancel button in ion-options?

I need an output as the below image after clicking the ion-option.

I have tried all the options as per http://ionicframework.com/docs/v2/api/components/select/Select/.

Yet I am not able to achieve this ui.

Even after typing interface="action-sheet" I am not able to achieve the wanted look.

Where can I find a demo or any help to get this view?


回答1:


This question was actually something I myself needed and I know some people have needed it for a while. So I hope this helps..

OPTION 1: WRAPPED SUPER COMPONENT

First we are creating a component called select-alertless. Here is the HTML that has the options:

<ion-select [(ngModel)]="model" #select>
    <ion-option *ngFor="let option options" [value]="option.id">{{option.name}}</ion-option>
</ion-select>

Really simple with a link for a view child.

Now the scss to hide the ok/cancel buttons:

.select-alertless{
    .alert-button-group{
        display:none;
        }
    }

The actual component class which looks for sets on the select inside the html. Looks for the options and sets an emit on the clicks. Thus everytime someone clicks one of the options it. The open function is just here to dismiss the alert after you click.

 @Component({
    templateUrl: 'select-alertless.html',
    selector: 'select-alertless',
})
export class select_alertless {
    // the options that are displayed
    @Input('options') public options: any[];
    @Input('model') public model: any;

    // the event that is to be emitted when changes occures
    @Output('change') public change: EventEmitter<any> = new EventEmitter<any>();

    // The sets here capture events and emit the data to change when its needed. It also switched the open function for our own open function so then the viewcontroller can be closed.
    @ViewChild('select') public set ex(select: any | undefined) {
        if (select === undefined) return;
        select.open = this.open;
        if (select._options === undefined) {
            Object.defineProperty(select, '_options', {
                set: (val) => {
                    select['__options'] = val;
                    val.forEach(option => option.ionSelect.subscribe(d => {
                        this.change.emit(d);
                        this.model = d;

                        select.overlay.dismiss();
                    }));
                },
                get: function () { return select['__options'] }
            })
        }
    }
    open() {
        if ((<any>this)._disabled) {
            return;
        }

        console.debug('select, open alert');

        // the user may have assigned some options specifically for the alert
        const selectOptions = deepCopy((<any>this).selectOptions);

        // make sure their buttons array is removed from the options
        // and we create a new array for the alert's two buttons
        selectOptions.buttons = [{
            text: (<any>this).cancelText,
            role: 'cancel',
            handler: () => {
                (<any>this).ionCancel.emit(null);
            }
        }];

        // if the selectOptions didn't provide a title then use the label's text
        if (!selectOptions.title && (<any>this)._item) {
            selectOptions.title = (<any>this)._item.getLabelText();
        }

        let options = (<any>this)._options.toArray();


        // default to use the alert interface
        (<any>this).interface = 'alert';

        // user cannot provide inputs from selectOptions
        // alert inputs must be created by ionic from ion-options
        selectOptions.inputs = (<any>this)._options.map(input => {
            return {
                type: ((<any>this)._multi ? 'checkbox' : 'radio'),
                label: input.text,
                value: input.value,
                checked: input.selected,
                disabled: input.disabled,
                handler: (selectedOption: any) => {
                    // Only emit the select event if it is being checked
                    // For multi selects this won't emit when unchecking
                    if (selectedOption.checked) {
                        input.ionSelect.emit(input.value);
                    }
                }
            };
        });

        var selectCssClass = 'select-alert';

        // create the alert instance from our built up selectOptions
        (<any>this).overlay = new Alert((<any>(<any>this))._app, selectOptions);

        if ((<any>this)._multi) {
            // use checkboxes
            selectCssClass += ' multiple-select-alert select-alertless';
        } else {
            // use radio buttons
            selectCssClass += ' single-select-alert select-alertless';
        }

        // If the user passed a cssClass for the select, add it
        selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
        (<any>this).overlay.setCssClass(selectCssClass);

        (<any>this).overlay.addButton({
            text: (<any>this).okText,
            handler: (selectedValues: any) => {
                (<any>this).onChange(selectedValues);
                (<any>this).ionChange.emit(selectedValues);
            }
        });


        (<any>this).overlay.present(selectOptions);

        (<any>this)._isOpen = true;
        (<any>this).overlay.onDidDismiss(() => {
            (<any>this)._isOpen = false;
        });
    }
}

This answer would've been a lot shorter if the created alert in select was public rather than a local variable.

Add this to your app module and you are free to use it. Here is an example:

<ion-item>
            <ion-label>stuff</ion-label>
            <select-alertless [model]="data" item-content [options]="options" (change)="data = $event"></select-alertless>
</ion-item>

You can add more inputs that are passed to the ion-select to have more configuration.

OPTION 2: EXTEND SELECT ITSELF

This would be a better solution since it gives you the option to just write the component like ion-select only select-alertless

import { AfterContentInit, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, HostListener, OnDestroy, Optional, Output, Renderer, QueryList, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

import { ActionSheet, Alert, App, Config, Form, Ion, Item, NavController, Option, ViewController } from 'ionic-angular';
import { isBlank, isCheckedProperty, isTrueProperty, deepCopy } from 'ionic-angular/util/util';
import { Select as ImportSelect } from 'ionic-angular/components/select/select';


export class TempSelect extends ImportSelect {
    static decorators = undefined;
    // static propDecorators = undefined;
}

export const SELECT_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => Select),
    multi: true
};

@Component({
    selector: 'select-alertless',
    styles: ['.select-alertless .alert-button-group{display:none}'],
    template:
'<div *ngIf="!_text" class="select-placeholder select-text">{{placeholder}}</div>' +
'<div *ngIf="_text" class="select-text">{{selectedText || _text}}</div>' +
'<div class="select-icon">' +
'<div class="select-icon-inner"></div>' +
'</div>' +
'<button aria-haspopup="true" ' +
'[id]="id" ' +
'ion-button="item-cover" ' +
'[attr.aria-labelledby]="_labelId" ' +
'[attr.aria-disabled]="_disabled" ' +
'class="item-cover">' +
'</button>',
host: {
        '[class.select-disabled]': '_disabled'
    },
    providers: [SELECT_VALUE_ACCESSOR],
    encapsulation: ViewEncapsulation.None,
})
export class Select extends TempSelect implements AfterContentInit, ControlValueAccessor, OnDestroy {
    public overlay: Alert;
    private __options: any;
    constructor(
        _app: App,
        _form: Form,
        config: Config,
        elementRef: ElementRef,
        renderer: Renderer,
        @Optional() public _item: Item,
        @Optional() _nav: NavController
    ) {
        super(_app, _form, config, elementRef, renderer, _item, _nav);
        this.setElementClass(`${this._componentName}-${this._mode}`, false);
    }
public set _options(val) {
    this.__options = val;
    if (!this._multi) {
        this.__options.forEach(option => {
            option.ionSelect.subscribe(selectedValues => {
                this.onChange(selectedValues);
                this.ionChange.emit(selectedValues);
                this._isOpen = false;
                this.overlay.dismiss();
            });
        });
    }
}
public get _options() {
    return this.__options;
}
open() {
    if (this._disabled) {
        return;
    }

    // the user may have assigned some options specifically for the alert
    const selectOptions = deepCopy(this.selectOptions);

    // make sure their buttons array is removed from the options
    // and we create a new array for the alert's two buttons
    selectOptions.buttons = [{
        text: this.cancelText,
        role: 'cancel',
        handler: () => {
            this.ionCancel.emit(null);
        }
    }];

    // if the selectOptions didn't provide a title then use the label's text
    if (!selectOptions.title && this._item) {
        selectOptions.title = this._item.getLabelText();
    }

    let options = this._options.toArray();


    // default to use the alert interface
    this.interface = 'alert';

    // user cannot provide inputs from selectOptions
    // alert inputs must be created by ionic from ion-options
    selectOptions.inputs = this._options.map(input => {
        return {
            type: (this._multi ? 'checkbox' : 'radio'),
            label: input.text,
            value: input.value,
            checked: input.selected,
            disabled: input.disabled,
            handler: (selectedOption: any) => {
                // Only emit the select event if it is being checked
                // For multi selects this won't emit when unchecking
                if (selectedOption.checked) {
                    input.ionSelect.emit(input.value);
                }
            }
        };
    });

    var selectCssClass = 'select-alert';

    // create the alert instance from our built up selectOptions
    this.overlay = new Alert((<any>this)._app, selectOptions);

    if (this._multi) {
        // use checkboxes
        selectCssClass += ' multiple-select-alert';
    } else {
        // use radio buttons
        selectCssClass += ' single-select-alert select-alertless';
    }

    // If the user passed a cssClass for the select, add it
    selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
    this.overlay.setCssClass(selectCssClass);

    this.overlay.addButton({
        text: this.okText,
        handler: (selectedValues: any) => {
            this.onChange(selectedValues);
            this.ionChange.emit(selectedValues);
        }
    });


    this.overlay.present(selectOptions);

    this._isOpen = true;
    this.overlay.onDidDismiss(() => {
        this._isOpen = false;
    });
}

}

Use like:

<select-alertless item-content  [(ngModel)]="data"><ion-option></ion-option></select-alertless>

Basically use like normal select

For more information and an example project on how to use it consult this github: https://github.com/misha130/ionic2-select-nobuttons



来源:https://stackoverflow.com/questions/40925172/how-to-avoid-ok-cancel-button-in-ion-option-ion-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!