-
-
Save fomichigo/874489d748b2b9aa309c to your computer and use it in GitHub Desktop.
Binding handlers used in my App. Extracted from everywhere. Some of the original sources unknown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ko.bindingHandlers.money = { | |
update: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var value = valueAccessor(); | |
var allBindings = allBindingsAccessor(); | |
var valueUnwrapped = ko.utils.unwrapObservable(value) || 0; | |
var output = output = accounting.formatMoney(valueUnwrapped, OKLO.CurrencySign); | |
if ($(element).is("input") === true) { | |
$(element).val(output); | |
} else { | |
$(element).html(output); | |
} | |
} | |
}; | |
//<input type="text" data-bind="value: comment, valueUpdate: 'afterkeydown', maxLength: 20"> | |
ko.bindingHandlers.maxLength = { | |
update: function (element, valueAccessor, allBindings) { | |
if (allBindings().value()) { | |
allBindings() | |
.value(allBindings().value().substr(0, valueAccessor())); | |
} | |
} | |
} | |
//<div data-bind="trimText: myText1"></div> | |
//<div data-bind="trimText: myText1, trimTextLength: 10"></div> | |
ko.bindingHandlers.trimLengthText = {}; | |
ko.bindingHandlers.trimText = { | |
init: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var trimmedText = ko.computed(function () { | |
var untrimmedText = ko.utils.unwrapObservable(valueAccessor()); | |
var defaultMaxLength = 20; | |
var minLength = 5; | |
var maxLength = ko.utils.unwrapObservable(allBindingsAccessor().trimTextLength) || defaultMaxLength; | |
if (maxLength < minLength) maxLength = minLength; | |
var text = untrimmedText.length > maxLength ? untrimmedText.substring(0, maxLength - 1) + '...' : untrimmedText; | |
return text; | |
}); | |
ko.applyBindingsToNode(element, { | |
text: trimmedText | |
}, viewModel); | |
return { | |
controlsDescendantBindings: true | |
}; | |
} | |
}; | |
//<span data-bind="currency: price"></span> | |
//<span data-bind="currency: price, symbol: '€'"></span> | |
ko.bindingHandlers.currency = { | |
symbol: ko.observable('$'), | |
update: function (element, valueAccessor, allBindingsAccessor) { | |
return ko.bindingHandlers.text.update(element, function () { | |
var value = +(ko.utils.unwrapObservable(valueAccessor()) || 0), | |
symbol = ko.utils.unwrapObservable(allBindingsAccessor().symbol === undefined | |
? allBindingsAccessor().symbol | |
: ko.bindingHandlers.currency.symbol); | |
return symbol + value.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,"); | |
}); | |
} | |
}; | |
//Usage: <span data-bind="text: FromDate, data: { 'item' : ItemID}"></span> | |
ko.bindingHandlers.data = { | |
name: ko.observable(''), | |
update: function (element, valueAccessor, allBindingsAccessor) { | |
var va = ko.utils.unwrapObservable(valueAccessor()); | |
var value = "", name = ""; | |
var d = {}; | |
if (typeof (va) === "object") { | |
for (var k in va) { | |
var _val = ko.utils.unwrapObservable(va[k]); | |
if (typeof (_val) !== "object") { | |
d["data-" + k] = _val; | |
} else { | |
d["data-" + k] = ko.toJSON(_val); | |
} | |
} | |
} else { | |
value = va; | |
name = ko.utils.unwrapObservable(allBindingsAccessor().name !== undefined | |
? allBindingsAccessor().name | |
: ko.bindingHandlers.data.name); | |
d["data-" + name] = value; | |
} | |
ko.bindingHandlers.attr.update(element, function () { | |
return d; | |
}); | |
} | |
}; | |
// <a data-bind="href: myUrl">Click Me</a> | |
ko.bindingHandlers.href = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { href: valueAccessor() }; | |
}); | |
} | |
}; | |
ko.bindingHandlers.name = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { name: valueAccessor() }; | |
}); | |
} | |
}; | |
ko.bindingHandlers.id = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { id: valueAccessor() }; | |
}); | |
} | |
}; | |
// <img data-bind="src: imgSrc" /> | |
ko.bindingHandlers.src = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { src: valueAccessor() }; | |
}); | |
} | |
}; | |
//<form data-bind="hidden: hideForm"></form> | |
ko.bindingHandlers.hidden = { | |
update: function (element, valueAccessor) { | |
var value = ko.utils.unwrapObservable(valueAccessor()); | |
ko.bindingHandlers.visible.update(element, function () { return !value; }); | |
} | |
}; | |
/* | |
* | |
<!-- ko stopBinding: true --> | |
<div id="widget"> | |
... | |
</div> | |
<!-- /ko --> | |
* | |
*/ | |
ko.bindingHandlers.stopBinding = { | |
init: function () { | |
return { controlsDescendantBindings: true }; | |
} | |
}; | |
ko.virtualElements.allowedBindings.stopBinding = true; | |
//<pre data-bind="toJSON: $root"></pre> | |
ko.bindingHandlers.toJSON = { | |
update: function (element, valueAccessor) { | |
return ko.bindingHandlers.text.update(element, function () { | |
return OKLO.DebugEnabled ? ko.toJSON(valueAccessor(), null, 2) : ""; | |
}); | |
} | |
}; | |
// Usage: <input tabindex="10" data-bind="numericValue: myNumericObservable"> | |
// <input data-bind="numericValue: myNumericObservable, positions: 0, noDecimalPoints: true"> | |
ko.bindingHandlers.numericValue = { | |
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
ko.utils.registerEventHandler(element, 'change', function (event) { | |
var observable = valueAccessor(); | |
var positions = ko.utils.unwrapObservable(allBindingsAccessor().positions) || ko.bindingHandlers.numericValue.defaultPositions; | |
if (ko.utils.unwrapObservable(allBindingsAccessor().positions) == 0) { | |
positions = 0; | |
} | |
if (isNaN(parseFloat($(element).val()))) | |
observable(0); | |
else { | |
if (!ko.utils.unwrapObservable(allBindingsAccessor().noDecimalPoints)) | |
observable(parseFloat($(element).val().replace(".", "").replace(",", ".")).toFixed(positions).replace(",", ".")); | |
else | |
observable(parseFloat($(element).val().replace(".", "").replace(",", ".")).toFixed(positions)); | |
} | |
}); | |
}, | |
update: function (element, valueAccessor, allBindingsAccessor) { | |
var value = ko.utils.unwrapObservable(valueAccessor()); | |
if (value != null) { | |
var positions = ko.utils.unwrapObservable(allBindingsAccessor().positions) || ko.bindingHandlers.numericValue.defaultPositions; | |
if (ko.utils.unwrapObservable(allBindingsAccessor().positions) == 0) { | |
positions = 0; | |
} | |
var formattedValue = parseFloat(value).toFixed(positions); | |
var finalFormatted = formattedValue; | |
if (!ko.utils.unwrapObservable(allBindingsAccessor().noDecimalPoints)) | |
finalFormatted = ko.bindingHandlers.numericValue.withCommas(formattedValue); | |
ko.bindingHandlers.value.update(element, function () { return finalFormatted; }); | |
} | |
}, | |
defaultPositions: 2, | |
noDecimalPoints: false, | |
withCommas: function (original) { | |
original += ''; | |
x = original.split('.'); | |
x1 = x[0]; | |
x2 = x.length > 1 ? ',' + x[1] : ''; | |
var rgx = /(\d+)(\d{3})/; | |
while (rgx.test(x1)) { | |
x1 = x1.replace(rgx, '$1' + '.' + '$2'); | |
} | |
return x1 + x2; | |
} | |
}; | |
ko.bindingHandlers.date = { | |
update: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var value = valueAccessor(); | |
var allBindings = allBindingsAccessor(); | |
var valueUnwrapped = ko.utils.unwrapObservable(value); | |
// Date formats: http://momentjs.com/docs/#/displaying/format/ | |
var pattern = allBindings.format || OKLO.DateFormat || "DD/MM/YYYY"; | |
var output = "-"; | |
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) { | |
if (valueUnwrapped && valueUnwrapped != "0001-01-01T00:00:00") | |
output = parseDate(valueUnwrapped).format(pattern); | |
} | |
if ($(element).is("input") === true) { | |
$(element).val(output); | |
} else { | |
$(element).text(output); | |
} | |
} | |
}; | |
ko.bindingHandlers.datetime = { | |
update: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var value = valueAccessor(); | |
var allBindings = allBindingsAccessor(); | |
var valueUnwrapped = ko.utils.unwrapObservable(value); | |
// Date formats: http://momentjs.com/docs/#/displaying/format/ | |
var pattern = allBindings.format || OKLO.DateFormat || "DD/MM/YYYY"; | |
var output = "-"; | |
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) { | |
if (valueUnwrapped && valueUnwrapped != "0001-01-01T00:00:00") | |
output = moment(valueUnwrapped).format(pattern + " hh:mm:ss a"); | |
} | |
if ($(element).is("input") === true) { | |
$(element).val(output); | |
} else { | |
$(element).text(output); | |
} | |
} | |
}; | |
ko.bindingHandlers.duration = { | |
update: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var value = valueAccessor(); | |
var allBindings = allBindingsAccessor(); | |
var valueUnwrapped = ko.utils.unwrapObservable(value); | |
var output = "-"; | |
var format = allBindings.format || 'seconds'; | |
if (valueUnwrapped !== null && valueUnwrapped !== undefined) { | |
output = moment.duration(valueUnwrapped, format).format("h [hrs] m [min]"); | |
} | |
if ($(element).is("input") === true) { | |
$(element).val(output); | |
} else { | |
$(element).text(output); | |
} | |
} | |
}; | |
ko.bindingHandlers.toggleClick = { | |
init: function (element, valueAccessor) { | |
var value = valueAccessor(); | |
ko.utils.registerEventHandler(element, "click", function () { | |
if (value() != undefined) | |
value(!value()); | |
else | |
value(false); | |
return false; | |
}); | |
//ko.applyBindingsToNode(element, { | |
// click: function () { | |
// value(!value()); | |
// } | |
//}); | |
} | |
}; | |
//<div data-bind="timeAgo: dateCreated"></div> | |
ko.bindingHandlers.timeAgo = { | |
update: function (element, valueAccessor) { | |
var val = unwrap(valueAccessor()), | |
date = new Date(val), // WARNING: this is not compatibile with IE8 | |
timeAgo = toTimeAgo(date); | |
return ko.bindingHandlers.html.update(element, function () { | |
return '<time datetime="' + encodeURIComponent(val) + '">' + timeAgo + '</time>'; | |
}); | |
} | |
}; | |
ko.bindingHandlers.loadingWhen = { | |
// any ViewModel using this extension needs a property called isLoading | |
// the div tag to contain the loaded content uses a data-bind="loadingWhen: isLoading" | |
init: function (element) { | |
var | |
$element = $(element), | |
currentPosition = $element.css("position"); | |
$loader = $("<div>").addClass("loading-loader").hide(); | |
//add the loader | |
$element.append($loader); | |
//console.log(currentPosition); | |
//make sure that we can absolutely position the loader against the original element | |
if (currentPosition == "auto" || currentPosition == "static") | |
$element.css("position", "relative"); | |
//center the loader | |
$loader.css({ | |
position: "absolute", | |
top: "50%", | |
left: "50%", | |
"margin-left": -($loader.width() / 2) + "px", | |
"margin-top": -($loader.height() / 2) + "px" | |
}); | |
}, | |
update: function (element, valueAccessor) { | |
var isLoading = ko.utils.unwrapObservable(valueAccessor()), | |
$element = $(element), | |
$childrenToHide = $element.children(":not(div.loading-loader)"), | |
$loader = $element.find("div.loading-loader"); | |
if (isLoading) { | |
//$childrenToHide.css("visibility", "hidden").attr("disabled", "disabled"); | |
$loader.show(); | |
} else { | |
$loader.fadeOut("fast"); | |
$childrenToHide.css("visibility", "visible").removeAttr("disabled"); | |
} | |
} | |
}; | |
ko.bindingHandlers.executeOnEnter = { | |
init: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var allBindings = allBindingsAccessor(); | |
$(element).keydown(function (event) { | |
var keyCode = (event.which ? event.which : event.keyCode); | |
if (keyCode === 13 || keyCode === 9) { | |
allBindings.executeOnEnter.call(viewModel); | |
return false; | |
} | |
return true; | |
}); | |
} | |
}; | |
ko.bindingHandlers.dataTable = { | |
init: function (element, valueAccessor) { | |
var binding = ko.utils.unwrapObservable(valueAccessor()); | |
// If the binding is an object with an options field, | |
// initialise the dataTable with those options. | |
if (binding.options) { | |
$(element).dataTable(binding.options); | |
} | |
}, | |
update: function (element, valueAccessor) { | |
var binding = ko.utils.unwrapObservable(valueAccessor()); | |
// If the binding isn't an object, turn it into one. | |
if (!binding.data) { | |
binding = { data: valueAccessor() } | |
} | |
// Clear table | |
$(element).dataTable().fnClearTable(); | |
// Rebuild table from data source specified in binding | |
$(element).dataTable().fnAddData(binding.data()); | |
} | |
}; | |
ko.unapplyBindings = function ($node, remove) { | |
// unbind events | |
$node.find("*").each(function () { | |
$(this).unbind(); | |
}); | |
// Remove KO subscriptions and references | |
if (remove) { | |
ko.removeNode($node[0]); | |
} else { | |
ko.cleanNode($node[0]); | |
} | |
}; | |
//wrapper for an observable that protects value until committed | |
ko.protectedObservable = function (initialValue) { | |
//private variables | |
var _temp = initialValue; | |
var _actual = ko.observable(initialValue); | |
var result = ko.dependentObservable({ | |
read: _actual, | |
write: function (newValue) { | |
_temp = newValue; | |
} | |
}); | |
//commit the temporary value to our observable, if it is different | |
result.commit = function () { | |
if (_temp !== _actual()) { | |
_actual(_temp); | |
} | |
}; | |
//notify subscribers to update their value with the original | |
result.reset = function () { | |
_actual.valueHasMutated(); | |
_temp = _actual(); | |
}; | |
return result; | |
}; | |
ko.bindingHandlers.filePreview = { | |
update: function (element, valueAccessor, allBindingsAccessor) { | |
var allBindings = allBindingsAccessor(); | |
if (!!FileReader && valueAccessor() && element.files.length) { | |
var reader = new FileReader(); | |
reader.onload = function (event) { | |
var dataUri = event.target.result; | |
allBindings.imagePreviewUris.push(dataUri); | |
}; | |
reader.onerror = function (e) { | |
console.log("error", e); | |
}; | |
for (var i = 0; i < element.files.length; i++) { | |
reader.readAsDataURL(element.files[i]); | |
} | |
} | |
} | |
}; | |
// http://jsfiddle.net/hd89y/ | |
//<label class="btn btn-primary"> | |
// <input type="radio" name="options" id="option1" value="1" | |
//data-bind="bsChecked: optionsValue"> Option 1 | |
//</label> | |
ko.bindingHandlers.bsChecked = { | |
init: function (element, valueAccessor, allBindingsAccessor, | |
viewModel, bindingContext) { | |
var value = valueAccessor(); | |
var newValueAccessor = function () { | |
return { | |
change: function () { | |
value(element.value); | |
} | |
} | |
}; | |
ko.bindingHandlers.event.init(element, newValueAccessor, | |
allBindingsAccessor, viewModel, bindingContext); | |
}, | |
update: function (element, valueAccessor, allBindingsAccessor, | |
viewModel, bindingContext) { | |
if ($(element).val() == ko.unwrap(valueAccessor())) { | |
$(element).closest('.btn').button('toggle'); | |
} | |
} | |
}; | |
ko.bindingHandlers.ckeditor = { | |
init: function (element, valueAccessor, allBindingsAccessor, context) { | |
// get observable | |
var modelValue = valueAccessor();; | |
var optionStandard = allBindingsAccessor().mode; | |
var options = {}; | |
if (optionStandard) { | |
options = { | |
toolbarGroups: [ | |
{ name: 'basicstyles', groups: ['basicstyles', 'cleanup'] }, | |
{ name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align', 'bidi'] }, | |
{ name: 'links' }, | |
{ name: 'styles' }, | |
{ name: 'colors' } | |
] | |
}; | |
} | |
$(element).ckeditor(function (textarea) { | |
// <span> element that contains the CKEditor markup | |
var $ckeContainer = $(this.container.$); | |
// <body> element within the iframe (<html> is contentEditable) | |
var $editorBody = | |
$ckeContainer.find('iframe').contents().find('body'); | |
// sets the initial value | |
try { | |
$editorBody.html(modelValue()); | |
} catch (e) { | |
} | |
// handle edits made in the editor - by typing | |
$editorBody.keyup(function () { | |
try { | |
modelValue($(this).html()); | |
} catch (e) { | |
} | |
}); | |
// handle edits made in the editor - by clicking in the toolbar | |
$ckeContainer.find('table.cke_editor').click(function () { | |
try { | |
modelValue($editorBody.html()); | |
} catch (e) { | |
} | |
}); | |
}, options); | |
// when ko disposes of <textarea>, destory the ckeditor instance | |
ko.utils.domNodeDisposal.addDisposeCallback(element, function () { | |
$(element).ckeditorGet().destroy(true); | |
}); | |
}, | |
update: function (element, valueAccessor, allBindingsAccessor, context) { | |
// handle programmatic updates to the observable | |
var newValue = ko.utils.unwrapObservable(valueAccessor()); | |
var $ckeContainer = $(element).ckeditorGet().container; | |
if ($ckeContainer) { | |
// <span> element that contains the CKEditor markup | |
$ckeContainer = $($ckeContainer.$); | |
// <body> element within the iframe (<html> is contentEditable) | |
var $editorBody = | |
$ckeContainer.find('iframe').contents().find('body'); | |
// if new value != existing value, replace it in the editor | |
if ($editorBody.html() != newValue) | |
$editorBody.html(newValue); | |
} | |
} | |
}; | |
/* | |
<div data-bind=" | |
value: selectedState, | |
select2: { | |
data: states, | |
placeholder: 'Select a State', | |
formatResult: format }" | |
class="select2" style="width: 200px"></div> | |
Selected: <span data-bind="text: selectedState"></span> | |
*/ | |
ko.bindingHandlers.select2 = { | |
init: function (el, valueAccessor, allBindingsAccessor, viewModel) { | |
ko.utils.domNodeDisposal.addDisposeCallback(el, function () { | |
$(el).select2('destroy'); | |
}); | |
var allBindings = allBindingsAccessor(), | |
select2 = ko.utils.unwrapObservable(allBindings.select2); | |
$(el).select2('destroy'); | |
$(el).select2(select2); | |
}, | |
update: function (el, valueAccessor, allBindingsAccessor, viewModel) { | |
var allBindings = allBindingsAccessor(); | |
if ("value" in allBindings) { | |
$(el).select2("val", allBindings.value()); | |
} else if ("selectedOptions" in allBindings) { | |
var converted = []; | |
var textAccessor = function (value) { return value; }; | |
if ("optionsText" in allBindings) { | |
textAccessor = function (value) { | |
var valueAccessor = function (item) { return item; } | |
if ("optionsValue" in allBindings) { | |
valueAccessor = function (item) { return item[allBindings.optionsValue]; } | |
} | |
var items = $.grep(allBindings.options(), function (e) { return valueAccessor(e) == value }); | |
if (items.length == 0 || items.length > 1) { | |
return "UNKNOWN"; | |
} | |
return items[0][allBindings.optionsText]; | |
} | |
} | |
$.each(allBindings.selectedOptions(), function (key, value) { | |
converted.push({ id: value, text: textAccessor(value) }); | |
}); | |
$(el).select2("data", converted); | |
} | |
} | |
}; | |
ko.bindingHandlers.foreachprop = { | |
transformObject: function (obj) { | |
var properties = []; | |
for (var key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
properties.push({ key: key, value: obj[key] }); | |
} | |
} | |
return properties; | |
}, | |
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
var value = ko.utils.unwrapObservable(valueAccessor()), | |
properties = ko.bindingHandlers.foreachprop.transformObject(value); | |
ko.applyBindingsToNode(element, { foreach: properties }, bindingContext); | |
return { controlsDescendantBindings: true }; | |
} | |
}; | |
/** | |
* Knockout Raty Binding | |
* Raty: http://www.wbotelhos.com/raty/ | |
* | |
*/ | |
(function ($, ko) { | |
var isObject = function (obj) { return (typeof obj === typeof {}); }; | |
var isFunction = function (func) { return (Object.prototype.toString.call(func) === "[object Function]"); }; | |
ko.bindingHandlers['raty'] = { | |
'init': function (element, valueAccessor) { | |
var options = {}; | |
var value = valueAccessor(); | |
value = isObject(value) ? value : {}; | |
if ('rating' in value) { | |
var rating = value['rating']; | |
var click = !!value['click'] ? value['click'] : function (score, evt) { }; | |
var start = !!value['start'] ? value['start'] : ko.utils.unwrapObservable(rating); | |
value['start'] = start; | |
value['click'] = !ko.isWriteableObservable(rating) ? click : function (score, evt) { | |
rating(score); | |
click.call(this, score, evt); | |
}; | |
} | |
for (key in value) { | |
val = value[key]; | |
options[key] = ko.utils.unwrapObservable(val); | |
}; | |
options['path'] = OKLO.RootPath + 'Content/rating/images/'; | |
$(element).raty(options); | |
}, | |
'update': function (element, valueAccessor) { | |
var value = valueAccessor(); | |
if ('rating' in value) | |
$(element).raty('click', ko.utils.unwrapObservable(value['rating'])); | |
if ('readOnly' in value) | |
$(element).raty('readOnly', ko.utils.unwrapObservable(value['readOnly'])); | |
} | |
}; | |
})($, ko); | |
ko.bindingHandlers.imgLazy = { | |
init: function (element, valueAccessor) { | |
var options = valueAccessor() || {}; | |
setTimeout(function () { | |
$(element).lazyload(options); | |
}, 0); | |
//handle disposal (if KO removes by the template binding) | |
ko.utils.domNodeDisposal.addDisposeCallback(element, function () { | |
$(element).lazyload("destroy"); | |
}); | |
}, | |
update: function (element, valueAccessor) { | |
var options = valueAccessor() || {}; | |
if (options.updateOn && ko.isObservable(options.updateOn)) { | |
options.updateOn(); | |
} | |
$(element).lazyload("destroy").lazyload(options); | |
} | |
}; | |
ko.bindingHandlers.accordion = { | |
init: function (element, valueAccessor) { | |
var options = valueAccessor() || {}; | |
setTimeout(function () { | |
$(element).smkAccordion(options); | |
}, 0); | |
//handle disposal (if KO removes by the template binding) | |
ko.utils.domNodeDisposal.addDisposeCallback(element, function () { | |
$(element).smkAccordion("destroy"); | |
}); | |
}, | |
update: function (element, valueAccessor) { | |
var options = valueAccessor() || {}; | |
if (options.updateOn && ko.isObservable(options.updateOn)) { | |
options.updateOn(); | |
} | |
$(element).smkAccordion("destroy").smkAccordion(options); | |
} | |
}; | |
ko.bindingHandlers.templateWithOptions = { | |
init: ko.bindingHandlers.template.init, | |
update: function (element, valueAccessor, allBindingsAccessor, viewModel, context) { | |
var options = ko.utils.unwrapObservable(valueAccessor()); | |
//if options were passed attach them to $data | |
if (options.templateOptions) { | |
context.$data.$item = ko.utils.unwrapObservable(options.templateOptions); | |
} | |
//call actual template binding | |
ko.bindingHandlers.template.update(element, valueAccessor, allBindingsAccessor, viewModel, context); | |
//clean up | |
delete context.$data.$item; | |
} | |
}; | |
ko.bindingHandlers.datepicker = { | |
init: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var unwrap = ko.utils.unwrapObservable; | |
var dataSource = valueAccessor(); | |
var binding = allBindingsAccessor(); | |
var mParsedDate = parseDate(dataSource()).format(OKLO.DateFormat); | |
var options = { | |
keyboardNavigation: true, | |
todayHighlight: true, | |
autoclose: true, | |
format: OKLO.DateFormat.toLowerCase(), | |
startDate: binding.limit ? moment().format(OKLO.DateFormat) : null | |
}; | |
if (binding.datePickerOptions) { | |
options = $.extend(options, binding.datePickerOptions); | |
} | |
$(element).datepicker(options); | |
$(element).datepicker('update', mParsedDate); | |
$(element).on("changeDate", function (ev) { | |
var observable = valueAccessor(); | |
if ($(element).is(':focus')) { | |
// Don't update while the user is in the field... | |
// Instead, handle focus loss | |
$(element).on('blur', function (eb) { | |
var dateVal = $(element).datepicker("getDate"); | |
observable(parseDate(dateVal).format(OKLO.DateFormat)); | |
}); | |
} | |
else { | |
observable(parseDate(ev.date).format(OKLO.DateFormat)); | |
} | |
}); | |
//handle removing an element from the dom | |
ko.utils.domNodeDisposal.addDisposeCallback(element, function () { | |
$(element).datepicker('remove'); | |
}); | |
}, | |
update: function (element, valueAccessor) { | |
var value = ko.utils.unwrapObservable(valueAccessor()); | |
$(element).datepicker('update', parseDate(value).format(OKLO.DateFormat)); | |
} | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment