Skip to content

Commit

Permalink
Checkbox, Radio, Switch, Range and Checkbox/Radio/Switch List components
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike North committed Apr 16, 2015
1 parent 0cac9fd commit 7296b55
Show file tree
Hide file tree
Showing 38 changed files with 925 additions and 54 deletions.
7 changes: 7 additions & 0 deletions addon/components/materialize-checkbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import SelectableItem from './materialize-selectable-item';
import layout from '../templates/components/materialize-checkbox';

export default SelectableItem.extend({
layout: layout,
classNames: ['materialize-checkbox']
});
11 changes: 11 additions & 0 deletions addon/components/materialize-checkboxes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import SelectableItemGroup from './materialize-selectable-item-group';
import CheckboxComponent from './materialize-checkbox';
import GroupSelectableItemMixin from '../mixins/group-selectable-item';


var GroupCheckboxComponent = CheckboxComponent.extend(GroupSelectableItemMixin, { });

export default SelectableItemGroup.extend({
selectableItemView: GroupCheckboxComponent,
multiple: true
});
40 changes: 40 additions & 0 deletions addon/components/materialize-radio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Ember from 'ember';
import SelectableItem from './materialize-selectable-item';
import layout from '../templates/components/materialize-radio';

export default SelectableItem.extend({
layout: layout,
className: ['materialize-radio'],
groupName: Ember.computed.alias('group.element.id'),

_inputId: Ember.computed('element.id', function () {
return this.get('element.id') + 'input';
}).readOnly(),

didInsertElement() {
this._super(...arguments);
this._checkboxInitialization();
},

_checkboxInitialization() {
/*
Workaround for a limitation of the {{input}} helper, where
the checked property doesn't two-way bind as expected when
type="radio" is used
*/
this._radioChangeListener = jqEvt => this.set('isSelected', jqEvt.target.checked);

this.$('.selectable-item-input')
.on('change', this._radioChangeListener);

// Potentially part of the same workaround. We need to
// set the initial state of the radio button explicitly
this.$('.selectable-item-input')
.prop('checked', this.get('isSelected'));
},

willDestroyElement() {
this.$('.selectable-item-input')
.off('change', this._radioChangeListener);
}
});
9 changes: 9 additions & 0 deletions addon/components/materialize-radios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SelectableItemGroup from './materialize-selectable-item-group';
import RadioComponent from './materialize-radio';
import GroupSelectableItemMixin from '../mixins/group-selectable-item';

var GroupRadioComponent = RadioComponent.extend(GroupSelectableItemMixin, { });

export default SelectableItemGroup.extend({
selectableItemView: GroupRadioComponent
});
10 changes: 10 additions & 0 deletions addon/components/materialize-range.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Ember from 'ember';
import layout from '../templates/components/materialize-range';

export default Ember.Component.extend({
min: 0,
max: 100,
step: 5,
layout: layout,
classNames: ['range-field']
});
81 changes: 81 additions & 0 deletions addon/components/materialize-selectable-item-group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Ember from 'ember';
import layout from '../templates/components/materialize-selectable-item-group';

var get = Ember.get,
map = Ember.EnumerableUtils.map,
indexOf = Ember.EnumerableUtils.indexOf;

export default Ember.Component.extend({
content: null,
selection: null,
layout: layout,
optionValuePath: 'content',
optionLabelPath: 'content',
multiple: false,
__materializeSelectableItemGroup: true,

init() {
this._super(...arguments);
if (this.get('selection') === null && !!this.get('multiple')) {
this.set('selection', Ember.A());
}
},

isValueSelected(value) {
if (this.get('multiple')) {
return indexOf(this.get('selection'), value) >= 0;
}
else {
return this.get('selection') === value;
}
},

setValueSelection(value, select) {
if (select) {
return this.addToSelection(value);
}
else {
return this.removeFromSelection(value);
}
},

addToSelection(value) {
if (this.get('multiple')) {
this.get('selection').addObject(value);
}
else {
this.set('selection', value);
}
},

removeFromSelection(value) {
if (this.get('multiple')) {
this.get('selection').removeObject(value);
}
else {
throw new Error('removeFromSelection is not supported in single-selection mode');
}
},

_valuePath: Ember.computed('optionValuePath', function () {
var optionValuePath = get(this, 'optionValuePath');
return optionValuePath.replace(/^content\.?/, '');
}),

_labelPath: Ember.computed('optionLabelPath', function () {
var optionLabelPath = get(this, 'optionLabelPath');
return optionLabelPath.replace(/^content\.?/, '');
}),

_content: Ember.computed('content.[]', '_valuePath', '_labelPath',function () {
var valuePath = get(this, '_valuePath');
var labelPath = get(this, '_labelPath');
var content = get(this, 'content') || Ember.A([]);

if (valuePath && labelPath) {
return Ember.A(map(content, function (el) { return {value: get(el, valuePath), label: get(el, labelPath)}; }));
} else {
return Ember.A(map(content, function (el) { return {value: el, label: el}; }));
}
})
});
50 changes: 50 additions & 0 deletions addon/components/materialize-selectable-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Ember from 'ember';

