rivets-backbone-validation.js
3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
define([
'jquery',
'underscore',
'backbone',
], function($, _, Backbone) {
var modelClass, collectionClass;
var bindings = {};
bindings['error-*'] = {
publishes: true,
bind: function(el) {
var self = this;
var holder = this.validationHolder = {
marker: el.parentNode.insertBefore(document.createComment(" rivets: " + this.type + " "), el),
focus: function() {
$(holder.container).find('> .validationfielderrors').show();
},
blur: function() {
holder.lastObj.seen(holder.lastId, true);
$(holder.container).find('> .validationfielderrors').hide();
holder.lastObj.validate();
},
validated: function(isValid, model, errors) {
var errorList = errors[holder.lastId];
var $container = $(holder.container);
var $fieldErrors = $container.find('> .validationfielderrors').empty();
if (errorList && holder.lastObj.seen(holder.lastId)) {
$container.addClass('has-errors');
localRequire(['text!./templates/fielderrorpopup.html!strip'], function(templateHtml) {
$fieldErrors.empty().append($($.parseHTML(templateHtml)).find('.template-content').append($.parseHTML(errorList)).end());
});
} else {
$container.removeClass('has-errors');
}
}
};
localRequire(['text!./templates/fielderrorpopup.html!strip']);
localRequire(['css!./css/styles.css']);
holder.container = $.parseHTML('<span class="validationerrorcontainer"><div class="validationfielderrors"></div></span>');
$(holder.container).find('> .validationfielderrors').hide();
$(holder.marker).after($(holder.container).append(el));
diveIntoObject(this.model, this.keypath, function(obj, id) {
holder.lastObj = obj;
holder.lastId = id;
obj.on('validated', holder.validated);
});
$(el).on('focus', holder.focus).on('blur', holder.blur);
rivetsBinderCall(this, this.args[0], 'bind', arguments);
},
unbind: function(el) {
var holder = this.validationHolder;
$(this.validationHolder.marker).after(el).remove();
$(el).off('focus', holder.focus).off('blur', holder.blur);
diveIntoObject(this.model, this.keypath, function(obj, id) {
obj.off('validated', holder.validated);
});
delete this.validationHolder;
rivetsBinderCall(this, this.args[0], 'unbind', arguments);
},
routine: function(el, value) {
rivetsBinderCall(this, this.args[0], 'routine', arguments);
}
}
modelClass = Backbone.Model.extend({
initialize: function(attrs, options) {
modelClass.__super__.initialize.apply(this, arguments);
this._seen = {};
},
seen: function(attrName, wasSeen) {
if (attrName == null) {
return _.keys(_.clone(this._seen));
}
if (wasSeen) {
this._seen[attrName] = true;
} else if (wasSeen == false) {
delete this._seen[attrName];
} else {
return this._seen[attrName];
}
return this;
},
});
collectionClass = Backbone.Collection.extend({
model: modelClass,
parse: function(models, options) {
var newModels = [];
var subOptions = _.extend({parse: true}, options);
for (var i = 0; i < models.length; i++) {
newModels[newModels.length] = new this.model(models[i], subOptions);
}
return newModels;
}
});
return {
Model: modelClass,
Collection: collectionClass,
bindings: bindings
};
});