0

Currently I have designed the page that contains the form to get the details from the user. The last field is the attachment field where the user can attach the files such as PDF and image files from camera and Gallery. For that purpose, I am using fab list with three buttons.

Now the problem is that when I opens the fab, it remains open even if I am moving to next page and returns back to this current page. I am using bottom tab menu to navigate between the pages in the app. What I would like to have is that, as soon as I leave this page, the fab list of button should close automatically, even if it remains open at the time of moving to next page.

I have tried many method such as this.fab.close() and fab.close() at the form reset method, but none works. I need the fab to get close each and every time I leaves the current page and return back to this current page.

Here's what I have tried:

Mypage.html:

<ion-header color="purple">
    <ion-navbar hideBackButton="true" color="purple">
        <ion-title>
            {{title}}
        </ion-title>
        <span class="titlesmall" *ngIf="hideEmail">
            {{email}}
        </span>
        <ion-buttons right>
            <button ion-button icon-only (click)="logoutWithConfirmation()">
                <ion-icon name="log-out"></ion-icon>
            </button>
        </ion-buttons>
    </ion-navbar>
</ion-header>
<ion-content class="ioncontent-background" scroll="true" >
    <form [formGroup]="form"  >
        <ion-row>
            <ion-item>
                <ion-icon class="icon-in" name="options" item-left></ion-icon>
                <ion-label color="textcolor" floating>Category</ion-label>
                <ion-select [(ngModel)]="vm.SupportCategory" class="textcolor" formControlName="category" (change)="onChange(vm.SupportCategory)">
                    <ion-option *ngFor="let item of list" [value]="item.key" >{{item.value}}</ion-option>
                </ion-select>
            </ion-item>
            <div class="error-message-support" *ngIf="form.controls.category.errors && (form.controls.category.dirty || form.controls.category.touched)">
                <span *ngIf="form.controls.category.errors?.required">Category is required</span>
            </div>
        </ion-row>

        <ion-row>
            <ion-item>
                <ion-icon class="icon-in" name="create" item-left></ion-icon>
                <ion-label color="textcolor" floating> Subject</ion-label>
                <ion-input type="text" [(ngModel)]="vm.Subject" class="textcolor" formControlName="subject" tabindex="1" (keyup)="moveFocus($event,query, false)"></ion-input>
            </ion-item>
            <div class="error-message-support" *ngIf="form.controls.subject.errors && (form.controls.subject.dirty || form.controls.subject.touched)">
                <span *ngIf="form.controls.subject.errors?.required">Subject is required</span>
            </div>
        </ion-row>

        <ion-row>
            <ion-item>
                <ion-icon class="icon-in" name="help" item-left></ion-icon>
                <ion-label color="textcolor" floating>Query</ion-label>
                <ion-input type="text" [(ngModel)]="vm.Query" class="textcolor" formControlName="query" tabindex="1" (keyup)="moveFocus($event,moreinfo, false)"
                           #query></ion-input>
            </ion-item>
            <div class="error-message-support" *ngIf="form.controls.query.errors && (form.controls.query.dirty || form.controls.query.touched)">
                <span *ngIf="form.controls.query.errors?.required">Query is required</span>
            </div>
        </ion-row>

        <ion-row>
            <ion-item>
                <ion-icon class="icon-in" name="quote" item-left></ion-icon>
                <ion-label color="textcolor" floating>More Information</ion-label>
                <ion-input  type="text" [(ngModel)]="vm.MoreInformation" class="textcolor" formControlName="moreinfo" tabindex="1"
                           [attr.required]="true" (keyup)="moveFocus($event,submitbutton, true)" #moreinfo></ion-input>
            </ion-item>
            <div class="error-message-support" *ngIf="form.controls.moreinfo.errors && (form.controls.moreinfo.dirty || form.controls.moreinfo.touched)">
                    <span *ngIf="form.controls.moreinfo.errors?.required">Query is required</span>
                </div>
        </ion-row>
        <ion-row no-lines class="fab-icon">
                <ion-col col-2>
                        <ion-icon name="md-attach" color="white" class="icon-in" item-left></ion-icon>
                </ion-col>
                <ion-col col-8 >
                     <span class="span-style-fab">{{vm.attach}}</span>  
                 </ion-col>
                 <ion-col col-2>
                <ion-fab right class="ion-fab-right"  #fab>
                  <button ion-fab mini color = "purple" (click)="click($event,fab)">
                    <ion-icon [name]="isAdded ? 'close' : 'add'" id="changeicon"></ion-icon>
                  </button>
                  <ion-fab-list side="top">
                    <button ion-fab class="fab-color" (click)="onCameraClick(1,fab)">
                      <ion-icon color="white" name="camera"></ion-icon>
                    </button>
                    <button ion-fab class="fab-color" (click)="onCameraClick(2,fab)">
                      <ion-icon color="white" name="images"></ion-icon>
                    </button>
                    <button ion-fab class="fab-color" (click)="fileattach(fab)">
                      <ion-icon color="white" name="document"></ion-icon>
                    </button>
                  </ion-fab-list>
                </ion-fab>
            </ion-col>
              </ion-row>
            <!-- <ion-row class="fab-icon" col-12>
                    <ion-col col-2>
                            <ion-icon name="md-attach" color="white" class="icon-in" item-left></ion-icon>
                    </ion-col>
                    <ion-col col-8>

                         <span class="span-style-fab">{{vm.attach}}</span>  
                     </ion-col>
                     <ion-col col-2>
                <ion-fab right class="ion-fab-right" #myfab>
                    <button ion-fab mini color="purple" (click)="click($event)">
                        <ion-icon [name]="isAdded ? 'close' : 'add'" id="changeicon"></ion-icon>
                    </button>
                    <ion-fab-list side="top" >
                        <button ion-fab class="fab-color" (click)="onCameraClick(1,fab)">
                            <ion-icon color="white" name="camera"></ion-icon>
                        </button>
                        <button ion-fab class="fab-color" (click)="onCameraClick(2,fab)">
                            <ion-icon color="white" name="images"></ion-icon>
                        </button>
                        <button ion-fab class="fab-color" (click)="fileattach(fab)">
                            <ion-icon color="white" name="document"></ion-icon>
                        </button>
                    </ion-fab-list>
                </ion-fab>
                </ion-col>
           </ion-row> -->


        <ion-item>
            <div class="button-bar">
                <button ion-button icon-end name="submitbutton" (click)="submit()" class="button" color="purple">
                    Submit
                    <ion-icon name="md-checkmark-circle"></ion-icon>
                </button>
            </div>
        </ion-item>
    </form>
