2012-02-06 12 views
10

sto utilizzando tale plugin: https://github.com/plentz/jquery-maskmoney per formattare il mio editore soldi ...È possibile utilizzare KnockoutJS con un input mascherato?

ho cercato di usare KnockoutJS in quel redattore, ma non funziona ... Senza quella maschera tutto funziona benissimo ...

La mia prova codice è semplice:

<input id="Price" data-bind="value: Price" type="text" name="Price"> 

Javascript per maschera di input

$("#Price").maskMoney({ symbol: 'R$ ', showSymbol: true, thousands: '.', decimal: ',', symbolStay: false }); 

E KnockoutJS

var ViewModel = function() { 
      this.Price = ko.observable(); 

      this.PriceFinal= ko.computed(function() { 
       return this.Price() 
      }, this); 
     }; 

     ko.applyBindings(new ViewModel()); 

risposta

11

È necessario utilizzare un osservabile calcolato scrivibile.

function MyViewModel() { 
    this.price = ko.observable(25.99); 

    this.formattedPrice = ko.computed({ 
     read: function() { 
      return '$' + this.price().toFixed(2); 
     }, 
     write: function (value) { 
      // Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable 
      value = parseFloat(value.replace(/[^\.\d]/g, "")); 
      this.price(isNaN(value) ? 0 : value); // Write to underlying storage 
     }, 
     owner: this 
    }); 
} 

ko.applyBindings(new MyViewModel()); 
+0

Se stai facendo qualcosa di simile in congiunzione con il plug-in di mappatura, crea questa proprietà come qualcosa di vuoto, come $ .noop(), quindi mappa, applica la logica simile a sopra, e THEN vincola – Jason

+0

Perché non utilizzare un estensore Knockout? –

14

È inoltre possibile registrare un gestore vincolante per MaskMoney con Knockout, qualcosa di simile a:

$(document).ready(function() { 

ko.bindingHandlers.currencyMask = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     var options = allBindingsAccessor().currencyMaskOptions || {}; 
     $(element).maskMoney(options); 

     ko.utils.registerEventHandler(element, 'focusout', function() { 
      var observable = valueAccessor(); 

      var numericVal = parseFloat($(element).val().replace(/[^\.\d]/g, '')); 
      numericVal = isNaN(numericVal) ? 0 : numericVal; 

      observable(numericVal); 
     }); 

     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).unmaskMoney(); 
     }); 
    }, 

    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 

     $(element).val(value); 
     $(element).trigger('focus'); 
    } 
}; 

});

e poi come vincolante:

<input type="text" data-bind="currencyMask: MyModel.TotalCost, currencyMaskOptions: { symbol: '$', showSymbol: true, thousands: ',', precision: 0 }" /> 

Si noti che ho ottimizzato il plugin MaskMoney un po 'di utilizzare input.on('focusout.maskMoney', blurEvent); piuttosto che input.bind('blur.maskMoney',blurEvent); perché non è stato innescando un aggiornamento sulla perdere la concentrazione tramite clic del mouse, solo su tabulazione.

Sono nuovo di knockout e sono state trovare l'approccio vincolante gestore veramente bello per i plugin di questo tipo e datepickers, ecc

+0

Questo è il metodo preferito IMO. Ho usato questo codice e ha funzionato alla grande. – BeaverProj

+0

Penso che sarebbe meglio chiamare '$ (elemento) .maskMoney ('maschera');' invece di '$ (elemento) .trigger ('focus');' in funzione di aggiornamento poiché l'evento di messa a fuoco causa un focus non necessario e non intenzionale –

0

Se si utilizza jquery.formatcurrency si potrebbe fare:

ko.bindingHandlers.currencyMask = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     var options = allBindingsAccessor().currencyMaskOptions || {}; 
     $(element).formatCurrency(options); 
     $(element).keyup(function() { 
      $(element).formatCurrency(options); 
     }); 


     ko.utils.registerEventHandler(element, 'focusout', function() { 
      var observable = valueAccessor(); 
      observable($(element).val()); 
     }); 

     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).formatCurrency('destroy'); 
     }); 
    }, 

    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 

     $(element).val(value); 
     $(element).trigger('focus'); 
    } 
}; 

<input data-bind="currencyMask: priceVal, currencyMaskOptions: { roundToDecimalPlace: 0 }" />