2012-11-28 4 views

risposta

2

Basta prendere il codice dalla risposta in quel link e metterlo in un extender (testo su carta bianca, può avere errori)

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

edit: Probabilmente si desidera fornire la maschera come opzioni, invece di averlo codificato a USD ecc

aggiornamento: Se si desidera utilizzare il plugin maschera dalla risposta di riceboyler ma con estensori si può fare

ko.extenders.mask = function(observable, mask) { 
    observable.mask = mask; 
    return observable; 
} 


var orgValueInit = ko.bindingHandlers.value.init; 
ko.bindingHandlers.value.init = function(element, valueAccessor) { 
    var mask = valueAccessor().mask; 
    if(mask) { 
     $(element).mask(mask); 
    } 

    orgValueInit.apply(this, arguments); 
} 

http://jsfiddle.net/rTK6G/

+0

La tua prima soluzione è davvero eccezionale. Mi ha aiutato a ottenere funzionalità di mascheramento senza usare il plugin di mascheramento :) Thx un sacco :) – Biki

33

Se si voleva utilizzare l'eccellente Masked Input Plugin in Knockout, è abbastanza facile scrivere una consuetudine di base vincolante piuttosto che un extender.

ko.bindingHandlers.masked = { 
    init: function(element, valueAccessor, allBindingsAccessor) { 
     var mask = allBindingsAccessor().mask || {}; 
     $(element).mask(mask); 
     ko.utils.registerEventHandler(element, 'focusout', function() { 
      var observable = valueAccessor(); 
      observable($(element).val()); 
     }); 
    }, 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     $(element).val(value); 
    } 
}; 

E poi nel codice HTML:

<input type="text" data-bind="masked: dateValue, mask: '99/99/9999'" /> 
<input type="text" data-bind="masked: ssnValue, mask: '999-99-9999'" /> 

E così via con varie maschere. In questo modo, puoi semplicemente inserire la maschera nel tuo database e consente una grande flessibilità.

+2

[Un commento utente anonimo] (http://stackoverflow.com/review/suggested-edits/2574505) che il 'registerEventHandler' dovrebbe essere sull'evento 'blur' non' focusout'. – Rup

+1

+1 - Ottima risposta - Ho appena aggiunto questo al mio progetto e funziona come un fascino. –

+0

Se si inizializzano i dati dal modello di vista, non mostra la maschera di input finché non si fa clic sull'input. Ad esempio, mostrerebbe 999999999 per SSN anziché 999-99-9999. –

2

Ho provato a utilizzare la prima risposta ma non ha funzionato con ko.validation plug-in. I miei errori di convalida non venivano visualizzati.

Volevo avere un po 'più intuitivo ko binder. Ecco la mia soluzione. Sto usando jquery.inputmask plug in. Pulisco anche la proprietà sul mio viewmodel se non il valore inserito.

ko.bindingHandlers.mask = { 
     init: function (element, valueAccessor, allBindingsAccessor, viewModel,  bindingContext) { 
      var mask = valueAccessor() || {}; 
      $(element).inputmask({ "mask": mask, 'autoUnmask': false }); 
      ko.utils.registerEventHandler(element, 'focusout', function() { 
       var value = $(element).inputmask('unmaskedvalue');    
       if (!value) { 
        viewModel[$(element).attr("id")]("");     
       } 
      }); 
     } 
    }; 

Ecco l'utilizzo:

<input type="text" data-bind="value: FEIN, mask: '99-9999999'" id="FEIN" > 
0

È possibile utilizzare questa soluzione fatta in casa, lavorano perfettamente per me:

Il mio invito ad eliminazione diretta Binding mascherato ispirato dalla rete, ho aggiunto un po 'di linguaggio gestito e aggiornamento da diversi eventi. Anche io uso questo js libreria per l'utilizzo in fondo: https://plugins.jquery.com/maskedinput/

Si può vedere nel mio vincolante il termine "allBindingsAccessor().maschera" questo è dalla libreria maskedinput

ko.bindingHandlers.masked = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     var mask = allBindingsAccessor().mask || {}, 
     getCaretPosition, 
     setCaretPosition; 

     // Permet d'obtenir la position du curseur 
     getCaretPosition = function getCaretPosition(element) { 
      // Initialise la position 
      var caretPos = 0, sel; 

      // IE 
      if (document.selection) { 
       // Donne le focus à l'élément 
       element.focus(); 
       // Afin d'obtenir la position du curseur 
       sel = document.selection.createRange(); 
       // On place le curseur à 0 
       sel.moveStart('character', -element.value.length); 
       caretPos = sel.text.length; 
      } 
       // Firefox 
      else if (element.selectionStart || element.selectionStart === '0') { 
       caretPos = element.selectionStart; 
      } 
      return (caretPos); 
     }; 

     // Permet de définir la position du curseur en fonction d'une position donnée 
     setCaretPosition = function setCaretPosition(element, pos) { 
      var range; 
      if (element.setSelectionRange) { 
       element.focus(); 
       element.setSelectionRange(pos, pos); 
      } 
      else if (element.createTextRange) { 
       range = element.createTextRange(); 
       range.collapse(true); 
       range.moveEnd('character', pos); 
       range.moveStart('character', pos); 
       range.select(); 
      } 
     }; 

     // Définition du masque inséré dans le champ 
     if (configSvc.culture === "fr-FR") { 
      // Cas francais 
      $(element).mask("99/99/9999", { placeholder: "JJ/MM/AAAA" }); 
     } 
     else { 
      // Cas anglophone 
      $(element).mask("99/99/9999", { placeholder: "MM/DD/YYYY" }); 
     } 

     // On capte l'événement d'appuie sur une touche 
     ko.utils.registerEventHandler(element, 'keypress', function() { 
      var observable = valueAccessor(), 
       position; 
      // Afin de résoudre le pb de déplacement du curseur a la fin du mask lors de la mise à jour de l'observable knockout 
      if ($(element).val().length === 10) { 
       // On récupère la dernière position 
       position = getCaretPosition(this); 
       // On met à jour la valeur de l'obersable (en cas de sauvegarde) 
       observable($(element).val()); 
       // On force la position du curseur apres mise à jour de l'observable à la derniere position récupéré 
       setCaretPosition(this, position); 
      } 
     }); 

     // On capte l'événement de perte de focus pour mettre l'obersable à jour 
     ko.utils.registerEventHandler(element, 'blur', function() { 
      var observable = valueAccessor(); 
      observable($(element).val()); 
     }); 

     // On capte l'événement change pour mettre l'obersable à jour 
     ko.utils.registerEventHandler(element, 'change', function() { 
      var observable = valueAccessor(); 
      observable($(element).val()); 
     }); 
    }, 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     $(element).val(value); 
    } 

}; 