</ion-content>

Mypage.ts:

import { Component, NgZone,ViewChild } from '@angular/core';
import { NavController, App, AlertController, Events, FabContainer } from 'ionic-angular';
import { FormControl, Validators, FormGroup, AbstractControl } from '@angular/forms';
import { Support } from '../../models/support';

import { isNullOrUndefined } from 'util';
import { MessageService } from "../../services/message.service";
import { Camera, CameraOptions } from '@ionic-native/camera';
import { Keyboard } from '@ionic-native/keyboard';
import { FileChooser } from '@ionic-native/file-chooser';
import { FileOpener } from '@ionic-native/file-opener';
import { FilePath } from '@ionic-native/file-path';
import { SupportService } from '../../services/support.service';
import { FileTransfer} from '@ionic-native/file-transfer';
import { File } from '@ionic-native/file';
import { Base64 } from '@ionic-native/base64';
import { BroadCastService } from '../../services/broadcast.service';
import { AuthenticationService } from '../../services/authentication.service';


@Component({
    selector: 'page-support',
    templateUrl: 'support.html',
    providers: [AuthenticationService, MessageService, Camera, SupportService, FileChooser, FileOpener, FilePath, FileTransfer, File, Base64]
})
export class SupportPage {
    @ViewChild('myfab') fabRef: FabContainer;
    vm: Support;
    // private platform: Platform; public app: App;
    service: any;
    form: FormGroup;
    list = [];
    public n: any;
    files: any[];
    support = new Support();
    fab: FabContainer;
    message: any;
    todayDate: any;
    newFileName: any;

