From 418470166e04cf9d8b1e0fe474844515d844b1c8 Mon Sep 17 00:00:00 2001 From: Matt Wright Date: Thu, 6 Jan 2011 09:12:50 +0000 Subject: [PATCH 1/3] Allow optionsText parameter in options binding to accept a function to which each value is passed to determine the text (cherry picked from commit 392445d2d31e85b7436b5e734a753f09750518f5) --- src/binding/defaultBindings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/binding/defaultBindings.js b/src/binding/defaultBindings.js index eea109982..4dd215641 100755 --- a/src/binding/defaultBindings.js +++ b/src/binding/defaultBindings.js @@ -154,7 +154,7 @@ ko.bindingHandlers['options'] = { for (var i = 0, j = value.length; i < j; i++) { var option = document.createElement("OPTION"); var optionValue = typeof allBindings['optionsValue'] == "string" ? value[i][allBindings['optionsValue']] : value[i]; - var optionText = typeof allBindings['optionsText'] == "string" ? value[i][allBindings['optionsText']] : optionValue; + var optionText = typeof allBindings['optionsText'] == "function" ? allBindings['optionsText'](value[i]) : (typeof allBindings['optionsText'] == "string" ? value[i][allBindings['optionsText']] : optionValue); optionValue = ko.utils.unwrapObservable(optionValue); optionText = ko.utils.unwrapObservable(optionText); ko.selectExtensions.writeValue(option, optionValue); @@ -323,4 +323,4 @@ ko.bindingHandlers['checked'] = { element.mergeAttributes(document.createElement(""), false); } } -}; \ No newline at end of file +}; From 44e9c6c850fdf99aa2086030b166dbd99d4278bf Mon Sep 17 00:00:00 2001 From: Matt Wright Date: Thu, 6 Jan 2011 09:36:19 +0000 Subject: [PATCH 2/3] Ran build based on optionsText change (prior commit) (cherry picked from commit e1f7bab5dccca1ec93b5b41d62f8bc95e9744c29) --- build/output/knockout-latest.debug.js | 3 ++- build/output/knockout-latest.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build/output/knockout-latest.debug.js b/build/output/knockout-latest.debug.js index 295a0f0f7..74b73b97f 100644 --- a/build/output/knockout-latest.debug.js +++ b/build/output/knockout-latest.debug.js @@ -1221,7 +1221,7 @@ ko.bindingHandlers['options'] = { for (var i = 0, j = value.length; i < j; i++) { var option = document.createElement("OPTION"); var optionValue = typeof allBindings['optionsValue'] == "string" ? value[i][allBindings['optionsValue']] : value[i]; - var optionText = typeof allBindings['optionsText'] == "string" ? value[i][allBindings['optionsText']] : optionValue; + var optionText = typeof allBindings['optionsText'] == "function" ? allBindings['optionsText'](value[i]) : (typeof allBindings['optionsText'] == "string" ? value[i][allBindings['optionsText']] : optionValue); optionValue = ko.utils.unwrapObservable(optionValue); optionText = ko.utils.unwrapObservable(optionText); ko.selectExtensions.writeValue(option, optionValue); @@ -1391,6 +1391,7 @@ ko.bindingHandlers['checked'] = { } } }; + ko.templateEngine = function () { this['renderTemplate'] = function (templateName, data, options) { throw "Override renderTemplate in your ko.templateEngine subclass"; diff --git a/build/output/knockout-latest.js b/build/output/knockout-latest.js index 5c564b453..56616e850 100644 --- a/build/output/knockout-latest.js +++ b/build/output/knockout-latest.js @@ -40,7 +40,7 @@ r.c.visible={update:function(f,b){var c=r.a.d(b()),d=f.style.display!="none";if( r.c.value={init:function(f,b,c){var d=c().valueUpdate||"change",e=p;if(r.a.Va(d,"after")){e=m;d=d.substring(5)}var g=e?function(h){setTimeout(h,0)}:function(h){h()};r.a.q(f,d,function(){g(function(){var h=b(),i=r.f.k(f);if(r.D(h))h(i);else{h=c();h._ko_property_writers&&h._ko_property_writers.value&&h._ko_property_writers.value(i)}})})},update:function(f,b){var c=r.a.d(b()),d=r.f.k(f),e=c!=d;if(c===0&&d!==0&&d!=="0")e=m;if(e){d=function(){r.f.I(f,c)};d();f.tagName=="SELECT"&&setTimeout(d,0)}if(f.tagName== "SELECT"){d=r.f.k(f);d!==c&&r.a.qa(f,"change")}}}; r.c.options={update:function(f,b,c){if(f.tagName!="SELECT")a(Error("options binding applies only to SELECT elements"));var d=r.a.K(r.a.J(f.childNodes,function(k){return k.tagName&&k.tagName=="OPTION"&&k.selected}),function(k){return r.f.k(k)||k.innerText||k.textContent}),e=f.scrollTop,g=r.a.d(b());r.a.aa(f);if(g){var h=c();if(typeof g.length!="number")g=[g];if(h.optionsCaption){var i=document.createElement("OPTION");i.innerHTML=h.optionsCaption;r.f.I(i,undefined);f.appendChild(i)}c=0;for(b=g.length;c< -b;c++){i=document.createElement("OPTION");var j=typeof h.optionsValue=="string"?g[c][h.optionsValue]:g[c],l=typeof h.optionsText=="string"?g[c][h.optionsText]:j;j=r.a.d(j);l=r.a.d(l);r.f.I(i,j);i.innerHTML=l.toString();f.appendChild(i)}g=f.getElementsByTagName("OPTION");c=h=0;for(b=g.length;c=0){r.a.na(g[c],m);h++}if(e)f.scrollTop=e}}};r.c.options.ha="__ko.bindingHandlers.options.optionValueDomData__"; +b;c++){i=document.createElement("OPTION");var j=typeof h.optionsValue=="string"?g[c][h.optionsValue]:g[c],l=typeof h.optionsText=="function"?h.optionsText(g[c]):typeof h.optionsText=="string"?g[c][h.optionsText]:j;j=r.a.d(j);l=r.a.d(l);r.f.I(i,j);i.innerHTML=l.toString();f.appendChild(i)}g=f.getElementsByTagName("OPTION");c=h=0;for(b=g.length;c=0){r.a.na(g[c],m);h++}if(e)f.scrollTop=e}}};r.c.options.ha="__ko.bindingHandlers.options.optionValueDomData__"; r.c.selectedOptions={ea:function(f){var b=[];f=f.childNodes;for(var c=0,d=f.length;c=0)}}};r.c.text={update:function(f,b){var c=r.a.d(b());if(c===o||c===undefined)c="";typeof f.innerText=="string"?f.innerText=c:f.textContent=c}};r.c.html={update:function(f,b){var c=r.a.d(b());if(c===o||c===undefined)c="";f.innerHTML=c}}; r.c.css={update:function(f,b){var c=r.a.d(b()||{}),d;for(d in c)if(typeof d=="string"){var e=r.a.d(c[d]);r.a.Xa(f,d,e)}}};r.c.style={update:function(f,b){var c=r.a.d(b()||{}),d;for(d in c)if(typeof d=="string"){var e=r.a.d(c[d]);f.style[d]=e||""}}};r.c.uniqueName={init:function(f,b){if(b()){f.name="ko_unique_"+ ++r.c.uniqueName.Aa;r.a.P&&f.mergeAttributes(document.createElement(""),p)}}};r.c.uniqueName.Aa=0; From deeb2e6bd350cee97d1087bfbf5b62e06c0a6a8c Mon Sep 17 00:00:00 2001 From: Matt Wright Date: Thu, 6 Jan 2011 10:00:35 +0000 Subject: [PATCH 3/3] Added spec test to cover optionsText parameter accepting a function (cherry picked from commit 3d23c9a85b4d87c9c4fe84a1247c39c54fd7a7b4) --- spec/defaultBindingsBehaviors.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/spec/defaultBindingsBehaviors.js b/spec/defaultBindingsBehaviors.js index be585aa34..9760e27ff 100755 --- a/spec/defaultBindingsBehaviors.js +++ b/spec/defaultBindingsBehaviors.js @@ -327,6 +327,17 @@ describe('Binding: Options', { value_of(displayedValues).should_be([6, 13]); }, + 'Should accept function in optionsText param to display subproperties of the model values': function() { + var modelValues = new ko.observableArray([ + { name: 'bob', job: 'manager' }, + { name: 'frank', job: 'coder' } + ]); + testNode.innerHTML = ""; + ko.applyBindings({ myValues: modelValues }, testNode); + var displayedText = ko.utils.arrayMap(testNode.childNodes[0].childNodes, function (node) { return node.innerHTML; }); + value_of(displayedText).should_be(["bob (manager)", "frank (coder)"]); + }, + 'Should update the SELECT node\'s options if the model changes': function () { var observable = new ko.observableArray(["A", "B", "C"]); testNode.innerHTML = ""; @@ -598,4 +609,4 @@ describe('Binding: Checked', { ko.utils.triggerEvent(testNode.childNodes[0], "click"); value_of(model.someProp).should_be("this radio button value"); } -}); \ No newline at end of file +});