Skip to content

Commit

Permalink
Added vaadin-checkbox-group MVP
Browse files Browse the repository at this point in the history
  • Loading branch information
Sohrab Taee authored and sohrabtaee committed Jun 29, 2018
1 parent 5fbc9c2 commit c2644c2
Show file tree
Hide file tree
Showing 14 changed files with 951 additions and 46 deletions.
534 changes: 491 additions & 43 deletions analysis.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"webcomponentsjs": "^1.0.1",
"web-component-tester": "^6.1.5",
"vaadin-demo-helpers": "vaadin/vaadin-demo-helpers#^2.0.0",
"iron-form": "^2.0.1"
"iron-form": "^2.0.1",
"vaadin-button": "^2.0.1"
}
}
111 changes: 111 additions & 0 deletions demo/checkbox-group-demos.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<dom-module id="checkbox-group-demos">
<template>
<style include="vaadin-component-demo-shared-styles">
:host {
display: block;
}
</style>

<h3>Checkbox Group</h3>
<vaadin-demo-snippet id="checkbox-group-demos-checkbox-group-value">
<template preserve-content>
<dom-bind>
<template>
<p>Preferred language of contact:</p>
<vaadin-checkbox-group value="{{checkboxValue}}">
<vaadin-checkbox value="en">English</vaadin-checkbox>
<vaadin-checkbox value="fr">Français</vaadin-checkbox>
<vaadin-checkbox value="de">Deutsch</vaadin-checkbox>
</vaadin-checkbox-group>
<p>Selected value: [[checkboxValue]]</p>
</template>
</dom-bind>
</template>
</vaadin-demo-snippet>

<h3>Checkbox Group Disabled</h3>
<vaadin-demo-snippet id="checkbox-group-demos-checkbox-group-disabled">
<template preserve-content>
<vaadin-checkbox-group disabled>
<vaadin-checkbox value="1">1</vaadin-checkbox>
<vaadin-checkbox value="2">2</vaadin-checkbox>
<vaadin-checkbox value="3">3</vaadin-checkbox>
<vaadin-checkbox value="4">4</vaadin-checkbox>
</vaadin-checkbox-group>
</template>
</vaadin-demo-snippet>

<h3>Checkbox Group with Iron Form with same names</h3>
<vaadin-demo-snippet id="checkbox-group-demos-checkbox-group-with-iron-form">
<template preserve-content>
<iron-form id="test-form">
<form>
<vaadin-checkbox-group>
<vaadin-checkbox name="checkbox-group" value="1">1</vaadin-checkbox>
<vaadin-checkbox name="checkbox-group" value="2">2</vaadin-checkbox>
<vaadin-checkbox name="checkbox-group" value="3">3</vaadin-checkbox>
<vaadin-checkbox name="checkbox-group" value="4">4</vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-button id="submit-button">Submit</vaadin-button>
</form>
<div id="iron-form-output"></div>
</iron-form>
<script>
window.addDemoReadyListener('#checkbox-group-demos-checkbox-group-with-iron-form', function(document) {
const testForm = document.getElementById('test-form');
const submitButton = document.getElementById('submit-button');

submitButton.addEventListener('click', function(event) {
testForm.submit();
});

testForm.addEventListener('iron-form-submit', function(event) {
this.querySelector('#iron-form-output').innerHTML = JSON.stringify(event.detail);
});
});
</script>
</template>
</vaadin-demo-snippet>

<h3>Checkbox Group with Iron Form with different names</h3>
<vaadin-demo-snippet id="checkbox-group-demos-checkbox-group-with-iron-form-with-custom-value">
<template preserve-content>
<iron-form id="test-form-custom-value">
<form>
<vaadin-checkbox-group>
<vaadin-checkbox name="first-checkbox-group" value="1">1</vaadin-checkbox>
<vaadin-checkbox name="second-checkbox-group" value="2">2</vaadin-checkbox>
<vaadin-checkbox name="third-checkbox-group" value="3">3</vaadin-checkbox>
<vaadin-checkbox name="fourth-checkbox-group" value="4">4</vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-button id="submit-button-custom-value">Submit</vaadin-button>
</form>
<div id="iron-form-output-custom-value"></div>
</iron-form>
<script>
window.addDemoReadyListener('#checkbox-group-demos-checkbox-group-with-iron-form-with-custom-value', function(document) {
const testForm = document.getElementById('test-form-custom-value');
const submitButton = document.getElementById('submit-button-custom-value');

submitButton.addEventListener('click', function(event) {
testForm.submit();
});

testForm.addEventListener('iron-form-submit', function(event) {
this.querySelector('#iron-form-output-custom-value').innerHTML = JSON.stringify(event.detail);
});
});
</script>
</template>
</vaadin-demo-snippet>

</template>
<script>
class CheckboxGroupDemos extends DemoReadyEventEmitter(CheckboxDemo(Polymer.Element)) {
static get is() {
return 'checkbox-group-demos';
}
}
customElements.define(CheckboxGroupDemos.is, CheckboxGroupDemos);
</script>
</dom-module>
11 changes: 11 additions & 0 deletions demo/demos.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,16 @@
"image": ""
}
}
,
{
"name": "Vaadin Checkbox Group",
"url": "checkbox-group-demos",
"src": "checkbox-group-demos.html",
"meta": {
"title": "vaadin-checkbox-group Examples",
"description": "",
"image": ""
}
}
]
}
4 changes: 3 additions & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
<script src="../../vaadin-demo-helpers/vaadin-demo-ready-event-emitter.js"></script>

