jQuery UI datepickerを使用しています。その背後のHTML入力フィールドは現在、dependentObservableとして KnockoutJS に接続されていますが、その値がビューモデルで設定されると、datepickerは形式を失います。
どうすればフォーマットを失うことはありませんか? viewModelが jQuery datepickerであることを知りたくないのですが。
Datepicker APIを使用してフィールドに日付を設定し、日付を適切に読み取ることでオブザーバブルの値を設定するカスタムバインディングを作成できます。
カスタムバインディングは次のようになります。
_ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().datepickerOptions || {},
$el = $(element);
//initialize datepicker with some optional options
$el.datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", function() {
var observable = valueAccessor();
observable($el.datepicker("getDate"));
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$el.datepicker("destroy");
});
},
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
$el = $(element),
current = $el.datepicker("getDate");
if (value - current !== 0) {
$el.datepicker("setDate", value);
}
}
};
_
次のように使用します。
_<input data-bind="datepicker: myDate, datepickerOptions: { minDate: new Date() }" />
_
datepickeroptions
はオプションであり、datepicker()
呼び出しに渡すものを含めることができます。
また、これは、日付にオブザーバブルを使用していることを前提としています。観察不可能な一方向のバインディングを行う場合、バインディングはもう少し作業を行う必要がありますが、それはほとんどありません。
ここのサンプル: http://jsfiddle.net/rniemeyer/NAgNV/
上記の答えとしてマークされたRP Niemeyerのコードを使用しましたが、使用して以来、いくつかの小さな変更を加えました。ここに投稿すると思いました。たぶん他の人を助けるでしょう。ほとんど同じですが、唯一の違いは、ページの読み込み時に要素に値がある場合、その値を保持することです。また、jQueryが行う必要のある$(element)
の処理が少なくなるように、$elem
を変数にしました。
ko.bindingHandlers['jqDatePicker'] = {
'init': function(element, valueAccessor, allBindingsAccessor) {
/* Initialize datepicker with some optional options */
var options = allBindingsAccessor().jqDatePickerOptions || {},
prop = valueAccessor(),
$elem = $(element);
prop($elem.val());
$elem.datepicker(options);
/* Handle the field changing */
ko.utils.registerEventHandler(element, "change", function () {
prop($elem.datepicker("getDate"));
});
/* Handle disposal (if KO removes by the template binding) */
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$elem.datepicker("destroy");
});
},
'update': function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
$elem = $(element),
current = $elem.datepicker("getDate");
if (value - current !== 0) {
$elem.datepicker("setDate", value);
}
}
};
DateFormatオプションを使用してコードで動作するように、RP Niemeyerのコードをわずかに編集する必要がありました。
$(element).datepicker("getDate")
と
$(element).val()
したがって、フォーマットされた日付のバージョンは、内部で正しく渡されました。
これが私の特定の状況に合ったものです。デフォルトの日時シリアライザーがISO 8601でレンダリングするMVCの新しい十分なバージョンを実行しています(JSON Datesである悪夢に加えて、JSON.NETおよびASPを参照してください)。 NET Web API)。私のバインディングは日付ピッカーに直接書き込みませんが、代わりに入力タグの「値」属性に書き込みます。
また、注意して、私は date.js を使用しています
ko.bindingHandlers.dateValue = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor(),
allBindings = allBindingsAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var pattern = allBindings.datePattern || 'MM/dd/yyyy';
var date = Date.parse(valueUnwrapped)
$(element).val(date.toString(pattern));
},
init: function(element, valueAccessor, allBindingsAccessor) {
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
var date = Date.parse($(element).val());
observable(date.toString("yyyy-MM-ddThh:mm:ss"));
});
}
}
バインドは次のようになります。
<input class="date" type="text" data-bind="dateValue: SomeViewModelDate" />
そして、日付ピッカーをオンにするJavaScriptコード:
$(document).ready(function () {
$('.date').datepicker({ dateFormat: "mm/dd/yy" });
});
上記の日付ピッカーのサンプルでは、ユーザーが日付ピッカーコントロールから新しい日付を選択すると、ビューモデルの日付の形式を [〜#〜] wcf [〜#〜] 形式からJavaScript日付形式に変更します。
私の場合、日付をWCFサービスに返していましたが、デシリアライズされたJavaScriptの日付を受け入れず、WCF形式の日付が必要でした。上記のスクリプトを変更して、日付をWCF形式でビューモデルに保存し、その形式でサーバーに返送できるようにしました。
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//Initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
//Handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
// observable($(element).datepicker("getDate"));
// store the date in 'WCF String format"
var tempdate=$(element).datepicker("getDate");
var tempdatestr="/Date("+tempdate.getTime()+")/";
observable(tempdatestr);
});
//Handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datepicker("destroy");
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
//Handle date data coming via JSON from Microsoft
if (String(value).indexOf('/Date(') == 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
current = $(element).datepicker("getDate");
if (value - current !== 0) {
$(element).datepicker("setDate", value);
}
}
};
DependentObservable内で日付を(mm/dd/yyyyに)書式設定することは、私がどうすればいいのかと思っていたものです。あなたが助けることができるなら、私は私のコードの少しを投稿します、ピーター・モーテンセンおよび/またはnEEBz。
<div data-bind="with: technology">
<div class="titleblock">
<label><b>End of Life Date</b></label>
<Input type="text" class="ui-datepicker" id="datepicker" data-bind="value: END_OF_LIFE_DATE"/>
</div>
</div>
viewModelで-technologydetail.js:
var technology = ko.observable();
アクティベート中:
return dataContext.getTechnologyById(currentTechnologyId, technology);
これにより、テキストボックスに次のような日付が表示されます:2014年1月29日水曜日19:00:00 EST 2014年1月29日:このdatepickerオプション-dateFormat: "mm/dd/yy"を使用していますが、表示される初期値には影響しません。
モーメントを使用してフォーマットすることができ、現在のデータベース値を表示するのにうまく機能しますが、SAVEで更新されなくなるため、observableへのバインディングを解除しているようです。
<Input type="text" class="ui-datepicker" id="datepicker" data-bind="value: moment(END_OF_LIFE_DATE()).format('MM/DD/YYYY')" />
1つの解決策は、dependentObservable関数内で日付を自分でフォーマットすることです。したがって、関数でreturn viewModel.someOtherObservable()
のようなものを返す必要があります。戻り値をフォーマットします。
コードを含めれば、さらに説明できます。