2016-09-05 10 views
1

私はカスタムバインディングを使ってjQueryのdatepickerを使用しています。はっきりする。日付を変更するとすべて正常に動作しますが、私の問題はユーザーが日付を変更しないというシナリオにあります。つまり、datepickerの値は、datepickerとtextbox要素に入力される最初の日付にする必要があります。jQuery datepicker - ノックアウトバインディングセットの初期日付

これはMVCですので、通常のC#DateTimeオブジェクトを使用しています。このDateTimeはヌル可能なので、DateTime?オブジェクトであることに注意してください。

は、このシナリオを取る:

ユーザーがWebページをロードし、私のMVCモデルは、そのページに送信されます。私のモデルは、この(JSON形式)のようになります。

{ 
    "User": "Christian Haase", 
    "Username": "ChristianH", 
    "Date": "/Date({som-random-millisecond-number})/" 
} 

注:これは、コピー・貼り付けられませんので、いくつかのものは、このDate値のような面白い少し見えるかもしれません。

は、この値を変更するユーザーのための簡単なWebページを作ることができます:

<p data-bind="text: User" ></p> 
<input data-bind="value: Username" /> 
<input data-bind="datepicker: Date, datepickerOptions: { dateFormat: 'dd/mm/yy' }" /> 

非常にシンプルなのが、これは、物事のマークアップ側から十分なはずです。ノックアウトとデートピッカーバインディングを結びましょう。今

<script type="text/javascript"> 
    $(document).ready(function(){ 

     // Loading the viemodel from MVC (the JSON object) 
     var vm = ko.mapping.fromJSON('@Model'); 

     // Adding the datepicker binding! 
     ko.bindingHandlers.datepicker = { 
      init: function (element, valueAccessor, allBindingsAccessor) { 
       // Getting the datepickerOptions value applied to the binding, if any. Else just an empty object. 
       var options = allBindingsAccessor().datepickerOptions || {}; 

       // Instantiating the datepicker with the options object 
       $(element).datepicker(options); 

       // Listen for any changes in the element 
       ko.utils.registerEventHandler(element, "change", function(){ 
        var observable = valueAccessor(); 
        var value = $(element).val(); 

        // Check to see whether the element.val() is empty or not 
        if(!value){ 
         // If empty, I want the observable to hold value 'null' 
         observable(null); 
        } else{ 
         // Converting the string '01/09/2016' to an actual JS Date object and settings the observable to that value 
         var date = convertStringToDate(value); 
         observable(date); 
        } 
       }); 
      }, 
      update: function(element, valueAccessor){ 
       // Get the value from the viewmodel 
       var value = ko.unwrap(valueAccessor()); 
       // Get the observable 
       var observable = valueAccessor(); 

       // Check whether the value is null or not 
       if(value === null){ 
        // If the value is null, set the value of the element equal to an empty string 
        $(element).val(''); 
       } 
       else{ 
        // If the value is not null (is it something) set the new date on the datepicker. 

        // Parse the JSON date string ('/Date({some-random-millisecond})') 
        var date = parsejsonDateString(value); 

        // Set the new JS Date object to the datepickers 'setDate' function 
        $(element).datepicker('setDate', value); 
       } 
      } 
     } 

     vm.save = function(){ 
      // Function to save the changes made to the object 
      // Loggign the date to see the value that'll be sent to the MVC controller 
      console.log(vm.Date()); 
      .... 
      // The ajax request is irrelevant 
     } 

     ko.applyBindings(vm); 
    }); 
</script> 

、あなたは私がDateオブジェクト、JSONの日付文字列('/Date({some-random-millisecond})/')、そして生の文字列('01/09/2016')で日付を操作するためのいくつかの呼び出しをやっていることに気づくかもしれない、と私はこれらのいずれかと疑います日付をつぶすかもしれない。ここではそれらの機能は次のとおりです。

var jsonDateRE = /^\/Date\((-?\d+)(\+|-)?(\d+)?\)\/$/; 
var parseJsonDateString = function (value) { 
    var arr = value && jsonDateRE.exec(value); 
    if (arr) { 
     return new Date(parseInt(arr[1])); 
    } 
    return value; 
}; 

var convertStringToDate = function (stringDate) { 
    if (stringDate != null || stringdate || string != "") { 
     var from = stringDate.split("/"); 
     return new Date(from[2], from[1] - 1, from[0]); 
    } 
    return ""; 
} 

私は日付ピッカーの初期化時に実際に何が起こるかについてはかなり失われたんだけど、ユーザーのヒット「保存」であれば、最初の日付を変更せずに、私のコンソール氏は述べています。 '無効な日付'です。一方、ユーザーがdatepickerから日付を変更すると、すべてが期待通りに機能します。

