0

I'm writing a date picker plugin. I know there is a lot of plugins like that out there but because there will be a few special needs in the near future I think it's best to write my own solution.

The code is very simple and straight forward but I think I'm doing something very wrong because after I move the calendar left a few times it begins to get very slow.

(function ($) {

    var defaults = {
        single: false,
        start: new Date()
    };

    var methods = {

        init: function (options) {

            var configs = $.extend(defaults, options);

            var calendar = $(this[0]);
            calendar.html(build_calendar(configs.single, configs.start));

            var date = new Date(configs.start);
            date.setDate(1);
            date.setMonth(date.getMonth() - 1);

            $("#acalendar_left").live("click", function (e) {
                e.preventDefault();
                calendar.calendar({ single: configs.single, start: date });
            });

        }

    };

    $.fn.calendar = function (method) {

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === "object" || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error("Method " + method + " does not exist on jQuery.calendar");
        }

    };

    var build_calendar = function (single, start) {

        var html = "";

        html += "<table>";
        html += "<tr>";
        html += "<td>";
        html += "<a href=\"#\" id=\"acalendar_left\">L</a>";
        html += "</td>";

        if (single) {

            html += "<td>" + build_month(start.getFullYear(), start.getMonth()) + "</td>";

        } else {

            for (var i = -1; i < 2; i++) {

                var date = new Date(start);
                date.setDate(1);
                date.setMonth(date.getMonth() + i);

                html += "<td>" + build_month(date.getFullYear(), date.getMonth()) + "</td>";

            }

        }

        html += "<td>";
        html += "<a href=\"#\" id=\"acalendar_right\">R</a>";
        html += "</td>";
        html += "</tr>";
        html += "</table>";

        return html;

    };

    var build_month = function (year, month) {

        var months = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];

        var size = (new Date(year, month + 1, 0)).getDate();

        var row = "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td></tr>";

        var temporary = row;

        var html = "";

        html += "<table>";
        html += "<tr><td colspan=\"7\">" + months[month] + " " + year + "</td></tr>";
        html += "<tr><td>D</td><td>S</td><td>T</td><td>Q</td><td>Q</td><td>S</td><td>S</td></tr>";

        for (var i = 0; i < size; i++) {

            var date = new Date(year, month, i + 1);

            if (date.getDay() == 0 && i > 0) {
                html += temporary;
                temporary = row;
            }

            temporary = temporary.replace("{" + date.getDay() + "}", date.getDate());

            if (i + 1 == size) {
                html += temporary;
            }

        }

        html += "</table>";

        html = html.replace(new RegExp("{[0-9]}", "g"), "");

        return html;

    };

})(jQuery);

$(document).ready(function () {

    $("#dcalendar").calendar();

});
2
  • I would start by creating jQuery objects instead of manipulating strings containing HTML.
    – Blender
    Commented Sep 25, 2012 at 21:46
  • I think it can improve the performance, but I don't see how manipulating strings can cause memory leaks.
    – lolol
    Commented Sep 25, 2012 at 21:49

1 Answer 1

2

First off.. live() is deprecated, you should be using on().

It seems that everytime you click on #acalendar_left, creating the whole calendar again, but i don't see where you unregister the event; so the live() event will be firing 2 times at the next run, etc, which should explain why it's getting slower and slower.

3
  • yeh, I didn't check it yet, but I'm sure you are right. Thank you.
    – lolol
    Commented Sep 25, 2012 at 21:51
  • About the on keyword, I know, but I don't have the jquery 1.7 version.
    – lolol
    Commented Sep 25, 2012 at 21:52
  • since you seem to be newly creating the anchor everytime the plugin is initialized, you can just use .click()
    – Gung Foo
    Commented Sep 25, 2012 at 21:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.