knockout.js - Wrapping Knockout's hasFocus to change an elements text when selected -


i have knockout binding handler called valuenumber parses , displays numbers little globalize:

ko.bindinghandlers.valuenumber = {     init: function (element, valueaccessor, allbindingsaccessor, viewmodel, bindingcontext) {         // called when binding first applied element         // set initial state, event handlers, etc. here          var observable = valueaccessor(),             properties = allbindingsaccessor();          var interceptor = ko.computed({             read: function () {                  var format = properties.numberformat || "n2",                     formattednumber = globalize.format(ko.utils.unwrapobservable(observable), format);                  return formattednumber;             },             write: function (newvalue) {                 var currentvalue = ko.utils.unwrapobservable(observable),                     numbervalue = globalize.parsefloat(newvalue);                  if (!isnan(numbervalue)) {                      if (numbervalue !== currentvalue) {                         // value has changed update observable                         observable(numbervalue);                     }                 } else if (newvalue.length === 0) {                     if (properties.isnullable) {                         // if newvalue blank string , isnullable property has been set nullify observable                         observable(null);                     } else {                         // if newvalue blank string , isnullable property has not been set set observable 0                         observable(0);                     }                 }             }         });          if (element.tagname.tolowercase() === 'input') {             ko.applybindingstonode(element, { value: interceptor });         } else {             ko.applybindingstonode(element, { text: interceptor });         }     } }; 

to use pretty straightforward:

<input data-bind="valuenumber: cost, numberformat: 'n1', isnullable: true" type="text" value="" /> 

when input textbox loses focus value displayed based on numberformat property. if user had entered "1.123" in textbox above when tabbed out "1.1" left displayed in input value stored in observable 1.123.

this gets tricky.

when input element gains focus / becomes active element want display full value (the 1.123) users in input element. i've got idea depending on hasfocus achieve i'm not "correct" approach like.

i'm ideally hoping wrap within 1 binding handler rather introducing need markup.

update

based on robert westerlund's answer i've come jsfiddle demonstrates solution nicely. robert's solution restyled based on conventions used in built-in hasfocus binding.

oh , completeness solution using globalize 0.1.1. having had quick @ github repo looks api globalize going change @ point in future.

it's hard "correct" approach be, i'll give sample of 1 approach @ least. first, add observable keep track of focus state.

var elementhasfocus = ko.observable(element === document.activeelement); 

next, need make sure change value when onblur or onfocus events occur.

element.onblur = function(){ elementhasfocus(false); }; element.onfocus = function(){ elementhasfocus(true); }; 

the above 3 lines added in init method, right before create interceptor computed observable.

finally, update read-method of interceptor make sure determines value based on focus state.

read: function () {     if (elementhasfocus()) {         return ko.unwrap(observable); // if use newer versions of knockout, have convenient ko.unwrap path ko.utils.unwrapobservable method.     }     else {         var format = properties.numberformat || "n2",             formattednumber = globalize.format(ko.utils.unwrapobservable(observable), format);          return formattednumber;     } } 

Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -