I am trying to have my screen move to the newly added elements position in my React/Ionic App but no matter what I try it doesn't work right.
I have tried using refs. I have tried using scrollTo(), ScrollIntoView - which with refs moved the screen at all at least, I am trying to use IonContent Scroll functions now but it wont budge.
My goal is to have my screen scroll to the new exercise when i click the button
this is my code
const AddWorkout: React.FC<Props & InjectedFormProps<{}, Props>> = (
props: any
) => {
const { pristine, submitting, handleSubmit } = props;
const dispatch = useDispatch();
const [duration, setDuration] = useState("");
const [openPicker, setOpenPicker] = useState(false);
return (
<>
<IonModal isOpen={props.show} animated backdropDismiss>
<IonHeader>
<IonToolbar>
<IonTitle>Add A New Workout</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent
scrollEvents={true}
onIonScrollStart={_e => {
console.log(_e);
}}
onIonScroll={() => { }}
onIonScrollEnd={() => { }}
>
<form className="edit-modal">
<IonGrid className="ion-no-margin">
<IonRow>
<Field
name="name"
title="Name"
component={ReduxFormInput}
/>
</IonRow>
<IonRow>
<Field
name="date"
title="Date"
type="date"
values={new Date().toISOString()}
component={ReduxFormDateTime}
/>
</IonRow>
<IonRow>
<Field
name="duration"
title="Duration"
duration={duration}
setDuration={setDuration}
openPicker={openPicker}
setOpenPicker={setOpenPicker}
component={ReduxDurationInput}
/>
</IonRow>
<FieldArray name="exercises" component={renderExercises} />
</IonGrid>
</form>
</IonContent>
<IonFooter>
<IonRow>
<IonCol>
<IonButton expand="block" fill="clear" onClick={props.onCancel}>
Cancel
</IonButton>
</IonCol>
<IonCol>
<IonButton
expand="block"
color="success"
type="submit"
onClick={handleSubmit(submitForm)}
disabled={submitting || pristine}
>
Add Workout
</IonButton>
</IonCol>
</IonRow>
</IonFooter>
</IonModal>
</>
);
};
const renderExercises = (props: WrappedFieldArrayProps<{}>) => {
const { fields } = props;
const { error, submitFailed } = props.meta;
const groupIdx: Array<any> = fields.getAll()
const moveExerciseUp = (from: number, to: number) => {
if (from !== 0) {
fields.move(from, to);
}
};
const moveExerciseDown = (from: number, to: number) => {
if (from !== fields.length - 1) {
fields.move(from, to);
}
};
const onMovePosition = (from: number, pos: number) => {
if (pos > 0 && pos <= fields.length) {
let breakOutOfLoop = false
groupIdx.forEach((field, idx) => {
// if one of the items has the correct group number,
// assign the position to move to to that position
if (field.group === pos && !breakOutOfLoop) {
fields.move(from, idx)
breakOutOfLoop = true
}
if (idx + 1 < fields.length && field.group > groupIdx[idx + 1].group) {
fields.swap(idx, idx + 1)
}
})
}
}
// THIS IS WHERE MY CODE IS!!!!!!!!!!!!!!!
const gotoButton = () => {
let y = document.getElementById("exerciseScroll")!.offsetTop;
let content = document.querySelector("ion-content");
content?.scrollToPoint(0, y);
};
return (
<>
<IonRow className="sticky-button">
<IonCol>
<IonButton
type="button"
expand="full"
onClick={() => {
fields.push({ group: fields.length + 1 })
gotoButton()
}}
>
Add Exercise
</IonButton>
</IonCol>
</IonRow>
<IonRow>
<IonCol>
{fields.map((exercise, idx) => {
return (
<div key={idx} className="ion-text-center" style={{ border: "1px solid black", borderRadius: "5px" }}>
<IonRow className="ion-margin-vertical">
<IonCol size="6" className="ion-no-padding ion-margin-vertical ion-text-right">
<h4 style={{ margin: 0 }}>
Exercise Group #
</h4>
</IonCol>
<Field
name={`${exercise}.group`}
component={ReduxFormGroupInput}
position={idx}
parse={(value: string) => parseInt(value, 10)}
normalize={
(value: any, previousValue: any, allValues: any) => {
if (value < 0 || value > fields.length || isNaN(value)) {
return previousValue
}
if (idx > 0 && allValues.exercises[idx - 1].group - 1 < allValues.exercises[idx].group) {
let i = idx + 1;
for (i; i < fields.length; i++) {
if (groupIdx[i].group === groupIdx[idx].group) {
allValues.exercises[i].group--
}
}
}
return allValues.exercises[idx].group
}
}
change={onMovePosition}
className="ion-no-padding ion-float-left ion-text-center"
/>
<IonCol>
<small style={{ color: "gray" }}>(Change the group # to create supersets)</small>
</IonCol>
</IonRow>
<IonRow>
<div style={{ position: "relative", marginRight: 30 }}>
<IonButton
fill="clear"
size="small"
style={{ position: "absolute", top: 10, left: 0 }}
onClick={() => moveExerciseUp(idx, idx - 1)}
>
<IonIcon icon={arrowUp} slot="icon-only" />
</IonButton>
<IonButton
fill="clear"
size="small"
style={{ position: "absolute", bottom: 0, left: 0 }}
onClick={() => moveExerciseDown(idx, idx + 1)}
>
<IonIcon icon={arrowDown} slot="icon-only" />
</IonButton>
</div>
<Field
name={`${exercise}.name`}
title="Exercise Name"
component={ReduxFormInput}
/>
</IonRow>
<IonButton
onClick={() => fields.remove(idx)}
color="danger"
fill="clear"
size="small"
>
REMOVE EXERCISE
</IonButton>
<FieldArray
name={`${exercise}.sets`}
props={null}
component={renderSets}
/>
</div>
);
})}
{submitFailed && error && (
<span style={{ color: "red" }}>{error}</span>
)}
</IonCol>
</IonRow>
<div id="exerciseScroll" />
</>
);
};