    public dateToday: any;
    createFile: AbstractControl;
    value: any;
    photoencodetype: number;
    datas: any;
    filetypename: any;
    isAdded: boolean = false;
    changeicon: any = "add";
    attach: any;
    public unregisterBackButtonAction: any;

    constructor(public navCtrl: NavController,
        private camera: Camera,
        private keyboard: Keyboard, private zone: NgZone,
        public authService: SupportService,
        public alertctr: AlertController,
        authenticationservice: SupportService,
        public logoutservice: AuthenticationService,
        private filechooser: FileChooser,
        public broadCastService: BroadCastService,
        private filepath: FilePath,
        private base64: Base64,
        message: MessageService,

        private event: Events,
        public app: App) {
        this.vm = new Support();
        this.files = [];
        this.message = message;
        this.vm.attach = "Attachment:";
        this.isAdded = false;
        authenticationservice.category().subscribe(res => {
            if (!isNullOrUndefined(res)) {
                this.list = res;
            }
        });
    }

    ionViewDidLoad() {
        console.log('support page - ionViewDidLoad');
        this.keyboard.onKeyboardShow().subscribe(() => this.event.publish('hideTabs'));
        this.keyboard.onKeyboardHide().subscribe(() => this.event.publish('showTabs'));
    }

    showAlert() {
        let alert = this.alertctr.create({
          title: `Greetings`,
          message: `
            <p>My Message</p>
            <p>My Message here</p>
            <p>The Home-Connect Team</p>
          `,
          buttons: ['Continue']
        });

        alert.present();
      }

    submit() {
        if (this.form.valid) {
            this.support.Subject = this.vm.Subject;
            this.support.Query = this.vm.Query;
            this.support.MoreInformation = this.vm.MoreInformation;
            this.support.SupportAttachmentMapping = this.files;
            this.support.SupportCategory = this.vm.SupportCategory;
            this.support.UserId = localStorage.getItem('userid');
            this.authService.support(this.support).subscribe(res => {
                if (!isNullOrUndefined(res)) {
                    console.log("Message" + res);
                    if (res.status == 200) {
                        this.value = "Your ticket has been submitted successfully";
                        this.ticketsuccess(this.value);
                        this.refresh();
                    } else {
                        this.value = "Your ticket has not been submitted";
                        this.ticketsuccess(this.value);
                        this.refresh();
                    }
                }
            }, err => {
                alert(JSON.stringify(err));
            });
        } else {
            this.validateFormControl(this.form);

        }
    }

    fileattach(fab: FabContainer) {
        fab.close();
        //const fileTransfer: FileTransferObject = this.transfer.create();
        this.filechooser.open().then(file => {
            this.filepath.resolveNativePath(file).then(resolvedFilepath => {
                // this.fileopener.open(resolvedFilepath, 'application/pdf').then(value => {
                let name = resolvedFilepath.split("/");
                let currentName = name[name.length - 1];
                let fileextension = currentName.split(".")[1].toUpperCase();
                if (currentName.split(".")[1].toUpperCase() == "PNG" || currentName.split(".")[1].toUpperCase() == "PDF" 
                    || currentName.split(".")[1].toUpperCase() == "JPG") {
                    let filePath: string = resolvedFilepath;
                    this.base64.encodeFile(filePath).then((base64File: string) => {
                        console.log(base64File);

                        if (fileextension == "PNG") {
                            this.filetypename = "image/png";
                        } else if (fileextension == "PDF") {
                            this.filetypename = "application/pdf";
                        }else if (fileextension == "JPG") {
                            this.filetypename = "application/jpg";
                        }
                        this.files = [];
                        this.files.push({ FileName: currentName, FileExtention: this.filetypename, FileType: this.filetypename, FileData: base64File });
                        this.vm.attach = currentName;
                        this.attach = this.vm.attach;
                        this.isAdded = true;
                    }, (err) => {
                        console.log(err);
                    });
                }
                else {
                    alert("The file being uploaded needs to be of type png or jpg or pdf Format.");
                }
            }).catch(err => {
                // alert(JSON.stringify(err));
                console.log(JSON.stringify(err));
            });
        }).catch(err => {
            console.log(JSON.stringify(err));
        });
    }

