Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Update readme and fields files

  • Loading branch information...
commit cc2463527838e535fb05f75da308306121d76b41 1 parent 3215e9f
@schneiderik authored
Showing with 113 additions and 48 deletions.
  1. +1 −1  README.md
  2. +49 −22 fields.coffee
  3. +63 −25 fields.js
View
2  README.md
@@ -1,4 +1,4 @@
fields
======
-A better way of interacting with fields. [schneiderik.github.com/fields](http://schneiderik.github.com/fields)
+An abstract way of interacting with fields. [schneiderik.github.com/fields](http://schneiderik.github.com/fields)
View
71 fields.coffee
@@ -140,6 +140,7 @@ class Field extends Events
@el = $(element)
@parent = $(parent)
@attributes = {}
+ @val = @value
# Update attributes when a user interacts with the field
@parent.find("[name='#{@el.attr('name')}']").on 'keyup blur focus change', (e, options={})=>
@@ -147,28 +148,40 @@ class Field extends Events
@value @getFieldValueFromDOM()
# Evaluate the field for any errors, warnings, etc. when the value changes
- @on 'change:value', (value)->
- @isEmpty = @attributes.empty = value.length is 0
+ @on 'change:value', (value)=>
+ @attributes.empty = @isEmpty()
@evaluate()
@setAttributes()
- @val = @value
@
setAttributes: ->
- @attributes.name = @el.attr 'name'
- @attributes.type = @el.attr 'type'
- @attributes.value = @getFieldValueFromDOM()
+ @attributes.name = @el.attr 'name'
+ @attributes.type = @el.attr 'type'
+ @attributes.value = @getFieldValueFromDOM()
+ @attributes.required = @isRequired()
+ @attributes.empty = @isEmpty()
+ @attributes.evaluations = {}
+ @evaluate()
- @isRequired = @attributes.required = (@el.hasClass 'required' or @el.is('[required]'))
- @isEmpty = @attributes.empty = @el.val().length is 0
+ isEmpty: ()->
+ return true if @val().length is 0
+ return true if @val() is []
+ return false
- @evaluate()
+ isRequired: ()->
+ return true if @el.hasClass 'required'
+ return true if @el.is('[required]')
+ return false
+
+ isValid: ()->
+ return false if @get('evaluations').errors?
+ return true
# Get value of an attribute at a specific key
get: (attr)->
- @attributes[attr]
+ return @attributes[attr]
# Get value of the field, or set it by passing an argument
value: (arg)->
@@ -178,26 +191,38 @@ class Field extends Events
@attributes.value = arg
@trigger "change:value", @, arg
@updateFieldValueInDOM arg
+
return @
# Convenience method for setting the value back to nothing
clear: ->
@value ''
+ return @
+
+ errors: ->
+ if @get('evaluations').errors?
+ return @get('evaluations').errors
+ else
+ return []
+
# Evaluate the field against evaluations stored in the evaluationRegistry and
# return an object of any results keyed on the context of the evaluation. i.e. 'errors'
evaluate: ->
+ oldValidity = @isValid()
@attributes.evaluations = {}
- if @isRequired and @isEmpty
+ if @isRequired() and @isEmpty()
@attributes.evaluations.errors = ['Field required']
else
$.extend @attributes.evaluations, window.FieldsUtils.evaluationRegistry.evaluate(@el)
+ # Trigger event if validity changes
+ @trigger('change:valid', @, @isValid()) if oldValidity isnt @isValid()
+
# A field is valid if it has no errors.
- @isValid = @attributes.valid = !@get('evaluations').errors?
+ @attributes.valid = @isValid()
- errors: ->
- @get('evaluations').errors
+ return @get('evaluations')
# Getting and setting values is a bit complicated because of radio and checkbox inputs.
# Only one field model should be generated for the set of inputs with the same name.
@@ -308,6 +333,8 @@ class Fields extends Events
model.on 'change:value', (e)=>
@trigger 'change:value'
+ return @
+
# Get a field model by it's name
get: (name)-> @models[name]
@@ -315,6 +342,8 @@ class Fields extends Events
clear: ->
model.clear() for name, model of @models
+ return @
+
# Collect a specified value from each field model keyed on the name of that field.
collect: (value)->
dict = {}
@@ -322,20 +351,18 @@ class Fields extends Events
dict[name] = model.get(value)
return dict
- # Check the validity of all of the field models to see if the collection is valid.
- getValidity: ()->
+ isValid: ()->
valid = true
- valid = false for name, model of @models when model.isValid is false
-
- @trigger('change:valid', @, valid) if @isValid isnt valid
- @isValid = valid
+ valid = false for name, model of @models when model.isValid() is false
+ return valid
# Update the collections validity whenever one of its models validity changes
trackValidity: ()->
- @getValidity()
+ oldValidity = @isValid()
+
for name, model of @models
model.on 'change:valid', (e)=>
- @getValidity()
+ @trigger('change:valid', @, @isValid()) if @isValid() isnt oldValidity
generateModels: ()->
@models = {}
View
88 fields.js
@@ -126,6 +126,7 @@
this.el = $(element);
this.parent = $(parent);
this.attributes = {};
+ this.val = this.value;
this.parent.find("[name='" + (this.el.attr('name')) + "']").on('keyup blur focus change', function(e, options) {
if (options == null) {
options = {};
@@ -136,11 +137,10 @@
return _this.value(_this.getFieldValueFromDOM());
});
this.on('change:value', function(value) {
- this.isEmpty = this.attributes.empty = value.length === 0;
- return this.evaluate();
+ _this.attributes.empty = _this.isEmpty();
+ return _this.evaluate();
});
this.setAttributes();
- this.val = this.value;
this;
}
@@ -149,11 +149,39 @@
this.attributes.name = this.el.attr('name');
this.attributes.type = this.el.attr('type');
this.attributes.value = this.getFieldValueFromDOM();
- this.isRequired = this.attributes.required = this.el.hasClass('required' || this.el.is('[required]'));
- this.isEmpty = this.attributes.empty = this.el.val().length === 0;
+ this.attributes.required = this.isRequired();
+ this.attributes.empty = this.isEmpty();
+ this.attributes.evaluations = {};
return this.evaluate();
};
+ Field.prototype.isEmpty = function() {
+ if (this.val().length === 0) {
+ return true;
+ }
+ if (this.val() === []) {
+ return true;
+ }
+ return false;
+ };
+
+ Field.prototype.isRequired = function() {
+ if (this.el.hasClass('required')) {
+ return true;
+ }
+ if (this.el.is('[required]')) {
+ return true;
+ }
+ return false;
+ };
+
+ Field.prototype.isValid = function() {
+ if (this.get('evaluations').errors != null) {
+ return false;
+ }
+ return true;
+ };
+
Field.prototype.get = function(attr) {
return this.attributes[attr];
};
@@ -172,21 +200,32 @@
};
Field.prototype.clear = function() {
- return this.value('');
+ this.value('');
+ return this;
+ };
+
+ Field.prototype.errors = function() {
+ if (this.get('evaluations').errors != null) {
+ return this.get('evaluations').errors;
+ } else {
+ return [];
+ }
};
Field.prototype.evaluate = function() {
+ var oldValidity;
+ oldValidity = this.isValid();
this.attributes.evaluations = {};
- if (this.isRequired && this.isEmpty) {
+ if (this.isRequired() && this.isEmpty()) {
this.attributes.evaluations.errors = ['Field required'];
} else {
$.extend(this.attributes.evaluations, window.FieldsUtils.evaluationRegistry.evaluate(this.el));
}
- return this.isValid = this.attributes.valid = !(this.get('evaluations').errors != null);
- };
-
- Field.prototype.errors = function() {
- return this.get('evaluations').errors;
+ if (oldValidity !== this.isValid()) {
+ this.trigger('change:valid', this, this.isValid());
+ }
+ this.attributes.valid = this.isValid();
+ return this.get('evaluations');
};
Field.prototype.getFieldValueFromDOM = function() {
@@ -375,6 +414,7 @@
return _this.trigger('change:value');
});
}
+ return this;
}
Fields.prototype.get = function(name) {
@@ -382,14 +422,13 @@
};
Fields.prototype.clear = function() {
- var model, name, _ref, _results;
+ var model, name, _ref;
_ref = this.models;
- _results = [];
for (name in _ref) {
model = _ref[name];
- _results.push(model.clear());
+ model.clear();
}
- return _results;
+ return this;
};
Fields.prototype.collect = function(value) {
@@ -403,32 +442,31 @@
return dict;
};
- Fields.prototype.getValidity = function() {
+ Fields.prototype.isValid = function() {
var model, name, valid, _ref;
valid = true;
_ref = this.models;
for (name in _ref) {
model = _ref[name];
- if (model.isValid === false) {
+ if (model.isValid() === false) {
valid = false;
}
}
- if (this.isValid !== valid) {
- this.trigger('change:valid', this, valid);
- }
- return this.isValid = valid;
+ return valid;
};
Fields.prototype.trackValidity = function() {
- var model, name, _ref, _results,
+ var model, name, oldValidity, _ref, _results,
_this = this;
- this.getValidity();
+ oldValidity = this.isValid();
_ref = this.models;
_results = [];
for (name in _ref) {
model = _ref[name];
_results.push(model.on('change:valid', function(e) {
- return _this.getValidity();
+ if (_this.isValid() !== oldValidity) {
+ return _this.trigger('change:valid', _this, _this.isValid());
+ }
}));
}
return _results;
Please sign in to comment.
Something went wrong with that request. Please try again.