私はこのdatepickerバインディング作業を実際に行う方法がわかりません。すべての可能なガイダンスは高く評価されています!

さらなる説明やコードが必要な場合はお知らせください(これ以外の関連コードは実際には表示されません)。私は必要な情報をすべて喜んで適用します。

+1

ユーザーの前と後のあなたの 'Date'値を見て、それを変更します。形式が異なる場合は、最初は「後」形式に一致させる必要があります。 –

+0

@RoyJわかりません。あなたは詳細を教えていただけますか? – Detilium

答えて

0

私は少しの例をまとめました。 Dateの値を示すスパンを追加したことに注目してください。起動時に何が表示されているのか、別の値を選択したときに表示されるのかを簡単に確認できます。この例では日付のようなものはないようですが、システムに異なる条件があるかもしれません。

parsejsonDateStringからparseJsonDateStringに大文字を修正しました。それがあなたのコードの中にあったなら、それは問題になります(しかしコンソールにエラーが表示されるはずです)。

var jsonDateRE = /^\/Date\((-?\d+)(\+|-)?(\d+)?\)\/$/; 
 
var parseJsonDateString = function (value) { 
 
    var arr = value && jsonDateRE.exec(value); 
 
    if (arr) { 
 
     return new Date(parseInt(arr[1])); 
 
    } 
 
    return value; 
 
}; 
 

 
var convertStringToDate = function (stringDate) { 
 
    if (stringDate != null || stringdate || string != "") { 
 
     var from = stringDate.split("/"); 
 
     return new Date(from[2], from[1] - 1, from[0]); 
 
    } 
 
    return ""; 
 
}; 
 

 
ko.bindingHandlers.datepicker = { 
 
    init: function(element, valueAccessor, allBindingsAccessor) { 
 
    // Getting the datepickerOptions value applied to the binding, if any. Else just an empty object. 
 
    var options = allBindingsAccessor().datepickerOptions || {}; 
 

 
    // Instantiating the datepicker with the options object 
 
    $(element).datepicker(options); 
 

 
    // Listen for any changes in the element 
 
    ko.utils.registerEventHandler(element, "change", function() { 
 
     var observable = valueAccessor(); 
 
     var value = $(element).val(); 
 

 
     // Check to see whether the element.val() is empty or not 
 
     if (!value) { 
 
     // If empty, I want the observable to hold value 'null' 
 
     observable(null); 
 
     } else { 
 
     // Converting the string '01/09/2016' to an actual JS Date object and settings the observable to that value 
 
     var date = convertStringToDate(value); 
 
     observable(date); 
 
     } 
 
    }); 
 
    }, 
 
    update: function(element, valueAccessor) { 
 
    // Get the value from the viewmodel 
 
    var value = ko.unwrap(valueAccessor()); 
 
    // Get the observable 
 
    var observable = valueAccessor(); 
 

 
    // Check whether the value is null or not 
 
    if (value === null) { 
 
     // If the value is null, set the value of the element equal to an empty string 
 
     $(element).val(''); 
 
    } else { 
 
     // If the value is not null (is it something) set the new date on the datepicker. 
 

 
     // Parse the JSON date string ('/Date({some-random-millisecond})') 
 
     var date = parseJsonDateString(value); 
 

 
     // Set the new JS Date object to the datepickers 'setDate' function 
 
     $(element).datepicker('setDate', value); 
 
    } 
 
    } 
 
} 
 

 

 
ko.applyBindings({ 
 
    User: ko.observable('1'), 
 
    Username: ko.observable('The guy'), 
 
    Date: ko.observable('?') 
 
});
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/css/bootstrap-datepicker.min.css" rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.min.js"></script> 
 
<p data-bind="text: User" ></p> 
 
<input data-bind="value: Username" /> 
 
<input data-bind="datepicker: Date, datepickerOptions: { dateFormat: 'dd/mm/yy' }" /> 
 
<div>Date as text: <span data-bind="text:Date"></span></div>

+0

申し訳ありませんが、私は 'bindingHandler'に何の違いも見られません。あなたが言及したように、違いは 'parseJsonDateString()'と、あなたがスパン内に日付を表​​示しているという事実だけです。この回答から私は何を理解するべきですか? – Detilium

+0

@Detiliumこれはあなたの問題を再現するための試みでした。問題を再現できない場合、私はそれを解決できません。あなたの最初の 'Date'値で何かが間違っている可能性があります。コードに "Date as text"ビットを追加すると、どのように表示されますか? –

+0

助けていただきありがとうございますが、私の問題が見つかりました。 MVCコントローラにデータを送信する前に私の観察可能なものを乱していたので、日付を変更してオブザーバブルを無効なものに変更しました。 – Detilium

関連する問題