3
\$\begingroup\$

I've done some tinkering about with Knockout in search for a better solution on how to bind select lists (dropdowns). I came up with a extender in combination with a binding.

Extender:

ko.extenders.selectList = function (target, params) {
 var result = ko.computed({
 read: target,
 write: function (newValue) {
 if (newValue) {
 target(newValue);
 } else {
 target(undefined);
 }
 }
 });
 //add some sub-observables
 result.options = $.map(params.options, function (v, k) { return { val: k, txt: v }; });
 result.caption = params.caption;
 function getInitialEnableValue(){
 if(params.hasOwnProperty('enable')){
 if($.isFunction(params.enable)){
 return params.enable();
 }
 return params.enable;
 }
 return true;
 }
 var isEnabled = ko.observable(getInitialEnableValue());
 result.enable = ko.computed({
 read: function(){
 return isEnabled();
 },
 write: function(newValue){
 if(!newValue) result(undefined);
 isEnabled(newValue);
 }
 });
 if(isEnabled() && result.options.length === 1){
 result(result.options[0].val);
 }
 //return the new observable
 return result;
 };

Binding:

var selectListHTML = "<select data-bind=\"value: {0}, options: {0}.options, optionsCaption: {0}.caption, optionsText: 'txt', optionsValue: 'val', enable: {0}.enable\"></select>";
 ko.bindingHandlers.selectList = {
 init: function(element, vA, aBA,vm,bc){
 $(element).html(selectListHTML.replace(/\{0\}/g,vA()));
 }
 };

Example fiddle

Are there any pitfalls I'm missing? Does this look like good code? Any comments welcome, thanks in advance!

asked Sep 14, 2012 at 16:48
\$\endgroup\$
1
  • \$\begingroup\$ This is an old question, but still, it would be great it you could update your fiddle, right now it stopped working because it relies on cloud.github.com/downloads/SteveSanderson/knockout/… \$\endgroup\$ Commented Feb 7, 2014 at 16:16

1 Answer 1

2
\$\begingroup\$

From a once over:

  • Your indentation in ko.extenders.selectList = function (target, params) { should be 4 spaces to make it far more readable
  • write could use a ternary approach:

    write: function (newValue) {
     target( newValue || undefined );
    }
    
  • This code could use some more/better comment
  • JSHint could find nothing wrong with it
  • I am not too excited by seeing all those options as part of the HTML, it just feels wrong. None of the tools work for you in this case ( linting, beautifying, even colored syntax ). I guess that's more a reflection on knockout than on your code.
answered Feb 7, 2014 at 16:20
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.