export default Ember.Component.extend({
checked: null,
classNames: ['materialize-selectable-item'],
_checked: Ember.computed('group.selection', 'group.selection.[]', function (key, val) {

This comment has been minimized.

Copy link
@jacobq

jacobq Feb 28, 2018

Collaborator

I know this commit is ancient relative to EmberJS time, but I wanted to mention that, at least in recent EmberJS versions, it is redundant to list both foo.bar and foo.bar.[] as dependent keys. Using foo.bar.[] implies foo.bar.

This comment has been minimized.

Copy link
@mike-north

mike-north Feb 28, 2018

Owner

I believe there are consumers of this library who still use 1.10. I'm not sure if this here for compatibility reasons

This comment has been minimized.

Copy link
@jacobq

jacobq Feb 28, 2018

Collaborator

Hmm, I think foo.[] was added in 2.0, but it replaced foo.@each (with no prop), not foo by itself, so I'm not sure what this code would do in 1.x.

var group = this.get('group');
if (!group) {
if (arguments.length <= 1) {
return this.get('checked');
}
else {
this.set('checked', val);
return val;
}
}
else {
// Operate in the context of a group. The group owns
// the selection state
if (arguments.length <= 1) {
// get
return group.isValueSelected(this.get('value'));
}
else {
//set
group.setValueSelection(this.get('value'), val);
return !!val;
}
}
}),

isSelected: Ember.computed.alias('_checked'),
_setupLabel() {
var $input = this.$('.selectable-item-input')[0];

var inputId = $input ? $input.id : null;
if (inputId) {
this.$('.selectable-item-label').attr('for', inputId);
}
},

didInsertElement() {
this._super(...arguments);
this._setupLabel();
},

group: Ember.computed(function () {
return this.nearestWithProperty('__materializeSelectableItemGroup');
})
});
15 changes: 15 additions & 0 deletions addon/components/materialize-switch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Ember from 'ember';
import SelectableItem from './materialize-selectable-item';
import layout from '../templates/components/materialize-switch';

export default SelectableItem.extend({
layout: layout,
offLabel: 'Off',
onLabel: 'On',
disabled: false,

classNames: ['switch', 'materialize-switch'],
_labelClass: Ember.computed('name', function () {
return this.get('name') ? 'right' : '';
})
});
10 changes: 10 additions & 0 deletions addon/components/materialize-switches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import SelectableItemGroup from './materialize-selectable-item-group';
import GroupSelectableItemMixin from '../mixins/group-selectable-item';
import SwitchComponent from './materialize-switch';

var GroupSwitchComponent = SwitchComponent.extend(GroupSelectableItemMixin, { });

export default SelectableItemGroup.extend({
selectableItemView: GroupSwitchComponent,
multiple: true
});
7 changes: 7 additions & 0 deletions addon/mixins/group-selectable-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Ember from 'ember';

export default Ember.Mixin.create({
name: Ember.computed.alias('content.label'),
value: Ember.computed.alias('content.value'),
disabled: Ember.computed.alias('group.disabled')
});
1 change: 1 addition & 0 deletions addon/templates/components/materialize-button.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
<i {{bind-attr class="icon iconPosition"}}></i>
{{/if}}
{{text}}
{{yield}}
2 changes: 2 additions & 0 deletions addon/templates/components/materialize-checkbox.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{input type="checkbox" class="selectable-item-input" checked=isSelected disabled=disabled}}
<label class="materialize-selectable-item-label">{{name}}{{yield}}</label>
3 changes: 3 additions & 0 deletions addon/templates/components/materialize-radio.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<input type="radio" class="selectable-item-input" {{bind-attr checked=isSelected id=_inputId name=groupName disabled=disabled value=value}} />
<label class="materialize-selectable-item-label selectable-item-label" >{{name}}{{yield}}</label>

