KnockoutJS에 의해 잡히지 않는 jQuery UI 날짜 선택기 변경 이벤트
jQuery UI에서 KnockoutJS를 사용하려고합니다. 날짜 선택기가 첨부 된 입력 요소가 있습니다. 현재 실행 중이며 knockout.debug.1.2.1.js
변경 이벤트가 Knockout에 걸리지 않는 것 같습니다. 요소는 다음과 같습니다.
<input type="text" class="date" data-bind="value: RedemptionExpiration"/>
valueUpdate
이벤트 유형을 변경하려고 했지만 아무 소용이 없습니다. Chrome이 focus
값을 변경하기 직전 에 이벤트를 일으키는 것처럼 보이지만 IE는 그렇지 않습니다.
"모든 바인딩을 리 바인딩하는"녹아웃 방법이 있습니까? 기술적으로 서버로 다시 보내기 전에 변경된 값만 있으면됩니다. 그래서 나는 그런 종류의 해결 방법으로 살 수있었습니다.
문제는 datepicker의 잘못이라고 생각하지만이 문제를 해결하는 방법을 알 수는 없습니다.
어떤 아이디어?
jQuery UI datepicker의 경우 datepicker에서 제공하는 API를 사용하여 Date 객체로 읽고 쓰는 사용자 정의 바인딩을 사용하는 것이 좋습니다.
바인딩은 다음과 같습니다 ( 여기서 내 대답 에서 ).
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {},
$el = $(element);
$el.datepicker(options);
//handle the field changing by registering datepicker's changeDate event
ko.utils.registerEventHandler(element, "changeDate", 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);
//handle date data coming via json from Microsoft
if (String(value).indexOf('/Date(') == 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
var current = $el.datepicker("getDate");
if (value - current !== 0) {
$el.datepicker("setDate", value);
}
}
};
당신은 그것을 다음과 같이 사용할 것입니다 :
<input data-bind="datepicker: myDate, datepickerOptions: { minDate: new Date() }" />
jsFiddle의 샘플은 다음과 같습니다. http://jsfiddle.net/rniemeyer/NAgNV/
다음은 RP Niemeyer의 답변 버전입니다. http://github.com/ericmbarnard/Knockout-Validation
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).val());
if (observable.isValid()) {
observable($(element).datepicker("getDate"));
$(element).blur();
}
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datepicker("destroy");
});
ko.bindingHandlers.validationCore.init(element, valueAccessor, allBindingsAccessor);
},
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);
}
}
};
변경 이벤트 핸들러는 날짜가 아닌 입력 된 값을 유효성 검증 스크립트에 먼저 전달한 다음 유효 할 경우 관찰 가능 항목으로 날짜 만 설정하도록 변경됩니다. 또한 여기에 설명 된 사용자 정의 바인딩에 필요한 validationCore.init를 추가했습니다.
http://github.com/ericmbarnard/Knockout-Validation/issues/69
또한 변경에 대한 rpenrose의 제안을 추가하여 성가신 날짜 선택기 시나리오를 제거합니다.
다른 접근법을 사용했습니다. knockout.js는 변경시 이벤트를 발생시키지 않는 것이므로 datepicker가 입력을 닫을 때 change ()를 호출하도록 강요했습니다.
$(".date").datepicker({
onClose: function() {
$(this).change(); // Forces re-validation
}
});
이 모든 대답이 저에게 많은 작업을 절약 해 주었지만 그 중 어느 것도 나를 위해 완전히 효과가 없었습니다. 날짜를 선택한 후에는 바인드 된 값이 업데이트되지 않습니다. 키보드를 사용하여 날짜 값을 변경 한 다음 입력 상자를 클릭 할 때만 업데이트 할 수 있습니다. 나는 syb의 코드로 RP Niemeyer의 코드를 보강하여 이것을 고쳤다.
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
var funcOnSelectdate = function () {
var observable = valueAccessor();
observable($(element).datepicker("getDate"));
}
options.onSelect = funcOnSelectdate;
$(element).datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", funcOnSelectdate);
//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());
if (typeof(value) === "string") { // JSON string from server
value = value.split("T")[0]; // Removes time
}
var current = $(element).datepicker("getDate");
if (value - current !== 0) {
var parsedDate = $.datepicker.parseDate('yy-mm-dd', value);
$(element).datepicker("setDate", parsedDate);
}
}
};
observable ($ (element) .datepicker ( "getDate")); 자체 기능으로 문장을 작성하고 options.onSelect에 등록하면 트릭이 수행됩니까?
이 기사에 감사드립니다. 매우 유용하다는 것을 알았습니다.
DatePicker가 JQuery UI 기본 동작과 똑같이 동작하도록하려면 change 이벤트 핸들러에서 요소에 흐림을 추가하는 것이 좋습니다.
즉
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($(element).datepicker("getDate"));
$(element).blur();
});
포함 된 스크립트 파일의 순서를 변경하여이 문제를 해결했습니다.
<script src="@Url.Content("~/Scripts/jquery-ui-1.10.2.custom.js")"></script>
<script src="@Url.Content("~/Scripts/knockout-2.2.1.js")"></script>
RP Niemeyer와 동일하지만 WCF DateTime, 시간대 및 DatePicker onSelect JQuery 속성 사용에 대한 지원이 향상되었습니다.
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
var funcOnSelectdate = function () {
var observable = valueAccessor();
var d = $(element).datepicker("getDate");
var timeInTicks = d.getTime() + (-1 * (d.getTimezoneOffset() * 60 * 1000));
observable("/Date(" + timeInTicks + ")/");
}
options.onSelect = funcOnSelectdate;
$(element).datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", funcOnSelectdate);
//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);
}
}
};
즐겨 :)
http://jsfiddle.net/yechezkelbr/nUdYH/
훨씬 더 쉽게 할 수 있다고 생각합니다. <input data-bind="value: myDate, datepicker: myDate, datepickerOptions: {}" />
따라서 init 함수에서 수동 변경 처리가 필요하지 않습니다.
그러나이 경우 'myDate'변수는 Date 객체가 아닌 보이는 값만 가져옵니다.
또는 바인딩에서이를 지정할 수 있습니다.
최신 정보:
function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
current = $(element).datepicker("getDate");
if (typeof value === "string") {
var dateValue = new Date(value);
if (dateValue - current !== 0)
$(element).datepicker("setDate", dateValue);
}
}
Based on Ryan's solution, myDate returns the standard date string, which is not the ideal one in my case. I used date.js to parse the value so it will always return the date format you want. Take a look at this example fiddle Example.
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
current = $(element).datepicker("getDate");
var d = Date.parse(value);
if (value - current !== 0) {
$(element).datepicker("setDate", d.toString("MM/dd/yyyy"));
}
}
I needed to repeatedly update my data from the server came across this but didn't quite finish the job for my needs sharing below(my date format /Date(1224043200000)/):
//Object Model
function Document(data) {
if (String(data.RedemptionExpiration).indexOf('/Date(') == 0) {
var newDate = new Date(parseInt(data.BDate.replace(/\/Date\((.*?)\)\//gi, "$1")));
data.RedemptionExpiration = (newDate.getMonth()+1) +
"/" + newDate.getDate() +
"/" + newDate.getFullYear();
}
this.RedemptionExpiration = ko.observable(data.RedemptionExpiration);
}
//View Model
function DocumentViewModel(){
///additional code removed
self.afterRenderLogic = function (elements) {
$("#documentsContainer .datepicker").each(function () {
$(this).datepicker();
});
};
}
After the model is formatted correctly for the output I added a template with the documentation knockoutjs:
<div id="documentsContainer">
<div data-bind="template: { name: 'document-template', foreach: documents, afterRender: afterRenderLogic }, visible: documents().length > 0"></div>
</div>
//Inline template
<script type="text/html" id="document-template">
<input data-bind="value: RedemptionExpiration" class="datepicker" />
</script>
Few people asked for dynamic datepicker options. In my case I needed a dynamic date range - so the first input defines the min value of the second and the second sets the max value for the first. I solved it by extending the RP Niemeyer's handler. So to his original:
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {},
$el = $(element);
$el.datepicker(options);
//handle the field changing by registering datepicker's changeDate event
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);
//handle date data coming via json from Microsoft
if (String(value).indexOf('/Date(') == 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
var current = $el.datepicker("getDate");
if (value - current !== 0) {
$el.datepicker("setDate", value);
}
}
};
I've added two more handlers corresponding to the options I wanted to modify:
ko.bindingHandlers.minDate = {
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
current = $(element).datepicker("option", "minDate", value);
}
};
ko.bindingHandlers.maxDate = {
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
current = $(element).datepicker("option", "maxDate", value);
}
};
And used them like that in my template:
<input data-bind="datepicker: selectedLowerValue, datepickerOptions: { minDate: minValue()}, maxDate: selectedUpperValue" />
<input data-bind="datepicker: selectedUpperValue, datepickerOptions: { maxDate: maxValue()}, minDate: selectedLowerValue" />
Using custom bindings provided in previous answers is not always possible. Calling $(element).datepicker(...)
takes some considerable time, and if you have, for example, a few dozens, or even hundreds of elements to call this method with, you have to do it "lazy", i.e. on demand.
For example, the view model may be initialized, the input
s being inserted into the DOM, but the corresponding datepickers will only be initialized when a user clicks them.
So, here is my solution:
Add a custom binding that allows to attach arbitrary data to a node:
KO.bindingHandlers.boundData = {
init: function(element, __, allBindings) {
element.boundData = allBindings.get('boundData');
}
};
Use the binding to attcah the observable used for the input
's value:
<input type='text' class='my-date-input'
data-bind='textInput: myObservable, boundData: myObservable' />
And finally, when initializing the datepicker, use it's onSelect
option:
$('.my-date-input').datepicker({
onSelect: function(dateText) {
this.myObservable(dateText);
}
//Other options
});
This way, every time a user changes the date with the datepicker, the corresponding Knockout observable is also updated.
'Programing' 카테고리의 다른 글
mysql에서 문자열을 날짜로 변환하는 방법은 무엇입니까? (0) | 2020.06.26 |
---|---|
Android 사용자 정의보기를 위해 세 생성자가 모두 필요합니까? (0) | 2020.06.26 |
정렬 뒤의 구문 (key = lambda :…) (0) | 2020.06.26 |
Bootstrap 3의 탐색 표시 줄에 아이콘이있는 검색 상자를 추가하는 방법은 무엇입니까? (0) | 2020.06.26 |
bash의 정수 비교, 단항 연산자 예상 (0) | 2020.06.26 |