    ticketsuccess(value: any) {
        let alert = this.alertctr.create({
            cssClass: 'alert-message',
            title: 'Submission',
            message: value,
            buttons: [
                {
                    text: 'Okay',
                    handler: () => {
                        console.log('Buy clicked');
                        this.resetForm(this.form);
                        this.broadCastService.broadCastSupportCreated("Your ticket has been submitted successfully");
                    }
                }
            ]
        });
        alert.present();
    }

    ngOnInit() {
        this.initializeValidators();
    }

    click(event, fab: FabContainer) {
        if (this.isAdded) {
            fab.close();
            let alert = this.alertctr.create({
                cssClass: 'alert-confirmation',
                title: 'Confirm Remove!',
                message: 'Are you sure you want to remove the attachement ?',
                buttons: [
                    {
                        text: 'No',
                        handler: () => {
                            console.log('Cancel clicked');
                            fab.close();
                        }
                    },
                    {
                        text: 'Yes',
                        handler: () => {
                            this.isAdded = false;
                            this.files = [];
                            this.vm.attach = "Attachment";
                            fab.close();
                        }
                    }
                ]
            });
            alert.present().then(() => {
                fab.close();
            });
        }
    }

    initializeValidators() {
        this.form = new FormGroup({
            category: new FormControl('', Validators.required),
            subject: new FormControl('', [Validators.required]),
            query: new FormControl('', [Validators.required]),
            moreinfo: new FormControl('', null),
            attachment: new FormControl('', null)
        });
        this.form.controls['moreinfo'].markAsTouched();
        // this.form.controls['attachment'].markAsTouched();
    }
    ionViewDidEnter() {
        this.resetForm(this.form)
    }
    validateFormControl(formGroup: FormGroup) {
        Object.keys(formGroup.controls).forEach(field => {
            const control = formGroup.get(field);
            if (control instanceof FormControl) {
                control.markAsTouched({ onlySelf: true });
            } else if (control instanceof FormGroup) {
                this.validateFormControl(control);
            }
        });
    }

    resetForm(formGroup: FormGroup) {
        let control: AbstractControl = null;
        formGroup.reset();
        // this.vm.Subject = '';
        // this.vm.Query = '';
        //  this.vm.MoreInformation= '';
        // this.vm.SupportCategory= '';
        formGroup.markAsUntouched();
        this.vm.attach = "Attachment";
        this.isAdded = false;

        Object.keys(formGroup.controls).forEach((name) => {
            control = formGroup.controls[name];
            control.setErrors(null);
        });
        this.initializeValidators();
    }

    moveFocus(event, nextElement, isLastControl, fab: FabContainer) {
        if (event.key === 'Enter') {
            if (isLastControl && isLastControl === true) {
                this.keyboard.hideKeyboardAccessoryBar(true);
                this.refresh();
                this.submit();
            } else {
                nextElement.setFocus();
            }
        }
    }

    createFileName() {
        this.todayDate = new Date();
        this.dateToday = (this.todayDate.getFullYear() + '-' + ((this.todayDate.getMonth() + 1)) + '-' + this.todayDate.getDate() + ' ' + this.todayDate.getHours() + ':' + this.todayDate.getMinutes() + ':' + this.todayDate.getSeconds()),
            this.newFileName = "Support " + this.dateToday;
        return this.newFileName;
    }