nella mia pagina html, io uso questo osservabile "mascherato":

<input type="text" id="head-birthDate" class="form-control" data-bind="masked: birthDate" /> 

Infine nei miei js:

birthDate è solo un osservabile

this.birthDate = ko.observable(); 
6

Ben fatto, riceboyler. Ho preso il tuo codice e l'ho esteso un po 'per usare il "pla" ceholder" proprietà del Plugin ingresso mascherato:

ko.bindingHandlers.masked = { 
     init: function (element, valueAccessor, allBindingsAccessor) { 
      var mask = allBindingsAccessor().mask || {}; 
      var placeholder = allBindingsAccessor().placeholder; 
      if (placeholder) { 
       $(element).mask(mask, { placeholder: placeholder }); 
      } else { 
       $(element).mask(mask); 
      } 
      ko.utils.registerEventHandler(element, "blur", function() { 
       var observable = valueAccessor(); 
       observable($(element).val()); 
      }); 
     }, 
     update: function (element, valueAccessor) { 
      var value = ko.utils.unwrapObservable(valueAccessor()); 
      $(element).val(value); 
     } 
    }; 

HTML con segnaposto:

<input id="DOB" type="text" size="12" maxlength="8" data-bind="masked: BirthDate, mask: '99/99/9999', placeholder: 'mm/dd/yyyy', valueUpdate: 'input'"/> 

HTML senza segnaposto:

<input id="DOB" type="text" size="12" maxlength="8" data-bind="masked: BirthDate, mask: '99/99/9999', valueUpdate: 'input'"/> 

opere vincolanti Il KO in entrambi i casi.

+0

Come hai deciso di associare l'evento 'sfocatura' vs 'focusout'? Risolve un problema fastidioso per me dove i campi vuoti non richiesti venivano contrassegnati come non validi (usando la convalida KO). Ad esempio, il valore di un numero di telefono vuoto non richiesto a volte sarebbe (___) ___-____ utilizzando il focusout (e quindi non valido). Per sfocare era sempre vuoto. Comunque, grazie. – Jibran