2012-02-06 11 views
10

estoy usando ese plugin: https://github.com/plentz/jquery-maskmoney para dar formato a mi editor dinero ...¿Es posible utilizar KnockoutJS con una entrada enmascarada?

He intentado utilizar KnockoutJS en ese editor, pero no funciona ... Sin máscara que todo trabaja muy bien ...

Mi código de prueba es simple:

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

Javascript para máscara de entrada

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

Y KnockoutJS

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

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

     ko.applyBindings(new ViewModel()); 

Respuesta

11

Debe utilizar un observable computable escribible.

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

Si está haciendo algo como esto junto con el plugin de mapeo, cree esta propiedad como algo vacío, como $ .noop(), luego mapee, aplique lógica similar a la anterior, y LUEGO vincule – Jason

+0

¿Por qué no utiliza un extensor Knockout? –

14

También puede registrar un controlador de unión para MaskMoney con Knockout, algo así como:

$(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'); 
    } 
}; 

});

y luego como su unión:

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

Tenga en cuenta que pellizqué el plugin MaskMoney ligeramente para usar en lugar de input.on('focusout.maskMoney', blurEvent);input.bind('blur.maskMoney',blurEvent); porque no estaba desencadenando una actualización de perder el foco a través de clic del ratón, sólo en la tabulación.

Soy nuevo en knockout y han sido encontrar el enfoque manejador de unión muy agradable para los plugins como este y datepickers, etc.

+0

Este es el método preferido de IMO. He usado este código y funcionó muy bien. – BeaverProj

+0

Creo que sería mejor llamar '$ (elemento) .maskMoney ('máscara');' en lugar de '$ (elemento) .trigger ('focus');' en la función de actualización ya que el evento de foco provoca un enfoque innecesario e involuntario –

0

Si está utilizando jquery.formatcurrency que podría hacer:

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 }" /> 
Cuestiones relacionadas