How to submit #atlaskit/form remotely - reactjs

I want to submit a #atlaskit/form from the button outside the form. I have gone through https://atlaskit.atlassian.com/packages/core/form but no documentation regarding this

Warning: When trying to submit a form remotely, you would need to go out of your way to actually make the validation work. This is applicable to HTML forms, thus not limited by Atlaskit forms.
Read about it here:
How to force a html5 form validation without submitting it via jQuery
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation
Answer:
Atlaskit form actually renders the native html form underneath. Therefore,
we can attach a ref to the Form element and then trigger submit of the form property of the current ref.
Example:
// attach the ref to form
class extends React.Component{
form = React.createRef();
render() {
<Form
ref={this.form}
{...props}
>
{children}
</Form>
}
}
Trigger submit on html form:
this.form.current.form.submit()
See example codesandox here.

Related

Google Tag Manager Form Submission with Formik

Try as I may, I am unable to successfully track any form submissions with Google Tag Manager when the form is submitted by Formik in a React project. I have tried every possible variable, trigger, tag option that I can find. Nothing. gtm.formsubmit is never firing.
Any ideas why?
Event has to be prevent before send to formik. My current workaround:
const handleSubmit = event => {
formFormik.handleSubmit(event.preventDefault());
};
<form id="form-test" onSubmit={handleSubmit}>
...
</form>

#testing-library/React : Clicking outside of component not working

I'm using react testing library to test my component built with FluentUI.
Here is link:
https://codesandbox.io/s/keen-borg-2tqmj?file=/src/App.spec.js
The code is basically a pasted snippet of the example code of Dialog component from FluentUI docs site. The behavior that I'm testing is:
User opens the dialog
User clicks outside of the dialog
onDimiss prop of the component should be fired.
It works when I'm playing with it manually however it seems that I failed to simulate a click outside of the component with testing library.
I tried using userEvent.click(document.body) as mentioned in this post but got no luck
Does anyone has any idea how to make test work?
It is not working because the Dialog component is not listening for the onClick event on the body, so what you need to do in this case is to find the actual element that is being clicked, observing the dom you'll find that the overlay is a div with some overlay classes on it.
<div
class="ms-Modal is-open ms-Dialog root-94"
role="document"
>
<div
aria-hidden="true"
class="ms-Overlay ms-Overlay--dark root-99"
/>
The problem now is to find a way to select it. Unfortunately, you cannot select elements in RTL by their className, so you need to use another selector; in this case, we can get the parent element by the role and then access the first child.
const onDismiss = jest.fn();
const { getByRole } = render(<App onDismiss={onDismiss} />);
UserEvent.click(screen.getByText("Open Dialog"));
const document = getByRole("document");
UserEvent.click(document.firstChild);
expect(onDismiss).toHaveBeenCalled();
https://codesandbox.io/s/hungry-joliot-tjcph?file=/src/App.spec.js

How should I show editable data after it has been submitted with a form so that I can reuse a form components?

If I was making a website where the user submits some data using a form and then the user is redirected to a page with a unique URL where they can view this data, what is the best way to display this data to user in a way in which they can make updates to it?
To give some context I am using react and right now I am showing the same form again on the view data page, but as the forms have slightly different display options, such as some fields being disabled and some extra buttons I am repeating the same form in two seperate components which seems to go against the react way of doing things.
The way I would personally do it is have all your form elements in a single component and use it for the create and edit page, then just pass a "isCreating" or "isEditing" prop, or something similar. In that component, you can then conditionally disable your inputs.
Component
const SomeForm = ({ isEditing }) => {
const onSubmit = () => {
if (isEditing) {
// Make request to update endpoint
} else {
// Make request to create endpoint
}
};
return (
<>
<form onSubmit={onSubmit}>
<input disabled={isEditing} />
<input />
</form>
</>
);
};
Create Page Usage
<MyForm />
Edit Page Usage
<MyForm isEditing />
Note that if you're doing a ton of conditional logic/rendering based on whether you're creating or editing a form, it might be better to split it into two separate form components. If you're simply disabling some inputs on the edit page and doing different submit logic, then I think this is fine.

Show warning on leaving without saving

I'm working on a React page which has a card component which opens on clicking a button. I'm trying to show a warning if the user tries to close the card without saving the changes. The card doesn't have a close button, it closes when clicking anywhere on the screen outside of the card.
I've built a similar warning modal by checking if the route has changed, however since in this case the card component is part of the same page I cannot apply the same logic.
<CardSidebar
onHide={(e) => this.setState({ showSidebar: false})}
>
<FormComponent
data={this.state.item}
filterTypes={this.state.filterTypes}
dataFields={stores.dataFieldStore.dataFieldsForDropDownComponents}
refresh={this.refreshListHandler}
cancelHandler={this.cancelHandler}
/>
<>
<RouteLeavingGuard
// when={?}
/>
</>
</CardSidebar>
So basically you want to know when the form is dirty and data is not saved so the guard would pop up. As far as I can see you are not using any library for handling this kind of behavior in forms so you need to build custom. I also don't see that you are using something as Redux so you need to lift state up and keep the isDirty value in the state of the component that is shown in the snippet.
//This code goes in the snippet that you pasted
state={
isDirty:false
}
isDirtyHandler(value){
this.setState({isDirty:value})
}
Pass the isDirtyHandler and isDirty as prop for check into the <FormComponent/> and inside the component make the following check
//This goes in <FormComponent/>
componentDidUpdate(prevProps, prevState) {
if(this.state.data !== prevState.data && !this.props.isDirty) {
this.props.isDirtyHandler(true)
}
onSubmitHandler(){
this.props.isDirtyHandler(false)
//whole logic for submitting the form
}
and just in the guard you are checking if form is dirty
<RouteLeavingGuard
popUp={isDirty}
/>

Redux Form - how to disable sync/async validation with a flag

I am looking for the most non invasive way to disable validation of redux form for dev/debug purposes
I have a wizard form similar to the tutorial https://redux-form.com/8.1.0/examples/wizard/ but I am using field validators plus an async validator
I would still like to display errors but be able to proceed to the next wizard step even when validation fails
I would like to add a flag to the url like ?ignore-validation=true (using react router)
here is a fragment of my wizard step1:
export class CustomerStep1 extends React.PureComponent<FormProps> {
render(): React.Node {
const {
handleSubmit,
} = this.props;
const submit = handleSubmit(createValidateCardAction);
return (
<form onSubmit={submit}>
<Field
name="card_number"
placeholder="7777 1234 5678 9012"
component={Input}
validate={cardNumber}
/>
...
export default reduxForm({
form: 'customerWizard',
destroyOnUnmount: false,
forceUnregisterOnUnmount: true,
})(CustomerStep1);
I see two possibilities here:
1) Split your wizard forms in more than one form and validate them separately. You could create another state to control which form you want to show. Even though it has more states to manage, I would pick that one.
2) You could leave just the async validation for each field and throw the errors there. Also, You must create a state to manage the page and manage it inside the async validation functions. I create an example of this second approach: https://codesandbox.io/s/o46k8lx7kz

Resources