2011-06-18 16 views
35

के साथ knockoutjs डेटाबेस मैं jQuery UI डेटपिकर का उपयोग कर रहा हूं। इसके पीछे एचटीएमएल इनपुट फ़ील्ड वर्तमान में KnockoutJS पर निर्भर है, जो एक आश्रित ओब्सर्वेबल के रूप में है, लेकिन जब इसका मान व्यूमोडेल में सेट होता है, तो डेटपिकर अपना प्रारूप खो देता है।jquery-ui datepicker

मुझे यह कैसे करना चाहिए और प्रारूप को खोना नहीं चाहिए? मैं दृश्य को देखना चाहता हूं मॉडल को यह नहीं पता कि यह डेटपिकर है।

उत्तर

73

आप एक कस्टम बाध्यकारी लिख सकते हैं जो डेटपिकर एपीआई का उपयोग करके क्षेत्र में दिनांक सेट करता है और तिथि को सही ढंग से पढ़कर आपके अवलोकन योग्य मूल्य भी सेट करता है।

कस्टम बंधन लग सकती है:

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/

+0

डेटपेकर और "साथ: submodelObject" शैली बाध्यकारी के बीच बेहतर सहयोग करने के लिए इस कस्टम बाध्यकारी आवश्यकताओं को बदलने के बारे में क्या? मेरे उपयोग में, यह डेटपिकर के div को तब तक दिखाई देने के लिए प्रेरित करता है जब तक कि इसे दृश्यमान से जोड़ा जा सके; "टेम्पलेट का उपयोग करके: {afterRender: jqueryDecoratingMethod, डेटा: submodelObject}" ठीक काम किया, हालांकि। –

+0

@TetsujinnoOni क्या आपके पास एक नमूना है जहां आप कोई समस्या देख रहे हैं या क्या आपका फर्क मेरे बेवकूफ हो सकता है? एक नज़र डालने में खुशी होगी। –

+0

रयान - प्रस्ताव के लिए धन्यवाद; मैं पहेली में पुन: उत्पन्न करने में सक्षम नहीं हूँ। मुझे संदेह है (पृष्ठ पर अन्य कुरूपता के कारण) कि मैं या तो विषय jqueryui के लिए भूल गया है या मेरे सीएसएस में कुछ भी बदसूरत चल रहा है .... अगर मैं इसे कारकों के एक विशिष्ट संयोजन में संकीर्ण कर सकता हूं, तो मैं पोस्ट करूंगा एक लिंक या एक पहेली। –

0

एक समाधान निर्भरता ऑब्जेर्जेबल फ़ंक्शन के अंदर स्वयं को दिनांकित करना है। इसलिए आपको फ़ंक्शन में return viewModel.someOtherObservable() जैसे कुछ लौटाना होगा। वापसी मूल्य प्रारूपित करें।

यदि आप अपना कोड शामिल करते हैं, तो मैं और समझा सकता हूं।

6

मैं अपने कोड DateFormat विकल्प का उपयोग करने में काम करने के लिए आरपी नीमेयेर के कोड में एक मामूली संपादित करना था,

$(element).datepicker("getDate") 

की जगह के साथ

$(element).val() 

तो तिथि का स्वरूपित संस्करण हुड के नीचे सही ढंग से पारित किया गया था।

6

मैं आरपी निमेयर के कोड का उपयोग ऊपर दिए गए उत्तर के रूप में चिह्नित कर रहा हूं, लेकिन जब से मैं इसका उपयोग कर रहा हूं, मैंने इसमें कुछ छोटे बदलाव किए हैं। मैंने सोचा कि मैं यहां पोस्ट करूंगा। शायद यह दूसरों की मदद करेगा। यह काफी समान है, केवल अंतर यह है कि यदि पृष्ठ लोड होने पर तत्व का मान होता है तो यह उसका मान बनाए रखेगा। इसके अलावा, मैंने $elem एक चर बना दिया ताकि $(element) की कम प्रोसेसिंग हो जो jQuery को करना होगा।

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); 
     } 
    } 
}; 
+0

