Skip to content

Commit 71fa6cc

Browse files
committed
Extract rule: template-no-form-action
1 parent 484c3c6 commit 71fa6cc

4 files changed

Lines changed: 172 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ rules in templates can be disabled with eslint directives with mustache or html
266266
| [no-string-prototype-extensions](docs/rules/no-string-prototype-extensions.md) | disallow usage of `String` prototype extensions || | |
267267
| [template-no-action](docs/rules/template-no-action.md) | disallow {{action}} helper | | | |
268268
| [template-no-attrs-in-components](docs/rules/template-no-attrs-in-components.md) | disallow attrs in component templates | | | |
269+
| [template-no-form-action](docs/rules/template-no-form-action.md) | disallow usage of action attribute on form elements | | | |
269270

270271
### Ember Data
271272

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# ember/template-no-form-action
2+
3+
<!-- end auto-generated rule header -->
4+
5+
Disallows the use of the `action` attribute on form elements.
6+
7+
In modern Ember applications, form submissions should be handled using the `{{on}}` modifier with the `"submit"` event instead of the `action` attribute. This provides better control and follows modern Ember patterns.
8+
9+
## Rule Details
10+
11+
This rule disallows the use of the `action` attribute on `<form>` elements.
12+
13+
## Examples
14+
15+
Examples of **incorrect** code for this rule:
16+
17+
```gjs
18+
<template>
19+
<form action="/submit">
20+
<input type="text" />
21+
</form>
22+
</template>
23+
```
24+
25+
```gjs
26+
<template>
27+
<form action="">
28+
<button>Submit</button>
29+
</form>
30+
</template>
31+
```
32+
33+
Examples of **correct** code for this rule:
34+
35+
```gjs
36+
<template>
37+
<form {{on "submit" this.handleSubmit}}>
38+
<input type="text" />
39+
</form>
40+
</template>
41+
```
42+
43+
```gjs
44+
<template>
45+
<form>
46+
<button type="submit">Submit</button>
47+
</form>
48+
</template>
49+
```
50+
51+
## Migration
52+
53+
Replace:
54+
55+
```gjs
56+
<form action="/submit">
57+
```
58+
59+
With:
60+
61+
```gjs
62+
<form {{on "submit" this.handleSubmit}}>
63+
```
64+
65+
## References
66+
67+
- [eslint-plugin-ember template-no-form-action](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/template-no-form-action.md)
68+
- [Ember.js Guides - Event Handling](https://guides.emberjs.com/release/components/component-state-and-actions/)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'problem',
5+
docs: {
6+
description: 'disallow usage of action attribute on form elements',
7+
category: 'Deprecations',
8+
strictGjs: true,
9+
strictGts: true,
10+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-form-action.md',
11+
},
12+
fixable: null,
13+
schema: [],
14+
messages: {
15+
unexpected:
16+
'Do not use the action attribute on <form> elements. Use the (on) modifier with the "submit" event instead.',
17+
},
18+
},
19+
20+
create(context) {
21+
return {
22+
GlimmerElementNode(node) {
23+
if (node.tag !== 'form') {
24+
return;
25+
}
26+
27+
const actionAttr = node.attributes?.find((a) => a.name === 'action');
28+
if (actionAttr) {
29+
context.report({
30+
node: actionAttr,
31+
messageId: 'unexpected',
32+
});
33+
}
34+
},
35+
};
36+
},
37+
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//------------------------------------------------------------------------------
2+
// Requirements
3+
//------------------------------------------------------------------------------
4+
5+
const rule = require('../../../lib/rules/template-no-form-action');
6+
const RuleTester = require('eslint').RuleTester;
7+
8+
//------------------------------------------------------------------------------
9+
// Tests
10+
//------------------------------------------------------------------------------
11+
12+
const ruleTester = new RuleTester({
13+
parser: require.resolve('ember-eslint-parser'),
14+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
15+
});
16+
17+
ruleTester.run('template-no-form-action', rule, {
18+
valid: [
19+
`<template>
20+
<form {{on "submit" this.handleSubmit}}>
21+
<input type="text" />
22+
</form>
23+
</template>`,
24+
`<template>
25+
<form>
26+
<button type="submit">Submit</button>
27+
</form>
28+
</template>`,
29+
`<template>
30+
<div action="some-action">Not a form</div>
31+
</template>`,
32+
],
33+
34+
invalid: [
35+
{
36+
code: `<template>
37+
<form action="/submit">
38+
<input type="text" />
39+
</form>
40+
</template>`,
41+
output: null,
42+
errors: [
43+
{
44+
message:
45+
'Do not use the action attribute on <form> elements. Use the (on) modifier with the "submit" event instead.',
46+
type: 'GlimmerAttrNode',
47+
},
48+
],
49+
},
50+
{
51+
code: `<template>
52+
<form action="">
53+
<button>Submit</button>
54+
</form>
55+
</template>`,
56+
output: null,
57+
errors: [
58+
{
59+
message:
60+
'Do not use the action attribute on <form> elements. Use the (on) modifier with the "submit" event instead.',
61+
type: 'GlimmerAttrNode',
62+
},
63+
],
64+
},
65+
],
66+
});

0 commit comments

Comments
 (0)