Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Calendar - a hack for repeating events

    The fantastic calendar (and other great stuff) is what drew me to evaluate SmartClient. As others have noted there are a few issues that make Calendar not quite ready for prime time, notably the javascript errors you receive when try to invalidate your data source cache. This would be needed when you want to generate repeating events on the server side.

    I was determined to find out how the Calendar would perform in a repeating event situation so kept hacking at it until I got pretty much error free version working which I want to offer up here. Hopefully it will work for you.

    Caveats:
    - It's based on 70rc2. Isomorphic are probably working on these issues and this code will likely be broken on the next release. Recommend you use it for performance evaluation purposes, only.
    - If you're using SmartGWT this probably won't help you. I don't know enough about SmartGWT to say.
    - All situations have not been tested. There are probably some errors still lurking.
    - It's slower than plain Calendar because it's fetching from server on every event change and tab click. This subverts much of the redraw optimizations built in to Calendar. Still quite acceptable though IMO.
    - I'm justing giving you the basic calendar, not the extra form fields and server code you need to implement repeating events.
    - I do not claim to be following best practices in SmartClient architecture. It's a compete hack job.

    I marked the customization I made with comments. Note the special datasource class that must be used with it.

    Code:
    isc.defineClass("MyCalendar", isc.Calendar);
    isc.MyCalendar.addProperties({
        dateChanged : function () // kg - added whole function
        {
            var criteria = {};
            criteria.startDate = this.chosenDate;
            this.setData([]); // to force delete of recurring events
            this.fetchData(criteria);
        },
        $655 : function(_1)
        {
            if (_1.length > 1)
            {
                this.mainView = this.createAutoChild("mainView", {tabs:_1,tabSelected:function(_2, _3, _4, _5)
                {
                    this.creator.$567 = _3.viewName;
                    this.creator.setDateLabel();
                    this.creator.refreshSelectedView(); // kg - added line
                }})
            }
            else
            {
                this.mainView = _1[0].pane
            }
        },
        closeClick : function()
        {
            var _1 = this.calendar;
            if (_1.eventRemoveClick(this.event) == false)
            {
                this.$67e = true;
                return
            }
            this.Super("closeClick", arguments);
            this.calendar.removeEvent(this.event, false);   // kg - modified, change boolean true to false
            this.$53u = true
        },
        $64h : function(_1, _2, _3)
        {
            var _4 = [],_5 = Date.getWeekendDays(),_6 = _1.getTime(),_7 = this.getDayEnd(_1),_8 = _2.getHours() != 0 ? _2.getTime() : _7.getTime(),_9 = _6,_10 = _8,_11 = false;
            var _12 = (_2.getHours() == 0 || Date.compareDates(_1, _2) < 0) ? _7 : _2;
            while (!_11)
            {
                for (var i = 0; i < this.data.getLength(); i++)
                {
                    var _14 = this.data.get(i);
                    if (_14 == "loading")   // kg - added line
                    {                       // kg - added line
                        _11 = true;         // kg - added line
                        break               // kg - added line
                    }                       // kg - added line
                    var _15 = _14[this.startDateField],_16 = _14[this.endDateField];
                    if (_16.getHours() == 0 || _16 < _15)
                    {
                        _16 = _7
                    }
                    if (!_15)return[];
                    if ((_15.getTime() >= _6 && _15.getTime() < _8 && _15.getDay() == _1.getDay()) || (_16.getTime() > _6 && _16.getTime() <= _8 && _16.getDay() == _2.getDay()) || (_15.getTime() < _6 && _16.getTime() > _8 && (_15.getDay() == _1.getDay() || _16.getDay() == _2.getDay())) && (this.showWeekends || !_5.contains(_15.getDay())))
                    {
                        _4.add(_14);
                        if (_3)
                        {
                            if (_15.getTime() < _9)
                            {
                                _9 = _15.getTime()
                            }
                            if (_16.getTime() > _10)
                            {
                                _10 = _16.getTime()
                            }
                        }
                    }
                }
                if (!_3 || (_9 == _6 && _10 == _8))
                {
                    _11 = true
                }
                else
                {
                    _6 = _9;
                    _8 = _10;
                    _4.clear()
                }
            }
            return _4
        }
    });
    This is just the stuff in the datasource relevant to Calendar. I'm using JSON so my actual datasource has some other stuff, too.

    Code:
    isc.defineClass("CalendarServerDataSource", DataSource);
    isc.CalendarServerDataSource.addProperties(
    {
        dropCacheOnUpdate: true,
        transformResponse : function (dsResponse, dsRequest, jsonData)
        {
    	    if (dsRequest.operationType != "fetch")
    	    {
    		eventCalendar.dateChanged();    // hack - this must match your calendar id
    	    }
    	    return dsResponse;
        }
    });
    Good luck.

    #2
    another error eliminated

    Didn't get any feedback here but in case anyone takes it on here's another javascript error elimination hack. Add this function to MyCalendar class above.

    Code:
        $64n : function(_1, _2, _3)
        {
            var _4 = (_1 ? this.weekView : this.dayView);
            if (!_4.body)     // kg - added line
                return;         // kg - added line
            var _5 = _4.getRowHeight(1),_6 = _4.getColumnWidth(_4.isLabelCol(0) ? 1 : 0);
            var _7 = _2,_8 = _3;
            if (Date.compareDates(_7, _8) < 0 || _8.getHours() == 0)
            {
                _8 = this.getDayEnd(_7)
            }
            var _9 = this.$64h(_7, _8, true);
            _9.sortByProperties([this.startDateField,this.endDateField], [true,false]);
            var _10 = this.$64j(_9, _4);
            if (_10 == 0)_10 = 1;
            _9.unsort();
            _9.sortByProperties(["$64k"], [true]);
            var _11 = _6 / _10;
            for (var i = 0; i < _9.getLength(); i++)
            {
                var _13 = _9.get(i);
                if (_13.$64l == 0)_13.$64l = 1;
                var _14 = this.getEventLeft(_13, _1);
                _14 += (_13.$64k * _11);
                var _15 = (_13.$64l - _13.$64k) * _11;
                if (this.eventOverlap && _13.$64m)
                {
                    if (_13.$64k > 0)
                    {
                        _14 -= _11 * (this.eventOverlapPercent / 100);
                        _15 += _11 * (this.eventOverlapPercent / 100)
                    }
                }
                var _16 = _13[this.endDateField].getHours() == 0 ? 24 : _13[this.endDateField].getHours();
                var _17 = (_16 - _13[this.startDateField].getHours()) * (_5 * 2)
                if (this.weekEventBorderOverlap && _4.$53i)_15 += 1;
                if (_13[this.startDateField].getMinutes() > 0)
                {
                    _17 -= this.$54g(_13[this.startDateField].getMinutes(), _5)
                }
                if (_13[this.endDateField].getMinutes() > 0)
                {
                    _17 += this.$54g(_13[this.endDateField].getMinutes(), _5)
                }
                var _18 = _13[this.startDateField].getHours() * (_5 * 2);
                if (_13[this.startDateField].getMinutes() > 0)
                {
                    _18 += this.$54g(_13[this.startDateField].getMinutes(), _5)
                }
                var _19 = this.$64i(_13, _1);
                if (_19)
                {
                    _19.renderEvent(_18, _14, _15, _17)
                }
            }
        }

    Comment

    Working...
    X