-
Notifications
You must be signed in to change notification settings - Fork 9.3k
/
staticChecked.js
106 lines (88 loc) · 3.44 KB
/
staticChecked.js
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
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'ko',
'../template/renderer'
], function (ko, renderer) {
'use strict';
ko.bindingHandlers.staticChecked = {
'after': ['value', 'attr'],
/**
* Implements same functionality as a standard 'checked' binding,
* but with a difference that it wont' change values array if
* value of DOM element changes.
*/
init: function (element, valueAccessor, allBindings) {
var isCheckbox = element.type === 'checkbox',
isRadio = element.type === 'radio',
isValueArray,
oldElemValue,
useCheckedValue,
checkedValue,
updateModel,
updateView;
if (!isCheckbox && !isRadio) {
return;
}
checkedValue = ko.pureComputed(function () {
if (allBindings.has('checkedValue')) {
return ko.utils.unwrapObservable(allBindings.get('checkedValue'));
} else if (allBindings.has('value')) {
return ko.utils.unwrapObservable(allBindings.get('value'));
}
return element.value;
});
isValueArray = isCheckbox && ko.utils.unwrapObservable(valueAccessor()) instanceof Array;
oldElemValue = isValueArray ? checkedValue() : undefined;
useCheckedValue = isRadio || isValueArray;
/**
* Updates values array if it's necessary.
*/
updateModel = function () {
var isChecked = element.checked,
elemValue = useCheckedValue ? checkedValue() : isChecked,
modelValue;
if (ko.computedContext.isInitial()) {
return;
}
if (isRadio && !isChecked) {
return;
}
modelValue = ko.dependencyDetection.ignore(valueAccessor);
if (isValueArray) {
if (oldElemValue !== elemValue) {
oldElemValue = elemValue;
} else {
ko.utils.addOrRemoveItem(modelValue, elemValue, isChecked);
}
} else {
ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'checked', elemValue, true);
}
};
/**
* Updates checkbox state.
*/
updateView = function () {
var modelValue = ko.utils.unwrapObservable(valueAccessor());
if (isValueArray) {
element.checked = ko.utils.arrayIndexOf(modelValue, checkedValue()) >= 0;
} else if (isCheckbox) {
element.checked = modelValue;
} else {
element.checked = checkedValue() === modelValue;
}
};
ko.computed(updateModel, null, {
disposeWhenNodeIsRemoved: element
});
ko.utils.registerEventHandler(element, 'click', updateModel);
ko.computed(updateView, null, {
disposeWhenNodeIsRemoved: element
});
}
};
ko.expressionRewriting._twoWayBindings.staticChecked = true;
renderer.addAttribute('staticChecked');
});