मैंने इसमें खोद नहीं लिया, लेकिन डेट-पिकर का प्रारंभिक मूल्य बाध्य अवलोकन के मूल्य पर सेट नहीं किया गया था। – dhochee

1

datepicker नमूने ऊपर जावास्क्रिप्ट दिनांक स्वरूप को WCF प्रारूप से viewmodel में तारीख का स्वरूप बदलने जब उपयोगकर्ता datepicker नियंत्रण से एक नई तारीख का चयन करता है।

मेरे मामले में, मैं तारीख को एक डब्ल्यूसीएफ सेवा में वापस भेज रहा था, और यह एक deserialized जावास्क्रिप्ट दिनांक स्वीकार नहीं करेगा, इसे डब्ल्यूसीएफ प्रारूप में तारीख की आवश्यकता है। मैंने उपर्युक्त स्क्रिप्ट को संशोधित किया ताकि यह डब्लूसीएफ प्रारूप में व्यूमोडेल में तारीख को संग्रहीत कर सके ताकि उसे उस प्रारूप में सर्वर पर वापस भेजा जा सके।

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); 
     } 
    } 
}; 
1

यहां मेरे विशेष परिस्थितियों के लिए क्या काम किया गया है। मैं एमवीसी का एक नया पर्याप्त संस्करण चला रहा हूं, कि डिफ़ॉल्ट डेटाटाइम सीरियलाइज़र आईएसओ 8601 पर प्रस्तुत करता है (On the nightmare that is JSON Dates. Plus, JSON.NET and 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" /> 

और जावा स्क्रिप्ट कोड datepicker चालू करने के लिए:

$(document).ready(function() { 
    $('.date').datepicker({ dateFormat: "mm/dd/yy" }); 
}); 
+0

मेरे पास एक सवाल है कि मुझे बाइंडिंग लागू करने से पहले कोड कहां रखना चाहिए? अब मुझे त्रुटि मिल रही है: Uncaught TypeError: बाइंडिंग को संसाधित करने में असमर्थ "foreach: function() {वापसी नीतियां}" संदेश: बाइंडिंग को संसाधित करने में असमर्थ "दिनांक वैल्यू: फ़ंक्शन() {वापसी प्रारंभ दिनांक}" संदेश: संपत्ति को पढ़ नहीं सकता 'toString शून्य की –

0

आश्रित के अंदर तिथि (मिमी/डीडी/yyyy) को स्वरूपित करना बिल्कुल सही है कि मैं सोच रहा था कि मैं कैसे सोच रहा था करने के लिए। यदि आप मदद कर सकते हैं, तो पीटर मॉर्टेंसन और/या एनईईबीजेज़ मैं आपकी थोड़ी सी कोड पोस्ट करूंगा।

<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(); 
सक्रिय में

: बुध जनवरी 29 19:00:

return dataContext.getTechnologyById(currentTechnologyId, technology); 

यह एक तारीख है कि पाठ बॉक्स में इस तरह दिखता है प्रदर्शित करता है: 00 ईएसटी 2014 लेकिन मैं इसे सिर्फ दिखाना चाहता हूं: 01/29/2014। मैं इस डेटपिकर विकल्प का उपयोग कर रहा हूं - डेटफॉर्मैट: "मिमी/डीडी/वाई" लेकिन इसका प्रारंभिक मूल्य प्रदर्शित होने पर कोई प्रभाव नहीं पड़ता है।

मैं इसे पल का उपयोग करके प्रारूपित करने में सक्षम था और यह वर्तमान डेटाबेस मान प्रदर्शित करने के लिए अच्छी तरह से काम करता है, लेकिन ऐसा लगता है कि यह बाध्यकारी को अवलोकन करने के लिए वापस तोड़ रहा है क्योंकि यह अब सहेजने पर अपडेट नहीं होगा।

<Input type="text" class="ui-datepicker" id="datepicker" data-bind="value: moment(END_OF_LIFE_DATE()).format('MM/DD/YYYY')" /> 
संबंधित मुद्दे