Reputation: 183
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>
);
};
Upvotes: 3
Views: 1843
Reputation: 111
in ionic 7 if you use interface popover
constructor(private popoverController: PopoverController) {}
closeSelect(){
if (this.popoverController && await this.popoverController.getTop()) {
await this.popoverController.dismiss();
}
}
Upvotes: 0
Reputation: 2112
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>
....
);
};
Upvotes: 0
Reputation: 183
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");
}
}, [])
Upvotes: 3