j'ai lu beaucoup de tutoriels mais je ne sais pas comment faire cela, c'est l'entrée
input(type="text",name="price",id="price"data-bind="text: price,valueUpdate:['afterkeydown','propertychange','input']")
et c'est mon point de vue
price: ko.computed(function()
{
return parseFloat(this.replace(' ','').replace(/[^0-9\.]+/g,"")) || '';
},this)
mais cette erreur de cause: cela n'a pas de méthode remplacer ??? Comment puis-je passer la valeur du prix à la fonction calculée?
Il est préférable de créer une liaison personnalisée http://knockoutjs.com/documentation/custom-bindings.html qui n'accepte que les caractères autorisés [0-9 ,.] sous forme de représentation numérique.
mettre cette ligne dans votre vue
<input id="text" type="text" data-bind="numeric, value: number">
mettre cette ligne dans votre modèle (n'oubliez pas de lier le numéro en tant que propriété observable)
ko.bindingHandlers.numeric = {
init: function (element, valueAccessor) {
$(element).on("keydown", function (event) {
// Allow: backspace, delete, tab, escape, and enter
if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
// Allow: Ctrl+A
(event.keyCode == 65 && event.ctrlKey === true) ||
// Allow: . ,
(event.keyCode == 188 || event.keyCode == 190 || event.keyCode == 110) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
else {
// Ensure that it is a number and stop the keypress
if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
event.preventDefault();
}
}
});
}
};
Knockout a des rallonges pour cela. Cochez cette case de knockoutjs.com expliquant comment utiliser des extensions observables pour forcer l'entrée numérique Je colle le code de la documentation ici:
Code source: Voir
<p><input data-bind="value: myNumberOne" /> (round to whole number)</p>
<p><input data-bind="value: myNumberTwo" /> (round to two decimals)</p>
Code source: Voir le modèle
ko.extenders.numeric = function(target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
read: target, //always return the original observables value
write: function(newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({ notify: 'always' });
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
function AppViewModel(one, two) {
this.myNumberOne = ko.observable(one).extend({ numeric: 0 });
this.myNumberTwo = ko.observable(two).extend({ numeric: 2 });
}
ko.applyBindings(new AppViewModel(221.2234, 123.4525));
J'avais un problème similaire.
Je devais également assurer uniquement les valeurs inter, et pour IE9 et les versions ultérieures (le type = numérique n'était donc pas suffisant), et comme nous avons beaucoup de clients internationaux, je ne pouvais pas compter non plus sur les codes clés. avec:
//In my js class method (self is this as usual)
self.ensureNumberical = function (data, e) {
var keyValue = e.key;
if (keyValue.match(/[0-9]/g)) {
return true;
}
return false;
}
//In my MVC View
data-bind="event: { keypress: ensureNumberical }"
Une approche alternative: j'ai trouvé que Knockout fonctionne bien en combinaison avec jQuery-validate . Vous devez simplement vous assurer que vous validez le formulaire avant d'essayer d'utiliser la valeur numérique.
Disons que vous avez un élément de formulaire DOM, vous pouvez configurer des règles de validation via
$(".yourform").validate({
rules: {
year: {
digits: true,
minlength: 4,
maxlength: 4
}
},
messages: {
year: "Please enter four digits (e.g. 2009).",
}
});
Dans votre modèle de vue, vous définissez la liaison bidirectionnelle comme d'habitude, par exemple via self.year = ko.observable("")
. Assurez-vous maintenant que vous appelez $(".yourform").valid()
avant de poursuivre le traitement de self.year()
. Dans mon cas, je fais var year = parseInt(self.year(), 10)
. Immédiatement après la validation du formulaire, cela devrait toujours produire un résultat significatif.
Idéal pour le scénario d'aujourd'hui https://github.com/Knockout-Contrib/Knockout-Validation
lancez l'extrait ci-dessous. Si vous entrez un chiffre ou un chiffre supérieur à 255, le message sera affiché.
function model() {
var self = this;
this.myObj = ko.observable().extend({ digit: true }).extend({ max: 255});
}
var mymodel = new model();
$(document).ready(function() {
ko.validation.init();
ko.applyBindings(mymodel);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.min.js"></script>
enter a digit less than or equal to 255 <input type="text" data-bind="textInput: myObj">
<p>
Enter something other than a digit or over 255 will cause an error.
</p>
courtoisie: Bryan Dellinger: https://stackoverflow.com/a/42940109/3868653
<input type="text" id="alpha-validation" data-bind="value: YourDataName, valueUpdate: 'afterkeydown' , event: { 'input': AlphaCheck}" style="text-transform:uppercase">
créez la fonction AlphaCheck et ajoutez-la.
$('#alpha-validation').keyup(function () {
if (this.value.match(/[^0-9 ]/g)) {
this.value = this.value.replace(/[^0-9 ]/g, '');
}
});
Ça va marcher!
Avec l'aide de l'événement "keydown", nous pouvons restreindre d'autres clés dans la zone de texte qui devrait contenir des valeurs numériques.
$(document).ready(function(){
$("selector").on("keydown", function (e) {
//numbers, delete, backspace, arrows
var validKeyCodes = [8, 9, 37, 38, 39, 40, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
if (!($.inArray(e.keyCode, validKeyCodes) >= 0))
e.preventDefault();
});
});
Créez votre liaison de données en pointant vers votre nouveau code brillant:
<input id="price" name="price" type="text" data-bind="numeric">
Nouveau code KO brillant:
price = ko.observable();
price.subscribe(function(newValue) {
price = newValue.replace(/[\D\.]/g, '');
});
Cela signifie que chaque fois que vous mettez à jour le prix, il appliquera la logique de la fonction (en supprimant tout ce qui n'est pas un nombre ou une période) et l'appliquera directement au prix. Vous pouvez également ajouter d’autres fonctionnalités de validation ou intéressantes, telles que l’ajout d’un sybmol de devise au début, son maintien à 2 décimales, etc.
Nous pouvons limiter l'utilisateur à saisir plus de deux nombres décimaux, par ex. 23.81, 3452.83 Le code modifié est comme ci-dessous. Le code de référence provient de la réponse @Martin Surynek.
HTML -
<p>
<input data-bind="value: myNumberOne" /> (round to whole number)</p>
<p>
<input data-bind="num, value: myNumberTwo" /> (round to two decimals)</p>
Script -
<script>
ko.bindingHandlers.num = {
init: function (element, valueAccessor) {
$(element).on("keypress", function (event) {
//debugger
console.log(event.keyCode);
var $this = $(this);
var text = $this.val();
// Stop insert two dots
if ($this.val().indexOf('.') != -1 && (event.which == 190 || event.which == 110)) {
event.preventDefault();
}
// Allow: backspace, delete, tab, escape, and enter
if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode ==
13 ||
// Allow: Ctrl+A
(event.keyCode == 65 && event.ctrlKey === true) ||
// Allow: . ,event.keyCode == 188 ||
( event.keyCode == 190 || event.keyCode == 110) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
// Ensure that it is a number and stop the keypress
if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode >
105)) {
event.preventDefault();
}
if ((event.which == 46) && (text.indexOf('.') == -1)) {
setTimeout(function () {
if ($this.val().substring($this.val().indexOf('.')).length > 3) {
$this.val($this.val().substring(0, $this.val().indexOf('.') + 3));
}
}, 1);
}
if ((text.indexOf('.') != -1) &&
(text.substring(text.indexOf('.')).length > 2) &&
(event.which != 0 && event.which != 8) &&
($(this)[0].selectionStart >= text.length - 2)) {
event.preventDefault();
}
//console.log($(this)[0].selectionStart >= text.length - 2);
});
}
};
ko.extenders.numeric = function (target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
read: target, //always return the original observables value
write: function (newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
function AppViewModel(one, two) {
this.myNumberOne = ko.observable(one).extend({
numeric: 0
});
this.myNumberTwo = ko.observable(two).extend({
numeric: 2
});
}
ko.applyBindings(new AppViewModel(221.2234, 123.4525));
</script>