Last active
December 20, 2015 07:49
-
-
Save togakangaroo/6096040 to your computer and use it in GitHub Desktop.
dialog binding for doing dialogs in an mvvm manner.
This file contains 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
// Elements with this binding will appear as a jquery ui dialog when the bound value exists | |
// This binding works similar to the 'with' data-binding in that its contents will only exist when its bound parameter is truthy. | |
// Also like with, it will start a new binding context. | |
// Unlike the 'with' binding, when the contents are visible this will not appear in place but instead be initialized in a | |
// jquery ui dialog. This dialog will close if the bounded value becomes falsy. Conversely, if the bound value is observable, | |
// closing the dialog will empty the observable. | |
var dialogDomDataKey = '__ko_dialogBindingData'; | |
ko.bindingHandlers.dialog = { | |
init: function(el, valueAccessor) { | |
var $el = $(el) | |
,observable = ko.isObservable(valueAccessor()) && valueAccessor() //the observable itself or falsy | |
,clearObservable = function(){ observable && observable(null) } | |
,closeDialog = function(){ $el.dialog('close') } | |
; | |
//for unknown reasons, ko might call init twice so check that initialization has not occurred already | |
if( !$el.data(dialogDomDataKey) ) | |
initializeVirtualElementCloning($el); | |
$el.dialog({ //jq ui widgets protect themselves against double initialization | |
close: clearObservable | |
,buttons: {"Ok": closeDialog } | |
}); | |
return { 'controlsDescendantBindings': true }; | |
}, | |
update: function(el, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
var $el = $(el) | |
,val = ko.utils.unwrapObservable(valueAccessor()) //the value itself | |
,dialogContents = $el.data(dialogDomDataKey).savedNodes | |
; | |
if(!val) { | |
$el.dialog('close'); | |
return ko.virtualElements.emptyNode(el); | |
} | |
ko.virtualElements.setDomNodeChildren(el, ko.utils.cloneNodes(dialogContents)); | |
ko.applyBindingsToDescendants( bindingContext['createChildContext'](val) , el); //start context at to the value | |
return $el.dialog('open'); | |
} | |
}; | |
//This is the initalization required to make the binding work like a 'with' | |
function initializeVirtualElementCloning($el){ | |
$el.data(dialogDomDataKey, { | |
savedNodes: ko.utils.cloneNodes(ko.virtualElements.childNodes($el[0]), true /*shouldCleanNodes*/) //record contents for later use | |
}); | |
ko.virtualElements.emptyNode($el[0]); //because we're about to empty them | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment