diff --git a/addon/components/materialize-date-input.js b/addon/components/materialize-date-input.js new file mode 100644 index 00000000..3682684c --- /dev/null +++ b/addon/components/materialize-date-input.js @@ -0,0 +1,20 @@ +import MaterializeInput from './materialize-input'; +import layout from '../templates/components/materialize-date-input'; + +export default MaterializeInput.extend({ + layout: layout, + selectMonths: true, + numberOfYears: 15, + min: '', + max: '', + didInsertElement: function() { + this._super(); + var self = this; + this.$('.datepicker').pickadate({ + selectMonths: self.selectMonths, + selectYears: self.numberOfYears, + min: self.min, + max: self.max + }); + } +}); diff --git a/addon/components/materialize-input-field.js b/addon/components/materialize-input-field.js new file mode 100644 index 00000000..c68827f8 --- /dev/null +++ b/addon/components/materialize-input-field.js @@ -0,0 +1,28 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + init: function() { + this._super(); + // bind validation errors + var propertyPath = this.get('valueBinding._label'); + if (Ember.isPresent(propertyPath)) { + Ember.Binding.from('targetObject.errors.' + propertyPath) + .to('errors') + .connect(this); + } + }, + bindAttributes: ['disabled', 'readonly'], + tagName: 'div', + classNames: ['input-field'], + validate: false, + id: Ember.computed(function() { + var elementId = this.get('elementId'); + return elementId + '-input'; + }), + didInsertElement: function() { + // pad the errors element when an icon is present + if (Ember.isPresent(this.get('icon'))) { + this.$('>span').css('padding-left', '3rem'); + } + } +}); diff --git a/addon/components/materialize-input.js b/addon/components/materialize-input.js index a881ea18..15b6b5e6 100644 --- a/addon/components/materialize-input.js +++ b/addon/components/materialize-input.js @@ -1,31 +1,15 @@ import Ember from 'ember'; +import MaterializeInputField from './materialize-input-field'; import layout from '../templates/components/materialize-input'; -export default Ember.Component.extend({ - init: function() { - this._super(); - // bind validation errors - var propertyPath = this.get('valueBinding._label'); - if (Ember.isPresent(propertyPath)) { - Ember.Binding.from('targetObject.errors.' + propertyPath) - .to('errors') - .connect(this); - } - }, +export default MaterializeInputField.extend({ layout: layout, - tagName: 'div', - classNames: ['input-field'], - validate: false, - id: Ember.computed(function() { - var elementId = this.get('elementId'); - return elementId + '-input'; - }), didInsertElement: function() { + this._super(); // make sure the label moves when a value is bound. var labelSelector = this.$('>label'); if (Ember.isPresent(this.get('value')) && !labelSelector.hasClass('active')) { labelSelector.addClass('active'); - labelSelector.trigger('validate'); } } }); diff --git a/addon/components/materialize-select.js b/addon/components/materialize-select.js new file mode 100644 index 00000000..d3dc385a --- /dev/null +++ b/addon/components/materialize-select.js @@ -0,0 +1,26 @@ +import Ember from 'ember'; +import MaterializeInputField from './materialize-input-field'; +import layout from '../templates/components/materialize-select'; + +export default MaterializeInputField.extend({ + layout: layout, + didInsertElement: function() { + this._super(); + this.$('select').material_select(); + }, + errorsDidChange: function() { + var self = this; + var inputSelector = this.$('input'); + // monitor the select's validity and copy the appropriate validation class to the materialize input element. + Ember.run.later(function() { + var isValid = self.$('select').hasClass('valid'); + if (isValid) { + inputSelector.removeClass('invalid'); + inputSelector.addClass('valid'); + } else { + inputSelector.removeClass('valid'); + inputSelector.addClass('invalid'); + } + }, 150); + }.observes('errors') +}); diff --git a/addon/components/materialize-textarea.js b/addon/components/materialize-textarea.js new file mode 100644 index 00000000..8c422c31 --- /dev/null +++ b/addon/components/materialize-textarea.js @@ -0,0 +1,15 @@ +import Ember from 'ember'; +import InputField from './materialize-input-field'; +import layout from '../templates/components/materialize-textarea'; + +export default InputField.extend({ + layout: layout, + didInsertElement: function() { + this._super(); + // make sure the label moves when a value is bound. + var labelSelector = this.$('>label'); + if (Ember.isPresent(this.get('value')) && !labelSelector.hasClass('active')) { + labelSelector.addClass('active'); + } + } +}); diff --git a/addon/templates/components/materialize-date-input.hbs b/addon/templates/components/materialize-date-input.hbs new file mode 100644 index 00000000..9ebf9057 --- /dev/null +++ b/addon/templates/components/materialize-date-input.hbs @@ -0,0 +1,11 @@ +{{#if icon}} + +{{/if}} + + + + {{#if errors}} {{errors.firstObject}} {{else}} {{/if}} + + diff --git a/addon/templates/components/materialize-input.hbs b/addon/templates/components/materialize-input.hbs index f9a640d8..9e5717a9 100644 --- a/addon/templates/components/materialize-input.hbs +++ b/addon/templates/components/materialize-input.hbs @@ -1,7 +1,7 @@ {{#if icon}} {{/if}} -{{input id=id value=value classNameBindings="validate:validate: errors:invalid:valid" type="text" +{{input id=id value=value classNameBindings="validate:validate: errors.firstObject:invalid:valid" type="text" required=required pattern=pattern maxlength=maxlength readonly=readonly disabled=disabled autocomplete=autocomplete}} diff --git a/addon/templates/components/materialize-select.hbs b/addon/templates/components/materialize-select.hbs new file mode 100644 index 00000000..2dfde08e --- /dev/null +++ b/addon/templates/components/materialize-select.hbs @@ -0,0 +1,6 @@ + +{{view "select" id=id content=content optionValuePath=optionValuePath optionLabelPath=optionLabelPath prompt=prompt + value=value classNameBindings="validate:validate: errors:invalid:valid"}} + + {{#if errors}} {{errors.firstObject}} {{else}} {{/if}} + diff --git a/addon/templates/components/materialize-textarea.hbs b/addon/templates/components/materialize-textarea.hbs new file mode 100644 index 00000000..cffbd5ee --- /dev/null +++ b/addon/templates/components/materialize-textarea.hbs @@ -0,0 +1,10 @@ +{{#if icon}} + +{{/if}} +{{textarea id=id value=value name=name required=required readonly=readonly disabled=disabled maxlength=maxlength + class="materialize-textarea"}} + + + {{#if errors}} {{errors.firstObject}} {{else}} {{/if}} + + diff --git a/app/components/materialize-date-input.js b/app/components/materialize-date-input.js new file mode 100644 index 00000000..4e4997ff --- /dev/null +++ b/app/components/materialize-date-input.js @@ -0,0 +1,3 @@ +import materializeDateInput from 'ember-cli-materialize/components/materialize-date-input'; + +export default materializeDateInput; diff --git a/app/components/materialize-input-field.js b/app/components/materialize-input-field.js new file mode 100644 index 00000000..34e0279f --- /dev/null +++ b/app/components/materialize-input-field.js @@ -0,0 +1,3 @@ +import materializeInputField from 'ember-cli-materialize/components/materialize-input-field'; + +export default materializeInputField; diff --git a/app/components/materialize-select.js b/app/components/materialize-select.js new file mode 100644 index 00000000..3c0baa6c --- /dev/null +++ b/app/components/materialize-select.js @@ -0,0 +1,3 @@ +import materializeSelect from 'ember-cli-materialize/components/materialize-select'; + +export default materializeSelect; diff --git a/app/components/materialize-textarea.js b/app/components/materialize-textarea.js new file mode 100644 index 00000000..d4b1418e --- /dev/null +++ b/app/components/materialize-textarea.js @@ -0,0 +1,3 @@ +import materializeTextarea from 'ember-cli-materialize/components/materialize-textarea'; + +export default materializeTextarea; diff --git a/tests/dummy/app/controllers/input.js b/tests/dummy/app/controllers/input.js index f1df59db..d98978ee 100644 --- a/tests/dummy/app/controllers/input.js +++ b/tests/dummy/app/controllers/input.js @@ -1,15 +1,33 @@ import Ember from 'ember'; export default Ember.ObjectController.extend({ - + frameworks: [ + {id: 1, value: 'Materialize CSS'}, + {id: 2, value: 'Ember-CLI Materialize'} + ], + errors: Ember.Object.create({ + name: [], + framework: [] + }), nameDidChange: function() { - var errors = { name: [] }; + var errors = this.get('errors'); + var messages = []; if (!Ember.isPresent(this.get('name'))) { - errors.name = ['This field is required']; - } else { - errors.name = []; + messages = ['This field is required']; } + errors.set('name', messages); this.set('errors', errors); - }.observes('name') - + }.observes('name'), + frameworkDidChange: 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); + }.observes('framework') }); diff --git a/tests/dummy/app/templates/index.hbs b/tests/dummy/app/templates/index.hbs index 4a7ec0ff..9442cfb5 100644 --- a/tests/dummy/app/templates/index.hbs +++ b/tests/dummy/app/templates/index.hbs @@ -34,7 +34,7 @@ {{#link-to 'navbar' class="collection-item"}}Navbar1{{/link-to}} {{#link-to 'cards' class="collection-item"}}Cards1{{/link-to}} {{#link-to 'collapsible' class="collection-item"}}Collapsible1{{/link-to}} - {{#link-to 'input' class="collection-item"}}Input1{{/link-to}} + {{#link-to 'input' class="collection-item"}}Input4{{/link-to}} diff --git a/tests/dummy/app/templates/input.hbs b/tests/dummy/app/templates/input.hbs index 1d72523c..b6787b63 100644 --- a/tests/dummy/app/templates/input.hbs +++ b/tests/dummy/app/templates/input.hbs @@ -9,9 +9,12 @@