Skip to content

Commit 1d8e95d

Browse files
committed
fix(textarea): implement formResetCallback to reset forms
1 parent 9d14d67 commit 1d8e95d

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

core/src/components/textarea/test/form/textarea.e2e.ts

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
136136
expect(isValidAfterSubmit).toBe(true);
137137
});
138138

139-
test('should set formData when submitted', async ({ page }) => {
139+
test('should set formData when submit button is clicked', async ({ page }) => {
140140
await page.setContent(
141141
`
142142
<form onsubmit="return onSubmit(event)">
@@ -195,5 +195,88 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
195195
expect(formData).toBeDefined();
196196
expect(formData?.['textarea']).toBe('Test value');
197197
});
198+
199+
test('should reset formData when reset button is clicked', async ({ page }) => {
200+
await page.setContent(
201+
`
202+
<form onsubmit="return onSubmit(event)">
203+
<ion-textarea label="textarea" name="textarea" required></ion-textarea>
204+
<button type="submit">Submit</button>
205+
<button type="reset">Reset</button>
206+
</form>
207+
<script>
208+
function onSubmit(event) {
209+
window.formSubmitted = true;
210+
event.preventDefault();
211+
return false;
212+
}
213+
</script>
214+
`,
215+
config
216+
);
217+
218+
const textarea = page.locator('ion-textarea');
219+
const submitButton = page.locator('button[type="submit"]');
220+
const resetButton = page.locator('button[type="reset"]');
221+
222+
// Type into the native textarea
223+
await textarea.evaluate((el: HTMLIonTextareaElement) => {
224+
const nativeTextarea = el.shadowRoot?.querySelector('textarea') as HTMLTextAreaElement | null;
225+
if (nativeTextarea) {
226+
nativeTextarea.value = 'Test value';
227+
nativeTextarea.dispatchEvent(new Event('input', { bubbles: true }));
228+
}
229+
});
230+
231+
// Click submit button - form should submit since validation passes
232+
await submitButton.click();
233+
234+
// Wait for any async operations to complete
235+
await page.waitForChanges();
236+
237+
// Verify that the formData is set
238+
let formData = await page.evaluate(() => {
239+
const form = document.querySelector('form');
240+
if (!form) {
241+
return null;
242+
}
243+
const formData = new FormData(form);
244+
const entries: Record<string, string> = {};
245+
for (const [key, value] of formData.entries()) {
246+
entries[key] = value.toString();
247+
}
248+
return entries;
249+
});
250+
expect(formData).toBeDefined();
251+
expect(formData?.['textarea']).toBe('Test value');
252+
253+
// Click reset button - form should reset
254+
await resetButton.click();
255+
256+
// Wait for any async operations to complete
257+
await page.waitForChanges();
258+
259+
// Verify that the textarea's value is cleared
260+
const textareaValue = await textarea.evaluate((el: HTMLIonTextareaElement) => {
261+
const nativeTextarea = el.shadowRoot?.querySelector('textarea') as HTMLTextAreaElement | null;
262+
return nativeTextarea?.value ?? '';
263+
});
264+
expect(textareaValue).toBe('');
265+
266+
// Verify that the formData is cleared
267+
formData = await page.evaluate(() => {
268+
const form = document.querySelector('form');
269+
if (!form) {
270+
return null;
271+
}
272+
const formData = new FormData(form);
273+
const entries: Record<string, string> = {};
274+
for (const [key, value] of formData.entries()) {
275+
entries[key] = value.toString();
276+
}
277+
return entries;
278+
});
279+
expect(formData?.['textarea']).toBe('');
280+
});
198281
});
199282
});

core/src/components/textarea/textarea.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,14 @@ export class Textarea implements ComponentInterface {
589589
return this.value || '';
590590
}
591591

592+
/**
593+
* Called when the form is reset.
594+
* Resets the component's value.
595+
*/
596+
formResetCallback() {
597+
this.value = '';
598+
}
599+
592600
/**
593601
* Updates the form value and reports validity state to the browser via
594602
* ElementInternals. This should be called when the component loads, when

0 commit comments

Comments
 (0)