2 changes: 2 additions & 0 deletions addon/templates/components/materialize-range.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<label>{{name}}</label>
{{input type="range" min=min max=max step=step value=value disabled=disabled}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{yield}}
{{#each _content as |item|}}
<p>{{view selectableItemView content=item}}</p>
{{/each}}
8 changes: 8 additions & 0 deletions addon/templates/components/materialize-switch.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<span class="switch-label materialize-selectable-item-label">{{name}}</span>
<label {{bind-attr class=_labelClass}}>
<span class="offlabel">{{offLabel}}</span>
{{input type="checkbox" disabled=disabled checked=isSelected}}
<span class="lever"></span>
<span class="onlabel">{{onLabel}}</span>
</label>

3 changes: 3 additions & 0 deletions app/components/materialize-checkbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import materializeCheckbox from 'ember-cli-materialize/components/materialize-checkbox';

export default materializeCheckbox;
3 changes: 3 additions & 0 deletions app/components/materialize-checkboxes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import materializeCheckboxes from 'ember-cli-materialize/components/materialize-checkboxes';

export default materializeCheckboxes;
3 changes: 3 additions & 0 deletions app/components/materialize-radio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import materializeRadio from 'ember-cli-materialize/components/materialize-radio';

export default materializeRadio;
3 changes: 3 additions & 0 deletions app/components/materialize-radios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import materializeRadios from 'ember-cli-materialize/components/materialize-radios';

export default materializeRadios;
3 changes: 3 additions & 0 deletions app/components/materialize-range.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import materializeRange from 'ember-cli-materialize/components/materialize-range';

export default materializeRange;
3 changes: 3 additions & 0 deletions app/components/materialize-switch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import materializeSwitch from 'ember-cli-materialize/components/materialize-switch';

export default materializeSwitch;
3 changes: 3 additions & 0 deletions app/components/materialize-switches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import materializeSwitches from 'ember-cli-materialize/components/materialize-switches';

export default materializeSwitches;
70 changes: 70 additions & 0 deletions tests/dummy/app/controllers/forms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import Ember from "ember";

function asJSON(propKey) {
return new Ember.computed(propKey,propKey + '.[]', function () {
return JSON.stringify(this.get(propKey));
});
}

export default Ember.Controller.extend({
frameworks: new Ember.A([
{id: 1, value: 'Materialize CSS'},
{id: 2, value: 'Ember-CLI Materialize'}
]),

errors: Ember.Object.create({
name: new Ember.A([]),
framework: new Ember.A([])
}),

nameDidChange: Ember.observer('name', function() {
var errors = this.get('errors');
var messages = [];
if (!Ember.isPresent(this.get('name'))) {
messages = ['This field is required'];
}
errors.set('name', messages);
this.set('errors', errors);
}),

frameworkDidChange: Ember.observer('framework', function() {
var self = this;
var errors = self.get('errors');
Ember.run.later(function() {
var messages = [];
if (!Ember.isPresent(self.get('framework'))) {
messages = ['This field is required'];
}
errors.set('framework', messages);
self.set('errors', errors);
}, 100);
}),
rangeValue: 64,
switchValue1: true,
notSwitchValue: Ember.computed.not('switchValue'),
switchValue: true,
checkValueOne: false,
checkValueTwo: true,

checkboxIsSelected: false,
radioIsSelected: false,
radioSelection: 2,
otherRadioSelection: 'green',
radioChoices: Ember.A([{ id: 1, text: "One" }, { id: 2, text: "Two" }]),

radioSelectionString: asJSON("radioSelection"),
radioChoicesString: asJSON("radioChoices"),

checkboxSelections: Ember.A([3, 4]),
checkboxChoices: Ember.A([{ id: 3, label: "Three" }, { id: 4, label: "Four" }, { id: 5, label: "Five" }]),

switchesChoicesString: asJSON('switchesChoices'),
switchesChoices: Ember.A([{ key: 6, name: "Six" }, { key: 7, name: "Seven" }, { key: 8, name: "Eight" }]),
switchesSelections: Ember.A([7]),
switchesSelection: 7,
switchesSelectionString: asJSON('switchesSelection'),
switchesSelectionsString: asJSON('switchesSelections'),

checkboxChoicesString: asJSON("checkboxChoices"),
checkboxSelectionsString: asJSON("checkboxSelections")
});
Loading

0 comments on commit 7296b55

Please sign in to comment.