2013-04-23 8 views
40

का उपयोग करके प्रारंभिक रूप से प्रारंभ और समाप्ति दिनांक-समय पर प्रतिबंध को प्रतिबंधित करना हमारे पास उपयोगकर्ता को दो पी: कैलेंडर घटक प्रस्तुत करने की आवश्यकता है, जो प्रत्येक की शुरुआत और समाप्ति तिथि का प्रतिनिधित्व करती है। दोनों डेटाटाइम में तिथियां, घंटे और मिनट होते हैं। प्राइमफेस के पास mindate, maxdate, minHour, maxHour, minMinute, और minMinute विशेषताएँ उपलब्ध हैं।पी: कैलेंडर (कोई सत्यापन नहीं)

आवश्यकता है:

यह अंत दिनांक के बराबर या उससे अधिक कुछ भी करने के लिए शुरू दिनांक सेट करने के लिए असंभव है। एंड डेटटाइम को अंत डेटाटाइम से कम या उसके बराबर कुछ भी सेट करना असंभव है।

निम्न समीकरण सच धारण करना चाहिए:

:

<p:calendar id="begin-date" 
      value="#{debugManager.selectedBeginDate}" 
      mindate="#{debugManager.minBeginDate}" 
      maxdate="#{debugManager.maxBeginDate}" 
      maxHour="#{debugManager.maxBeginHour}" 
      maxMinute="#{debugManager.maxBeginMinute}" 
      pattern="yyyy-MM-dd HH:mm" 
      showButtonPanel="true" 
      readonlyInput="true" 
      navigator="true" 
      showOn="button" 
      required="true"> 
    <p:ajax event="dateSelect" update="end-date" /> 
</p:calendar> 

<p:calendar id="end-date" 
      value="#{debugManager.selectedEndDate}" 
      mindate="#{debugManager.minEndDate}" 
      minHour="#{debugManager.minEndHour}" 
      minMinute="#{debugManager.minEndMinute}" 
      pattern="yyyy-MM-dd HH:mm" 
      showButtonPanel="true" 
      readonlyInput="true" 
      navigator="true" 
      showOn="button"> 
    <p:ajax event="dateSelect" update="begin-date" /> 
</p:calendar> 

यहाँ एक examplary न्यूनतम/अधिकतम विधि (अंत की तारीख की mindate) है:

begin datetime < end datetime 

अब हम निम्नलिखित JSF की कोशिश की

public Date getMinEndDate() 
{ 
    return this.getSelectedBeginDate(); 
} 

जैसा कि आप देख सकते हैं, न्यूनतम समाप्ति तिथि वर्तमान में AJAX- चयनित प्रारंभ तिथि है। समाप्ति तिथि को सही तिथि से पहले की आरंभ तिथि को सही ढंग से सेट करने से मना कर दिया जाता है।

समस्याओं शुरू जब समीकरण में समय शामिल ...

पी के इंटरफेस के बाद से: कैलेंडर अलग तरीकों है, सेम तर्क प्रदान करने के लिए है:

public int getMinEndHour() 
{ 
    Date selectedBeginDate = this.getSelectedBeginDate(); 
    Date selectedEndDate = this.getSelectedEndDate(); 

    if (selectedBeginDate != null && DateUtil.isSameDay(selectedBeginDate, selectedEndDate)) 
    { 
     return DateUtil.getHourOf(selectedBeginDate); 
    } 

    return ComplianceConstants.DEFAULT_COMPLIANCE_CASE_MIN_END_HOUR; 
} 

यह मूलतः केवल कहता है कि अगर एक प्रारंभ तिथि निर्धारित की गई है और शुरुआत और समाप्ति तिथियां वर्तमान में समान हैं, तो प्रारंभिक घंटे के चयन योग्य अंत घंटे (minHour) को प्रतिबंधित करें।

संचालन:

Set the begin datetime to 2013-04-20 12:34 (legit) 
Set the end datetime to 2013-04-22 00:00 (legit) 

अब समाप्ति तिथि के लिए समय 0:00 पर बैठता है और एक कैलेंडर की तारीख 2013-04-20 समाप्ति समय के रूप में लंबे समय के रूप अनुमति दी जानी चाहिए का चयन किसी भी तरह कम से कम 12 के लिए निकाला जाता : 35।

p: कैलेंडर घटक लेकिन इस में पता नहीं कर सकते हैं और अब

sets the end datetime to 2013-04-20 00:00 (legit, but false) 

...

समस्या अब यह है कि जब उपयोगकर्ता कैलेंडर में एक निश्चित नई समाप्ति तिथि दबाता है, mindate/maxdate विशेषताएँ उपयोगकर्ता को प्रारंभ तिथि के समान हिट करने के लिए प्रतिबंधित नहीं कर सकती हैं। यदि समाप्ति दिनांक समय अब से पहले होता है तो उसी शुरुआत की तारीख कुछ भी नहीं है जो हम इसके बारे में कर सकते हैं (जो गलत है)।

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

