Salad.Guyo
Salad.Guyo

Reputation: 3395

How to add checkbox to ionic 4 alercontroller

I am using ionic 4. Wanted to have a checkbox field in Alert Controller that gets its data from array of objects. I want to make each of array value as checkbox option but with the code I have I only get one checkbox.

alert popup

This is the code:

 async addPassenger() {
let alert = await this.alertCtrl.create({
  cssClass: "custom-alert",
  header: "Add passenger",
  backdropDismiss: false,
  inputs: [
    {
      name: "name",
      type: "text"
    },
    {
      name: "id",
      type: "number"
    },
    {
      name: "phone",
      type: "number"
    },
    {
      name: "seats",
      value: this.selectedSeats.map(st => st.label)
    },
    {
      name: "seats2",
      type: "checkbox",
      value: this.selectedSeats.map(st => st.label)
    }
  ],
  buttons: [
    {
      text: "Save",
      role: "save",
      cssClass: "btnSave",
      handler: data => {
        console.log("data", data);
        if (
          data.name == "" ||
          data.id == "" ||
          data.phone == "" ||
          data.seats == "" ||
          data.seats2
        ) {
          this.presentToast();
          alert.dismiss();
          return false;
        } else {
          data.name, data.id, data.phone, data.seats, data.seats2;
          try {
            this.passengerInfo = data;
            console.log("Passengers info-->", data);
          } catch (error) {
            console.log("Error: ", error);
          }}}
    },
    {
      text: "Cancel",
      role: "cancel",
      cssClass: "btnCancel",
      handler: () => {
        console.log("data-->");
      }}
  ]
});
alert.present();
}

How can I have the labels in the array as checkbox options. Now all I have is one unlabeled checkbox instead of 4.

Upvotes: 1

Views: 1731

Answers (3)

Luis Rita
Luis Rita

Reputation: 392

Like @AJT82 said, mixing types of inputs is not supported by Ionic. Recommended action is definitely to build a separate modal for that.

In any case, My workaround is also a bit messy but works quite well for me. The idea is to nest alerts. Here is a working demo of the code below in stackblitz.

this.alertCtrl.create({
cssClass: "custom-alert",
header: "Step 1 - this is not that nasty...",
subHeader: 'Add Passenger',
backdropDismiss: false,
inputs: [{
        name: "name",
        type: "text"
    },
    {
        name: "id",
        type: "number"
    },
    {
        name: "phone",
        type: "number"
    },
    {
        name: "seats",
        value: "this.selectedSeats.map(st => st.label)"
    }
],
buttons: [{
        text: "Next",
        handler: textData => {
            console.log("data", textData);
            if (textData) { //validate data here
                // alert.dismiss(); //As far as I know, practically in ionic 5, there is no need to dismiss, clicking any button does that. But maybe it's the right thing to do 🤷🏽‍♂️

                this.alertCtrl.create({
                    cssClass: "custom-alert",
                    header: "Step 2 - ok, maybe it is a little nasty...",
                    subHeader: 'Select Seat Passenger',
                    backdropDismiss: false,
                    inputs: [{
                        name: "seats2",
                        type: "checkbox",
                        label: "this.selectedSeats.map(st => st.label)",
                        value: "this.selectedSeats.map(st => st.label)"
                    }],
                    buttons: ['Cancel',
                        {
                            text: 'Save',
                            role: "save",
                            cssClass: "btnSave",
                            handler: (checkboxData) => {
                                console.log('text data:', textData);
                                console.log('checkbox data:', checkboxData);
                                /* Do Main Data processing here */
                            }
                        }
                    ]
                }).then(alert => alert.present());
            } else {
                /*Do something with invalid data */
            }
        }
    },
    {
        text: "Cancel",
        role: "cancel",
        cssClass: "btnCancel",
        handler: () => {
            console.log("data-->");
        }
    }
]}).then(alert => alert.present());

Note: I put the OP's variables as strings just as placeholders to show where they go

I Hope that helps anybody still struggling with this limitation. Any questions ask, I'll do my best to answer. 👊🏽

Upvotes: 0

AVJT82
AVJT82

Reputation: 73357

The documentation states that:

Alerts can also include several different inputs whose data can be passed back to the app. Inputs can be used as a simple way to prompt users for information. Radios, checkboxes and text inputs are all accepted, but they cannot be mixed. For example, an alert could have all radio button inputs, or all checkbox inputs, but the same alert cannot mix radio and checkbox inputs. Do note however, different types of "text" inputs can be mixed, such as url, email, text, etc. If you require a complex form UI which doesn't fit within the guidelines of an alert then we recommend building the form within a modal instead.

They mention that radio buttons and checkboxes cannot be mixed. Even though the documentation doesn't explicitly say that text inputs and checkboxes (or text inputs and radio buttons for that matter) cannot be mixed, they cannot. This is just how it is. Like the documentation lastly states, you can use a modal instead and style it like a alert with css. That is what we have done.

Or, you can hack it like Ira W has suggested :)

Upvotes: 2

Ira Watt
Ira Watt

Reputation: 2135

This is nasty but I think it does what you want

enter image description here

 let alert = await this.alertCtrl.create({
   cssClass: "custom-alert",
   header: "this is nasty...",
   backdropDismiss: false,
   message:  '<ion-checkbox></ion-checkbox><ion-label style="vertical-align: top;margin-left: 5px;">'+this.selectedSeats[0].label+'</ion-label>',
   buttons: [
     {
       text: "Save",
       role: "save",
       cssClass: "btnSave",
       handler: data => {
         console.log("data", data);
         if (
           data.name == "" ||
           data.id == "" ||
           data.phone == "" ||
           data.seats == "" ||
           data.seats2
         ) {
          // this.presentToast();
           alert.dismiss();
           return false;
         } else {
           data.name, data.id, data.phone, data.seats, data.seats2;
           try {
             this.passengerInfo = data;
             console.log("Passengers info-->", data);
           } catch (error) {
             console.log("Error: ", error);
           }}}
     },
     {
       text: "Cancel",
       role: "cancel",
       cssClass: "btnCancel",
       handler: () => {
         console.log("data-->");
       }}
   ]
 });

in order to get the veriable from the check box you could use [(ngModel)]="someValueInTheTS"

comment if you need any help

Upvotes: 2

Related Questions