fix #7760 - translation allowed on date and time fields
[roojs1] / Roo / bootstrap / form / DateField.js
index 6f07f05..f392310 100644 (file)
@@ -27,7 +27,7 @@
  * Create a new DateField
  * @param {Object} config The config object
  */
-
 Roo.bootstrap.form.DateField = function(config){
     Roo.bootstrap.form.DateField.superclass.constructor.call(this, config);
      this.addEvents({
@@ -70,12 +70,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
      * valid according to {@link Date#parseDate} (defaults to 'm/d/y').
      */
     format : "m/d/y",
-    /**
-     * @cfg {String} altFormats
-     * Multiple date formats separated by "|" to try when parsing a user input value and it doesn't match the defined
-     * format (defaults to 'm/d/Y|m-d-y|m-d-Y|m/d|m-d|d').
-     */
-    altFormats : "m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d",
     
     weekStart : 0,
     
@@ -102,6 +96,8 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     _events: [],
     
     singleMode : false,
+
+    hiddenField : false,
     
     UTCDate: function()
     {
@@ -129,17 +125,77 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     
     setUTCDate: function(d) {
             this.date = d;
-            this.setValue(this.formatDate(this.date));
+            this.setValue(this.date);
+    },
+
+    translateDates: function(lang) 
+    {
+        var translation = Roo.bootstrap.form.DateField.dates[lang] = {
+            days: [],
+            daysShort: [],
+            daysMin: [],
+            months: [],
+            monthsShort: []
+        };
+
+        var locale = lang.replace('_', '-');
+
+        var is_latin = [ 'zh-hk', 'zh-cn', 'jp', 'ko' ].indexOf(locale.toLowerCase()) < 0; 
+                
+
+        // fill days
+        for(var i = 0; i < 7; i++) {
+            var date = new Date(2020, 0, 5 + i);
+
+            var day = new Intl.DateTimeFormat(locale, {
+                weekday : 'long'
+            }).format(date);
+
+            var dayShort = new Intl.DateTimeFormat(locale, {
+                weekday : 'short'
+            }).format(date);
+
+            var dayMin = new Intl.DateTimeFormat(locale, {
+                weekday : 'narrow'
+            }).format(date);
+
+            if(is_latin) {
+                dayShort = day.substring(0, 3);
+                dayMin = day.substring(0, 2);
+            }
+            
+            translation.days.push(day);
+            translation.daysShort.push(dayShort);
+            translation.daysMin.push(dayMin);
+        }
+
+        // fill months
+        for(var i = 0; i < 12; i++) {
+            var date = new Date(2020, i);
+
+            var month = new Intl.DateTimeFormat(locale, {
+                month : 'long'
+            }).format(date);
+
+            var monthShort = new Intl.DateTimeFormat(locale, {
+                month : 'short'
+            }).format(date);
+
+            if(is_latin) {
+                monthShort = month.substring(0, 3);
+            }
+
+            translation.months.push(month);
+            translation/monthsShort.push(monthShort);
+        }
     },
         
     onRender: function(ct, position)
     {
         
         Roo.bootstrap.form.DateField.superclass.onRender.call(this, ct, position);
-        
-        this.language = this.language || 'en';
-        this.language = this.language in Roo.bootstrap.form.DateField.dates ? this.language : this.language.split('-')[0];
-        this.language = this.language in Roo.bootstrap.form.DateField.dates ? this.language : "en";
+
+        this.translateDates(this.language);
         
         this.isRTL = Roo.bootstrap.form.DateField.dates[this.language].rtl || false;
         this.format = this.format || 'm/d/y';
@@ -202,15 +258,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         }
         
         Roo.each(this.picker().select('tfoot th.today', true).elements, function(v){
-            if(!this.calendarWeeks){
-                v.remove();
-                return;
-            }
-            
-            v.dom.innerHTML = Roo.bootstrap.form.DateField.dates[this.language].today;
-            v.attr('colspan', function(i, val){
-                return parseInt(val) + 1;
-            });
+            v.dom.innerHTML = Roo.bootstrap.form.DateField.todayText;
         });
                        
         
@@ -229,6 +277,14 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         if(this.isInline) {
             this.showPopup();
         }
+
+        this.hiddenField = this.inputEl().insertSibling(
+            {tag : 'input', type : 'hidden', name : this.name},
+            'before',
+            true
+        );
+        this.inputEl().dom.setAttribute('name', this.name + '____hidden___');
+
     },
     
     picker : function()
@@ -248,14 +304,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
             ]
         };
         
-        if(this.calendarWeeks){
-            dow.cn.push({
-                tag: 'th',
-                cls: 'cw',
-                html: '&nbsp;'
-            })
-        }
-        
         while (dowCnt < this.weekStart + 7) {
             dow.cn.push({
                 tag: 'th',
@@ -314,12 +362,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                 today = this.UTCToday();
         
         this.picker().select('>.datepicker-days thead th.switch', true).first().dom.innerHTML = Roo.bootstrap.form.DateField.dates[this.language].months[month]+' '+year;
-        
-//        this.picker().select('>tfoot th.today', true).first().dom.innerHTML = Roo.bootstrap.form.DateField.dates[this.language].today;
-        
-//        this.picker.select('>tfoot th.today').
-//                                             .text(dates[this.language].today)
-//                                             .toggle(this.todayBtn !== false);
     
         this.updateNavArrows();
         this.fillMonths();
@@ -354,26 +396,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                     tag: 'tr',
                     cn: []
                 };
-                
-                if(this.calendarWeeks){
-                    // ISO 8601: First week contains first thursday.
-                    // ISO also states week starts on Monday, but we can be more abstract here.
-                    var
-                    // Start of current week: based on weekstart/current date
-                    ws = new Date(+prevMonth + (this.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
-                    // Thursday of this week
-                    th = new Date(+ws + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
-                    // First Thursday of year, year from thursday
-                    yth = new Date(+(yth = this.UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
-                    // Calendar week: ms between thursdays, div ms per day, div 7 days
-                    calWeek =  (th - yth) / 864e5 / 7 + 1;
-                    
-                    fillMonths.cn.push({
-                        tag: 'td',
-                        cls: 'cw',
-                        html: calWeek
-                    });
-                }
             }
             
             if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {
@@ -481,24 +503,18 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         this.picker().setTop(this.inputEl().getBottom()).setLeft(this.inputEl().getLeft());
     },
     
+    // return false when it fails
     parseDate : function(value)
     {
-        if(!value || value instanceof Date){
-            return value;
-        }
-        var v = Date.parseDate(value, this.format);
-        if (!v && (this.useIso || value.match(/^(\d{4})-0?(\d+)-0?(\d+)/))) {
-            v = Date.parseDate(value, 'Y-m-d');
+        if(!value) {
+            return false;
         }
-        if(!v && this.altFormats){
-            if(!this.altFormatsArray){
-                this.altFormatsArray = this.altFormats.split("|");
-            }
-            for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
-                v = Date.parseDate(value, this.altFormatsArray[i]);
-            }
+        if(value instanceof Date){
+            return value;
         }
-        return v;
+        var v = Date.parseDate(value, 'Y-m-d');
+
+        return (typeof(v) == 'undefined') ? false : v;
     },
     
     formatDate : function(date, fmt)
@@ -506,6 +522,20 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         return (!date || !(date instanceof Date)) ?
         date : date.dateFormat(fmt || this.format);
     },
+
+    translateDate : function(date)
+    {
+        switch(this.language) {
+            case 'zh_CN':
+                return new Intl.DateTimeFormat('zh-CN', {
+                    year : 'numeric',
+                    month : 'long',
+                    day : 'numeric'
+                }).format(date);
+            default :
+                return this.formatDate(date);
+        }
+    },
     
     onFocus : function()
     {
@@ -516,10 +546,17 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     onBlur : function()
     {
         Roo.bootstrap.form.DateField.superclass.onBlur.call(this);
-        
-        var d = this.inputEl().getValue();
-        
-        this.setValue(d);
+
+        if(!this.readOnly) {
+            var d = this.inputEl().getValue();
+            var date = this.parseDate(d);
+            if(date) {
+                this.setValue(date);
+            }
+            else {
+                this.setValue(this.getValue());
+            }
+        }
                 
         this.hidePopup();
     },
@@ -561,17 +598,56 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     setValue: function(v)
     {
         if(this.fireEvent('beforeselect', this, v) !== false){
-            var d = new Date(this.parseDate(v) ).clearTime();
-        
-            if(isNaN(d.getTime())){
-                this.date = this.viewDate = '';
-                Roo.bootstrap.form.DateField.superclass.setValue.call(this, '');
+            var d = this.parseDate(v);
+
+            if(!d) {
+                this.date = this.viewDate = this.value = this.hiddenField.value =  '';
+                if(this.rendered){
+                    this.inputEl().dom.value = '';
+                    this.validate();
+                }
+                return;
+            }
+
+            d = new Date(d).clearTime();
+
+            this.value = this.hiddenField.value = d.dateFormat('Y-m-d');
+
+            v = this.translateDate(d);
+            if(this.rendered){
+                this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+                this.validate();
+            }
+
+            this.date = new Date(d.getTime() - d.getTimezoneOffset()*60000);
+
+            this.update();
+
+            this.fireEvent('select', this, this.date);
+        }
+    },
+
+    // bypass validation
+    setRawValue : function(v){
+        if(this.fireEvent('beforeselect', this, v) !== false){
+            var d = this.parseDate(v);
+
+            if(!d) {
+                this.date = this.viewDate = this.value = this.hiddenField.value =  '';
+                if(this.rendered){
+                    this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+                }
                 return;
             }
 
-            v = this.formatDate(d);
+            d = new Date(d).clearTime();
+
+            this.value = this.hiddenField.value = d.dateFormat('Y-m-d');
 
-            Roo.bootstrap.form.DateField.superclass.setValue.call(this, v);
+            v = this.translateDate(d);
+            if(this.rendered){
+                this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+            }
 
             this.date = new Date(d.getTime() - d.getTimezoneOffset()*60000);
 
@@ -583,7 +659,11 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     
     getValue: function()
     {
-        return this.formatDate(this.date);
+        return this.value;
+    },
+
+    getRawValue : function(){
+        return this.getValue();
     },
     
     fireKey: function(e)
@@ -626,7 +706,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                 if (this.dateWithinRange(newDate)){
                     this.date = newDate;
                     this.viewDate = newViewDate;
-                    this.setValue(this.formatDate(this.date));
+                    this.setValue(this.date);
 //                    this.update();
                     e.preventDefault();
                     dateChanged = true;
@@ -653,19 +733,19 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                 if (this.dateWithinRange(newDate)){
                     this.date = newDate;
                     this.viewDate = newViewDate;
-                    this.setValue(this.formatDate(this.date));
+                    this.setValue(this.date);
 //                    this.update();
                     e.preventDefault();
                     dateChanged = true;
                 }
                 break;
             case 13: // enter
-                this.setValue(this.formatDate(this.date));
+                this.setValue(this.date);
                 this.hidePopup();
                 e.preventDefault();
                 break;
             case 9: // tab
-                this.setValue(this.formatDate(this.date));
+                this.setValue(this.date);
                 this.hidePopup();
                 break;
             case 16: // shift
@@ -719,7 +799,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                         var date = new Date();
                         this.date = this.UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
 //                        this.fill()
-                        this.setValue(this.formatDate(this.date));
+                        this.setValue(this.date);
                         
                         this.hidePopup();
                         break;
@@ -740,7 +820,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                     }
                     
                     if(this.singleMode){
-                        this.setValue(this.formatDate(this.viewDate));
+                        this.setValue(this.viewDate);
                         this.hidePopup();
                         return;
                     }
@@ -776,8 +856,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                     this.date = this.UTCDate(year, month, day,0,0,0,0);
                     this.viewDate = this.UTCDate(year, month, Math.min(28, day),0,0,0,0);
 //                    this.fill();
-                    //Roo.log(this.formatDate(this.date));
-                    this.setValue(this.formatDate(this.date));
+                    this.setValue(this.date);
                     this.hidePopup();
                 }
                 break;
@@ -788,7 +867,8 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     {
         this.startDate = startDate || -Infinity;
         if (this.startDate !== -Infinity) {
-            this.startDate = this.parseDate(this.startDate);
+            var date = this.parseDate(this.startDate);
+            this.startDate = date ? date : -Infinity;
         }
         this.update();
         this.updateNavArrows();
@@ -798,7 +878,8 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     {
         this.endDate = endDate || Infinity;
         if (this.endDate !== Infinity) {
-            this.endDate = this.parseDate(this.endDate);
+            var date = this.parseDate(this.endDate);
+            this.endDate = date ? date : Infinity;
         }
         this.update();
         this.updateNavArrows();
@@ -967,7 +1048,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
             return false;
         }
         
-        if(typeof(this.parseDate(value)) == 'undefined'){
+        if(!this.parseDate(value)){
             return false;
         }
         
@@ -1053,16 +1134,9 @@ Roo.apply(Roo.bootstrap.form.DateField,  {
         ]
     },
     
-    dates:{
-        en: {
-            days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
-            daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
-            daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
-            months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
-            monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
-            today: "Today"
-        }
-    },
+    dates : {},
+
+    todayText : "Today",
     
     modes: [
     {