क्या हम अगले कोशिश कर रहे थे सेट java.util.Date समय भाग समायोजित करने के लिए यदि दिनांक एक ही दिन में थे setSelectedBeginDate(Date selectedBeginDate) और setSelectedEndDate(Date selectedEndDate) तरीकों पैच करने के लिए किया गया था। कुछ इस तरह:

public void adjustSelectedEndDate() 
{ 
    if (this.selectedEndDate != null) 
    { 
     this.log.infov("adjustSelectedEndDate: b-hour = {0}, e-hour = {1}", DateUtil.getHourOf(this.selectedBeginDate), DateUtil.getHourOf(this.selectedEndDate)); 

     if (DateUtil.isSameDay(this.selectedBeginDate, this.selectedEndDate) && 
      (DateUtil.getHourOf(this.selectedEndDate) < DateUtil.getHourOf(this.selectedBeginDate)) || 
       DateUtil.getHourOf(this.selectedEndDate) == DateUtil.getHourOf(this.selectedBeginDate) && DateUtil.getMinuteOf(this.selectedEndDate) <= DateUtil.getMinuteOf(this.selectedBeginDate)) 
     { 
      this.log.info("Adjusting selected end date!"); 

      this.selectedEndDate = DateUtil.addOneMinuteTo(DateUtil.copyTime(this.selectedBeginDate, this.selectedEndDate)); 
     } 
    } 
} 

यह प्रत्येक p:calendar की update विशेषता तो संबंधित ही टिककर खेल (getSelectedBeginDate() और getSelectedEndDate + न्यूनतम/अधिकतम limiters) अद्यतन के दौरान कहा जाएगा कि करने के लिए @this जोड़ने के लिए हमें की आवश्यकता है।

अद्यतन पर @this रखकर हालांकि, पी: कैलेंडर घटकों को भ्रमित करता है, जिससे समय स्लाइडर्स केवल एक बार फिसलने योग्य होते हैं। बाद में स्लाइडर घटनाओं को तोड़ दिया जाता है, टूटा व्यवहार करते हैं।

क्यू के

  • कैसे आप आम तौर पर इस सुलझाने के दृष्टिकोण करते हैं?
  • क्या हम चाहते हैं प्राप्त करने के लिए p:remoteCommand का उपयोग कर रहा है?

वैकल्पिक क्यू:

  • क्यों नहीं PrimeFaces पी गया है: कैलेंडर एक भी minDateTime और maxDateTime प्रदान करने के लिए लागू किया गया, संभावित हाथ में समस्याओं का समाधान कर सकता है जो?

मैं इस परिदृश्य को शर्त लगाता हूं जिसका वर्णन मैंने पहले ही हल कर लिया है। यदि आप इस दृष्टिकोण को हल करने के लिए प्रबंधित दृष्टिकोण का वर्णन कर सकते हैं (या आंशिक समाधान भी साझा करते हैं) तो मैं बहुत सराहना करता हूं।

+1

अपने वैकल्पिक प्रश्न का उत्तर दें: कहें कि किसी को केवल 8 और 17 बजे (ऑफिस टाइम) के बीच डेटाटाइम चुन सकता है, हालांकि कई दिनों में। आपको पूरे डेटाटाइम के बजाय घंटों को सीमित करना होगा। – Aquillo

+1

समस्या का अच्छा स्पष्टीकरण। AFAIK Omnifaces आपको इस पर एक हाथ देता है [''] (http://showcase.omnifaces.org/validators/validateOrder)। इसमें '' :) का उपयोग करके नमूना भी शामिल है। –

+2

थोड़ी देर पहले एक ही समस्या का सामना कर रहा था, मैंने अंत में केवल अंतराल को नियंत्रित करने के लिए चुना है दिनांक शुरू होने से अधिक होने के लिए और तारीखों के बराबर होने पर प्रबंधित बीन में घंटों और मिनटों के लिए सत्यापन संभाल लें। यदि ऐसा है, तो मैं उपयोगकर्ता को एक संवाद धनुष दिखा रहा था कि endDate> startDate। – javadev

उत्तर

1

प्रस्तावना:

मैं JSF साथ काम नहीं करते, लेकिन वहाँ चीजें हैं जो आप जहाँ आप होना चाहते करने के लिए वापस चलाने हो सकता है के एक जोड़े हैं:

क) जब working with just the date portion of a dateTime in a standard calendar, उपयोग करने पर विचार :

someCalendar.set(Calendar.MILLISECOND, 0) 

ख), joda-time उपयोग करने पर विचार के रूप में यह अक्सर सिफारिश की जा करने के लिए (here, here, और many other places) से अधिक लगता है कई स्थितियों में शुद्धता, प्रदर्शन, और उपयोग की आसानी के लिए मानक पुस्तकालय।

