diff --git a/addon/components/validated-input/render.js b/addon/components/validated-input/render.js
index 9ddde1a9..e248992e 100644
--- a/addon/components/validated-input/render.js
+++ b/addon/components/validated-input/render.js
@@ -7,6 +7,9 @@ export default Component.extend({
layout,
selectComponent: themedComponent("validated-input/types/select"),
radioGroupComponent: themedComponent("validated-input/types/radio-group"),
+ checkboxGroupComponent: themedComponent(
+ "validated-input/types/checkbox-group"
+ ),
checkboxComponent: themedComponent("validated-input/types/checkbox"),
textareaComponent: themedComponent("validated-input/types/textarea"),
inputComponent: themedComponent("validated-input/types/input"),
diff --git a/addon/components/validated-input/types/-themes/bootstrap/checkbox-group.js b/addon/components/validated-input/types/-themes/bootstrap/checkbox-group.js
new file mode 100644
index 00000000..8c207449
--- /dev/null
+++ b/addon/components/validated-input/types/-themes/bootstrap/checkbox-group.js
@@ -0,0 +1,6 @@
+import layout from "../../../../../templates/components/validated-input/types/-themes/bootstrap/checkbox-group";
+import Component from "../../checkbox-group";
+
+export default Component.extend({
+ layout,
+});
diff --git a/addon/components/validated-input/types/-themes/uikit/checkbox-group.js b/addon/components/validated-input/types/-themes/uikit/checkbox-group.js
new file mode 100644
index 00000000..33828b5d
--- /dev/null
+++ b/addon/components/validated-input/types/-themes/uikit/checkbox-group.js
@@ -0,0 +1,6 @@
+import layout from "../../../../../templates/components/validated-input/types/-themes/uikit/checkbox-group";
+import Component from "../../checkbox-group";
+
+export default Component.extend({
+ layout,
+});
diff --git a/addon/components/validated-input/types/checkbox-group.js b/addon/components/validated-input/types/checkbox-group.js
new file mode 100644
index 00000000..631154ac
--- /dev/null
+++ b/addon/components/validated-input/types/checkbox-group.js
@@ -0,0 +1,23 @@
+import Component from "@ember/component";
+import { action } from "@ember/object";
+
+import layout from "../../../templates/components/validated-input/types/checkbox-group";
+
+export default Component.extend({
+ layout,
+
+ @action
+ onUpdate(key) {
+ const value = this.value || [];
+ const index = value.indexOf(key);
+
+ if (index > -1) {
+ value.splice(index, 1);
+ } else {
+ value.push(key);
+ }
+
+ this.update(value);
+ this.setDirty();
+ },
+});
diff --git a/addon/templates/components/validated-input/-themes/uikit/render.hbs b/addon/templates/components/validated-input/-themes/uikit/render.hbs
index 1d3cee35..503ef096 100644
--- a/addon/templates/components/validated-input/-themes/uikit/render.hbs
+++ b/addon/templates/components/validated-input/-themes/uikit/render.hbs
@@ -33,6 +33,20 @@
isValid=isValid
isInvalid=isInvalid
+ update=update
+ setDirty=setDirty
+ }}
+ {{else if (or (eq type "checkboxGroup") (eq type "checkbox-group"))}}
+ {{component checkboxGroupComponent
+ value=value
+ options=options
+ inputId=inputId
+ name=(or inputName name)
+ disabled=disabled
+
+ isValid=isValid
+ isInvalid=isInvalid
+
update=update
setDirty=setDirty
}}
diff --git a/addon/templates/components/validated-input/render.hbs b/addon/templates/components/validated-input/render.hbs
index 89a1e2be..c896321d 100644
--- a/addon/templates/components/validated-input/render.hbs
+++ b/addon/templates/components/validated-input/render.hbs
@@ -33,6 +33,20 @@
isValid=isValid
isInvalid=isInvalid
+ update=update
+ setDirty=setDirty
+ }}
+{{else if (or (eq type "checkboxGroup") (eq type "checkbox-group"))}}
+ {{component checkboxGroupComponent
+ value=value
+ options=options
+ inputId=inputId
+ name=(or inputName name)
+ disabled=disabled
+
+ isValid=isValid
+ isInvalid=isInvalid
+
update=update
setDirty=setDirty
}}
diff --git a/addon/templates/components/validated-input/types/-themes/bootstrap/checkbox-group.hbs b/addon/templates/components/validated-input/types/-themes/bootstrap/checkbox-group.hbs
new file mode 100644
index 00000000..3baf7109
--- /dev/null
+++ b/addon/templates/components/validated-input/types/-themes/bootstrap/checkbox-group.hbs
@@ -0,0 +1,14 @@
+{{#each options as |option i|}}
+
+
+
+
+{{/each}}
\ No newline at end of file
diff --git a/addon/templates/components/validated-input/types/-themes/uikit/checkbox-group.hbs b/addon/templates/components/validated-input/types/-themes/uikit/checkbox-group.hbs
new file mode 100644
index 00000000..11b8a498
--- /dev/null
+++ b/addon/templates/components/validated-input/types/-themes/uikit/checkbox-group.hbs
@@ -0,0 +1,15 @@
+{{#each options as |option i|}}
+ {{#unless (eq i 0)}}
{{/unless}}
+
+{{/each}}
\ No newline at end of file
diff --git a/addon/templates/components/validated-input/types/checkbox-group.hbs b/addon/templates/components/validated-input/types/checkbox-group.hbs
new file mode 100644
index 00000000..cf856134
--- /dev/null
+++ b/addon/templates/components/validated-input/types/checkbox-group.hbs
@@ -0,0 +1,14 @@
+{{#each options as |option i|}}
+
+{{/each}}
\ No newline at end of file
diff --git a/app/components/validated-input/types/-themes/bootstrap/checkbox-group.js b/app/components/validated-input/types/-themes/bootstrap/checkbox-group.js
new file mode 100644
index 00000000..58edb9d1
--- /dev/null
+++ b/app/components/validated-input/types/-themes/bootstrap/checkbox-group.js
@@ -0,0 +1 @@
+export { default } from "ember-validated-form/components/validated-input/types/-themes/bootstrap/checkbox-group";
diff --git a/app/components/validated-input/types/-themes/uikit/checkbox-group.js b/app/components/validated-input/types/-themes/uikit/checkbox-group.js
new file mode 100644
index 00000000..26c69b96
--- /dev/null
+++ b/app/components/validated-input/types/-themes/uikit/checkbox-group.js
@@ -0,0 +1 @@
+export { default } from "ember-validated-form/components/validated-input/types/-themes/uikit/checkbox-group";
diff --git a/app/components/validated-input/types/checkbox-group.js b/app/components/validated-input/types/checkbox-group.js
new file mode 100644
index 00000000..3715a102
--- /dev/null
+++ b/app/components/validated-input/types/checkbox-group.js
@@ -0,0 +1 @@
+export { default } from "ember-validated-form/components/validated-input/types/checkbox-group";
diff --git a/tests/dummy/app/templates/docs/components/validated-input.md b/tests/dummy/app/templates/docs/components/validated-input.md
index 1ca11127..26e86fd9 100644
--- a/tests/dummy/app/templates/docs/components/validated-input.md
+++ b/tests/dummy/app/templates/docs/components/validated-input.md
@@ -42,7 +42,7 @@ two arguments: `update(value, changeset)`.
**autocomplete ``**
Binding to the [`` `autocomplete` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-autocomplete).
-The supported field types are `checkbox`, `radioGroup`, `select`, `textarea`
+The supported field types are `checkbox`, `checkboxGroup`, `radioGroup`, `select`, `textarea`
and any type that can be specified on an `` element. This addon does
not much more than translating `{{f.input type='select'}}` to
`{{one-way-select}}` or `{{f.input type='text'}}` to ``
@@ -189,3 +189,24 @@ localize your labels using an internationalization addon like
{{demo.snippet 'translations.js' label='locales/fr/translations.js'}}
{{/docs-demo}}
-->
+
+### Checkbox group
+
+This component renders a list of `` elements.
+
+
+{{#docs-demo as |demo|}}
+ {{#demo.example name='checkbox-group-template.hbs'}}
+ {{#validated-form model=(changeset (hash shape=null)) as |f|}}
+ {{f.input
+ type = 'checkboxGroup'
+ label = 'Shapes'
+ name = 'shape'
+ options = (array (hash key='t' label='Triangle') (hash key='s' label='Square') (hash key='c' label='Circle'))
+ }}
+ {{/validated-form}}
+ {{/demo.example}}
+
+ {{demo.snippet 'checkbox-group-template.hbs'}}
+{{/docs-demo}}
+
diff --git a/tests/integration/components/validated-input/types/-themes/bootstrap/checkbox-group-test.js b/tests/integration/components/validated-input/types/-themes/bootstrap/checkbox-group-test.js
new file mode 100644
index 00000000..a8088c30
--- /dev/null
+++ b/tests/integration/components/validated-input/types/-themes/bootstrap/checkbox-group-test.js
@@ -0,0 +1,26 @@
+import { render } from "@ember/test-helpers";
+import setupConfigTest from "dummy/tests/helpers/setup-config-test";
+import { hbs } from "ember-cli-htmlbars";
+import { setupRenderingTest } from "ember-qunit";
+import { module, test } from "qunit";
+
+module(
+ "Integration | Component | validated-input/types/-themes/bootstrap/checkbox-group",
+ function (hooks) {
+ setupRenderingTest(hooks);
+ setupConfigTest(hooks, { theme: "bootstrap" });
+
+ test("it renders", async function (assert) {
+ await render(hbs`
+ {{validated-input/types/-themes/bootstrap/checkbox-group
+ options = (array (hash key='t' label='Triangle') (hash key='s' label='Square'))
+ update=(action (mut value))
+ }}
+ `);
+
+ assert.dom("div.custom-control.custom-checkbox").exists();
+ assert.dom("input").hasClass("custom-control-input");
+ assert.dom("label").hasClass("custom-control-label");
+ });
+ }
+);
diff --git a/tests/integration/components/validated-input/types/-themes/uikit/checkbox-group-test.js b/tests/integration/components/validated-input/types/-themes/uikit/checkbox-group-test.js
new file mode 100644
index 00000000..70a66775
--- /dev/null
+++ b/tests/integration/components/validated-input/types/-themes/uikit/checkbox-group-test.js
@@ -0,0 +1,34 @@
+import { render } from "@ember/test-helpers";
+import setupConfigTest from "dummy/tests/helpers/setup-config-test";
+import { setupRenderingTest } from "ember-qunit";
+import hbs from "htmlbars-inline-precompile";
+import { module, test } from "qunit";
+
+module(
+ "Integration | Component | validated-input/types/-themes/uikit/checkbox-group",
+ function (hooks) {
+ setupRenderingTest(hooks);
+ setupConfigTest(hooks, { theme: "uikit" });
+
+ test("it renders", async function (assert) {
+ this.set("options", [
+ {
+ key: "opt1",
+ label: "Option 1",
+ },
+ {
+ key: "opt2",
+ label: "Option 2",
+ },
+ ]);
+
+ await render(
+ hbs`{{validated-input/types/-themes/uikit/checkbox-group options=options update=(action (mut value))}}`
+ );
+
+ assert.dom("label > input").exists();
+ assert.dom("input").hasClass("uk-checkbox");
+ assert.dom("label").hasClass("uk-form-label");
+ });
+ }
+);
diff --git a/tests/integration/components/validated-input/types/checkbox-group-test.js b/tests/integration/components/validated-input/types/checkbox-group-test.js
new file mode 100644
index 00000000..61aeb6eb
--- /dev/null
+++ b/tests/integration/components/validated-input/types/checkbox-group-test.js
@@ -0,0 +1,27 @@
+import { render } from "@ember/test-helpers";
+import { setupRenderingTest } from "ember-qunit";
+import hbs from "htmlbars-inline-precompile";
+import { module, test } from "qunit";
+
+module(
+ "Integration | Component | validated-input/types/checkbox-group",
+ function (hooks) {
+ setupRenderingTest(hooks);
+
+ test("it renders", async function (assert) {
+ this.set("options", [
+ { key: 1, label: 1 },
+ { key: 2, label: 2 },
+ ]);
+
+ await render(hbs`
+ {{validated-input/types/checkbox-group
+ options=options
+ update=(action (mut value))
+ }}
+ `);
+
+ assert.dom("input[type=checkbox]").exists({ count: 2 });
+ });
+ }
+);