2016-08-29 10 views
1

正規表現で入力をフォーマットしているノックアウトページがあります。入力フィールドをMM/dd/yyyy形式にします。したがって、ユーザが "1111"を入力すると、入力されたvboxは "01/01/2011"に、または "01111"には "01/01/2011"と表示されます。ノックアウトが更新された値を送信しない

私が直面している問題は、完全にフォーマットされたアイテムではなく、ユーザーが入力したキーストロークのみを返すことです。たとえば、ユーザーが入力している場合は、「1111年は、」私はここのHTMLセグメント

<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"/> 

がある代わりに、「2011年1月1日」

の「1111」取り戻すそして、私はノックアウトを持っているか、これはありますバインディング

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

viewModel = new ViewModel(""); 

ko.applyBindings(viewModel); 

私が間違っていることを理解しようとしています。

+0

あなたのテキスト入力は、 'dateofevent'変数に束縛されています。だからノックアウト以外のものを使って入力値を変更するときはいつでもノックアウト変数を新しい値で更新する必要があります。私はノックアウトを使用して拡張またはサブスクライブし、サブスクライブ関数内の正規表現の検証を行うことをお勧めします –

+0

あなたは例がありますか? – Mhoque

+0

https://jsfiddle.net/kyr6w2x3/68/ここでは、ユーザーが特殊文字を入力しないようにする例を示します。 validate関数内で妥当性検査を行い、それを再度ターゲットに置き換える必要があります。 –

答えて

1

ユーザーが入力中にテキスト入力をフォーマットしようとしません。ユーザーインターフェイスと直感的ではない入力操作を理解しにくいためです。

さらに、入力中に入力が無効になる可能性があるため、より複雑です。キーストロークでそれを検証中

、いくつかのイベント(例えばぼかし)にご入力をフォーマットする代わりに試してみてください。

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

私はあなたの提案が本当に好きです。あなたの実装で失うことの1つは、使いやすさです。現在私のユーザーは "1111"(4桁のみ)と入力することができ、それはUI上で "01/01/2011"に変換されます。しかし、@ティム・ヨンカーと一緒に、私はまだそれを持っています。これは間違いなく素晴らしい解決策です。 – Mhoque

+0

数字だけを日付にフォーマットする方法はありません。 たとえば、文字列122011から何を期待していますか? 2011年1月2日(2011年1月2日)または2011年12月1日(2011年12月1日)または2011年12月2日(12/2/011)の2日目?だからこそ、私はフォーマット関数を入れておかないと、自分でそれを聞かせてください –

+0

それは私の正確な応答でした。しかし、ユーザーは実際に1111を入力するだけで、2011年1月1日を表示するということが本当に気に入っていました。正規表現とデータ日付の不鮮明さが原因でした。その後、ユーザーは文字列を適切な日付に更新できます。しかし、私が言ったように、私はあなたのソリューションの優雅さが本当に好きです。 – Mhoque

1

あなたはこのために計算された読み取り/書き込みを使用してみてください。計算された観測値については、ノックアウト文書のexample 3をご覧ください。

また、ここでは、日付の書式設定に役立つmoment.jsを使用してjsfiddleです。

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

私はまだあなたの友好を持っているので、私はあなたの提案が好きです。しかし、フリップサイドではmoment.jsへの依存性を追加します。 – Mhoque

+0

私はフィドルの例を簡単に提供するために瞬間を使いました。独自の日付解析コードでそれを微調整することができます。要は、テキスト入力とモデルの間でデータ型の書式設定を処理するためにobserverable read/writeを使用することができます。 –

関連する問題