I want to use IonModal to capture various inputs and then pass it back to the parent page in React. I’ve been able to get one value to go over but not multiple. I’ve search this forum and other sites with no luck.
It seems that onDismiss below is looking for a string instead of type ModalInput which contains the two values I need to pass back to the parent.
Any help would be appreciated.
<IonButton
onClick={() => {
onDismiss(addedCampaign, "confirm"); //looking for string instead of ModalInput type
}}
strong={true}
>
Confirm
</IonButton>
==> Full code below <==
VolCampaignList.tsx
import {
IonItem,
IonCol,
IonGrid,
IonRow,
IonCard,
IonCardContent,
IonFab,
IonFabButton,
IonIcon,
useIonModal,
} from "@ionic/react";
import { useEffect, useState } from "react";
import { db } from "../../hooks/firebase";
import {
onSnapshot,
query,
collection,
where,
orderBy,
} from "firebase/firestore";
import {
VolCampaignsData,
toVolCampaignsData,
} from "../../models/models4Campaigns";
import { RolesData, toRole } from "../../models/models4Roles";
import { CampaignsData, toCampaignsData } from "../../models/models4Campaigns";
import { mapRole, mapCampaign } from "../../utils/lookups";
import { addCircle, addCircleOutline } from "ionicons/icons";
import VolCampaignModal from "./VolCampaignModal";
import { OverlayEventDetail } from "@ionic/core/components";
import "./VolCampaignList.css";
interface RouteParams {
id: string;
}
interface ModalInputs {
campaignId?: string | null;
roleId?: string | null;
}
const VolCampaignList: React.FC<RouteParams> = ({ id }) => {
const [campaignsList, setCampaignsList] = useState<VolCampaignsData[]>([]);
const [allRoles, setAllRoles] = useState<RolesData[]>([]);
const [allCampaigns, setAllCampaigns] = useState<CampaignsData[]>([]);
const [addedCampaign, setAddedCampaign] = useState<ModalInputs>();
const [present, dismiss] = useIonModal(VolCampaignModal, {
onDismiss: (data: ModalInputs, button: string) => dismiss(data, button),
});
useEffect(() => {
const ref = query(
collection(db, "campaignsByVolunteers"),
where("volunteer", "==", id)
);
return onSnapshot(ref, ({ docs }) => {
setCampaignsList(docs.map(toVolCampaignsData));
});
}, [id]);
useEffect(() => {
const rolesRef = query(collection(db, "roles"), orderBy("role"));
return onSnapshot(rolesRef, ({ docs }) => {
setAllRoles(docs.map(toRole));
});
}, []);
useEffect(() => {
const campaignsRef = query(
collection(db, "campaigns"),
orderBy("year", "desc")
);
return onSnapshot(campaignsRef, ({ docs }) => {
setAllCampaigns(docs.map(toCampaignsData));
});
}, []);
const openModal = () => {
present({
onWillDismiss: (ev: CustomEvent<OverlayEventDetail>) => {
if (ev.detail.role === "confirm") {
console.log(`Hello, ${ev.detail.data}!`);
}
console.log(ev.detail.data);
},
});
};
const addFabButton = () => {
return (
<>
<IonFab slot="fixed" vertical="top" horizontal="end">
<IonFabButton
onClick={() => {
openModal();
}}
>
<IonIcon ios={addCircleOutline} md={addCircle} />
</IonFabButton>
</IonFab>
</>
);
};
return (
<IonCard>
<IonCardContent>
{addFabButton()}
<IonGrid fixed={true}>
<IonRow className="vcamp-col-header">
<IonCol size="6">Campaign</IonCol>
<IonCol size="6">Role</IonCol>
</IonRow>
</IonGrid>
<IonGrid fixed={true}>
{campaignsList.map((campaign) => (
<IonItem button key={campaign.id}>
<IonRow className="vcamp-data">
<IonCol size="6">
{mapCampaign(campaign.campaign, allCampaigns)}
</IonCol>
<IonCol size="6">{mapRole(campaign.role, allRoles)}</IonCol>
</IonRow>
</IonItem>
))}
</IonGrid>
</IonCardContent>
</IonCard>
);
};
export default VolCampaignList;
VolCampaignModal.tsx
import { useState, useEffect } from "react";
import {
IonButtons,
IonButton,
IonHeader,
IonContent,
IonToolbar,
IonTitle,
IonItem,
IonPage,
IonSelect,
IonSelectOption,
} from "@ionic/react";
import { db } from "../../hooks/firebase";
import {
onSnapshot,
query,
collection,
where,
orderBy,
} from "firebase/firestore";
import { RolesData, toRole } from "../../models/models4Roles";
import { CampaignsData, toCampaignsData } from "../../models/models4Campaigns";
import "./VolunteersEdit.css";
interface ModalInputs {
campaignId?: string | null;
roleId?: string | null;
}
export const VolCampaignModal = ({
onDismiss,
}: {
onDismiss: (
campaignId?: string | null | undefined,
roleId?: string | null | undefined,
button?: string
) => void;
}) => {
const [activeRoles, setActiveRoles] = useState<RolesData[]>([]);
const [activeCampaigns, setActiveCampaigns] = useState<CampaignsData[]>([]);
const [addedCampaign, setAddedCampaign] = useState<ModalInputs>();
// const inputRef = useRef<HTMLIonInputElement>(null);
useEffect(() => {
const rolesRef = query(
collection(db, "roles"),
where("active", "==", true),
orderBy("role")
);
return onSnapshot(rolesRef, ({ docs }) => {
setActiveRoles(docs.map(toRole));
});
}, []);
useEffect(() => {
const campaignsRef = query(
collection(db, "campaigns"),
where("active", "==", true),
orderBy("year", "desc")
);
return onSnapshot(campaignsRef, ({ docs }) => {
setActiveCampaigns(docs.map(toCampaignsData));
});
}, []);
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonButton color="medium" onClick={() => onDismiss(null, "cancel")}>
Cancel
</IonButton>
</IonButtons>
<IonTitle>Campaign Addition</IonTitle>
<IonButtons slot="end">
<IonButton
onClick={() => {
onDismiss(addedCampaign, "confirm"); //looking for string instead of ModalInput type
}}
strong={true}
>
Confirm
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<IonItem key="selection-campaign">
<IonSelect
label="Campaign"
placeholder="Make a Selection"
onIonChange={(event) => {
setAddedCampaign({
...addedCampaign,
campaignId: event.detail.value,
});
}}
>
{activeCampaigns.map((campaign) => (
<IonSelectOption key={campaign.id} value={campaign.id}>
{campaign.year + " - " + campaign.event}
</IonSelectOption>
))}
;
</IonSelect>
</IonItem>
<IonItem key="selection-role">
<IonSelect
label="Role"
placeholder="Make a Selection"
onIonChange={(event) => {
setAddedCampaign({
...addedCampaign,
roleId: event.detail.value,
});
}}
>
{activeRoles.map((role) => (
<IonSelectOption key={role.id} value={role.id}>
{role.role}
</IonSelectOption>
))}
;
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
export default VolCampaignModal;