diff --git a/vendors/knockout/src/binding/defaultBindings/checked.js b/vendors/knockout/src/binding/defaultBindings/checked.js new file mode 100644 index 000000000..0d52df80a --- /dev/null +++ b/vendors/knockout/src/binding/defaultBindings/checked.js @@ -0,0 +1,57 @@ +(()=>{ + +ko.bindingHandlers['checked'] = { + 'after': ['value', 'attr'], + 'init': function (element, valueAccessor, allBindings) { + var isCheckbox = element.type == "checkbox", + isRadio = element.type == "radio"; + + // Only bind to check boxes and radio buttons + if (isCheckbox || isRadio) { + const checkedValue = ko.pureComputed(()=>{ + if (isRadio) { + return allBindings['has']('value') + ? ko.utils.unwrapObservable(allBindings.get('value')) + : element.value; + } + }); + + // Set up two computeds to update the binding: + + // The first responds to element clicks + element.addEventListener("click", () => { + // When we're first setting up this computed, don't change any model state. + if (ko.dependencyDetection.isInitial()) { + return; + } + + // This updates the model value from the view value. + // It runs in response to DOM events (click) and changes in checkedValue. + var isChecked = element.checked; + + // We can ignore unchecked radio buttons, because some other radio + // button will be checked, and that one can take care of updating state. + // Also ignore value changes to an already unchecked checkbox. + if (!isChecked && (isRadio || ko.dependencyDetection.getDependenciesCount())) { + return; + } + + var elemValue = isCheckbox ? isChecked : checkedValue(), + modelValue = ko.dependencyDetection.ignore(valueAccessor); + ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'checked', elemValue, true); + }), + + // The second responds to changes in the model value (the one associated with the checked binding) + ko.computed(() => { + // This updates the view value from the model value. + // It runs in response to changes in the bound (checked) value. + var modelValue = ko.utils.unwrapObservable(valueAccessor()); + element.checked = isCheckbox ? !!modelValue : (checkedValue() === modelValue); + }, null, { disposeWhenNodeIsRemoved: element }); + } + } +}; + +ko.expressionRewriting.twoWayBindings['checked'] = true; + +})();