ग) सुनिश्चित करें कि आपके सेम गुंजाइश प्रत्येक ajax कॉल जीवित है (पुन: निर्देशित नहीं, केवल मानक के बाद पीठ भेजने, आदि बनाने) और प्रत्येक ईवेंट हैंडलर चेहरे संदर्भ हो रही है (उदाहरण के लिए। FacesContext facesContext = FacesContext.getCurrentInstance();)

घ) mindate और जैसा कि आप उम्मीद करते हैं जैसे काम नहीं करते हैं, और मुझे उम्मीद नहीं है कि स्वचालित व्यवहार को आसानी से इंजेक्शन दिया जा सकता है।

जब उन विकल्पों में उपलब्ध नहीं हैं, और आप इसे सभी अपने आप को तुम्हारे पास क्या है के साथ क्या करना है:

Philisophical/UX: पहली बात मैं करना होगा व्यवस्था की उम्मीद को दूर है या तारीखों की जोड़ी से परिप्रेक्ष्य। जोड़ी को एक वेक्टर के रूप में न करें जो टाइमलाइन पर एक दिशा का खुलासा करता है या उम्मीद करता है।

  • दूसरे शब्दों में, एक start या from तारीख हमेशा से कम या एक end या to तारीख से पहले है? नहीं, जैसा कि ऐतिहासिक डेटा की एक क्वेरी के लिए देखा जा सकता है, या उन घटनाओं में सुधार लागू करने के लिए जो अभी तक हो चुके हैं या पहले ही हो चुके हैं?

    यह अर्थ आसानी से उपयोगकर्ता को भ्रमित कर सकता है कि वे 'वापस' या 'आगे से' जा रहे हैं (और आसानी से भ्रमित हो सकते हैं)। इसके बजाय मैं उनके बीच की समय-अवधि के साथ दिनांक और अवधि के साथ a pair of dates या या period जो अंतराल घोषित करता है, और किसी भी परिणामी चुने हुए मूल्यों के आधार पर समय रेखा पर उनकी सापेक्ष स्थिति का अनुमान लगाता है। इस तरह आप संबंधित और अंतर्निहित आवश्यकताओं का सम्मान कर सकते हैं कि तिथियां कभी बराबर नहीं होतीं, और बाएं हमेशा बाईं ओर होती है, दाईं ओर दाईं ओर सही होती है।

हम का अर्थ है 'से' क्या शुरू 'या अनुमान नहीं लगा सकता, लेकिन हम कुछ अर्थ और रिश्तेदार संबंध अनुमान लगा सकते हैं: एक ठीक है, एक छोड़ दिया है, और एक कालानुक्रमिक समय रेखा पर जो। नोट: किसी भी गणना या तुलना करने से पहले हमेशा यूटीसी की तारीखों को हल करें।

long oneDateValue = oneDate.toUtc().toMilliseconds(); 
long anotherDateValue = anotherDate.toUtc().toMilliseconds(); 

long right = max (oneDateValue, anotherDateValue); 
long left = min (oneDateValue, anotherDateValue); 

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

const int dateTimeResolutionInMs = 86400000; // milliseconds per day 

public bool areEssentiallySame(long left, long right) { 

    // the difference between right and left is less than our precision 
    // requires, thus dates are effectively the same 
    return (right - left < dateTimeResolutionInMs); 
} 

coercing प्रेसिजन: तीसरा, हम कैसे अंतर को हल करते हैं संकल्प की सीमा के भीतर भी मूल्यों में? (आउट एप्लिकेशन को संभालने या अपेक्षा करने या जरूरतों की तुलना में अधिक सटीकता दी गई थी)।

long diff = value % dateTimeResolutionInMs;

  1. काटना: return value - diff;

  2. निकटतम (w/पूर्वाग्रह): return value + (diff < dateTimeResolutionInMs/ 2) ? -1 * diff : dateTimeResolutionInMs - diff;

  3. अन्य: वहाँ या तो सिकुड़ या एक के लिए एक मूल्य के विस्तार के लिए अन्य रणनीतियों के बहुत सारे हैं पसंदीदा संकल्प या परिशुद्धता

परिशिष्ट: जहाँ तक हो रही के बाद पीठ के रूप में/अजाक्स मूल्यों आप घटनाओं एक calendar तत्व द्वारा चलाई के लिए उम्मीद के साथ एक दृश्य के वापस जाने के लिए कहता है, तो आप को अलग करना चाहते हो सकता है कि टिप्पणी करता है, तो एक नया सवाल के लिए रवाना चिंता प्रस्तावना में आपको कहीं भी नहीं मिला, और आप know for certain your bean is properly registered and recognized. आपके पास कुछ ब्राउज़र/ब्राउज़र-संस्करण विशिष्ट समस्याएं हो सकती हैं जो अवांछित व्यवहार में योगदान देती हैं, और किसी और चीज की तरह, ज्ञात और अज्ञात दोनों मुद्दे हैं।

संबंधित मुद्दे