Hybrid View

  1. #1
    Ext User
    Join Date
    Apr 2007
    Posts
    122
    Vote Rating
    0
    cocorossello is on a distinguished road

      0  

    Default extension datepicker-range (day/week/month)

    extension datepicker-range (day/week/month)


    Hi,

    Here is a datepicker with support for selecting a single day, week or month.

    Its an extension of the datepicker but now you can set a selection mode ('day', 'week', 'month').

    Code:
    Ext.namespace('Ext.ux'); 
    
    
    Date.prototype.getFirstDateOfWeek = function(){
            var value=this.clearTime();
            var semana=this.getWeekOfYear();
            while(semana == value.getWeekOfYear())
                value=value.add(Date.DAY,-1);
            value=value.add(Date.DAY,1);
            return value;
        }
    
    
    Ext.ux.DatePickerRange = Ext.extend(Ext.DatePicker, { 
        selectionMode:'month',
        setSelectionMode:function(mode){
            this.selectionMode=mode;
            this.setValue(this.value);
        },
        getSelectionMode:function(){
            return this.selectionMode();
        },
    
        //private
        update : function(date){
            var vd = this.activeDate;
            this.activeDate = date;
            if(vd && this.el){
                var t = date.getTime();
                if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
                    this.cells.removeClass("x-date-selected");
                    this.cells.each(function(c){
                       if(this.isSelected(  c.dom.firstChild.dateValue  )){
                           c.addClass("x-date-selected");
                       }
                    },this);
                    return;
                }
            }
            var days = date.getDaysInMonth();
            var firstOfMonth = date.getFirstDateOfMonth();
            var startingPos = firstOfMonth.getDay()-this.startDay;
    
            if(startingPos <= this.startDay){
                startingPos += 7;
            }
    
            var pm = date.add("mo", -1);
            var prevStart = pm.getDaysInMonth()-startingPos;
    
            var cells = this.cells.elements;
            var textEls = this.textNodes;
            days += startingPos;
    
            
            var day = 86400000;
            var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
            var today = new Date().clearTime().getTime();
            var sel = date.clearTime().getTime();
            var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
            var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
            var ddMatch = this.disabledDatesRE;
            var ddText = this.disabledDatesText;
            var ddays = this.disabledDays ? this.disabledDays.join("") : false;
            var ddaysText = this.disabledDaysText;
            var format = this.format;
    
    
    
            var setCellClass = function(cal, cell){
                cell.title = "";
                var t = d.getTime();
                cell.firstChild.dateValue = t;
                if(t == today){
                    cell.className += " x-date-today";
                    cell.title = cal.todayText;
                }
                if(cal.isSelected(cell.firstChild.dateValue)){
                    cell.className += " x-date-selected";
                }
                
                if(t < min) {
                    cell.className = " x-date-disabled";
                    cell.title = cal.minText;
                    return;
                }
                if(t > max) {
                    cell.className = " x-date-disabled";
                    cell.title = cal.maxText;
                    return;
                }
                if(ddays){
                    if(ddays.indexOf(d.getDay()) != -1){
                        cell.title = ddaysText;
                        cell.className = " x-date-disabled";
                    }
                }
                if(ddMatch && format){
                    var fvalue = d.dateFormat(format);
                    if(ddMatch.test(fvalue)){
                        cell.title = ddText.replace("%0", fvalue);
                        cell.className = " x-date-disabled";
                    }
                }
            };
    
            var i = 0;
            for(; i < startingPos; i++) {
                textEls[i].innerHTML = (++prevStart);
                d.setDate(d.getDate()+1);
                cells[i].className = "x-date-prevday";
                setCellClass(this, cells[i]);
            }
    
            for(; i < days; i++){
                intDay = i - startingPos + 1;
                textEls[i].innerHTML = (intDay);
                d.setDate(d.getDate()+1);
                cells[i].className = "x-date-active";
                setCellClass(this, cells[i]);
            }
            var extraDays = 0;
            for(; i < 42; i++) {
                 textEls[i].innerHTML = (++extraDays);
                 d.setDate(d.getDate()+1);
                 cells[i].className = "x-date-nextday";
                 setCellClass(this, cells[i]);
            }
    
            this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
    
            if(!this.internalRender){
                var main = this.el.dom.firstChild;
                var w = main.offsetWidth;
                this.el.setWidth(w + this.el.getBorderWidth("lr"));
                Ext.fly(main).setWidth(w);
                this.internalRender = true;
                
                if(Ext.isOpera && !this.secondPass){
                    main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
                    this.secondPass = true;
                    this.update.defer(10, this, [date]);
                }
            }
        },
        isSelected:function(date){
            date=new Date(date);
            if(this.selectionMode=='day')
                return date.clearTime()==this.value.clearTime();
            if(this.selectionMode=='month')
                return date.getFirstDateOfMonth().clearTime().getTime ()==this.value.getFirstDateOfMonth().clearTime().getTime ();
            if(this.selectionMode=='week'){
                return date.getFirstDateOfWeek().clearTime().getTime ()==this.value.getFirstDateOfWeek().clearTime().getTime ();
            }
            throw 'Illegal selection mode';
        
        }
            
        
    }); 
    
    Ext.reg('datepickerrange', Ext.ux.DatePickerRange);
    Hope it is useful for someone
    Attached Images
    Last edited by cocorossello; 8 Jan 2008 at 7:01 AM. Reason: A little bit nicer code

  2. #2
    Ext JS Premium Member
    Join Date
    Mar 2007
    Location
    France
    Posts
    223
    Vote Rating
    0
    tof is on a distinguished road

      0  

    Default


    Nice, thank you !

  3. #3
    Ext User
    Join Date
    Nov 2007
    Posts
    8
    Vote Rating
    0
    stevenvegt is on a distinguished road

      0  

    Default


    Thanx for this extension. I use it in a calendar application. I found a small bug:
    When in selectionMode == 'day' the chosen day isn't selected. Fixed when you change this line of code:
    Code:
    return date.clearTime() == this.value.clearTime();
    into this one:
    Code:
    return date.clearTime().getTime() == this.value.clearTime().getTime();

  4. #4
    Ext User
    Join Date
    Apr 2007
    Posts
    122
    Vote Rating
    0
    cocorossello is on a distinguished road

      0  

    Default


    Thx esteven, i forgot that one.

    I am doing a calendar application too :P

  5. #5
    Ext User
    Join Date
    Nov 2007
    Posts
    8
    Vote Rating
    0
    stevenvegt is on a distinguished road

      0  

    Default


    I extended your extension: When you hold the shiftkey you can select more days or weeks. In my project it wasn't necessary to select more than one month, but it is easy to add this functionality.
    There is an public var "amount" which is set. When you select 1 day or week the amount is 1. If you select 2 days or weeks the amount is 2 etc. Simple Also the fireEvent sends this extra amount parameter.

    Here's the code:
    Code:
    Ext.namespace('Ext.ux'); 
    
    
    Date.prototype.getFirstDateOfWeek = function(){
    	
    	var value = this.clone();
    	var dayOfWeek = this.getDay();
    	dayOfWeek = (dayOfWeek + 6) % 7;
    	value.setDate(value.getDate() - dayOfWeek);
    	
    	return value;
    }
    
    
    Ext.ux.DatePickerRange = Ext.extend(Ext.DatePicker, { 
    	
        selectionMode:'month',
    	
    	amount: 1,
    	
        setSelectionMode:function(mode){
            this.selectionMode=mode;
            this.setValue(this.value);
        },
    	
        getSelectionMode:function(){
            return this.selectionMode();
        },
    
    	// private
        handleDateClick : function(e, t){
    		
    		e.stopEvent();
            if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){
    		
    		
    			if (Ext.EventObject.shiftKey) {
    				if (t.dateValue && t.dateValue >= this.activeDate) {
    					
    					var d = new Date(t.dateValue);
    					var DAY = 86400000;
    					
    					if(this.selectionMode=='day') {
    						this.amount = ((d.getTime() - this.activeDate.getTime()) / DAY) + 1;
    					//if(this.selectionMode=='month')
    					//	this.amount = 1;
    					} else if(this.selectionMode=='week'){
    						var days = d.getFirstDateOfWeek().getTime() - this.activeDate.getFirstDateOfWeek().getTime() + DAY;
    						this.amount = Math.ceil(days / (DAY * 7));
    					}
    					
    					this.setValue(new Date(this.value));
    				}
    			} else {
    				this.amount = 1;
    				this.setValue(new Date(t.dateValue));
    			}
    			this.fireEvent("select", this, this.value, this.amount);
            }
        },
    	//private
        update : function(date){
            var vd = this.activeDate;
            this.activeDate = date;
            if(vd && this.el){
                var t = date.getTime();
                if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
                    this.cells.removeClass("x-date-selected");
                    this.cells.each(function(c){
                       if(this.isSelected(  c.dom.firstChild.dateValue  )){
                           c.addClass("x-date-selected");
                       }
                    },this);
                    return;
                }
            }
            var days = date.getDaysInMonth();
            var firstOfMonth = date.getFirstDateOfMonth();
            var startingPos = firstOfMonth.getDay()-this.startDay;
    
            if(startingPos <= this.startDay){
                startingPos += 7;
            }
    
            var pm = date.add("mo", -1);
            var prevStart = pm.getDaysInMonth()-startingPos;
    
            var cells = this.cells.elements;
            var textEls = this.textNodes;
            days += startingPos;
    
            
            var day = 86400000;
            var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
            var today = new Date().clearTime().getTime();
            var sel = date.clearTime().getTime();
            var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
            var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
            var ddMatch = this.disabledDatesRE;
            var ddText = this.disabledDatesText;
            var ddays = this.disabledDays ? this.disabledDays.join("") : false;
            var ddaysText = this.disabledDaysText;
            var format = this.format;
    
    
    
            var setCellClass = function(cal, cell){
                cell.title = "";
                var t = d.getTime();
                cell.firstChild.dateValue = t;
                if(t == today){
                    cell.className += " x-date-today";
                    cell.title = cal.todayText;
                }
                if(cal.isSelected(cell.firstChild.dateValue)){
                    cell.className += " x-date-selected";
                }
                
                if(t < min) {
                    cell.className = " x-date-disabled";
                    cell.title = cal.minText;
                    return;
                }
                if(t > max) {
                    cell.className = " x-date-disabled";
                    cell.title = cal.maxText;
                    return;
                }
                if(ddays){
                    if(ddays.indexOf(d.getDay()) != -1){
                        cell.title = ddaysText;
                        cell.className = " x-date-disabled";
                    }
                }
                if(ddMatch && format){
                    var fvalue = d.dateFormat(format);
                    if(ddMatch.test(fvalue)){
                        cell.title = ddText.replace("%0", fvalue);
                        cell.className = " x-date-disabled";
                    }
                }
            };
    
            var i = 0;
            for(; i < startingPos; i++) {
                textEls[i].innerHTML = (++prevStart);
                d.setDate(d.getDate()+1);
                cells[i].className = "x-date-prevday";
                setCellClass(this, cells[i]);
            }
    
            for(; i < days; i++){
                intDay = i - startingPos + 1;
                textEls[i].innerHTML = (intDay);
                d.setDate(d.getDate()+1);
                cells[i].className = "x-date-active";
                setCellClass(this, cells[i]);
            }
            var extraDays = 0;
            for(; i < 42; i++) {
                 textEls[i].innerHTML = (++extraDays);
                 d.setDate(d.getDate()+1);
                 cells[i].className = "x-date-nextday";
                 setCellClass(this, cells[i]);
            }
    
            this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
    
            if(!this.internalRender){
                var main = this.el.dom.firstChild;
                var w = main.offsetWidth;
                this.el.setWidth(w + this.el.getBorderWidth("lr"));
                Ext.fly(main).setWidth(w);
                this.internalRender = true;
                
                if(Ext.isOpera && !this.secondPass){
                    main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
                    this.secondPass = true;
                    this.update.defer(10, this, [date]);
                }
            }
        },
        isSelected:function(date){
    		// date to test
            date=new Date(date).clearTime();
    		// activeDate
    		ad = new Date(this.value).clearTime();
    		var DAY = 86400000;
    		
            if(this.selectionMode=='day') {
    			date = date.getTime()
    			for (var i=0; i<this.amount;++i) {
    				if (date == ad.add(Date.DAY,i).getTime()) return true;
    			}
    			return false;
    		}
            if(this.selectionMode=='month')
                return date.getFirstDateOfMonth().getTime() == this.value.getFirstDateOfMonth().getTime();
    		
            if(this.selectionMode=='week'){
    			var refTime = date.getFirstDateOfWeek().getTime();
    			var ad = ad.getFirstDateOfWeek();
    			
    			if (refTime == ad.getTime())
    				return true;
    			
    			for (var i=1; i<this.amount;++i) {
    				ad.setDate(ad.getDate() + 7);
    				if (refTime == ad.getTime())
    					return true;
    			}
    			return false;
            }
            throw 'Illegal selection mode';
        
        }
            
        
    }); 
    
    Ext.reg('datepickerrange', Ext.ux.DatePickerRange);
    Any comments are welcome
    Last edited by stevenvegt; 18 Jan 2008 at 5:17 AM. Reason: less elegant, but much faster code

  6. #6
    Ext JS Premium Member mm_202's Avatar
    Join Date
    Dec 2007
    Location
    USA
    Posts
    59
    Vote Rating
    0
    mm_202 is on a distinguished road

      0  

    Thumbs up Excellent!

    Excellent!


    Excellent work guys!

    Just one question (and I really hope that it isnt an obvious answer that I missed), how do I programatically select a date range?

    Hopefully Im not the only one needing to do that..

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi