-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathknockout.x-editable.js
141 lines (124 loc) · 4.55 KB
/
knockout.x-editable.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// knockout.x-editable library v0.1.2
// (c) Brian Chance - https://github.com/brianchance/knockout-x-editable
// Licensed MIT
(function(factory) {
if (typeof define === "function" && define.amd) {
// AMD anonymous module
define(["knockout", "jquery"], factory);
} else {
// No module loader (plain <script> tag) - put directly in global namespace
factory(window.ko, window.jQuery);
}
})(function(ko, $) {
ko.bindingHandlers.editable = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var $element = $(element),
value = valueAccessor(),
allBindings = allBindingsAccessor(),
editableOptions = allBindings.editableOptions || {};
editableOptions.value = ko.utils.unwrapObservable(value);
if (!editableOptions.name) {
$.each(bindingContext.$data, function (k, v) {
if (v == value) {
editableOptions.name = k;
return false;
}
});
}
//wrap calls to knockout.validation
if (!editableOptions.validate && value.isValid) {
editableOptions.validate = function (testValue) {
//have to set to new value, then call validate, then reset to original value
//not pretty, but works
var initalValue = value();
value(testValue);
var res = value.isValid() ? null : ko.utils.unwrapObservable(value.error);
value(initalValue);
return res;
}
}
if ((editableOptions.type === 'select' || editableOptions.type === 'select2' || editableOptions.type === 'checklist'|| editableOptions.type === 'typeahead') && !editableOptions.source && editableOptions.options) {
if (editableOptions.optionsCaption)
editableOptions.prepend = editableOptions.optionsCaption;
//taken directly from ko.bindingHandlers['options']
function applyToObject(object, predicate, defaultValue) {
var predicateType = typeof predicate;
if (predicateType == "function") // Given a function; run it against the data value
return predicate(object);
else if (predicateType == "string") // Given a string; treat it as a property name on the data value
return object[predicate];
else // Given no optionsText arg; use the data value itself
return defaultValue;
}
editableOptions.source = function() {
return ko.utils.arrayMap(ko.utils.unwrapObservable(editableOptions.options), function (item) {
var optionValue = applyToObject(item, editableOptions.optionsValue, item);
var optionText = applyToObject(item, editableOptions.optionsText, optionValue);
return {
value: ko.utils.unwrapObservable(optionValue),
text: ko.utils.unwrapObservable(optionText)
};
});
}
}
if (editableOptions.visible && ko.isObservable(editableOptions.visible)) {
editableOptions.toggle = 'manual';
}
if (editableOptions.init) {
$element.on('init.ko', editableOptions.init);
}
//create editable
var $editable = $element.editable(editableOptions);
//apply textInput binding, if requested;
//or save otherwise
if (editableOptions.bindTextInput && editableOptions.bindTextInput === true) {
$editable.on('shown.ko', function(event, editable)
{
// distinguishes x-editable 'shown' event from bootstrap one
if (arguments.length != 2) return;
ko.applyBindingsToNode(editable.input.$input[0],
{
textInput: value
}, value);
});
} else {
if (ko.isObservable(value)) {
$editable.on('save.ko', function (e, params) {
value(params.newValue);
})
}
}
if (editableOptions.shown) {
$editable.on('shown.ko', editableOptions.shown);
}
if (editableOptions.save) {
$editable.on('save', editableOptions.save);
}
//setup observable to fire only when editable changes, not when options change
//http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html
ko.computed({
read: function () {
var val = ko.utils.unwrapObservable(valueAccessor());
if (val === null) val = '';
$editable.editable('setValue', val, true)
},
owner: this,
disposeWhenNodeIsRemoved: element
});
if (editableOptions.visible && ko.isObservable(editableOptions.visible)) {
ko.computed({
read: function () {
var val = ko.utils.unwrapObservable(editableOptions.visible());
if (val)
$editable.editable('show');
},
owner: this,
disposeWhenNodeIsRemoved: element
});
$editable.on('hidden.ko', function (e, params) {
editableOptions.visible(false);
});
}
}
};
});