remotemodel.js 5.11 KB
(function ($) {
    "use strict";
    function RemoteModel(data_url, search_index_url) {
        // private
        var PAGESIZE = 50;
        var data = {length: 0};
        var searchstr = "";
        var sortcol = null;
        var sortdir = 1;
        var h_request = null;
        var ajax_request = null;
        var sort_rules = null;
        var filter = {group_op: "AND", rules: []};

        // events
        var onDataLoading = new Slick.Event();
        var onDataLoaded = new Slick.Event();

        function init() {
        }

        function isDataLoaded(from, to) {
            for (var i = from; i <= to; i++) {
                if (data[i] === undefined || data[i] === null) {
                    return false;
                }
            }
            return true;
        }

        function clear() {
            for (var key in data) {
                if (data.hasOwnProperty(key))
                    delete data[key];
            }
            data.length = 0;
        }

        function ensureData(from, to) {
            if (ajax_request) {
                ajax_request.abort();
                for (var i = ajax_request.fromPage; i <= ajax_request.toPage; i++)
                    data[i * PAGESIZE] = undefined;
            }

            if (from < 0) {
                from = 0;
            }

            if (data.length > 0) {
                to = Math.min(to, data.length - 1);
            }

            var fromPage = Math.floor(from / PAGESIZE);
            var toPage = Math.floor(to / PAGESIZE);

            while (data[fromPage * PAGESIZE] !== undefined && fromPage < toPage)
                fromPage++;

            while (data[toPage * PAGESIZE] !== undefined && fromPage < toPage)
                toPage--;

            if (fromPage > toPage ||
                ((fromPage === toPage) && data[fromPage * PAGESIZE] !== undefined)) {
                onDataLoaded.notify({from: from, to: to});
                return;
            }

            if (h_request !== null) {
                clearTimeout(h_request);
            }

            h_request = setTimeout(function () {
                for (var i = fromPage; i <= toPage; i++)
                    data[i * PAGESIZE] = null; // requested but not available yet

                onDataLoading.notify({from: from, to: to});

                var ajax_data = {
                    rows: PAGESIZE,
                    from_page: fromPage,
                    to_page: toPage,
                    sort_rules: sort_rules,
                    filters: filter
                };
                if (searchstr !== '') ajax_data.mask = searchstr;

                ajax_request = $.ajaxJSON({
                    url: data_url,
                    method: 'get',
                    callback: onSuccess,
                    data: ajax_data,
                    error: function () {
                        onError(fromPage, toPage);
                    }
                });
                ajax_request.fromPage = fromPage;
                ajax_request.toPage = toPage;
            }, 50);
        }

        function onError(fromPage, toPage) {
            common.error_alert(
                "Błąd w ładowaniu stron od " + fromPage + " do " + toPage);
        }

        function onSuccess(ajax_data) {
            var from = ajax_data.page * PAGESIZE,
                to = from + ajax_data.rows.length;
            data.length = ajax_data.count;

            $.each(ajax_data.rows, function(i, row) {
                data[from + i] = row;
                data[from + i].index = from + i;
            });

            ajax_request = null;

            onDataLoaded.notify({from: from, to: to});
        }

        function reloadData(from, to) {
            for (var i = from; i <= to; i++)
                delete data[i];

            ensureData(from, to);
        }

        function setSort(rules) {
            sort_rules = rules;
            clear();
        }

        function setSearch(str) {
            searchstr = str;
            clear();
        }

        function setFilter(f) {
            filter = f;
            clear();
        }

        function searchRow(search_text, callback) {
            var data = {
                filters: filter,
                sort_rules: sort_rules,
                search: search_text
            };
            $.ajaxJSON({
                url: search_index_url,
                method: 'get',
                data: data,
                callback: function(data) {
                    callback(data.index);
                }
            });
        }

        init();

        return {
            // properties
            "data": data,

            // methods
            "clear": clear,
            "isDataLoaded": isDataLoaded,
            "ensureData": ensureData,
            "reloadData": reloadData,
            "setSort": setSort,
            "setSearch": setSearch,
            "setFilter": setFilter,
            "searchRow": searchRow,

            // events
            "onDataLoading": onDataLoading,
            "onDataLoaded": onDataLoaded
        };
    }

    // Slick.Data.RemoteModel
    $.extend(true, window, {Slick: {Data: {RemoteModel: RemoteModel}}});
})(jQuery);