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
104
105
106
107
|
function modelAccessor(scope, element) {
var expr = element.attr('name'),
farmatterName = element.attr('ng-format') || NOOP,
formatter = angularFormatter(farmatterName);
if (!expr) throw "Required field 'name' not found.";
if (!formatter) throw "Formatter named '" + farmatterName + "' not found.";
return {
get: function() {
return formatter['format'](scope.$eval(expr));
},
set: function(value) {
scope.$eval(expr + '=' + toJson(formatter['parse'](value)));
}
};
}
function valueAccessor(element) {
var validatorName = element.attr('ng-validate') || NOOP,
validator = angularValidator(validatorName),
required = element.attr('ng-required'),
lastError;
required = required || required == '';
if (!validator) throw "Validator named '" + validatorName + "' not found.";
function validate(value) {
var error = required && !trim(value) ? "Required" : validator(value);
if (error !== lastError) {
if (error) {
element.addClass(NG_VALIDATION_ERROR);
element.attr(NG_ERROR, error);
} else {
element.removeClass(NG_VALIDATION_ERROR);
element.removeAttr(NG_ERROR);
}
lastError = error;
}
return value;
}
return {
get: function(){ return validate(element.val()); },
set: function(value){ element.val(validate(value)); }
};
}
function checkedAccessor(element) {
var domElement = element[0];
return {
get: function(){ return !!domElement.checked; },
set: function(value){ domElement.checked = !!value; }
};
}
function radioAccessor(element) {
var domElement = element[0];
return {
get: function(){ return domElement.checked ? domElement.value : null; },
set: function(value){ domElement.checked = value == domElement.value; }
};
}
function noopAccessor() { return { get: noop, set: noop }; }
var NG_ERROR = 'ng-error',
NG_VALIDATION_ERROR = 'ng-validation-error',
textWidget = inputWidget('keyup change', modelAccessor, valueAccessor, ''),
buttonWidget = inputWidget('click', noopAccessor, noopAccessor, undefined),
INPUT_TYPE = {
'text': textWidget,
'textarea': textWidget,
'hidden': textWidget,
'password': textWidget,
'button': buttonWidget,
'submit': buttonWidget,
'reset': buttonWidget,
'image': buttonWidget,
'checkbox': inputWidget('click', modelAccessor, checkedAccessor, false),
'radio': inputWidget('click', modelAccessor, radioAccessor, undefined)
// 'select-one': [null, 'change'],
// 'select-multiple': [[], 'change'],
// 'file': [{}, 'click']
};
function inputWidget(events, modelAccessor, viewAccessor, initValue) {
return function(element) {
var scope = this,
model = modelAccessor(scope, element),
view = viewAccessor(element),
action = element.attr('ng-action') || '';
var value = view.get() || initValue;
if (isDefined(value)) model.set(value);
element.bind(events, function(){
model.set(view.get());
scope.$eval(action);
});
scope.$watch(model.get, view.set);
};
}
angularWidget('INPUT', function input(element){
return function(element) {
this.$eval(element.attr('ng-init')||'');
(INPUT_TYPE[lowercase(element[0].type)] || noop).call(this, element);
};
});
angularWidget('TEXTAREA', function(){
return textWidget;
});
|