ReactJS: Auto save form by using .click removes focus - reactjs

I have a form which I am auto saving by triggering a click every 1.5secs by targeting the button element and performing a .click:
let intervalID;
useEffect(() => {
if (editing) {
intervalID = setInterval(() => {
const formSubmitButton = document.querySelector(".btnaa");
formSubmitButton.click();
}, 1500);
This works well for the most part, but on modals etc it removes the focus and closes it.
How do I prevent this from happening? I tried using e.preventDefault() but then that does not save the form. Essentially what I am trying to do, is trigger the form to submit without removing focus.

Related

How to detect click outside React APPLICATION?

I want a functional React component to close whenever the user clicks outside the application as well as outside the component within the application.
I've worked out how to close the component so long as the user clicks inside the containing application, but it still ignores clicks in an entirely different Windows application.
I want to emulate the behavior of the "Avatar" button at the top right of a Google Maps window. The button opens a modal dialog that is dismissed when the user clicks anywhere outside the dialog.
My current code has a useEffect hook that calls addEventListener and removeEventListener on the current document:
useEffect(() => {
const handleClickOutside = (event) => {
if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
onCloseButtonClick(event)
}
};
document.addEventListener("click", handleClickOutside, true);
return () => {
document.removeEventListener("click", handleClickOutside, true);
};
}, [onCloseButtonClick]);
I had hoped the solution was as simple as attaching addEventListener and removeEventListener on window instead of document, but it doesn't work.
How can I clear the visible property of the component when the user clicks outside the containing application?
Thanks in advance for your attention.
You probably need to also listen to onblur on the window. That can call the onCloseButtonClick straight away as theres no element attached to those events.
useEffect(() => {
const handleClickOutside = (event) => {
if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
onCloseButtonClick(event)
}
};
document.addEventListener("click", handleClickOutside, true);
window.addEventListener("blur", onCloseButtonClick, true);
return () => {
document.removeEventListener("click", handleClickOutside, true);
window.removeEventListener("blur", onCloseButtonClick, true);
};
}, [onCloseButtonClick]);

Show default browser dialog to prevent user from going back

I know many questions about this have already been asked but I'm struggling finding what I need. I am using react-router 5.1.2 to manage navigation in my web-app. I want to alert the user before he leaves the page. Attach beforeUnload listener does not work when users press the browser's back button. I understand I can use history.block() or <Prompt>, but the alert does not behaves like the default one shown when beforeUnload is fired, e.g. I can press back button twice then press "cancel" and have inconsistencies between the route and the actual rendered component. The question is: how can I alert the user pressing back button obtaining a confirmation dialog that behaves as the default one (preventing further actions other than those proposed by the alert)?
This is the custom hook I've used so far:
const alertUser = (e: BeforeUnloadEvent | PopStateEvent) => {
e.preventDefault();
e.returnValue = '';
};
export const useAlertBeforeLeaving = (showAlert = true) => {
const history = useHistory();
const unblock = useRef<UnregisterCallback | null>(null);
useEffect(() => {
if (showAlert) {
window.addEventListener('beforeunload', alertUser);
unblock.current = history.block('Leave the page?');
}
return () => {
if (showAlert && unblock.current) {
window.removeEventListener('beforeunload', alertUser);
unblock.current();
}
};
}, [history, showAlert]);
};

Getting data with React and Spring pagination

I'm using Spring data Pagination with React to get some data. I have two ways of getting the data from the backend, the first one when the component re-render. The second way when clicking on a button.
const searchButton = () => {
isLoading(true);
searchOrder(searchInput, pageNumber, 'name').then((res) => {
setOrders(res.data.content);
setTotalElements(res.data.totalElements);
setCurrentPage(res.data.number);
setItemsCountPerPage(res.data.size);
isLoading(false);
});
};
useEffect(() => {
isLoading(true);
getOrders(pageNumber, 'name').then((res) => {
setOrders(res.data.content);
setTotalElements(res.data.totalElements);
setCurrentPage(res.data.number);
setItemsCountPerPage(res.data.size);
isLoading(false);
});
}, [pageNumber, refreshPage]);
When clicking on the button I will get the data, but when trying to go to the next page, it will fire the useEffect and will get the data from it. My question: how should I go to the next page from the data that I got when clicking the button?
I solved this by adding the content of the search button in the useEffect method as a conditional statement.

How to reset form in redux form with reset and getForm with getFormValues

i have a question about how to reset field via action cancel and after click button add again the form will be reset.
this is my container
client.js
actionBatalAdd = (event) => {
event.preventDefault();
this.props.hideModalAdd()
this.props.resetField;
}
const mapStateToProps = state => ({
...state.locale,
...state.client,
layoutData: { ...state.layout },
resetField : reset("add-client"),
formValue: getFormValues('edit-client')(state),
formValue2 : getFormValues('add-client')(state),
});
i already try with reset from redux-form, but still no change, when i try to typing any character and then i press the cancel button, and after that i press the button add, the character still there, still no reset.

Intercept back event in an react app to confirm save

I am building a react native app using expo.io.
The app is using a Stack Navigator to move between pages (cards).
My problem is that I have one page where users can create new items and I want to save the items when they leave the page.
Instead of saving all their changes, I want to prompt the user if they want to save changes before leaving the page so they get a chance to discard any changes they have made.
I have not been able to find an event for exiting the page that I can hook into and prompt the user if they want to save their changes?
The closest I have found to what I want to do is in backhandler, but that only works for Android back button.
Is there a way to do something similar if the user goes back with the back button in the header of the card, or if they use a swipe gesture?
Use NavigationEvents. Add event listeners to your components.
onWillFocus - event listener
onDidFocus - event listener
onWillBlur - event listener
onDidBlur - event listener
for example, the following will get fired when the next screen is focused.In the other screen, save user's changes in temporary storage, when they navigate back, get those unsaved changes and prompt the user, whether they want to save or not.
focusSubscription = null;
onWillFocus = (payload) => {
if (payload && payload.action && payload.action.type && payload.action.type === 'Navigation/BACK') {
// get values from storage here
// if there were unsaved changes prompt the user if they want to those changes or not
}
};
componentDidMount = () => {
this.focusSubscription = this.props.navigation.addListener(
'willFocus',
this.onWillFocus,
);
}
componentWillUnmount = () => {
this.focusSubscription && this.focusSubscription.remove();
this.focusSubscription = null;
};
Demo
React Navigation added in version 5.7 the beforeRemove event which you can use for this.
This is the demo from their site:
function EditText({ navigation }) {
const [text, setText] = React.useState('');
const hasUnsavedChanges = Boolean(text);
React.useEffect(
() =>
navigation.addListener('beforeRemove', (e) => {
if (!hasUnsavedChanges) {
// If we don't have unsaved changes, then we don't need to do anything
return;
}
// Prevent default behavior of leaving the screen
e.preventDefault();
// Prompt the user before leaving the screen
Alert.alert(
'Discard changes?',
'You have unsaved changes. Are you sure to discard them and leave the screen?',
[
{ text: "Don't leave", style: 'cancel', onPress: () => {} },
{
text: 'Discard',
style: 'destructive',
// If the user confirmed, then we dispatch the action we blocked earlier
// This will continue the action that had triggered the removal of the screen
onPress: () => navigation.dispatch(e.data.action),
},
]
);
}),
[navigation, hasUnsavedChanges]
);
return (
<TextInput
value={text}
placeholder="Type something…"
onChangeText={setText}
/>
);
}

Resources