2016-08-29 9 views
1

Ich habe eine Knockout-Seite, wo ich die Eingabe mit Regex formatiere. Es macht das Eingabefeld zu einem MM/TT/JJJJ-Format. Wenn also ein Benutzer "1111" eingibt, wird der Eingang vbox so geändert, dass "01/01/2011" angezeigt wird, oder "01111" zeigt "01.01.2011" an.Knockout sendet keinen aktualisierten Wert

Das Problem, mit dem ich konfrontiert bin, ist, dass meine beobachtbare nur den vom Benutzer eingegebenen Tastendruck zurückgibt und nicht das vollständig formatierte Element. Zum Beispiel ist die Eingabe, wenn der Benutzer „1111“ ich zurück „1111“ anstelle der „01.01.2011“

Hier ist das HTML-Segment

<input id="inpEventDt" placeholder="MM/DD/YYYY" class="input-small" data-date-blur="true" data-regex="^((\d{0,2})|(\d{1,2}/?\d{0,2})|(\d{1,2}/?\d{1,2}/?\d{0,4}))$" 
         type="text" data-bind="textInput: dateofevent"/> 

Und das ist, wie ich den Knockout habe Bindung

var ViewModel = function (eventdt) { 
var self = this; 
self.dateofevent = ko.observable(eventdt); 
} 

viewModel = new ViewModel(""); 

ko.applyBindings(viewModel); 

Ich versuche herauszufinden, was ich falsch mache.

+0

Ihre Texteingabe ist an die Variable 'dateofevent' gebunden. Wenn Sie also den Eingabewert mit einem anderen Wert als Knockout ändern, müssen Sie die Knockout-Variable ebenfalls mit einem neuen Wert aktualisieren. Ich schlage vor, knockout extend oder subscribe zu verwenden und dann Ihre Regex-Validierung innerhalb der Subscribe-Funktion durchzuführen. –

+0

Haben Sie ein Beispiel? – Mhoque

+0

Hier https://jsfiddle.net/kyr6w2x3/68/ nur ein Beispiel, um zu verhindern, dass Benutzer irgendwelche Sonderzeichen eingeben. Sie müssen Ihre Validierung innerhalb der Validierungsfunktion durchführen und sie dann erneut in das Ziel einfügen. –

Antwort

1

Ich würde nicht versuchen, die Texteingabe zu formatieren, während der Benutzer tippt, weil es eine schwer verständliche Benutzeroberfläche und nicht intuitive Tipperfahrung macht.

Darüber hinaus ist es komplizierter, weil während der Eingabe die Eingabe wahrscheinlich ungültig ist.

Versuchen Sie stattdessen Ihre Eingabe auf ein Ereignis zu formatieren (verwischen zum Beispiel), während es auf Tastendruck Validierung:

var viewModel = function() { 
 
    var self = this; 
 
    var regex = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/; 
 
    this.isValid = ko.observable(false); 
 
    this.date = ko.observable(""); 
 
    this.format = function() { 
 
    self.validate(self.date()); 
 
    // TODO: something else 
 
    } 
 
    
 
    this.validate = function(newVal) { 
 
    var matches = newVal.match(regex); 
 
    if (!matches || matches.length != 4) { 
 
     self.isValid(false); 
 
    } else { 
 
     self.isValid(true); 
 
    } 
 
    }; 
 
    
 
    this.date.subscribe(function(newVal) { 
 
    self.validate(newVal); 
 
    }); 
 

 
    this.style = ko.computed(function() { 
 
    return self.isValid() ? "valid" : "invalid"; 
 
    }, this); 
 
}; 
 

 
var vm = new viewModel(); 
 

 
ko.applyBindings(vm);
.invalid { 
 
    border: 1px solid red; 
 
} 
 
.valid { 
 
    border: 1px solid green; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<input id="inpEventDt" placeholder="MM/DD/YYYY" class="input-small" data-date-blur="true" type="text" data-bind="textInput: date, event: { blur: format }, css: style" /> 
 
<div data-bind="visible: isValid">OK</div>

+0

Ich mag deinen Vorschlag wirklich. Eine Sache, die ich mit Ihrer Implementierung verlieren werde, ist die Benutzerfreundlichkeit. Zurzeit kann mein Benutzer "1111" (nur 4 Ziffern) eingeben und wird auf der Benutzeroberfläche zu "01/01/2011" konvertiert. Aber mit @Tim Yonker habe ich das immer noch. Dies ist definitiv eine großartige Lösung. – Mhoque

+0

Ich verstehe nicht, wie Sie Ziffern nur Zeichenfolge zu einem Datum formatieren können. Zum Beispiel, was erwartest du von String 122011? 2. Januar 2011 (1/2/2011), oder 1. Dezember 2011 (/ 12/2011) oder 2. Dezember 2011 (12/2/011)? Deshalb habe ich die Formatierungsfunktion nicht auf –

+0

gelegt. Das war meine genaue Antwort. Aber der Benutzer mochte wirklich die Tatsache, dass sie einfach 1111 eingeben können und es zeigt 01.01.2011, es war die Regex und Data-Date-Blur lassen Sie uns das tun. Danach können Benutzer die Zeichenfolge auf das richtige Datum aktualisieren. Aber wie gesagt, ich mag die Eleganz Ihrer Lösung. – Mhoque

1

Sie sollten versuchen, eine mittels Schreib-/Lese für diese berechnet. Schauen Sie sich die example 3 in der KO-Dokumentation für errechnete Observablen an.

Auch hier ist ein jsfiddle mit moment.js, um mit Datumsformatierung zu helfen.

var ViewModel = function (eventdt) { 
var self = this; 
self.dateofevent = ko.observable(eventdt); 

self.formattedDate = ko.pureComputed({ 
     read: function() { 
      return moment(self.dateofevent()).format("MM/DD/YYYY"); 
     }, 
     write: function (value) { 
      self.dateofevent(moment(value).toDate()); // Write to underlying storage 
     } 
    }); 

} 

viewModel = new ViewModel(new Date("03/25/2015")); 

ko.applyBindings(viewModel); 
+0

Ich mag deinen Vorschlag, da ich noch die Benutzerfreundlichkeit habe. Aber auf der anderen Seite hinzufügen Abhängigkeit von moment.js. – Mhoque

+0

Ich verwendete Moment für die Einfachheit der Bereitstellung der Beispielgeige. Sie können es mit Ihrem eigenen Datumsanalyse-Code optimieren. Der Punkt ist, dass Sie mit read/write berechneter Observable Formatierungsdatentypen zwischen Texteingaben und Ihrem Modell hin und her verarbeiten können. –

Verwandte Themen