` **class** The class of the button
214 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input-test.js:
--------------------------------------------------------------------------------
1 | import { render, click, fillIn, settled } from "@ember/test-helpers";
2 | import Changeset from "ember-changeset";
3 | import { hbs } from "ember-cli-htmlbars";
4 | import { module, test } from "qunit";
5 |
6 | import { setupRenderingTest } from "dummy/tests/helpers";
7 |
8 | module("Integration | Component | validated input", function (hooks) {
9 | setupRenderingTest(hooks);
10 |
11 | test("it renders simple text inputs with correct name", async function (assert) {
12 | await render(hbs``);
13 |
14 | assert.dom("input").hasAttribute("type", "text");
15 | assert.dom("input").hasAttribute("name", "bar");
16 | });
17 |
18 | test("it renders email input", async function (assert) {
19 | await render(hbs``);
20 |
21 | assert.dom("input").hasAttribute("type", "email");
22 | });
23 |
24 | test("it renders tel input", async function (assert) {
25 | await render(hbs``);
26 |
27 | assert.dom("input").hasAttribute("type", "tel");
28 | });
29 |
30 | test("it renders disabled inputs", async function (assert) {
31 | await render(hbs``);
32 |
33 | assert.dom("input").isDisabled();
34 | });
35 |
36 | test("it renders inputs with placeholder", async function (assert) {
37 | await render(hbs``);
38 |
39 | assert.dom("input").hasAttribute("placeholder", "foo");
40 | });
41 |
42 | test("it renders inputs with value", async function (assert) {
43 | await render(hbs``);
44 |
45 | assert.dom("input").hasValue("foo");
46 | });
47 |
48 | test("it renders inputs with model", async function (assert) {
49 | this.set("model", new Changeset({ firstName: "Max" }));
50 |
51 | await render(
52 | hbs``,
53 | );
54 |
55 | assert.dom("input").hasValue("Max");
56 | });
57 |
58 | test("it calls on-update if given", async function (assert) {
59 | this.set("model", new Changeset({ firstName: "Max" }));
60 | this.set("update", (value, changeset) => {
61 | changeset.set("firstName", value.toUpperCase());
62 | });
63 | await render(
64 | hbs``,
69 | );
70 |
71 | await fillIn("input", "foo");
72 |
73 | assert.dom("input").hasValue("FOO");
74 | });
75 |
76 | test("it renders inputs with value even if model is defined", async function (assert) {
77 | this.set("model", new Changeset({ firstName: "Max" }));
78 |
79 | await render(
80 | hbs``,
81 | );
82 |
83 | assert.dom("input").hasValue("foobar");
84 | });
85 |
86 | test("it renders textarea inputs with correct name", async function (assert) {
87 | await render(hbs``);
88 |
89 | assert.dom("textarea").hasAttribute("name", "bar");
90 | });
91 |
92 | test("it renders disabled textareas", async function (assert) {
93 | await render(hbs``);
94 |
95 | assert.dom("textarea").isDisabled();
96 | });
97 |
98 | test("it renders textareas with placeholder", async function (assert) {
99 | await render(hbs``);
100 |
101 | assert.dom("textarea").hasAttribute("placeholder", "foo");
102 | });
103 |
104 | test("it renders textareas with value", async function (assert) {
105 | await render(hbs``);
106 |
107 | assert.dom("textarea").hasValue("foo");
108 | });
109 |
110 | test("it renders textareas with model", async function (assert) {
111 | this.set("model", new Changeset({ firstName: "Max" }));
112 |
113 | await render(
114 | hbs``,
115 | );
116 |
117 | assert.dom("textarea").hasValue("Max");
118 | });
119 |
120 | test("it renders textareas autocomplete attribute", async function (assert) {
121 | await render(
122 | hbs``,
123 | );
124 |
125 | assert.dom("textarea").hasAttribute("autocomplete", "given-name");
126 | });
127 |
128 | test("it renders input autocomplete attribute", async function (assert) {
129 | await render(
130 | hbs``,
135 | );
136 |
137 | assert.dom("input").hasAttribute("autocomplete", "new-password");
138 | });
139 |
140 | test("it renders the block if provided", async function (assert) {
141 | await render(
142 | hbs`
143 |
144 | `,
145 | );
146 |
147 | assert.dom("#custom-input").exists();
148 | });
149 |
150 | test("it yields the value provided to the block", async function (assert) {
151 | await render(
152 | hbs`
153 |
154 | `,
155 | );
156 |
157 | assert.dom("input").hasValue("my-value");
158 | });
159 |
160 | test("it yields the name from the model as value", async function (assert) {
161 | this.set("model", new Changeset({ firstName: "Max" }));
162 |
163 | await render(
164 | hbs`
165 |
166 | `,
167 | );
168 |
169 | assert.dom("input").hasValue("Max");
170 | });
171 |
172 | test("it yields the value as value if both model and value is provided", async function (assert) {
173 | this.set("model", new Changeset({ firstName: "Max" }));
174 |
175 | await render(
176 | hbs`
182 |
183 | `,
184 | );
185 |
186 | assert.dom("input").hasValue("Other Value");
187 | });
188 |
189 | test("it yields the provided name", async function (assert) {
190 | await render(
191 | hbs`
192 |
193 | `,
194 | );
195 |
196 | assert.dom("input").hasAttribute("name", "foobar");
197 | });
198 |
199 | test("it yields the model", async function (assert) {
200 | this.set("model", new Changeset({ firstName: "Max" }));
201 |
202 | await render(
203 | hbs`
204 |
205 | `,
206 | );
207 |
208 | assert.dom("input").hasValue("Max");
209 | });
210 |
211 | test("it yields an action for updating the model", async function (assert) {
212 | const model = new Changeset({ firstName: "Max" });
213 | this.set("model", model);
214 |
215 | await render(
216 | hbs`
217 |
218 | `,
219 | );
220 |
221 | await click("button");
222 |
223 | assert.strictEqual(model.get("firstName"), "Merlin");
224 | });
225 |
226 | test("it yields an action marking the input as dirty", async function (assert) {
227 | this.setTheme("bootstrap");
228 |
229 | this.set("model", { error: { test: { validation: ["Error"] } } });
230 |
231 | await render(
232 | hbs`
233 |
234 | `,
235 | );
236 |
237 | assert.dom("span.invalid-feedback").doesNotExist();
238 |
239 | await click("button");
240 |
241 | assert.dom("span.invalid-feedback").exists();
242 | });
243 |
244 | test("it yields the input id to the block", async function (assert) {
245 | await render(
246 | hbs`
247 |
248 | `,
249 | );
250 |
251 | const label = this.element.querySelector("label");
252 | const input = this.element.querySelector("input");
253 | assert.strictEqual(label.getAttribute("for"), input.getAttribute("id"));
254 | });
255 |
256 | test("it can change the value from outside the input", async function (assert) {
257 | this.set("model", new Changeset({ firstName: "Max" }));
258 |
259 | await render(
260 | hbs``,
261 | );
262 |
263 | assert.dom("input").hasValue("Max");
264 |
265 | this.set("model.firstName", "Hans");
266 |
267 | assert.dom("input").hasValue("Hans");
268 | });
269 |
270 | test("it can overwrite the input name", async function (assert) {
271 | this.set("model", new Changeset({ firstName: "Max" }));
272 |
273 | await render(
274 | hbs``,
279 | );
280 |
281 | assert.dom("input").hasValue("Max");
282 | assert.dom("input").hasAttribute("name", "testFirstName");
283 | });
284 |
285 | test("it updates _val on nested fields", async function (assert) {
286 | this.set("model", new Changeset({ nested: { name: "Max" } }));
287 |
288 | await render(
289 | hbs`{{this.model.nested.name}}
290 |
291 | {{Input.value}}
292 | `,
293 | );
294 |
295 | assert.dom("#raw").hasText("Max");
296 | assert.dom("#_val").hasText("Max");
297 |
298 | this.model.set("nested.name", "Tom");
299 | await settled();
300 |
301 | assert.dom("#raw").hasText("Tom");
302 | assert.dom("#_val").hasText("Tom");
303 | });
304 | });
305 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/types/select-test.js:
--------------------------------------------------------------------------------
1 | import { render, select } from "@ember/test-helpers";
2 | import hbs from "htmlbars-inline-precompile";
3 | import { module, test } from "qunit";
4 |
5 | import {
6 | setupRenderingTest,
7 | setupUikit,
8 | setupBootstrap,
9 | } from "dummy/tests/helpers";
10 |
11 | module(
12 | "Integration | Component | validated-input/types/select",
13 | function (hooks) {
14 | setupRenderingTest(hooks);
15 |
16 | test("it renders", async function (assert) {
17 | this.set("options", [
18 | { id: 1, label: 1 },
19 | { id: 2, label: 2 },
20 | ]);
21 |
22 | await render(
23 | hbs``,
24 | );
25 |
26 | assert.dom("select").exists();
27 | assert.dom("option").exists({ count: 2 });
28 | assert.dom("option:first-child").hasProperty("selected", true);
29 | });
30 |
31 | test("it supports plain (non-object) options", async function (assert) {
32 | assert.expect(6);
33 | this.set("options", ["foo", "bar"]);
34 |
35 | this.set("update", (value) => {
36 | assert.strictEqual(value, "bar");
37 | });
38 | await render(
39 | hbs``,
43 | );
44 |
45 | assert.dom("select").exists();
46 | assert.dom("option").exists({ count: 2 });
47 | assert.dom("option:first-child").hasProperty("selected", true);
48 | await select("select", "bar");
49 | assert.dom("option:first-child").hasProperty("selected", false);
50 | assert.dom("option:last-child").hasProperty("selected", true);
51 | });
52 |
53 | test("it works with solitary optionTargetPath property", async function (assert) {
54 | assert.expect(2);
55 | this.set("options", [
56 | { key: 111, label: "firstOption" },
57 | { key: 222, label: "secondOption" },
58 | ]);
59 |
60 | this.set("update", (value) => {
61 | assert.strictEqual(value, 222);
62 | });
63 |
64 | await render(
65 | hbs``,
70 | );
71 |
72 | assert.dom("option:first-child").hasText("firstOption");
73 | await select("select", "222");
74 | });
75 |
76 | test("it renders option groups via groupLabelPath", async function (assert) {
77 | this.set("options", [
78 | { key: 1, label: 1, group: "one" },
79 | { key: 2, label: 2, group: "two" },
80 | ]);
81 |
82 | await render(
83 | hbs``,
89 | );
90 |
91 | assert.dom("select").exists();
92 | assert.dom("optgroup[label='one']").exists({ count: 1 });
93 | assert.dom("optgroup[label='two']").exists({ count: 1 });
94 | assert.dom("optgroup:first-child option:first-child").hasText("1");
95 | assert.dom("optgroup:last-child option:first-child").hasValue("2");
96 | });
97 |
98 | test("it renders option groups pre grouped options", async function (assert) {
99 | this.set("options", [
100 | {
101 | groupName: "one",
102 | options: [
103 | { id: 1, label: "First", type: "group1" },
104 | { id: 2, label: "Second", type: "group1" },
105 | ],
106 | },
107 | {
108 | groupName: "two",
109 | options: [{ id: 3, label: "Third", type: "group2" }],
110 | },
111 | ]);
112 |
113 | await render(
114 | hbs``,
119 | );
120 |
121 | assert.dom("select").exists();
122 | assert.dom("optgroup[label='one']").exists({ count: 1 });
123 | assert.dom("optgroup:first-child option:first-child").hasText("First");
124 | assert.dom("optgroup[label='two']").exists({ count: 1 });
125 | assert.dom("optgroup:last-child option:first-child").hasText("Third");
126 | assert.dom("optgroup:last-child option:first-child").hasValue("3");
127 | });
128 |
129 | test("it selects the pre-defined value", async function (assert) {
130 | this.set("value", "2");
131 | this.set("options", [
132 | { key: "1", label: 1 },
133 | { key: "2", label: 2 },
134 | ]);
135 |
136 | await render(
137 | hbs``,
143 | );
144 |
145 | assert.dom("select").hasValue(this.options[1].key);
146 | assert.dom("option:first-child").hasProperty("selected", false);
147 | assert.dom("option:last-child").hasProperty("selected", true);
148 | });
149 |
150 | test("prompt is present and disabled", async function (assert) {
151 | this.set("options", [
152 | { key: 1, label: 1 },
153 | { key: 2, label: 2 },
154 | ]);
155 |
156 | await render(
157 | hbs``,
161 | );
162 |
163 | assert.dom("option:first-child").hasText("Choose this");
164 | assert.dom("option:first-child").hasProperty("disabled", true);
165 | });
166 |
167 | test("prompt is selectable", async function (assert) {
168 | this.set("options", [
169 | { key: 1, label: 1 },
170 | { key: 2, label: 2 },
171 | ]);
172 |
173 | await render(
174 | hbs``,
179 | );
180 |
181 | assert.dom("option:first-child").hasProperty("disabled", false);
182 | });
183 |
184 | test("multiselect is working", async function (assert) {
185 | assert.expect(4);
186 | this.set("options", [
187 | { id: 1, label: "label 1" },
188 | { id: 2, label: "label 2" },
189 | { id: 3, label: "label 3" },
190 | ]);
191 | this.set("update", (values) => {
192 | assert.deepEqual(values, [
193 | { id: 1, label: "label 1" },
194 | { id: 3, label: "label 3" },
195 | ]);
196 | });
197 |
198 | await render(
199 | hbs``,
204 | );
205 |
206 | await select("select", ["1", "3"]);
207 | assert.dom("option:first-child").hasProperty("selected", true);
208 | assert.dom("option:nth-child(2)").hasProperty("selected", false);
209 | assert.dom("option:last-child").hasProperty("selected", true);
210 | });
211 |
212 | test("multiselect is working with plain options", async function (assert) {
213 | assert.expect(4);
214 | this.set("options", ["1", "2", "3"]);
215 | this.set("update", (values) => {
216 | assert.deepEqual(values, ["1", "3"]);
217 | });
218 |
219 | await render(
220 | hbs``,
225 | );
226 |
227 | await select("select", ["1", "3"]);
228 | assert.dom("option:first-child").hasProperty("selected", true);
229 | assert.dom("option:nth-child(2)").hasProperty("selected", false);
230 | assert.dom("option:last-child").hasProperty("selected", true);
231 | });
232 |
233 | test("multiselect works with pre grouped options", async function (assert) {
234 | assert.expect(1);
235 | this.set("update", (values) => {
236 | assert.deepEqual(values, this.options[0].options);
237 | });
238 | this.set("options", [
239 | {
240 | groupName: "one",
241 | options: [
242 | { id: 1, label: "First", type: "group1" },
243 | { id: 2, label: "Second", type: "group1" },
244 | ],
245 | },
246 | {
247 | groupName: "two",
248 | options: [{ id: 3, label: "Third", type: "group2" }],
249 | },
250 | ]);
251 |
252 | await render(
253 | hbs``,
260 | );
261 |
262 | await select("select", ["1", "2"]);
263 | });
264 |
265 | test("multiselect works with pre grouped options and optionsTargetPath", async function (assert) {
266 | assert.expect(1);
267 | this.set("update", (values) => {
268 | assert.deepEqual(
269 | values,
270 | this.options[0].options.map((val) => val.id),
271 | );
272 | });
273 | this.set("options", [
274 | {
275 | groupName: "one",
276 | options: [
277 | { id: 1, label: "First", type: "group1" },
278 | { id: 2, label: "Second", type: "group1" },
279 | ],
280 | },
281 | {
282 | groupName: "two",
283 | options: [{ id: 3, label: "Third", type: "group2" }],
284 | },
285 | ]);
286 |
287 | await render(
288 | hbs``,
296 | );
297 |
298 | await select("select", ["1", "2"]);
299 | });
300 |
301 | module("uikit", function (hooks) {
302 | setupUikit(hooks);
303 |
304 | test("it renders", async function (assert) {
305 | this.set("options", [
306 | {
307 | key: "opt1",
308 | label: "Option 1",
309 | },
310 | {
311 | key: "opt2",
312 | label: "Option 2",
313 | },
314 | ]);
315 |
316 | await render(
317 | hbs``,
318 | );
319 |
320 | assert.dom("select").hasClass("uk-select");
321 | assert.dom("option").exists({ count: 2 });
322 | });
323 | });
324 |
325 | module("bootstrap", function (hooks) {
326 | setupBootstrap(hooks);
327 |
328 | test("it renders", async function (assert) {
329 | this.set("options", [
330 | {
331 | key: "opt1",
332 | label: "Option 1",
333 | },
334 | {
335 | key: "opt2",
336 | label: "Option 2",
337 | },
338 | ]);
339 |
340 | await render(
341 | hbs``,
342 | );
343 |
344 | assert.dom("select").hasClass("form-control");
345 | assert.dom("option").exists({ count: 2 });
346 | });
347 | });
348 |
349 | test("prompt is selectable in compination with optionTargetPath, optionValuePath and optionLabelPath", async function (assert) {
350 | assert.expect(3);
351 | const values = [2, undefined];
352 | this.set("options", [
353 | { value: 1, text: "one" },
354 | { value: 2, text: "two" },
355 | ]);
356 | this.set("update", (value) => {
357 | assert.strictEqual(value, values.shift());
358 | });
359 |
360 | await render(
361 | hbs``,
370 | );
371 |
372 | await select("select", "2");
373 | await select("select", "option:first-child");
374 | assert.dom("option:first-child").hasProperty("disabled", false);
375 | });
376 | },
377 | );
378 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-form-test.js:
--------------------------------------------------------------------------------
1 | import EmberObject from "@ember/object";
2 | import { run } from "@ember/runloop";
3 | import { render, click, blur, fillIn, focus } from "@ember/test-helpers";
4 | import { validateLength } from "ember-changeset-validations/validators";
5 | import hbs from "htmlbars-inline-precompile";
6 | import { module, test } from "qunit";
7 | import { defer } from "rsvp";
8 |
9 | import { setupRenderingTest } from "dummy/tests/helpers";
10 | import UserValidations from "dummy/validations/user";
11 |
12 | module("Integration | Component | validated form", function (hooks) {
13 | setupRenderingTest(hooks);
14 |
15 | test("it renders simple inputs", async function (assert) {
16 | await render(hbs`
17 |
18 | `);
19 |
20 | assert.dom("form label").hasText("First name");
21 | assert.dom("form input").hasAttribute("type", "text");
22 | });
23 |
24 | test("it renders textareas", async function (assert) {
25 | await render(hbs`
26 |
27 | `);
28 |
29 | assert.dom("form label").hasText("my label");
30 | assert.dom("form textarea").exists({ count: 1 });
31 | });
32 |
33 | test("it renders a radio group", async function (assert) {
34 | this.setTheme("bootstrap");
35 |
36 | this.set("buttonGroupData", {
37 | options: [
38 | { key: "1", label: "Option 1" },
39 | { key: "2", label: "Option 2" },
40 | { key: "3", label: "Option 3" },
41 | ],
42 | });
43 |
44 | await render(hbs`
45 |
51 | `);
52 |
53 | assert.dom('input[type="radio"]').exists({ count: 3 });
54 | assert.dom("label:nth-of-type(1)").hasText("Options");
55 | assert.dom("div:nth-of-type(1) > input + label").hasText("Option 1");
56 | assert.dom("div:nth-of-type(2) > input + label").hasText("Option 2");
57 | assert.dom("div:nth-of-type(3) > input + label").hasText("Option 3");
58 | assert.dom("div > input + label").exists({ count: 3 });
59 | assert.dom('input[type="radio"][value="1"]').exists();
60 | assert.dom('input[type="radio"][value="2"]').exists();
61 | assert.dom('input[type="radio"][value="3"]').exists();
62 | });
63 |
64 | test("it renders submit buttons", async function (assert) {
65 | this.set("stub", function () {});
66 |
67 | await render(hbs`
68 |
69 |
70 | `);
71 |
72 | assert.dom("form button").hasAttribute("type", "submit");
73 | assert.dom("form button").hasText("Save!");
74 | });
75 |
76 | test("it renders an always-showing hint", async function (assert) {
77 | await render(hbs`
78 |
79 | `);
80 |
81 | assert.dom("input + div").doesNotExist();
82 | assert.dom("input + small").exists({ count: 1 });
83 | assert.dom("input + small").hasText("Not your middle name!");
84 |
85 | const hintId = this.element.querySelector("input + small").id;
86 |
87 | assert.dom("input").hasAria("describedby", hintId);
88 | });
89 |
90 | test("does not render a tag for buttons if no callbacks were passed", async function (assert) {
91 | await render(hbs`
92 |
93 | `);
94 |
95 | assert.dom("form > p").doesNotExist();
96 | });
97 |
98 | test("it supports default button labels", async function (assert) {
99 | this.set("stub", function () {});
100 |
101 | await render(hbs`
102 |
103 | `);
104 |
105 | assert.dom("form button[type=submit]").hasText("Save");
106 | });
107 |
108 | test("it performs basic validations on submit", async function (assert) {
109 | this.setTheme("bootstrap");
110 |
111 | this.set("submit", function () {});
112 | this.set("UserValidations", UserValidations);
113 |
114 | run(() => {
115 | this.set(
116 | "model",
117 | EmberObject.create({
118 | firstName: "x",
119 | }),
120 | );
121 | });
122 |
123 | await render(hbs`
128 |
129 |
130 | `);
131 |
132 | assert.dom("span.invalid-feedback").doesNotExist();
133 | assert.dom("input").doesNotHaveAria("invalid");
134 |
135 | await click("button");
136 |
137 | assert.dom("input").hasValue("x");
138 | assert.dom("span.invalid-feedback").exists({ count: 1 });
139 | assert
140 | .dom("span.invalid-feedback")
141 | .hasText("First name must be between 3 and 40 characters");
142 |
143 | const errorId = this.element.querySelector("span.invalid-feedback").id;
144 |
145 | assert.dom("input").hasAria("invalid", "true");
146 | assert.dom("input").hasAria("describedby", errorId);
147 | });
148 |
149 | test("it shows error message for custom buttons if (and only if) triggerValidations is passed", async function (assert) {
150 | this.setTheme("bootstrap");
151 |
152 | this.set("UserValidations", UserValidations);
153 |
154 | run(() => {
155 | this.set(
156 | "model",
157 | EmberObject.create({
158 | firstName: "x",
159 | }),
160 | );
161 | });
162 |
163 | this.set("triggerValidations", false);
164 |
165 | await render(hbs`
166 |
167 |
168 | `);
169 |
170 | assert.dom("span.invalid-feedback").doesNotExist();
171 | await click("button");
172 | assert.dom("span.invalid-feedback").doesNotExist();
173 |
174 | this.set("triggerValidations", true);
175 | await click("button");
176 |
177 | assert.dom("input").hasValue("x");
178 | assert.dom("span.invalid-feedback").exists({ count: 1 });
179 | assert
180 | .dom("span.invalid-feedback")
181 | .hasText("First name must be between 3 and 40 characters");
182 | });
183 |
184 | test("it calls on-invalid-submit after submit if changeset is invalid", async function (assert) {
185 | let invalidSubmitCalled;
186 | this.set("invalidSubmit", function () {
187 | invalidSubmitCalled = true;
188 | });
189 | this.set("UserValidations", UserValidations);
190 |
191 | run(() => {
192 | this.set(
193 | "model",
194 | EmberObject.create({
195 | firstName: "x",
196 | }),
197 | );
198 | });
199 |
200 | await render(hbs`
205 |
206 |
207 | `);
208 |
209 | await click("button");
210 |
211 | assert.true(invalidSubmitCalled);
212 | });
213 |
214 | test("it does not call on-invalid-submit after submit if changeset is valid", async function (assert) {
215 | let invalidSubmitCalled;
216 | let submitCalled;
217 | this.set("submit", function () {
218 | submitCalled = true;
219 | });
220 | this.set("invalidSubmit", function () {
221 | invalidSubmitCalled = true;
222 | });
223 |
224 | run(() => {
225 | this.set("model", EmberObject.create({}));
226 | });
227 |
228 | await render(hbs`
234 |
235 |
236 | `);
237 |
238 | await click("button");
239 |
240 | assert.notOk(invalidSubmitCalled);
241 | assert.true(submitCalled);
242 | });
243 |
244 | test("it performs validation and calls onInvalidClick function on custom buttons", async function (assert) {
245 | assert.expect(5);
246 |
247 | this.set("onClick", function () {
248 | assert.step("onClick");
249 | });
250 | this.set("onInvalidClick", function (model) {
251 | assert.step("onInvalidClick");
252 | assert.strictEqual(model.firstName, "x");
253 | });
254 | this.set("SimpleValidations", {
255 | firstName: [validateLength({ min: 3, max: 40 })],
256 | });
257 |
258 | run(() => {
259 | this.set(
260 | "model",
261 | EmberObject.create({
262 | firstName: "x",
263 | }),
264 | );
265 | });
266 |
267 | await render(hbs`
268 |
269 |
273 | `);
274 |
275 | await click("button");
276 | assert.verifySteps(["onInvalidClick"]);
277 | await fillIn("input[name=firstName]", "Some name");
278 | await click("button");
279 | assert.verifySteps(["onClick"]);
280 | });
281 |
282 | test("it performs basic validations on focus out", async function (assert) {
283 | this.setTheme("bootstrap");
284 |
285 | this.set("submit", function () {});
286 | this.set("UserValidations", UserValidations);
287 |
288 | run(() => {
289 | this.set("model", EmberObject.create({}));
290 | });
291 |
292 | await render(hbs`
297 |
298 |
299 | `);
300 |
301 | assert.dom("input + div").doesNotExist();
302 |
303 | await focus("input");
304 | await blur("input");
305 |
306 | assert.dom("span.invalid-feedback").exists({ count: 1 });
307 | assert.dom("span.invalid-feedback").hasText("First name can't be blank");
308 | });
309 |
310 | test("it skips basic validations on focus out with validateBeforeSubmit=false set on the form", async function (assert) {
311 | this.setTheme("bootstrap");
312 |
313 | this.set("submit", function () {});
314 | this.set("UserValidations", UserValidations);
315 |
316 | run(() => {
317 | this.set("model", EmberObject.create({}));
318 | });
319 |
320 | await render(hbs`
326 |
327 |
328 | `);
329 |
330 | assert.dom("span.invalid-feedback").doesNotExist();
331 |
332 | await focus("input");
333 | await blur("input");
334 |
335 | assert.dom("span.invalid-feedback").doesNotExist();
336 |
337 | await click("button");
338 |
339 | assert.dom("span.invalid-feedback").exists({ count: 1 });
340 | });
341 |
342 | test("it skips basic validations on focus out with validateBeforeSubmit=false set on the input", async function (assert) {
343 | this.set("submit", function () {});
344 | this.set("UserValidations", UserValidations);
345 |
346 | run(() => {
347 | this.set("model", EmberObject.create({}));
348 | });
349 |
350 | await render(hbs`
355 |
360 | `);
361 |
362 | assert.dom("input + div").doesNotExist();
363 |
364 | await focus("input");
365 | await blur("input");
366 |
367 | assert.dom("input + div").doesNotExist();
368 | });
369 |
370 | test("on-submit can be an action returning a promise", async function (assert) {
371 | const deferred = defer();
372 |
373 | this.set("submit", () => deferred.promise);
374 |
375 | run(() => {
376 | this.set("model", EmberObject.create({}));
377 | });
378 |
379 | await render(hbs`
384 |
385 | `);
386 |
387 | assert.dom("button").doesNotHaveClass("loading");
388 |
389 | await click("button");
390 |
391 | assert.dom("button").hasClass("loading");
392 |
393 | run(() => deferred.resolve());
394 |
395 | assert.dom("button").doesNotHaveClass("loading");
396 | });
397 |
398 | test("on-submit can be an action returning a non-promise", async function (assert) {
399 | this.set("submit", () => undefined);
400 |
401 | run(() => {
402 | this.set("model", EmberObject.create({}));
403 | });
404 |
405 | await render(hbs`
410 |
411 | `);
412 |
413 | assert.dom("button").doesNotHaveClass("loading");
414 |
415 | await click("button");
416 |
417 | assert.dom("button").doesNotHaveClass("loading");
418 | });
419 |
420 | test("it yields the loading state", async function (assert) {
421 | const deferred = defer();
422 |
423 | this.set("submit", () => deferred.promise);
424 |
425 | run(() => {
426 | this.set("model", EmberObject.create({}));
427 | });
428 |
429 | await render(hbs`
434 | {{#if f.loading}}
435 | loading...
436 | {{/if}}
437 |
438 | `);
439 | assert.dom("span.loading").doesNotExist();
440 |
441 | await click("button");
442 |
443 | assert.dom("span.loading").exists();
444 |
445 | run(() => deferred.resolve());
446 |
447 | assert.dom("span.loading").doesNotExist();
448 | });
449 |
450 | test("it handles being removed from the DOM during sync submit", async function (assert) {
451 | this.set("show", true);
452 |
453 | this.set("submit", () => {
454 | this.set("show", false);
455 | });
456 |
457 | run(() => {
458 | this.set("model", EmberObject.create({}));
459 | });
460 |
461 | await render(hbs`{{#if this.show}}
462 |
467 | {{#if f.loading}}
468 | loading...
469 | {{/if}}
470 |
471 |
472 | {{/if}}`);
473 |
474 | await click("button");
475 | assert.ok(true);
476 | });
477 |
478 | test("it handles being removed from the DOM during async submit", async function (assert) {
479 | this.set("show", true);
480 | const deferred = defer();
481 |
482 | this.set("submit", () => {
483 | return deferred.promise.then(() => {
484 | this.set("show", false);
485 | });
486 | });
487 |
488 | run(() => {
489 | this.set("model", EmberObject.create({}));
490 | });
491 |
492 | await render(hbs`{{#if this.show}}
493 |
498 | {{#if f.loading}}
499 | loading...
500 | {{/if}}
501 |
502 |
503 | {{/if}}`);
504 |
505 | await click("button");
506 | run(() => deferred.resolve());
507 | assert.ok(true);
508 | });
509 |
510 | test("it binds the autocomplete attribute", async function (assert) {
511 | await render(hbs``);
512 |
513 | assert.dom("form").hasAttribute("autocomplete", "off");
514 | });
515 | });
516 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [7.0.1](https://github.com/adfinis/ember-validated-form/compare/v7.0.0...v7.0.1) (2024-03-18)
2 |
3 |
4 | ### Bug Fixes
5 |
6 | * **deps:** update dependencies ([c2d187b](https://github.com/adfinis/ember-validated-form/commit/c2d187bbbf8652f0bc30637a9b5b5f5c46e44296))
7 |
8 | # [7.0.0](https://github.com/adfinis/ember-validated-form/compare/v6.2.0...v7.0.0) (2023-11-21)
9 |
10 |
11 | ### chore
12 |
13 | * **deps:** update ember and dependencies ([fc26b0b](https://github.com/adfinis/ember-validated-form/commit/fc26b0be302c24dafccad37a53dc7dd2bcc59bc9))
14 |
15 |
16 | ### Features
17 |
18 | * allow html attributes to be passed to wrapping form element ([b29f4d8](https://github.com/adfinis/ember-validated-form/commit/b29f4d88133aa58a9613aa9bf9f1f6a2761a7974))
19 |
20 |
21 | ### BREAKING CHANGES
22 |
23 | * **deps:** Drop support for Ember v3.
24 |
25 | # [6.2.0](https://github.com/adfinis/ember-validated-form/compare/v6.1.2...v6.2.0) (2023-02-23)
26 |
27 |
28 | ### Bug Fixes
29 |
30 | * scroll error into view with nested key names ([#904](https://github.com/adfinis/ember-validated-form/issues/904)) ([5c192a5](https://github.com/adfinis/ember-validated-form/commit/5c192a5b00abf05d80f36d1fad8b67a79a36e43c))
31 |
32 |
33 | ### Features
34 |
35 | * **a11y:** add aria invalid and describedby attributes on validation ([6e16a51](https://github.com/adfinis/ember-validated-form/commit/6e16a5122f134ca991205c03c0dd8628288e4b08)), closes [#48](https://github.com/adfinis/ember-validated-form/issues/48)
36 |
37 | ## [6.1.2](https://github.com/adfinis/ember-validated-form/compare/v6.1.1...v6.1.2) (2022-09-20)
38 |
39 |
40 | ### Bug Fixes
41 |
42 | * **label:** only show requiredness indicator if a label is given ([72c212d](https://github.com/adfinis/ember-validated-form/commit/72c212dc036c643dca43e1c22a7ec43384f70ab5))
43 |
44 | ## [6.1.1](https://github.com/adfinis/ember-validated-form/compare/v6.1.0...v6.1.1) (2022-09-20)
45 |
46 |
47 | ### Bug Fixes
48 |
49 | * **bootstrap:** make sure error feedback is always visible ([1722144](https://github.com/adfinis/ember-validated-form/commit/17221448567a4fb6dc53c39c3f42eb8eb66bdc3d))
50 | * **checkbox-group:** fix multiple selection in checkbox group ([6bb902b](https://github.com/adfinis/ember-validated-form/commit/6bb902b0577c68671f09f9cda65b5f16ac1b8fcb))
51 |
52 | # [6.1.0](https://github.com/adfinis/ember-validated-form/compare/v6.0.2...v6.1.0) (2022-09-16)
53 |
54 |
55 | ### Features
56 |
57 | * **input:** allow custom date component to be configured ([#861](https://github.com/adfinis/ember-validated-form/issues/861)) ([33bbafa](https://github.com/adfinis/ember-validated-form/commit/33bbafa4ac6a24d332ab4b1548abc4f2daef541f))
58 |
59 | ## [6.0.2](https://github.com/adfinis/ember-validated-form/compare/v6.0.1...v6.0.2) (2022-09-09)
60 |
61 |
62 | ### Bug Fixes
63 |
64 | * **deps:** remove unnecessary dependency to tracked-toolbox ([605c001](https://github.com/adfinis/ember-validated-form/commit/605c0018c44dcfd99685c35b3ba656cfab420a35))
65 |
66 | ## [6.0.1](https://github.com/adfinis/ember-validated-form/compare/v6.0.0...v6.0.1) (2022-09-08)
67 |
68 |
69 | ### Bug Fixes
70 |
71 | * **deps:** add missing dependency tracked-toolbox ([5b0f1a7](https://github.com/adfinis/ember-validated-form/commit/5b0f1a74dd33b20bcdb6bc09d55b7dc1426f5642))
72 |
73 | # [6.0.0](https://github.com/adfinis/ember-validated-form/compare/v5.3.1...v6.0.0) (2022-09-08)
74 |
75 |
76 | ### chore
77 |
78 | * **deps:** update ember and drop node 12 support ([3f3fb67](https://github.com/adfinis/ember-validated-form/commit/3f3fb67e269b8e8e30f5939ccbbc58a01a2a6aa0))
79 | * **select:** remove deprecated option includeBlank on selects ([3ef60b2](https://github.com/adfinis/ember-validated-form/commit/3ef60b21c1bc10259ab3865aacb5b3e2fdeda6bc))
80 |
81 |
82 | ### Features
83 |
84 | * support embroider builds ([b0b0bde](https://github.com/adfinis/ember-validated-form/commit/b0b0bdea32a035fa499a9b0bae7ed245b4dd66f7))
85 |
86 |
87 | ### BREAKING CHANGES
88 |
89 | * **select:** Remove deprecated option `includeBlank` on select
90 | inputs.
91 | * This changes the global configuration for features,
92 | themes and default components completely. For instructions on how to
93 | migrate, check the migration to v6 guide.
94 | * **deps:** Drop support for Node v12 and Ember LTS 3.24
95 |
96 | ## [5.3.1](https://github.com/adfinis/ember-validated-form/compare/v5.3.0...v5.3.1) (2022-09-02)
97 |
98 | ### Bug Fixes
99 |
100 | - **select:** fix promptIsSelectable in combination with targetPath ([#853](https://github.com/adfinis/ember-validated-form/issues/853)) ([526d81f](https://github.com/adfinis/ember-validated-form/commit/526d81f25eb47f938fa2fa031d5f5e710a0386bf))
101 |
102 | # [5.3.0](https://github.com/adfinis/ember-validated-form/compare/v5.2.2...v5.3.0) (2022-02-22)
103 |
104 | ### Bug Fixes
105 |
106 | - addon docs root url ([7d8151f](https://github.com/adfinis/ember-validated-form/commit/7d8151fa9d854cdf9595f27347fa57652e58ef10))
107 | - **blueprint:** add ember-truth-helpers to default blueprint ([a401589](https://github.com/adfinis/ember-validated-form/commit/a401589dab6d013f5d659865927919346655295d))
108 | - **deps:** move required deps to dependencies instead of devDependencies ([46629ce](https://github.com/adfinis/ember-validated-form/commit/46629ceb48210bbc58898c299a9388ce7fa816ec))
109 | - new link to docs ([c1073e5](https://github.com/adfinis/ember-validated-form/commit/c1073e55e3a916ed393e33bcf4a045124c320967))
110 | - **select:** pass prompt argument down to input component ([64a1377](https://github.com/adfinis/ember-validated-form/commit/64a1377d64618fa880b332f8a693e1c7f1a321f7))
111 |
112 | ### Features
113 |
114 | - pass attributes to input components ([dc0417d](https://github.com/adfinis/ember-validated-form/commit/dc0417d125fe4c20cb59b76531ae4f7391258259))
115 |
116 | ## [5.2.2](https://github.com/adfinis/ember-validated-form/compare/v5.2.1...v5.2.2) (2022-02-10)
117 |
118 | ### Bug Fixes
119 |
120 | - select support for plain options ([#747](https://github.com/adfinis/ember-validated-form/issues/747)) ([a58e26d](https://github.com/adfinis/ember-validated-form/commit/a58e26ddcd46ec5328c3bb5351bafc7781eacdbd))
121 |
122 | ## [5.2.1](https://github.com/adfinis/ember-validated-form/compare/v5.2.0...v5.2.1) (2022-02-09)
123 |
124 | ### Bug Fixes
125 |
126 | - respect scrollErrorIntoView for validated buttons as well ([#743](https://github.com/adfinis/ember-validated-form/issues/743)) ([fd6be2a](https://github.com/adfinis/ember-validated-form/commit/fd6be2a49c5f947bfcf5eb3f7ab61a23ac00064a))
127 |
128 | # [5.2.0](https://github.com/adfinis/ember-validated-form/compare/v5.1.1...v5.2.0) (2022-02-03)
129 |
130 | ### Features
131 |
132 | - scroll first invalid element into view ([#733](https://github.com/adfinis/ember-validated-form/issues/733)) ([ae7c8b2](https://github.com/adfinis/ember-validated-form/commit/ae7c8b2b160307646adf90cd09a091effa549238))
133 | - **validated-button:** add `triggerValidations` flag ([#721](https://github.com/adfinis/ember-validated-form/issues/721)) ([765f5f4](https://github.com/adfinis/ember-validated-form/commit/765f5f40c9d2e5ccfca7129fb701ff3bb0ed661e))
134 |
135 | # [5.0.0](https://github.com/adfinis/ember-validated-form/compare/v4.1.0...v5.0.0) (2021-10-08)
136 |
137 | ### chore
138 |
139 | - **deps:** update ember and other dependencies ([41e099c](https://github.com/adfinis/ember-validated-form/commit/41e099c4da82135c562493e5b2a4f9420dca73c6))
140 | - **ember:** remove support for ember 3.20 ([0cfebfc](https://github.com/adfinis/ember-validated-form/commit/0cfebfcc5792a1df52093a972878af1617ec8100))
141 |
142 | ### Features
143 |
144 | - refactor all components to glimmer and use native classes ([cee7373](https://github.com/adfinis/ember-validated-form/commit/cee7373a3c0783a02fe00b5e510c41ba604403c2))
145 |
146 | ### BREAKING CHANGES
147 |
148 | - **ember:** Remove support for ember LTS 3.20 since that version
149 | has a bug with autotracking.
150 | - **deps:** Require `ember-auto-import` v2+
151 | - While the public API won't change, there is a huge
152 | chance that this will break implementations if someone's extending the
153 | components of this addon. Components that do need to be refactored to
154 | glimmer.
155 |
156 | # [4.1.0](https://github.com/adfinis/ember-validated-form/compare/v4.0.1...v4.1.0) (2021-09-30)
157 |
158 | ### Bug Fixes
159 |
160 | - **deps:** [security] bump handlebars from 4.7.6 to 4.7.7 ([#588](https://github.com/adfinis/ember-validated-form/issues/588)) ([d167207](https://github.com/adfinis/ember-validated-form/commit/d167207ee059bd9b968a08fb61f18f43dadab0ab))
161 | - **deps:** [security] bump striptags from 3.1.1 to 3.2.0 ([#637](https://github.com/adfinis/ember-validated-form/issues/637)) ([3632f52](https://github.com/adfinis/ember-validated-form/commit/3632f52e7fa1fc6f0e17dd3365a74a80ceb92833))
162 | - **deps:** [security] bump trim-newlines from 3.0.0 to 3.0.1 ([#634](https://github.com/adfinis/ember-validated-form/issues/634)) ([10e3974](https://github.com/adfinis/ember-validated-form/commit/10e397452b30a3af11a299c5bcdafd703d9b0c18))
163 | - **deps:** [security] bump ws from 6.2.1 to 6.2.2 ([#624](https://github.com/adfinis/ember-validated-form/issues/624)) ([910ec64](https://github.com/adfinis/ember-validated-form/commit/910ec64b2f84562fd77a8be14094fd2f326d60b6))
164 | - call on-update hook correctly ([#641](https://github.com/adfinis/ember-validated-form/issues/641)) ([b8688b6](https://github.com/adfinis/ember-validated-form/commit/b8688b6d9dedbd9096d34c3b236bf59efb045556))
165 |
166 | ### Features
167 |
168 | - checkbox groups ([#640](https://github.com/adfinis/ember-validated-form/issues/640)) ([9099ce8](https://github.com/adfinis/ember-validated-form/commit/9099ce81bbedc53c961653dca59c555d96ee9128))
169 |
170 | ## [4.0.1](https://github.com/adfinis/ember-validated-form/compare/v4.0.0...v4.0.1) (2021-05-21)
171 |
172 | ### Bug Fixes
173 |
174 | - **validated-input:** use changeset.set if available to preserve state tracking on nested objects ([#609](https://github.com/adfinis/ember-validated-form/issues/609)) ([d3b92ee](https://github.com/adfinis/ember-validated-form/commit/d3b92ee5dfb7e0a6f4fbdb1899d9be34b67d1722))
175 |
176 | # [4.0.0](https://github.com/adfinis/ember-validated-form/compare/v3.0.3...v4.0.0) (2021-05-19)
177 |
178 | ### Bug Fixes
179 |
180 | - **validated-input:** rewrite to glimmer and support nested changesets ([#581](https://github.com/adfinis/ember-validated-form/issues/581)) ([2f3e7c5](https://github.com/adfinis/ember-validated-form/commit/2f3e7c5c9e13ad39ecba9358305cfcc4bac8f6b8))
181 |
182 | ### BREAKING CHANGES
183 |
184 | - **validated-input:** This drops support for Ember LTS 3.16 and `ember-changeset` < 3.0.0 and `ember-changeset-validations` < 3.0.0
185 |
186 | - refactor(validated-input): refactor dynamic component call to angle-brackets
187 |
188 | - chore(\*): drop node v10 support
189 | - **validated-input:** drop node v10 support since v10 has reached EOL
190 |
191 | - fix(themed-component): convert array to string befor using in key path
192 |
193 | ## [3.0.3](https://github.com/adfinis/ember-validated-form/compare/v3.0.2...v3.0.3) (2021-04-15)
194 |
195 | ### Bug Fixes
196 |
197 | - **deps:** [security] bump elliptic from 6.5.3 to 6.5.4 ([#538](https://github.com/adfinis/ember-validated-form/issues/538)) ([b36030c](https://github.com/adfinis/ember-validated-form/commit/b36030cd289485154fbaaefe914535cad7639043))
198 | - **deps:** [security] bump ini from 1.3.5 to 1.3.8 ([#450](https://github.com/adfinis/ember-validated-form/issues/450)) ([97870d1](https://github.com/adfinis/ember-validated-form/commit/97870d152b12a273328fae257fb7399a067d7f9c))
199 | - **deps:** [security] bump socket.io from 2.3.0 to 2.4.1 ([#474](https://github.com/adfinis/ember-validated-form/issues/474)) ([fe46f19](https://github.com/adfinis/ember-validated-form/commit/fe46f197439ff85170c92b6236f73c34f459d01f))
200 | - **deps:** [security] bump y18n from 3.2.1 to 3.2.2 ([#560](https://github.com/adfinis/ember-validated-form/issues/560)) ([727144e](https://github.com/adfinis/ember-validated-form/commit/727144edc1920d323aee882240de695ca5f0e228))
201 | - remove unused modules which lead to invalid imports ([#464](https://github.com/adfinis/ember-validated-form/issues/464)) ([d0405bf](https://github.com/adfinis/ember-validated-form/commit/d0405bf8733119394c953f73155349f65e2e5a88))
202 | - **deps:** bump ember-auto-import from 1.10.1 to 1.11.2 ([#557](https://github.com/adfinis/ember-validated-form/issues/557)) ([f01f882](https://github.com/adfinis/ember-validated-form/commit/f01f8826fe6cddfa1d5776960fb773973a25545d))
203 | - **deps:** bump ember-auto-import from 1.7.0 to 1.10.1 ([#456](https://github.com/adfinis/ember-validated-form/issues/456)) ([d4940d7](https://github.com/adfinis/ember-validated-form/commit/d4940d7cf6a367184dccd0e6677f3bdae6afdee8))
204 | - **deps:** bump ember-cli-babel from 7.23.0 to 7.23.1 ([#473](https://github.com/adfinis/ember-validated-form/issues/473)) ([df7cec0](https://github.com/adfinis/ember-validated-form/commit/df7cec06c35b0665df6e177f495360a14572cb73))
205 | - **deps:** bump ember-cli-babel from 7.23.1 to 7.26.3 ([#558](https://github.com/adfinis/ember-validated-form/issues/558)) ([6b0ee99](https://github.com/adfinis/ember-validated-form/commit/6b0ee99faf936d329378959c63303a18fd855912))
206 | - **deps:** bump ember-cli-htmlbars from 5.6.4 to 5.7.1 ([#549](https://github.com/adfinis/ember-validated-form/issues/549)) ([e00e417](https://github.com/adfinis/ember-validated-form/commit/e00e41791039ce1b410f442900b8f079a42cae4d))
207 | - **deps:** bump ember-one-way-select from 4.0.0 to 4.0.1 ([#565](https://github.com/adfinis/ember-validated-form/issues/565)) ([0564346](https://github.com/adfinis/ember-validated-form/commit/05643467b6edffc6e08eb067f77acdd79161ae5b))
208 | - **deps:** bump uuid from 8.3.1 to 8.3.2 ([#439](https://github.com/adfinis/ember-validated-form/issues/439)) ([d72f013](https://github.com/adfinis/ember-validated-form/commit/d72f0130f5b34cda2bda3b82da5204403d026541))
209 |
210 | ## [3.0.2](https://github.com/adfinis/ember-validated-form/compare/v3.0.1...v3.0.2) (2020-11-20)
211 |
212 | ### Bug Fixes
213 |
214 | - **intl:** remove unused translation that caused warnings in apps ([f20f233](https://github.com/adfinis/ember-validated-form/commit/f20f2332cbf8cf70711f292864e7a9dd2df8b995))
215 |
216 | ## [3.0.1](https://github.com/adfinis/ember-validated-form/compare/v3.0.0...v3.0.1) (2020-11-18)
217 |
218 | ### Bug Fixes
219 |
220 | - **deps:** update ember-changeset and validations to v3+ ([a9d83e2](https://github.com/adfinis/ember-validated-form/commit/a9d83e208ad2599b0bd3847bc170179294d479ad))
221 |
222 | # [3.0.0](https://github.com/adfinis/ember-validated-form/compare/v2.0.0...v3.0.0) (2020-11-06)
223 |
224 | - chore!: update dependencies (#392) ([2664399](https://github.com/adfinis/ember-validated-form/commit/266439966050dee4ec6033f24828c84f5e0543b8)), closes [#392](https://github.com/adfinis/ember-validated-form/issues/392)
225 |
226 | ### Bug Fixes
227 |
228 | - **deps:** bump ember-auto-import from 1.6.0 to 1.7.0 ([#394](https://github.com/adfinis/ember-validated-form/issues/394)) ([9d464e4](https://github.com/adfinis/ember-validated-form/commit/9d464e4b5e83f19f3bd46897ef56a3caaaeb7153))
229 | - **select:** pass promptIsSelectable to select ([e739b4f](https://github.com/adfinis/ember-validated-form/commit/e739b4fea27165e97ae0130e5d330990bdf501ee))
230 |
231 | ### BREAKING CHANGES
232 |
233 | - This drops support for Ember LTS 3.8 and 3.12
234 |
235 | # Change Log
236 |
237 | All notable changes to this project will be documented in this file.
238 |
239 | The format is based on [Keep a Changelog](https://keepachangelog.com/)
240 | and this project adheres to [Semantic Versioning](https://semver.org/).
241 |
242 | ## [1.4.2]
243 |
244 | ### Changed
245 |
246 | - Bump version because of a wrong npm publish
247 |
248 | ## [1.4.1]
249 |
250 | ### Changed
251 |
252 | - Fix changing of a changeset property from outside of the form (#118)
253 |
254 | ## [1.4.0]
255 |
256 | ### Changed
257 |
258 | - Update ember to version 3.1
259 | - Fix mixed content in docs (#107 / #108, credits to @sliverc)
260 | - Fix wrong bootstrap class in documentation (#114, credits to @kimroen)
261 |
262 | ### Added
263 |
264 | - `on-invalid-submit` action gets called on submitting an invalid form (#111, credits to @omairvaiyani)
265 | - `inputId` is yielded from the `validated-input` component (#115, credits to @kimroen)
266 |
267 | ## [1.3.1]
268 |
269 | ### Changed
270 |
271 | - Addon docs with [`ember-cli-addon-docs`](https://github.com/ember-learn/ember-cli-addon-docs)
272 |
273 | ## [1.3.0]
274 |
275 | ### Changed
276 |
277 | - Bootstrap 4 support (#100, credits to @anehx)
278 | - Add valid and invalid class to input component (#100, credits to @anehx)
279 | - Only set valid class if value is dirty (#100, credits to @anehx)
280 |
281 | ## [1.2.0]
282 |
283 | ### Changed
284 |
285 | - Add support for custom label components (#95, credits to @przywartya)
286 | - Allow setting autocomplete attribute on validated-form and validated-input (#97, credits to @makepanic)
287 |
288 | ## [1.1.0]
289 |
290 | ### Changed
291 |
292 | - Update ember-cli to 3.0.0, update dependencies
293 |
294 | ## [1.0.1]
295 |
296 | ### Changed
297 |
298 | - fix: use radio value to expose option key (#91, credits to @makepanic)
299 |
300 | ## [1.0.0]
301 |
302 | ### Changed
303 |
304 | - Install `ember-changeset` and `ember-changeset-validations` from the blueprint (#86, credits to @bendemboski)
305 | - Update dependencies (#87, credits to @bendemboski)
306 | - Remove deprecated task support (#88, credits to @bendemboski)
307 |
308 | The 1.0.0 release removes ember-changeset and ember-changeset-validations as dependencies because this addon is built to make them very easy to use, but doesn't require them. So if you are using either or both of them in your application code but do not already have them in your package.json, you should run
309 |
310 | ```bash
311 | ember install ember-changeset
312 | ember install ember-changeset-validations
313 | ```
314 |
315 | This release also removes the previously deprecated API for passing ember-concourrency tasks to `on-submit`. Please see section [0.6.2] for migration instructions.
316 |
317 | ## [0.7.1]
318 |
319 | ### Changed
320 |
321 | - Fix for removal from DOM during submit (#85, credits to @bendemboski)
322 |
323 | ## [0.7.0]
324 |
325 | ### Changed
326 |
327 | - Wrap radio, checkbox in span to allow custom styles (#82, credits to @makepanic)
328 |
329 | ## [0.6.4]
330 |
331 | ### Changed
332 |
333 | - Update ember truth helpers (#79, credits to @bendemboski)
334 | - Update ember-cli to 2.18.0 (#80)
335 |
336 | ## [0.6.3]
337 |
338 | ### Changed
339 |
340 | - Add disabled flag on checkbox instance (#77, credits to @toumbask)
341 |
342 | ## [0.6.2]
343 |
344 | ### Changed
345 |
346 | - Yield loading state, change `on-submit` to promise semantics (#75, credits to @bendemboski)
347 |
348 | This release deprecates passing an ember-concurrency task directly to `on-submit`:
349 |
350 | ```Handlebars
351 | // deprecated:
352 | {{#validated-form on-submit = myTask (...)}}
353 | ```
354 |
355 | Instead, `on-submit` accepts a promise - which is returned by wrapping the task in `perform`:
356 |
357 | ```Handlebars
358 | {{#validated-form on-submit = (perform myTask) (...)}}
359 | ```
360 |
361 | ## [0.6.1]
362 |
363 | ### Added
364 |
365 | - Add more input attributes (#71, credits to @bendemboski)
366 | - Add validateBeforeSubmit option (#70, credits to @bendemboski)
367 |
368 | ## [0.6.0]
369 |
370 | ### Changed
371 |
372 | - Use yarn instead of npm (#62)
373 | - Update dependencies (#62)
374 | - Remove automatic disabling of submit button while task is running (#63)
375 |
376 | To restore the old behaviour, all you have to do is pass the `isRunning` state as `disabled` property to the submit button:
377 |
378 | ```Handlebars
379 | {{#validated-form
380 | ...
381 | on-submit = myTask
382 | as |f|}}
383 | {{f.submit label="Test" disabled=myTask.isRunning}}
384 | {{/validated-form}}
385 | ```
386 |
387 | ### Added
388 |
389 | - Add loading class to button if task is running (#63)
390 | - Support block style usage of submit button (#61)
391 |
392 | ### Removed
393 |
394 | - Useless class name binding on button (#65)
395 | - Dependency to ember-data (#62)
396 | - Various unused dependencies (#62)
397 |
398 | ## [0.5.4]
399 |
400 | ### Changed
401 |
402 | - Input, Textarea: Use native input tag instead of one-way-input (#60)
403 | - Dummy app: load bootstrap from CDN (#59)
404 |
405 | ## [0.5.3]
406 |
407 | ### Changed
408 |
409 | - Fix bug that caused ID collisions when multiple forms on the same page use inputs with
410 | the same name (#55, credits to @anehx)
411 |
412 | ## [0.5.2]
413 |
414 | ### Changed
415 |
416 | - Update ember-cli to v2.5.1 (#53)
417 |
418 | ## [0.5.1]
419 |
420 | ### Changed
421 |
422 | - Add proper `id` attributes to select and simple form components (#51)
423 |
424 | ## [0.5.0]
425 |
426 | ### Changed
427 |
428 | - Separate classes for field hints and validation messages (#42, credits to @jacob-financit). If you've
429 | been using the (previously undocumented) option `help` on input fields, you'll have to rename them to `hint`.
430 |
431 | ## [0.4.2]
432 |
433 | ### Added
434 |
435 | - Better documentation for custom component integration (#46)
436 |
437 | ### Changed
438 |
439 | - Fix bug that causes form to break for select fields without option `promptIsSelectable` (#45)
440 |
441 | ## [0.4.1]
442 |
443 | ### Added
444 |
445 | - Support selectable prompts from the select dropdown (#40, credits to @steverhoades)
446 |
447 | ### Changed
448 |
449 | - Update dependencies (#33, #34, credits to @okachynskyy)
450 | - Move addon from pods to default structure (#32, credits to @okachynskyy)
451 |
452 | ## [0.4.0]
453 |
454 | ### Added
455 |
456 | - Support block form usage of radioGroups (#28, credits to @jacob-financeit)
457 |
458 | ### Changed
459 |
460 | - remove hardcoded `radio` class for radio button groups. If you're using bootstrap, you
461 | might have to add `radio: 'radio'` to the CSS config.
462 |
463 | ## [0.3.1]
464 |
465 | ### Added
466 |
467 | - More CSS configuration options and docs on how to integrate semantic UI (#26)
468 |
469 | ## [0.3.0]
470 |
471 | ### Changed
472 |
473 | - Removed automatic inference if field is required (which appended "\*" to labels) because it
474 | was incorrect. (#27, credits to @andreabettich) Now, fields have to be marked as required explicitly:
475 |
476 | ```Handlebars
477 | {{f.input label="First name" name="firstName" required=true}}
478 | ```
479 |
480 | ## [0.2.2]
481 |
482 | - Upgrade to ember 2.12.0 (#24, credits to @sproj)
483 |
484 | ## [0.2.1]
485 |
486 | ### Added
487 |
488 | - Override initial value of input field using `value` attribute (#22, credits to @kaldras)
489 | - Document `on-update` property for custom update functions of input elements,
490 | and add `changeset` argument to its signature
491 |
492 | ## [0.2.0]
493 |
494 | ### Changed
495 |
496 | - yield `submit` button instead of automatically rendering it, removed `cancel` button. Migration is simple:
497 |
498 | Before:
499 |
500 | ```Handlebars
501 | {{#validated-form
502 | model = (changeset model UserValidations)
503 | on-submit = (action "submit")
504 | on-cancel = (action "cancel")
505 | submit-label = 'Save' as |f|}}
506 | {{!-- form content --}}
507 | {{/validated-form}}
508 | ```
509 |
510 | After:
511 |
512 | ```Handlebars
513 | {{#validated-form
514 | model = (changeset model UserValidations)
515 | on-submit = (action "submit")
516 | as |f|}}
517 | {{!-- form content --}}
518 | {{f.submit label='Save'}}
519 |
520 | {{/validated-form}}
521 | ```
522 |
523 | ## [0.1.11] - 2017-03-23
524 |
525 | ### Added
526 |
527 | - Checkbox support (#5, credits to @psteininger)
528 |
529 | ## [0.1.10] - 2017-03-23
530 |
531 | ### Added
532 |
533 | - Easy integration of custom components (#17, credits to @feanor07)
534 |
--------------------------------------------------------------------------------