How to close ion-select programmatically

1.5k Views Asked by At

In my ionic react app, I am using IonSelect in a form. I need to close the IonSelect dropdown programmatically inside a hardware back button event listener call when the dropdown is open. Here is the code

export const SingleSelection: React.FC = () => { 
   const [gender, setGender] = useState<string>();
   
    useEffect(() => {
     
      document.addEventListener('ionBackButton', (ev: any) => {
         ev.detail.register(1000, async (processNextHandler: any) => {
           console.log('Handler B was called!');
    
           processNextHandler();
         });
      });
      return () => {
        console.log("use effect return");
      }
   }, [])

   return (
     <IonPage>
        <IonContent>
          <IonItem>
              <IonLabel>Gender</IonLabel>
              <IonSelect value={gender} placeholder="Select One" onIonChange={e => setGender(e.detail.value)}>
                 <IonSelectOption value="female">Female</IonSelectOption>
                 <IonSelectOption value="male">Male</IonSelectOption>
               </IonSelect>
           </IonItem>
         </IonContent>
      </IonPage>   
    );
};

UPDATED: [solved]: here is my updated complete code with modal. Inside the hardware back button event listener method first the ion select is closed (if it kept open) and then the modal is closed

const ModalExample: React.FC = () => {
    const [showModal, setShowModal] = useState(false);
    const [gender, setGender] = useState<string>();

    useEffect(() => {
        document.addEventListener('ionBackButton', (ev: any) => {
            ev.detail.register(1000, async (processNextHandler: any) => {
                console.log('Handler B was called!');
                try {
                    console.log("close ion select");
                    const alert = await alertController.getTop();
                    if (alert) {
                        alert.dismiss();
                        return;
                    }
                    console.log("close modal")
                    const element = await modalController.getTop();
                    if (element) {
                        //element.dismiss();
                        setShowModal(false)
                        return;
                    }
                } catch (error) {
                    console.log(error);
                }
                processNextHandler();
            });
        });
        return () => {
            console.log("use effect return");
        }
    }, [])

    return (
        <IonContent>
            <IonModal isOpen={showModal} cssClass='my-custom-class'>
                <p>This is modal content</p>
                <IonItem>
                    <IonLabel>Gender</IonLabel>
                    <IonSelect value={gender} placeholder="Select One" onIonChange={e => setGender(e.detail.value)}>
                        <IonSelectOption value="female">Female</IonSelectOption>
                        <IonSelectOption value="male">Male</IonSelectOption>
                    </IonSelect>
                </IonItem>
                <IonButton onClick={() => setShowModal(false)}>Close Modal</IonButton>
            </IonModal>
            <IonButton onClick={() => setShowModal(true)}>Show Modal</IonButton>
        </IonContent>
    );
};
3

There are 3 best solutions below

0
On BEST ANSWER

I have got the solution. Using alertController IonSelect dropdown can be closed programmatically,

import { alertController } from "@ionic/core";
.....

useEffect(() => {

    document.addEventListener('ionBackButton', (ev: any) => {
      ev.detail.register(1005, async (processNextHandler: any) => {
        console.log('Handler D was called!');
        const alert = await alertController.getTop();
        console.log(alert);
        if (alert) {
          alert.dismiss();
          return;
        }
        processNextHandler();
      });
    });
    return () => {
      console.log("use effect return");
    }
  }, [])
12
On

Although pressing the hardware back button automatically closes the IonSelect dropdown. If that doesn't work for you, here is a work-around using useRef hook:

export const SingleSelection: React.FC = () => { 
    const [gender, setGender] = useState<string>();
    const selectRef = useRef<any>(null);

    useEffect(() => {
     
      document.addEventListener('ionBackButton', (ev: any) => {
         ev.preventDefault(); // TO PREVENT THE CLOSING OF MODAL
         ev.detail.register(1000, async (processNextHandler: any) => {
           console.log('Handler B was called!');
           selectRef.current.close() // SEE HERE


           // HERE YOU CAN NOW CLOSE THE MODAL

           processNextHandler();
         });
      });
      return () => {
        console.log("use effect return");
      }
   }, [])

    return (
         ...
         <IonSelect ref={(ref: any) => selectRef.current = ref} value={gender} placeholder="Select One" onIonChange={e => setGender(e.detail.value)}>
            <IonSelectOption value="female">Female</IonSelectOption>
            <IonSelectOption value="male">Male</IonSelectOption>
         </IonSelect>
         ....
    
        );

};
0
On

in ionic 7 if you use interface popover

constructor(private popoverController: PopoverController) {}
closeSelect(){
if (this.popoverController && await this.popoverController.getTop()) {
  await this.popoverController.dismiss();
}
}