    refresh(fab?: FabContainer): void {
        if (fab !== undefined) {
            fab.close();
        }
    }
    onCameraClick(sourceType, fab: FabContainer) {
        fab.close();
        const options: CameraOptions = {
            quality: 25,
            destinationType: this.camera.DestinationType.DATA_URL,
            encodingType: this.camera.EncodingType.JPEG,
            mediaType: this.camera.MediaType.PICTURE,
            sourceType: sourceType
        };


        this.camera.getPicture(options).then((imageUri) => {
            console.log(imageUri);
            // alert('Test' + this.camera.EncodingType.JPEG);
            // this.photoencodetype = this.camera.EncodingType.JPEG;

            this.files = [];
            let currentName = this.createFileName() + "" + ".jpg";
            let base64Image = 'data:image/jpg;base64,' + imageUri;
            this.files.push({ FileName: currentName, FileExtention: "image/jpg", FileType: "image/jpg", FileData: base64Image });
            // this.createFileName = this.newFileName;
            // currentName = this.form.controls['attachment'];
            //  this.message.alert('Uploaded Successfully '+ currentName);
            this.vm.attach = currentName;
            this.attach = this.vm.attach;
            this.isAdded = true;
        }, (error) => {
            console.log(error);
        });

    }
}

I have also attached the coding for the tabs page that I am using to navigate between the pages.

mytab.ts:

@Component({
    templateUrl: 'tabs.html',
    selector: 'page-tabs',
    providers: [AuthenticationService, HomeService, BroadCastService]
})
export class TabsPage{

    @ViewChild('myTabs') tabRef: Tabs;
    @ViewChild('fab') fabRef: FabContainer;

    changePasswordPage = ChangePasswordPage;
    title: string;
    email: string;

    dashboardpageTab = DashboardPage;
    supportpageTab = SupportPage;
    cancellationTab = CancellationPage;
    serviceChangeTab = ServiceChangePage;
    shoppingTab = ShoppingPage;
    myprofileTab = MyprofilePage;
    accounttransfertab = AccounttransferPage;
    changePasswordTab = ChangePasswordPage;
    aboutTab = AboutPage;



    userid: string;
    isEmpty: boolean;
    hideEmail: boolean = true;

    bankdetail: BankingDetails[];
    fabMenuIsOpened: boolean = false;
    hideFabmenu: boolean = true;
    public alertShown: boolean = false;
    mb: any;
    applicationlist = new ApplicationList();
    subscription: ISubscription;

    constructor(public navCtrl: NavController, private zone: NgZone,
        private elementRef: ElementRef,
        private alertCtrl: AlertController,
        public app: App, private platform: Platform,
        private event: Events,
        private renderer: Renderer,
        public homeservice: HomeService,
        private authService: AuthenticationService,
        private broadCastService: BroadCastService,
        private userSessionService: UserSessionService) {

        this.title = this.userSessionService.referenceNumber();
        this.email = this.userSessionService.email();

        this.subscription = this.broadCastService.onChangePassword()
            .subscribe(message => {
                this.logout();
            });

        this.broadCastService.onSupportCreated()
            .subscribe(message => {
                this.tabRef.select(0);
            });

        platform.registerBackButtonAction(() => {
            if (this.alertShown === false) {
                let nav = app.getActiveNavs()[0];
                let activeView = nav.getActive();
                console.log('activeView => ' + activeView.name);
               // alert(activeView.name);
                if (activeView.name !== 'DashboardPage') {
                    this.goToDashBoardPage();
                } else if (activeView.name === 'DashboardPage') {
                    this.logoutmethod();
                } else {
                    nav.pop();
                }
            }
        }, 0);

    }

    ionViewDidLeave() {
        this.subscription.unsubscribe();
    }

