T
TanStack2y ago
broad-brown

Is there a dirty flag? (True if there is even one character in the form.)

Hi, actually I find tanstack form, and I try it now!
16 Replies
automatic-azure
automatic-azure2y ago
Hi, I think the isTouched (field.state.meta.isTouched) flag is similar to what you're looking for! You can use it the following way:
<p>
Is {field.name} dirty? {field.state.meta.isTouched ? 'yes' : 'no'}
</p>
<p>
Is {field.name} dirty? {field.state.meta.isTouched ? 'yes' : 'no'}
</p>
See this example on StackBlitz: https://stackblitz.com/edit/tanstack-form-s5phf6?file=src%2Findex.tsx
fuko
StackBlitz
Form Simple Example (forked) - StackBlitz
Run official live example code for Form Simple, created by Tanstack on StackBlitz
broad-brown
broad-brownOP2y ago
@fuko Thankyou! yeah, I think so, but it is a little bit different. I want to avoid navigating when text remains in text field. This isTouch parameter, I click form then it flag is true forever. isn`t it? My English is poor, so please feel free to point this out
automatic-azure
automatic-azure2y ago
Yes, as far as I know, the isTouched flag does remain true until the form is reset (formApi.reset()). ☺️ Can you tell me more about how you would use the isDirty flag? (btw don't worry about your English, I'm not a native speaker as well! 😆 )
broad-brown
broad-brownOP2y ago
For example, our customer want to update user form. There is their name in this form. User touches form and add text, but delete added text. In this case, navigating other page is OK. But maybe isTouched is true. I want to compare with default values deeply.
automatic-azure
automatic-azure2y ago
😅 I think I still don't understand the problem completely... Tell me if I got the scenario correctly: 1. User visits a page where they can update their username 2. User sees their username in the input field (this is the default value) 3. User clicks on the input field of the username 4. User edits the username (<-- This is when isTouched becomes true) 5. User deletes everything in the input field (<-- isTouched is still true) 6. User navigates to a different page, so the input field disappears. If the component that holds the form gets unmounted, it resets the value of isTouched to false, so the next time the user visits this page, isTouched will be false. At step 5, you know: - if the user has touched the form (field.state.meta.isTouched) - what the current value of the field is (field.state.value) - what the default value was (form.options.defaultValues[theNameOfYourField]) My question is this: what piece of information is missing for you in the steps above? Where should isTouched behave differently, to fit your needs? ☺️
broad-brown
broad-brownOP2y ago
step 5: User deletes everything in the input field (<-- isTouched is still true)
User deletes some changes in the input field. So default value mattzn => edit mattzn1217 => delete mattzn This situation, field.state.value === defaultValue , so, this form is not dirty.
step 6: User navigates to a different page,
We develop BtoB SaaS application. Our user edit important data, user made a mistake and clicked on link. They do not want screen transitions when changes are made to the form. That’s why we use react-hook-form's isDirty flag to avoid navigating other pages. If isDirty flag is true, If a user tries to make a screen transition with a change in the form, a popup will appear. I can do something simillar with isTouched flag. But user made a mistake and touch a form, isTouched flag change true, doesn't it? In this situation, user want to navigate other pages. @fuko
sunny-green
sunny-green2y ago
I think there needs to be a distinction between isTouched and isDirty, which I don't think is built in right now. touched means they focused it at least once, dirty means currentValue !== originalValue I had talked with crutchcorn about adding it but when I started I realized complicated pieces like z.string().array() (in zod schemas for example) for checkboxes/radios was a little out of my comfort zone My original message: https://discord.com/channels/719702312431386674/1100437019857014895/1191884556341620816
automatic-azure
automatic-azure2y ago
Okay, I think I finally understood you! Yepp, that isTouched flag does not exist, but I have an idea for a workaround, let me check it and get back to you! Thanks for your input, it made things clearer to me. I read your conversation with crutchcorn and I think I could try picking up the task! I won't be able to do it immediately though, because I have some stuff going on with tanstack.com + the implementation of the array fields and the context provider are going through a refactor right now (thanks to crutchcorn), and I'm not sure if that affects this feature.
automatic-azure
automatic-azure2y ago
@mattzn(まっつん) I made this example, where I check if currentValue === defaultValue (if yes: isDirty: true, if no: isDirty: false). Was this what you were looking for? https://stackblitz.com/edit/tanstack-form-5vmwbm?file=src%2Findex.tsx
fuko
StackBlitz
Form Simple Example (isDirty) - StackBlitz
Run official live example code for Form Simple, created by Tanstack on StackBlitz
automatic-azure
automatic-azure2y ago
Here's another example where the isDirty check runs for the whole form instead of just one field: https://stackblitz.com/edit/tanstack-form-jprnoh?file=src%2Findex.tsx
fuko
StackBlitz
Form Simple Example (isDirty - form) - StackBlitz
Run official live example code for Form Simple, created by Tanstack on StackBlitz
automatic-azure
automatic-azure2y ago
Note that these workarounds only work when the values of the fields can be compared with the default values using the !== operator. So strings, numbers, and booleans are ok, but things like arrays and objects require some modifications.
broad-brown
broad-brownOP2y ago
yeah, I'm looking for this. If This feature is standard use like react hook form, this help me
automatic-azure
automatic-azure2y ago
No, unfortunately, this is not a standard feature, just a workaround. I basically run this code wherever I want to see if the form is dirty:
function checkIfFormDirty(values: typeof form.state.values) {
const { defaultValues } = form.options;
return Object.entries(values).some(([name, value]) => {
return defaultValues
? defaultValues[name as keyof typeof defaultValues] !== value
: /*
If no default values were defined,
then the field will be dirty if the
value of it is NOT falsy.
*/
!!value;
});
}

const isDirty = checkIfFormDirty(form.state.values)
function checkIfFormDirty(values: typeof form.state.values) {
const { defaultValues } = form.options;
return Object.entries(values).some(([name, value]) => {
return defaultValues
? defaultValues[name as keyof typeof defaultValues] !== value
: /*
If no default values were defined,
then the field will be dirty if the
value of it is NOT falsy.
*/
!!value;
});
}

const isDirty = checkIfFormDirty(form.state.values)
Unfortunately, this code snippet has some limitations, but they are solvable, I just didn't have the time to do it now: https://discord.com/channels/719702312431386674/1199336913862135900/1202738835155591168
automatic-azure
automatic-azure2y ago
@crutchcorn what do you think about me implementing the isDirty flag (https://discord.com/channels/719702312431386674/1199336913862135900/1202449369404547143) for the form (it has been previously discussed here: https://discord.com/channels/719702312431386674/1100437019857014895/1191884556341620816)? I know that some things are being refactored right now. Is it a good idea to wait a bit with this feature, or should I just go for it?
Discord
Discord - A New Way to Chat with Friends & Communities
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
wise-white
wise-white2y ago
Go for it! I don't think any of my refactor should impact this.
automatic-azure
automatic-azure2y ago
To keep everyone in this convo in the loop: I finished the PR over the weekend: https://github.com/TanStack/form/pull/598. (By "finished" I mean it's ready for review, so we might need a few more iterations before it gets merged.)

Did you find this page helpful?