<script src="./checkbox-demo.js"></script>

<link rel="import" href="../../iron-form/iron-form.html">
<link rel="import" href="../../vaadin-button/vaadin-button.html">
<link rel="import" href="../vaadin-checkbox.html">
<link rel="import" href="../vaadin-checkbox-group.html">

<link rel="import" href="../../vaadin-lumo-styles/icons.html">

Expand Down
179 changes: 179 additions & 0 deletions src/vaadin-checkbox-group.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<!--
@license
Copyright (c) 2017 Vaadin Ltd.
This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
-->

<link rel="import" href="../../polymer/polymer-element.html">
<link rel="import" href="../../polymer/lib/utils/flattened-nodes-observer.html">
<link rel="import" href="../../vaadin-themable-mixin/vaadin-themable-mixin.html">
<link rel="import" href="vaadin-checkbox.html">

<dom-module id="vaadin-checkbox-group">
<template>
<slot id="slot"></slot>
</template>

<script>
(function() {
/**
* `<vaadin-checkbox-group>` is a Polymer element for grouping vaadin-checkboxes.
*
* ```html
* <vaadin-checkbox-group>
* <vaadin-checkbox value="foo">Foo</vaadin-checkbox>
* <vaadin-checkbox value="bar">Bar</vaadin-checkbox>
* <vaadin-checkbox value="baz">Baz</vaadin-checkbox>
* </vaadin-checkbox-group>
* ```
*
* ### Styling
*
* The following state attributes are available for styling:
*
* Attribute | Description | Part name
* -----------|-------------|------------
* `disabled` | Set when the checkbox group and its children are disabled. | :host
*
* See [ThemableMixin – how to apply styles for shadow parts](https://github.com/vaadin/vaadin-themable-mixin/wiki)
*
* @memberof Vaadin
* @mixes Vaadin.ThemableMixin
* @element vaadin-checkbox-group
* @demo demo/index.html
*/
class CheckboxGroupElement extends Vaadin.ThemableMixin(Polymer.Element) {
static get is() {
return 'vaadin-checkbox-group';
}

static get properties() {
return {
/**
* The current disabled state of the checkbox group. True if group and all internal checkboxes are disabled.
*/
disabled: {
type: Boolean,
reflectToAttribute: true,
observer: '_disabledChanged'
},

/**
* Value of the checkbox group.
*/
value: {
type: Array,
value: () => [],
notify: true
}
};
}

static get observers() {
return [
'_valueChanged(value, value.splices)'
];
}

/**
* @private
*/
connectedCallback() {
super.connectedCallback();

const checkedChangedListener = (e) => {
this._changeSelectedCheckbox(e.target);
};

this._observer = new Polymer.FlattenedNodesObserver(this, (info) => {

this._filterCheckboxes(info.addedNodes).forEach(checkbox => {
checkbox.addEventListener('checked-changed', checkedChangedListener);
if (this.disabled) {
checkbox.disabled = true;
}
if (checkbox.checked) {
this._addCheckboxToValue(checkbox.value);
}
});

this._filterCheckboxes(info.removedNodes).forEach(checkbox => {
checkbox.removeEventListener('checked-changed', checkedChangedListener);
if (checkbox.checked) {
this._removeCheckboxFromValue(checkbox.value);
}
});

const checkboxWithoutValue = this._filterCheckboxes(info.addedNodes).filter(checkbox => !checkbox
.getAttribute('value'));
if (checkboxWithoutValue.length) {
console.warn('Please add value attribute to all checkboxes in checkbox group');
}
});
}

ready() {
super.ready();

this.setAttribute('role', 'checkboxgroup');
}

get _checkboxes() {
return this._filterCheckboxes(this.querySelectorAll('*'));
}

_filterCheckboxes(nodes) {
return Array.from(nodes)
.filter(child => child instanceof Vaadin.CheckboxElement);
}

_disabledChanged(disabled) {
this.setAttribute('aria-disabled', disabled);

this._checkboxes.forEach(checkbox => checkbox.disabled = disabled);
}

_addCheckboxToValue(value) {
this.push('value', value);
}

_removeCheckboxFromValue(value) {
const index = this.value.indexOf(value);
this.splice('value', index, 1);
}

_changeSelectedCheckbox(checkbox) {
if (this._updatingValue) {
return;
}

if (checkbox.checked) {
this._addCheckboxToValue(checkbox.value);
} else {
this._removeCheckboxFromValue(checkbox.value);
}

}

_valueChanged(newV, oldV) {
// set a flag to avoid updating loop
this._updatingValue = true;
// reflect the value array to checkboxes
this._checkboxes.forEach(checkbox => {
checkbox.checked = newV.indexOf(checkbox.value) > -1;
});
this._updatingValue = false;
}

}

customElements.define(CheckboxGroupElement.is, CheckboxGroupElement);

/**
* @namespace Vaadin
*/
window.Vaadin = window.Vaadin || {};
Vaadin.CheckboxGroupElement = CheckboxGroupElement;
})();
</script>
</dom-module>
1 change: 1 addition & 0 deletions test/test-suites.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
window.VaadinCheckboxSuites = [
'vaadin-checkbox_test.html',
'vaadin-checkbox-group_test.html',
'accessibility.html'
];
Loading

0 comments on commit c2644c2

Please sign in to comment.