    ionViewDidEnter() {
        let tabs = this.queryElement(this.elementRef.nativeElement, '.tabbar');
        let fabmenu = this.queryElement(this.elementRef.nativeElement, 'ion-fab');

        this.event.subscribe('hideTabs',
            () => {
                console.log('tabs page - hideTabs');
                this.renderer.setElementStyle(fabmenu, 'display', 'none');
                this.renderer.setElementStyle(tabs, 'display', 'none');
                let selectTab = this.tabRef.getSelected()._elementRef.nativeElement;
                let content = this.queryElement(selectTab, '.scroll-content');
                this.mb = content.style['margin-bottom'];
                this.renderer.setElementStyle(content, 'margin-bottom', '0');
            });
        this.event.subscribe('showTabs',
            () => {
                console.log('tabs page - showTabs');
                this.renderer.setElementStyle(tabs, 'display', '');
                this.renderer.setElementStyle(fabmenu, 'display', '');
                let selectTab = this.tabRef.getSelected()._elementRef.nativeElement;
                let content = this.queryElement(selectTab, '.scroll-content');
                this.renderer.setElementStyle(content, 'margin-bottom', this.mb);
            });
    }

    queryElement(elem: HTMLElement, q: string): HTMLElement {
        return <HTMLElement>elem.querySelector(q);
    }

    logoutmethod() {
        this.logoutWithConfirmation();
    }

    goToDashBoardPage() {
        this.zone.run(() => {
            this.tabRef.select(0);
        });
    }

    public onTabsChange() {
        this.fabRef.close();
        this.fabMenuIsOpened = false;

        this.title = this.tabRef.getSelected().index === 0 ?
            this.userSessionService.referenceNumber() : this.tabRef.getSelected().tabTitle;
        this.hideEmail = this.tabRef.getSelected().index === 0;
    }

    getOverlayStyle() {
        let myStyles = {
            'width': '100%',
            'height': '100%',
            'display': 'flex',
            'justify-content': 'flex-end',
            'align-items': 'flex-end',
            'position': 'absolute',
            'background-color': 'rgba(0, 0, 0, 0.7)',
            'z-index': 99,
            'bottom': '0px',
            'right': '0px',
            'padding-right': '10px',
            'padding-bottom': '10px'


        };
        return this.fabMenuIsOpened ? myStyles : {};
    }

    tab(fab: FabContainer) {
        this.fabMenuIsOpened = !this.fabMenuIsOpened;

        if (this.fabMenuIsOpened) {
            console.log('Opened...');
        } else {
            console.log('Closed...');
        }
    }

    logoutWithConfirmation() {
        let alert = this.alertCtrl.create({
            cssClass: 'alert-confirmation',
            title: 'Confirm Logout',
            message: 'Do you want to logout ?',
            buttons: [
                {
                    text: 'No',
                    handler: () => {
                        console.log('Cancel clicked');
                        this.alertShown = false;
                    }
                },
                {
                    text: 'Yes',
                    handler: () => {
                        this.authService.logOut();
                        //this.platform.exitApp();
                        this.navCtrl.push(LoginPage);
                    }
                }
            ]
        });
        alert.present().then(() => {
            this.alertShown = true;
        });
    }

    logout() {
        this.authService.logOut();
        this.navCtrl.push(LoginPage);
    }

    tabmenu(event, fab: FabContainer) {
        this.fabMenuIsOpened = !this.fabMenuIsOpened;
        fab.close();
        this.tabRef.select(event);
        if (this.fabMenuIsOpened) {
            console.log('Opened...');
        } else {
            console.log('Closed...');
        }

    }

    IonSelect(val: string) {
        this.title = val;
    }

    contentSettings = {
        theme: 'android'
    };
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Thedroider
  • 229
  • 1
  • 5
  • 18

1 Answers1

0

this works ok for me !!

html...

<ion-fab  top right edge #fab >
    <button ion-fab mini class="menu">
      <ion-icon ios="md-more" name="more" md="md-more"></ion-icon>
    </button>
    <ion-fab-list>
      <button ion-fab (click)="closeFab(fab)">
        <ion-icon name="md-camera" style="color:#761cca;">
        </ion-icon>
      </button>
    </ion-fab-list>
  </ion-fab>

ts...

import { FabContainer} from 'ionic-angular';

    closeFab(fab: FabContainer) {
        fab.close();
      }
Kevin Dias
  • 1,043
  • 10
  • 28