javascript - Knockout bindingHandler for comma separated numbers -
i'm building number-heavy app in knockoutjs , want have ability format large numbers they're comma-seperated , nice on eye (xxx,xxx).
as you'll see fiddle below, have working wrapping binded value inside of formatting function simple regex problem this overwrites value inside input , inserts ',' underlying value.
the large numbers used further down app , prevent nan errors i've had assign data attribute input value containing value no ',' , value gets stored in sessionstorage.
i feel have unncessarily bloated html markup , believe want achieve possible bindinghandler binding handler isn't quite there.
fiddle: http://jsfiddle.net/36sd9/2
formatlargenumber = function (number) { if (typeof (number) === 'function') { return number().tostring().replace(/\b(?=(\d{3})+(?!\d))/g, ','); } } ko.bindinghandlers.largenumber = { init: function(element, valueaccessor) { var value = ko.unwrap(valueaccessor()); var interceptor = ko.computed({ read: function() { return formatlargenumber(value); }, write: function(newvalue) { value(reverseformat(newvalue)); } }); if(element.tagname == 'input' ) ko.applybindingstonode(element, { value: interceptor }); else ko.applybindingstonode(element, { text: interceptor }); } }
any ideas?
you have multiple problems current approach:
element.tagname
returns input, etc need take care of casing when doing comparing.var value = ko.unwrap(valueaccessor());
unwrapping observable in computed using value , not function itself. needvar value = valueaccessor();
, need callko.unwrap
in computedread
method.you don't need format need "unformat" in
write
method,formatlargenumber
format direction.you have applied
value
,largenumber
on same input make 2 bindings interfering each otherdon't write formatting code use library like: http://numeraljs.com/
so here corrected version of binding using numeraljs:
ko.bindinghandlers.largenumber = { init: function(element, valueaccessor) { var value = valueaccessor(); var interceptor = ko.computed({ read: function() { return numeral(ko.unwrap(value)).format('0,0'); }, write: function(newvalue) { value(numeral().unformat(newvalue)); value.valuehasmutated(); } }).extend({notify: 'always'}); if(element.tagname.tolowercase() == 'input' ) ko.applybindingstonode(element, { value: interceptor }); else ko.applybindingstonode(element, { text: interceptor }); } }
and use this:
<input data-bind="largenumber: testval">
demo jsfiddle.
Comments
Post a Comment