Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"version":3,"file":"paged_content_factory.min.js","sources":["../src/paged_content_factory.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Factory to create a paged content widget.\n *\n * @module     core/paged_content_factory\n * @copyright  2018 Ryan Wyllie <ryan@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(\n[\n    'jquery',\n    'core/templates',\n    'core/notification',\n    'core/paged_content',\n    'core/paged_content_events',\n    'core/pubsub',\n    'core_user/repository'\n],\nfunction(\n    $,\n    Templates,\n    Notification,\n    PagedContent,\n    PagedContentEvents,\n    PubSub,\n    UserRepository\n) {\n    var TEMPLATES = {\n        PAGED_CONTENT: 'core/paged_content'\n    };\n\n    var DEFAULT = {\n        ITEMS_PER_PAGE_SINGLE: 25,\n        ITEMS_PER_PAGE_ARRAY: [25, 50, 100, 0],\n        MAX_PAGES: 3\n    };\n\n    /**\n     * Get the default context to render the paged content mustache\n     * template.\n     *\n     * @return {object}\n     */\n    var getDefaultTemplateContext = function() {\n        return {\n            pagingbar: false,\n            pagingdropdown: false,\n            skipjs: true,\n            ignorecontrolwhileloading: true,\n            controlplacementbottom: false\n        };\n    };\n\n    /**\n     * Get the default context to render the paging bar mustache template.\n     *\n     * @return {object}\n     */\n    var getDefaultPagingBarTemplateContext = function() {\n        return {\n            showitemsperpageselector: false,\n            itemsperpage: [{value: 35, active: true}],\n            previous: true,\n            next: true,\n            activepagenumber: 1,\n            hidecontrolonsinglepage: true,\n            pages: []\n        };\n    };\n\n    /**\n     * Calculate the number of pages required for the given number of items and\n     * how many of each item should appear on a page.\n     *\n     * @param  {Number} numberOfItems How many items in total.\n     * @param  {Number} itemsPerPage  How many items will be shown per page.\n     * @return {Number} The number of pages required.\n     */\n    var calculateNumberOfPages = function(numberOfItems, itemsPerPage) {\n        var numberOfPages = 1;\n\n        if (numberOfItems > 0) {\n            var partial = numberOfItems % itemsPerPage;\n\n            if (partial) {\n                numberOfItems -= partial;\n                numberOfPages = (numberOfItems / itemsPerPage) + 1;\n            } else {\n                numberOfPages = numberOfItems / itemsPerPage;\n            }\n        }\n\n        return numberOfPages;\n    };\n\n    /**\n     * Build the context for the paging bar template when we have a known number\n     * of items.\n     *\n     * @param {Number} numberOfItems How many items in total.\n     * @param {Number} itemsPerPage  How many items will be shown per page.\n     * @return {object} Mustache template\n     */\n    var buildPagingBarTemplateContextKnownLength = function(numberOfItems, itemsPerPage) {\n        if (itemsPerPage === null) {\n            itemsPerPage = DEFAULT.ITEMS_PER_PAGE_SINGLE;\n        }\n\n        if ($.isArray(itemsPerPage)) {\n            // If we're given a total number of pages then we don't support a variable\n            // set of items per page so just use the first one.\n            itemsPerPage = itemsPerPage[0];\n        }\n\n        var context = getDefaultPagingBarTemplateContext();\n        context.itemsperpage = buildItemsPerPagePagingBarContext(itemsPerPage);\n        var numberOfPages = calculateNumberOfPages(numberOfItems, itemsPerPage);\n\n        for (var i = 1; i <= numberOfPages; i++) {\n            var page = {\n                number: i,\n                page: \"\" + i,\n            };\n\n            // Make the first page active by default.\n            if (i === 1) {\n                page.active = true;\n            }\n\n            context.pages.push(page);\n        }\n\n        context.barsize = 10;\n        return context;\n    };\n\n    /**\n     * Convert the itemsPerPage value into a format applicable for the mustache template.\n     * The given value can be either a single integer or an array of integers / objects.\n     *\n     * E.g.\n     * In: [5, 10]\n     * out: [{value: 5, active: true}, {value: 10, active: false}]\n     *\n     * In: [5, {value: 10, active: true}]\n     * Out: [{value: 5, active: false}, {value: 10, active: true}]\n     *\n     * In: [{value: 5, active: false}, {value: 10, active: true}]\n     * Out: [{value: 5, active: false}, {value: 10, active: true}]\n     *\n     * @param {int|int[]} itemsPerPage Options for number of items per page.\n     * @return {int|array}\n     */\n    var buildItemsPerPagePagingBarContext = function(itemsPerPage) {\n        var context = [];\n\n        if ($.isArray(itemsPerPage)) {\n            // Convert the array into a format accepted by the template.\n            context = itemsPerPage.map(function(num) {\n                if (typeof num === 'number') {\n                    // If the item is just a plain number then convert it into\n                    // an object with value and active keys.\n                    return {\n                        value: num,\n                        active: false\n                    };\n                } else {\n                    // Otherwise we assume the caller has specified things correctly.\n                    return num;\n                }\n            });\n\n            var activeItems = context.filter(function(item) {\n                return item.active;\n            });\n\n            // Default the first item to active if one hasn't been specified.\n            if (!activeItems.length) {\n                context[0].active = true;\n            }\n        } else {\n            // Convert the integer into a format accepted by the template.\n            context = [{value: itemsPerPage, active: true}];\n        }\n\n        return context;\n    };\n\n    /**\n     * Build the context for the paging bar template when we have an unknown\n     * number of items.\n     *\n     * @param {Number} itemsPerPage  How many items will be shown per page.\n     * @return {object} Mustache template\n     */\n    var buildPagingBarTemplateContextUnknownLength = function(itemsPerPage) {\n        if (itemsPerPage === null) {\n            itemsPerPage = DEFAULT.ITEMS_PER_PAGE_ARRAY;\n        }\n\n        var context = getDefaultPagingBarTemplateContext();\n        context.itemsperpage = buildItemsPerPagePagingBarContext(itemsPerPage);\n        // Only display the items per page selector if there is more than one to choose from.\n        context.showitemsperpageselector = $.isArray(itemsPerPage) && itemsPerPage.length > 1;\n\n        return context;\n    };\n\n    /**\n     * Build the context to render the paging bar template with based on the number\n     * of pages to show.\n     *\n     * @param  {int|null} numberOfItems How many items are there total.\n     * @param  {int|null} itemsPerPage  How many items will be shown per page.\n     * @return {object} The template context.\n     */\n    var buildPagingBarTemplateContext = function(numberOfItems, itemsPerPage) {\n        if (numberOfItems) {\n            return buildPagingBarTemplateContextKnownLength(numberOfItems, itemsPerPage);\n        } else {\n            return buildPagingBarTemplateContextUnknownLength(itemsPerPage);\n        }\n    };\n\n    /**\n     * Build the context to render the paging dropdown template based on the number\n     * of pages to show and items per page.\n     *\n     * This control is rendered with a gradual increase of the items per page to\n     * limit the number of pages in the dropdown. Each page will show twice as much\n     * as the previous page (except for the first two pages).\n     *\n     * By default there will only be 4 pages shown (including the \"All\" option) unless\n     * a different number of pages is defined using the maxPages config value.\n     *\n     * For example:\n     * Items per page = 25\n     * Would render a dropdown will 4 options:\n     * 25\n     * 50\n     * 100\n     * All\n     *\n     * @param  {Number} itemsPerPage  How many items will be shown per page.\n     * @param  {object} config  Configuration options provided by the client.\n     * @return {object} The template context.\n     */\n    var buildPagingDropdownTemplateContext = function(itemsPerPage, config) {\n        if (itemsPerPage === null) {\n            itemsPerPage = DEFAULT.ITEMS_PER_PAGE_SINGLE;\n        }\n\n        if ($.isArray(itemsPerPage)) {\n            // If we're given an array for the items per page, rather than a number,\n            // then just use that as the options for the dropdown.\n            return {\n                options: itemsPerPage\n            };\n        }\n\n        var context = {\n            options: []\n        };\n\n        var totalItems = 0;\n        var lastIncrease = 0;\n        var maxPages = DEFAULT.MAX_PAGES;\n\n        if (config.hasOwnProperty('maxPages')) {\n            maxPages = config.maxPages;\n        }\n\n        for (var i = 1; i <= maxPages; i++) {\n            var itemCount = 0;\n\n            if (i <= 2) {\n                itemCount = itemsPerPage;\n                lastIncrease = itemsPerPage;\n            } else {\n                lastIncrease = lastIncrease * 2;\n                itemCount = lastIncrease;\n            }\n\n            totalItems += itemCount;\n            var option = {\n                itemcount: itemCount,\n                content: totalItems\n            };\n\n            // Make the first option active by default.\n            if (i === 1) {\n                option.active = true;\n            }\n\n            context.options.push(option);\n        }\n\n        return context;\n    };\n\n    /**\n     * Build the context to render the paged content template with based on the number\n     * of pages to show, items per page, and configuration option.\n     *\n     * By default the code will render a paging bar for the paging controls unless\n     * otherwise specified in the provided config.\n     *\n     * @param  {int|null} numberOfItems Total number of items.\n     * @param  {int|null|array} itemsPerPage  How many items will be shown per page.\n     * @param  {object} config  Configuration options provided by the client.\n     * @return {object} The template context.\n     */\n    var buildTemplateContext = function(numberOfItems, itemsPerPage, config) {\n        var context = getDefaultTemplateContext();\n\n        if (config.hasOwnProperty('ignoreControlWhileLoading')) {\n            context.ignorecontrolwhileloading = config.ignoreControlWhileLoading;\n        }\n\n        if (config.hasOwnProperty('controlPlacementBottom')) {\n            context.controlplacementbottom = config.controlPlacementBottom;\n        }\n\n        if (config.hasOwnProperty('hideControlOnSinglePage')) {\n            context.hidecontrolonsinglepage = config.hideControlOnSinglePage;\n        }\n\n        if (config.hasOwnProperty('ariaLabels')) {\n            context.arialabels = config.ariaLabels;\n        }\n\n        if (config.hasOwnProperty('dropdown') && config.dropdown) {\n            context.pagingdropdown = buildPagingDropdownTemplateContext(itemsPerPage, config);\n        } else {\n            context.pagingbar = buildPagingBarTemplateContext(numberOfItems, itemsPerPage);\n            if (config.hasOwnProperty('showFirstLast') && config.showFirstLast) {\n                context.pagingbar.first = true;\n                context.pagingbar.last = true;\n            }\n        }\n\n        return context;\n    };\n\n    /**\n     * Create a paged content widget where the complete list of items is not loaded\n     * up front but will instead be loaded by an ajax request (or similar).\n     *\n     * The client code must provide a callback function which loads and renders the\n     * items for each page. See PagedContent.init for more details.\n     *\n     * The function will return a deferred that is resolved with a jQuery object\n     * for the HTML content and a string for the JavaScript.\n     *\n     * The current list of configuration options available are:\n     *      dropdown {bool} True to render the page control as a dropdown (paging bar is default).\n     *      maxPages {Number} The maximum number of pages to show in the dropdown (only works with dropdown option)\n     *      ignoreControlWhileLoading {bool} Disable the pagination controls while loading a page (default to true)\n     *      controlPlacementBottom {bool} Render controls under paged content (default to false)\n     *\n     * @param  {function} renderPagesContentCallback  Callback for loading and rendering the items.\n     * @param  {object} config  Configuration options provided by the client.\n     * @return {promise} Resolved with jQuery HTML and string JS.\n     */\n    var create = function(renderPagesContentCallback, config) {\n        return createWithTotalAndLimit(null, null, renderPagesContentCallback, config);\n    };\n\n    /**\n     * Create a paged content widget where the complete list of items is not loaded\n     * up front but will instead be loaded by an ajax request (or similar).\n     *\n     * The client code must provide a callback function which loads and renders the\n     * items for each page. See PagedContent.init for more details.\n     *\n     * The function will return a deferred that is resolved with a jQuery object\n     * for the HTML content and a string for the JavaScript.\n     *\n     * The current list of configuration options available are:\n     *      dropdown {bool} True to render the page control as a dropdown (paging bar is default).\n     *      maxPages {Number} The maximum number of pages to show in the dropdown (only works with dropdown option)\n     *      ignoreControlWhileLoading {bool} Disable the pagination controls while loading a page (default to true)\n     *      controlPlacementBottom {bool} Render controls under paged content (default to false)\n     *\n     * @param  {int|array|null} itemsPerPage  How many items will be shown per page.\n     * @param  {function} renderPagesContentCallback  Callback for loading and rendering the items.\n     * @param  {object} config  Configuration options provided by the client.\n     * @return {promise} Resolved with jQuery HTML and string JS.\n     */\n    var createWithLimit = function(itemsPerPage, renderPagesContentCallback, config) {\n        return createWithTotalAndLimit(null, itemsPerPage, renderPagesContentCallback, config);\n    };\n\n    /**\n     * Create a paged content widget where the complete list of items is not loaded\n     * up front but will instead be loaded by an ajax request (or similar).\n     *\n     * The client code must provide a callback function which loads and renders the\n     * items for each page. See PagedContent.init for more details.\n     *\n     * The function will return a deferred that is resolved with a jQuery object\n     * for the HTML content and a string for the JavaScript.\n     *\n     * The current list of configuration options available are:\n     *      dropdown {bool} True to render the page control as a dropdown (paging bar is default).\n     *      maxPages {Number} The maximum number of pages to show in the dropdown (only works with dropdown option)\n     *      ignoreControlWhileLoading {bool} Disable the pagination controls while loading a page (default to true)\n     *      controlPlacementBottom {bool} Render controls under paged content (default to false)\n     *\n     * @param  {int|null} numberOfItems How many items are there in total.\n     * @param  {int|array|null} itemsPerPage  How many items will be shown per page.\n     * @param  {function} renderPagesContentCallback  Callback for loading and rendering the items.\n     * @param  {object} config  Configuration options provided by the client.\n     * @return {promise} Resolved with jQuery HTML and string JS.\n     */\n    var createWithTotalAndLimit = function(numberOfItems, itemsPerPage, renderPagesContentCallback, config) {\n        config = config || {};\n\n        var deferred = $.Deferred();\n        var templateContext = buildTemplateContext(numberOfItems, itemsPerPage, config);\n\n        Templates.render(TEMPLATES.PAGED_CONTENT, templateContext)\n            .then(function(html, js) {\n                html = $(html);\n                var id = html.attr('id');\n\n                // Set the id to the custom namespace provided\n                if (config.hasOwnProperty('eventNamespace')) {\n                    id = config.eventNamespace;\n                }\n\n                var container = html;\n\n                PagedContent.init(container, renderPagesContentCallback, id);\n\n                registerEvents(id, config);\n\n                deferred.resolve(html, js);\n                return;\n            })\n            .fail(function(exception) {\n                deferred.reject(exception);\n            })\n            .fail(Notification.exception);\n\n        return deferred.promise();\n    };\n\n    /**\n     * Create a paged content widget where the complete list of items is loaded\n     * up front.\n     *\n     * The client code must provide a callback function which renders the\n     * items for each page. The callback will be provided with an array where each\n     * value in the array is a the list of items to render for the page.\n     *\n     * The function will return a deferred that is resolved with a jQuery object\n     * for the HTML content and a string for the JavaScript.\n     *\n     * The current list of configuration options available are:\n     *      dropdown {bool} True to render the page control as a dropdown (paging bar is default).\n     *      maxPages {Number} The maximum number of pages to show in the dropdown (only works with dropdown option)\n     *      ignoreControlWhileLoading {bool} Disable the pagination controls while loading a page (default to true)\n     *      controlPlacementBottom {bool} Render controls under paged content (default to false)\n     *\n     * @param  {array} contentItems The list of items to paginate.\n     * @param  {Number} itemsPerPage  How many items will be shown per page.\n     * @param  {function} renderContentCallback  Callback for rendering the items for the page.\n     * @param  {object} config  Configuration options provided by the client.\n     * @return {promise} Resolved with jQuery HTML and string JS.\n     */\n    var createFromStaticList = function(contentItems, itemsPerPage, renderContentCallback, config) {\n        if (typeof config == 'undefined') {\n            config = {};\n        }\n\n        var numberOfItems = contentItems.length;\n        return createWithTotalAndLimit(numberOfItems, itemsPerPage, function(pagesData) {\n            var contentToRender = [];\n            pagesData.forEach(function(pageData) {\n                var begin = pageData.offset;\n                var end = pageData.limit ? begin + pageData.limit : numberOfItems;\n                var items = contentItems.slice(begin, end);\n                contentToRender.push(items);\n            });\n\n            return renderContentCallback(contentToRender);\n        }, config);\n    };\n\n    /**\n     * Reset the last page number for the generated paged-content\n     * This is used when we need a way to update the last page number outside of the getters callback\n     *\n     * @param {String} id ID of the paged content container\n     * @param {Int} lastPageNumber The last page number\n     */\n    var resetLastPageNumber = function(id, lastPageNumber) {\n        PubSub.publish(id + PagedContentEvents.ALL_ITEMS_LOADED, lastPageNumber);\n    };\n\n    /**\n     * Generate the callback handler for the page limit persistence functionality\n     *\n     * @param {String} persistentLimitKey\n     * @return {callback}\n     */\n    var generateLimitHandler = function(persistentLimitKey) {\n        return function(limit) {\n            UserRepository.setUserPreference(persistentLimitKey, limit);\n        };\n    };\n\n    /**\n     * Set up any events based on config key values\n     *\n     * @param {string} namespace The namespace for this component\n     * @param {object} config Config options passed to the factory\n     */\n    var registerEvents = function(namespace, config) {\n        if (config.hasOwnProperty('persistentLimitKey')) {\n            PubSub.subscribe(namespace + PagedContentEvents.SET_ITEMS_PER_PAGE_LIMIT,\n                generateLimitHandler(config.persistentLimitKey));\n        }\n    };\n\n    return {\n        create: create,\n        createWithLimit: createWithLimit,\n        createWithTotalAndLimit: createWithTotalAndLimit,\n        createFromStaticList: createFromStaticList,\n        // Backwards compatibility just in case anyone was using this.\n        createFromAjax: createWithTotalAndLimit,\n        resetLastPageNumber: resetLastPageNumber\n    };\n});\n"],"names":["define","$","Templates","Notification","PagedContent","PagedContentEvents","PubSub","UserRepository","TEMPLATES","DEFAULT","buildItemsPerPagePagingBarContext","itemsPerPage","context","isArray","map","num","value","active","filter","item","length","buildPagingBarTemplateContext","numberOfItems","showitemsperpageselector","itemsperpage","previous","next","activepagenumber","hidecontrolonsinglepage","pages","numberOfPages","partial","calculateNumberOfPages","i","page","number","push","barsize","buildPagingBarTemplateContextKnownLength","buildPagingBarTemplateContextUnknownLength","buildTemplateContext","config","pagingbar","pagingdropdown","skipjs","ignorecontrolwhileloading","controlplacementbottom","hasOwnProperty","ignoreControlWhileLoading","controlPlacementBottom","hideControlOnSinglePage","arialabels","ariaLabels","dropdown","options","totalItems","lastIncrease","maxPages","itemCount","option","itemcount","content","buildPagingDropdownTemplateContext","showFirstLast","first","last","createWithTotalAndLimit","renderPagesContentCallback","deferred","Deferred","templateContext","render","then","html","js","id","attr","eventNamespace","container","init","registerEvents","resolve","fail","exception","reject","promise","namespace","persistentLimitKey","subscribe","SET_ITEMS_PER_PAGE_LIMIT","limit","setUserPreference","create","createWithLimit","createFromStaticList","contentItems","renderContentCallback","pagesData","contentToRender","forEach","pageData","begin","offset","end","items","slice","createFromAjax","resetLastPageNumber","lastPageNumber","publish","ALL_ITEMS_LOADED"],"mappings":"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"}