Proyectos de Subversion Moodle

Rev

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

{"version":3,"file":"paged_content_paging_bar.min.js","sources":["../src/paged_content_paging_bar.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 * Javascript to enhance the paged content paging bar.\n *\n * @module     core/paged_content_paging_bar\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    'jquery',\n    'core/custom_interaction_events',\n    'core/paged_content_events',\n    'core/str',\n    'core/pubsub',\n    'core/pending',\n],\nfunction(\n    $,\n    CustomEvents,\n    PagedContentEvents,\n    Str,\n    PubSub,\n    Pending\n) {\n\n    var SELECTORS = {\n        ROOT: '[data-region=\"paging-bar\"]',\n        PAGE: '[data-page]',\n        PAGE_ITEM: '[data-region=\"page-item\"]',\n        PAGE_LINK: '[data-region=\"page-link\"]',\n        FIRST_BUTTON: '[data-control=\"first\"]',\n        LAST_BUTTON: '[data-control=\"last\"]',\n        NEXT_BUTTON: '[data-control=\"next\"]',\n        PREVIOUS_BUTTON: '[data-control=\"previous\"]',\n        DOTS_BUTTONS: '[data-dots]',\n        BEGINNING_DOTS_BUTTON: '[data-dots=\"beginning\"]',\n        ENDING_DOTS_BUTTON: '[data-dots=\"ending\"]',\n    };\n\n    /**\n     * Get the page element by number.\n     *\n     * @param {object} root The root element.\n     * @param {Number} pageNumber The page number.\n     * @return {jQuery}\n     */\n    var getPageByNumber = function(root, pageNumber) {\n        return root.find(SELECTORS.PAGE_ITEM + '[data-page-number=\"' + pageNumber + '\"]');\n    };\n\n    /**\n     * Get the next button element.\n     *\n     * @param {object} root The root element.\n     * @return {jQuery}\n     */\n    var getNextButton = function(root) {\n        return root.find(SELECTORS.NEXT_BUTTON);\n    };\n\n    /**\n     * Set the last page number after which no more pages\n     * should be loaded.\n     *\n     * @param {object} root The root element.\n     * @param {Number} number Page number.\n     */\n    var setLastPageNumber = function(root, number) {\n        root.attr('data-last-page-number', number);\n    };\n\n    /**\n     * Get the last page number.\n     *\n     * @param {object} root The root element.\n     * @return {Number}\n     */\n    var getLastPageNumber = function(root) {\n        return parseInt(root.attr('data-last-page-number'), 10);\n    };\n\n    /**\n     * Get the active page number.\n     *\n     * @param {object} root The root element.\n     * @returns {Number} The page number\n     */\n    var getActivePageNumber = function(root) {\n        return parseInt(root.attr('data-active-page-number'), 10);\n    };\n\n    /**\n     * Set the active page number.\n     *\n     * @param {object} root The root element.\n     * @param {Number} number Page number.\n     */\n    var setActivePageNumber = function(root, number) {\n        root.attr('data-active-page-number', number);\n    };\n\n    /**\n     * Check if there is an active page number.\n     *\n     * @param {object} root The root element.\n     * @returns {bool}\n     */\n    var hasActivePageNumber = function(root) {\n        var number = getActivePageNumber(root);\n        return !isNaN(number) && number != 0;\n    };\n\n    /**\n     * Get the page number for a given page.\n     *\n     * @param {object} root The root element.\n     * @param {object} page The page element.\n     * @returns {Number} The page number\n     */\n    var getPageNumber = function(root, page) {\n        if (page.attr('data-page') != undefined) {\n            // If it's an actual page then we can just use the page number\n            // attribute.\n            return parseInt(page.attr('data-page-number'), 10);\n        }\n\n        var pageNumber = 1;\n        var activePageNumber = null;\n\n        switch (page.attr('data-control')) {\n            case 'first':\n                pageNumber = 1;\n                break;\n\n            case 'last':\n                pageNumber = getLastPageNumber(root);\n                break;\n\n            case 'next':\n                activePageNumber = getActivePageNumber(root);\n                var lastPage = getLastPageNumber(root);\n                if (!lastPage) {\n                    pageNumber = activePageNumber + 1;\n                } else if (activePageNumber && activePageNumber < lastPage) {\n                    pageNumber = activePageNumber + 1;\n                } else {\n                    pageNumber = lastPage;\n                }\n                break;\n\n            case 'previous':\n                activePageNumber = getActivePageNumber(root);\n                if (activePageNumber && activePageNumber > 1) {\n                    pageNumber = activePageNumber - 1;\n                } else {\n                    pageNumber = 1;\n                }\n                break;\n\n            default:\n                pageNumber = 1;\n                break;\n        }\n\n        // Make sure we return an int not a string.\n        return parseInt(pageNumber, 10);\n    };\n\n    /**\n     * Get the limit of items for each page.\n     *\n     * @param {object} root The root element.\n     * @returns {Number}\n     */\n    var getLimit = function(root) {\n        return parseInt(root.attr('data-items-per-page'), 10);\n    };\n\n    /**\n     * Set the limit of items for each page.\n     *\n     * @param {object} root The root element.\n     * @param {Number} limit Items per page limit.\n     */\n    var setLimit = function(root, limit) {\n        root.attr('data-items-per-page', limit);\n    };\n\n    /**\n     * Show the paging bar.\n     *\n     * @param {object} root The root element.\n     */\n    var show = function(root) {\n        root.removeClass('hidden');\n    };\n\n    /**\n     * Hide the paging bar.\n     *\n     * @param {object} root The root element.\n     */\n    var hide = function(root) {\n        root.addClass('hidden');\n    };\n\n    /**\n     * Disable the next and last buttons in the paging bar.\n     *\n     * @param {object} root The root element.\n     */\n    var disableNextControlButtons = function(root) {\n        var nextButton = root.find(SELECTORS.NEXT_BUTTON);\n        var lastButton = root.find(SELECTORS.LAST_BUTTON);\n\n        nextButton.addClass('disabled');\n        nextButton.attr('aria-disabled', true);\n        lastButton.addClass('disabled');\n        lastButton.attr('aria-disabled', true);\n    };\n\n    /**\n     * Enable the next and last buttons in the paging bar.\n     *\n     * @param {object} root The root element.\n     */\n    var enableNextControlButtons = function(root) {\n        var nextButton = root.find(SELECTORS.NEXT_BUTTON);\n        var lastButton = root.find(SELECTORS.LAST_BUTTON);\n\n        nextButton.removeClass('disabled');\n        nextButton.removeAttr('aria-disabled');\n        lastButton.removeClass('disabled');\n        lastButton.removeAttr('aria-disabled');\n    };\n\n    /**\n     * Disable the previous and first buttons in the paging bar.\n     *\n     * @param {object} root The root element.\n     */\n    var disablePreviousControlButtons = function(root) {\n        var previousButton = root.find(SELECTORS.PREVIOUS_BUTTON);\n        var firstButton = root.find(SELECTORS.FIRST_BUTTON);\n\n        previousButton.addClass('disabled');\n        previousButton.attr('aria-disabled', true);\n        firstButton.addClass('disabled');\n        firstButton.attr('aria-disabled', true);\n    };\n\n    /**\n     * Adjusts the size of the paging bar and hides unnecessary pages.\n     *\n     * @param {object} root The root element.\n     */\n    var adjustPagingBarSize = function(root) {\n        var activePageNumber = getActivePageNumber(root);\n        var lastPageNumber = getLastPageNumber(root);\n\n        var dotsButtons = root.find(SELECTORS.DOTS_BUTTONS);\n        var beginningDotsButton = root.find(SELECTORS.BEGINNING_DOTS_BUTTON);\n        var endingDotsButton = root.find(SELECTORS.ENDING_DOTS_BUTTON);\n\n        var pages = root.find(SELECTORS.PAGE);\n        var barSize = parseInt(root.attr('data-bar-size'), 10);\n\n        if (barSize && lastPageNumber > barSize) {\n\n            var minpage = Math.max(activePageNumber - Math.round(barSize / 2), 1);\n            var maxpage = minpage + barSize - 1;\n\n            if (maxpage >= lastPageNumber) {\n                maxpage = lastPageNumber;\n                minpage = maxpage - barSize + 1;\n            }\n\n            if (minpage > 1) {\n                show(beginningDotsButton);\n                minpage++;\n            } else {\n                hide(beginningDotsButton);\n            }\n            if (maxpage < lastPageNumber) {\n                show(endingDotsButton);\n                maxpage--;\n            } else {\n                hide(endingDotsButton);\n            }\n            dotsButtons.addClass('disabled');\n            dotsButtons.attr('aria-disabled', true);\n\n            hide(pages);\n\n            pages.each(function(index, page) {\n                page = $(page);\n                if ((index + 1) >= minpage && (index + 1) <= maxpage) {\n                    show(page);\n                }\n            });\n\n        } else {\n            hide(dotsButtons);\n        }\n    };\n\n    /**\n     * Enable the previous and first buttons in the paging bar.\n     *\n     * @param {object} root The root element.\n     */\n    var enablePreviousControlButtons = function(root) {\n        var previousButton = root.find(SELECTORS.PREVIOUS_BUTTON);\n        var firstButton = root.find(SELECTORS.FIRST_BUTTON);\n\n        previousButton.removeClass('disabled');\n        previousButton.removeAttr('aria-disabled');\n        firstButton.removeClass('disabled');\n        firstButton.removeAttr('aria-disabled');\n    };\n\n    /**\n     * Get the components for a get_string request for the aria-label\n     * on a page. The value is a comma separated string of key and\n     * component.\n     *\n     * @param {object} root The root element.\n     * @return {array} First element is the key, second is the component.\n     */\n    var getPageAriaLabelComponents = function(root) {\n        var componentString = root.attr('data-aria-label-components-pagination-item');\n        var components = componentString.split(',').map(function(component) {\n            return component.trim();\n        });\n        return components;\n    };\n\n    /**\n     * Get the components for a get_string request for the aria-label\n     * on an active page. The value is a comma separated string of key and\n     * component.\n     *\n     * @param {object} root The root element.\n     * @return {array} First element is the key, second is the component.\n     */\n    var getActivePageAriaLabelComponents = function(root) {\n        var componentString = root.attr('data-aria-label-components-pagination-active-item');\n        var components = componentString.split(',').map(function(component) {\n            return component.trim();\n        });\n        return components;\n    };\n\n    /**\n     * Set page numbers on each of the given items. Page numbers are set\n     * from 1..n (where n is the number of items).\n     *\n     * Sets the active page number to be the last page found with\n     * an \"active\" class (if any).\n     *\n     * Sets the last page number.\n     *\n     * @param {object} root The root element.\n     * @param {jQuery} items A jQuery list of items.\n     */\n    var generatePageNumbers = function(root, items) {\n        var lastPageNumber = 0;\n        setActivePageNumber(root, 0);\n\n        items.each(function(index, item) {\n            var pageNumber = index + 1;\n            item = $(item);\n            item.attr('data-page-number', pageNumber);\n            lastPageNumber++;\n\n            if (item.hasClass('active')) {\n                setActivePageNumber(root, pageNumber);\n            }\n        });\n\n        setLastPageNumber(root, lastPageNumber);\n    };\n\n    /**\n     * Set the aria-labels on each of the page items in the paging bar.\n     * This includes the next, previous, first, and last items.\n     *\n     * @param {object} root The root element.\n     */\n    var generateAriaLabels = function(root) {\n        var pageAriaLabelComponents = getPageAriaLabelComponents(root);\n        var activePageAriaLabelComponents = getActivePageAriaLabelComponents(root);\n        var activePageNumber = getActivePageNumber(root);\n        var pageItems = root.find(SELECTORS.PAGE_ITEM);\n        // We want to request all of the strings at once rather than\n        // one at a time.\n        var stringRequests = pageItems.toArray().map(function(index, page) {\n            page = $(page);\n            var pageNumber = getPageNumber(root, page);\n\n            if (pageNumber === activePageNumber) {\n                return {\n                    key: activePageAriaLabelComponents[0],\n                    component: activePageAriaLabelComponents[1],\n                    param: pageNumber\n                };\n            } else {\n                return {\n                    key: pageAriaLabelComponents[0],\n                    component: pageAriaLabelComponents[1],\n                    param: pageNumber\n                };\n            }\n        });\n\n        Str.get_strings(stringRequests).then(function(strings) {\n            pageItems.each(function(index, page) {\n                page = $(page);\n                var string = strings[index];\n                page.attr('aria-label', string);\n                page.find(SELECTORS.PAGE_LINK).attr('aria-label', string);\n            });\n\n            return strings;\n        })\n        .catch(function() {\n            // No need to interrupt the page if we can't load the aria lang strings.\n            return;\n        });\n    };\n\n    /**\n     * Make the paging bar item for the given page number visible and fire\n     * the SHOW_PAGES paged content event to tell any listening content to\n     * update.\n     *\n     * @param {object} root The root element.\n     * @param {Number} pageNumber The number for the page to show.\n     * @param {string} id A uniqie id for this instance.\n     */\n    var showPage = function(root, pageNumber, id) {\n        var pendingPromise = new Pending('core/paged_content_paging_bar:showPage');\n        var lastPageNumber = getLastPageNumber(root);\n        var isSamePage = pageNumber == getActivePageNumber(root);\n        var limit = getLimit(root);\n        var offset = (pageNumber - 1) * limit;\n\n        if (!isSamePage) {\n            // We only need to toggle the active class if the user didn't click\n            // on the already active page.\n            root.find(SELECTORS.PAGE_ITEM).removeClass('active').removeAttr('aria-current');\n            var page = getPageByNumber(root, pageNumber);\n            page.addClass('active');\n            page.attr('aria-current', true);\n            setActivePageNumber(root, pageNumber);\n\n            adjustPagingBarSize(root);\n        }\n\n        // Make sure the control buttons are disabled as the user navigates\n        // to either end of the limits.\n        if (lastPageNumber && pageNumber >= lastPageNumber) {\n            disableNextControlButtons(root);\n        } else {\n            enableNextControlButtons(root);\n        }\n\n        if (pageNumber > 1) {\n            enablePreviousControlButtons(root);\n        } else {\n            disablePreviousControlButtons(root);\n        }\n\n        generateAriaLabels(root);\n\n        // This event requires a payload that contains a list of all pages that\n        // were activated. In the case of the paging bar we only show one page at\n        // a time.\n        PubSub.publish(id + PagedContentEvents.SHOW_PAGES, [{\n            pageNumber: pageNumber,\n            limit: limit,\n            offset: offset\n        }]);\n\n        pendingPromise.resolve();\n    };\n\n    /**\n     * Add event listeners for interactions with the paging bar as well as listening\n     * for custom paged content events.\n     *\n     * Each event will trigger different logic to update parts of the paging bar's\n     * display.\n     *\n     * @param {object} root The root element.\n     * @param {string} id A uniqie id for this instance.\n     */\n    var registerEventListeners = function(root, id) {\n        var ignoreControlWhileLoading = root.attr('data-ignore-control-while-loading');\n        var loading = false;\n\n        if (ignoreControlWhileLoading == \"\") {\n            // Default to ignoring control while loading if not specified.\n            ignoreControlWhileLoading = true;\n        }\n\n        CustomEvents.define(root, [\n            CustomEvents.events.activate\n        ]);\n\n        root.on(CustomEvents.events.activate, SELECTORS.PAGE_ITEM, function(e, data) {\n            data.originalEvent.preventDefault();\n            data.originalEvent.stopPropagation();\n\n            if (ignoreControlWhileLoading && loading) {\n                // Do nothing if configured to ignore control while loading.\n                return;\n            }\n\n            var page = $(e.target).closest(SELECTORS.PAGE_ITEM);\n\n            if (!page.hasClass('disabled')) {\n                var pageNumber = getPageNumber(root, page);\n                showPage(root, pageNumber, id);\n                loading = true;\n            }\n        });\n\n        // This event is fired when all of the items have been loaded. Typically used\n        // in an \"infinite\" pages context when we don't know the exact number of pages\n        // ahead of time.\n        PubSub.subscribe(id + PagedContentEvents.ALL_ITEMS_LOADED, function(pageNumber) {\n            loading = false;\n            var currentLastPage = getLastPageNumber(root);\n\n            if (!currentLastPage || pageNumber < currentLastPage) {\n                // Somehow the value we've got saved is higher than the new\n                // value we just received. Perhaps events came out of order.\n                // In any case, save the lowest value.\n                setLastPageNumber(root, pageNumber);\n            }\n\n            if (pageNumber === 1 && root.attr('data-hide-control-on-single-page')) {\n                // If all items were loaded on the first page then we can hide\n                // the paging bar because there are no other pages to load.\n                hide(root);\n                disableNextControlButtons(root);\n                disablePreviousControlButtons(root);\n            } else {\n                show(root);\n                disableNextControlButtons(root);\n            }\n        });\n\n        // This event is fired after all of the requested pages have been rendered.\n        PubSub.subscribe(id + PagedContentEvents.PAGES_SHOWN, function() {\n            // All pages have been shown so turn off the loading flag.\n            loading = false;\n        });\n\n        // This is triggered when the paging limit is modified.\n        PubSub.subscribe(id + PagedContentEvents.SET_ITEMS_PER_PAGE_LIMIT, function(limit) {\n            // Update the limit.\n            setLimit(root, limit);\n            setLastPageNumber(root, 0);\n            setActivePageNumber(root, 0);\n            show(root);\n            // Reload the data from page 1 again.\n            showPage(root, 1, id);\n        });\n    };\n\n    /**\n     * Initialise the paging bar.\n     * @param {object} root The root element.\n     * @param {string} id A uniqie id for this instance.\n     */\n    var init = function(root, id) {\n        root = $(root);\n        var pages = root.find(SELECTORS.PAGE);\n        generatePageNumbers(root, pages);\n        registerEventListeners(root, id);\n\n        if (hasActivePageNumber(root)) {\n            var activePageNumber = getActivePageNumber(root);\n            // If the the paging bar was rendered with an active page selected\n            // then make sure we fired off the event to tell the content page to\n            // show.\n            getPageByNumber(root, activePageNumber).click();\n            if (activePageNumber == 1) {\n                // If the first page is active then disable the previous buttons.\n                disablePreviousControlButtons(root);\n            }\n        } else {\n            // There was no active page number so load the first page using\n            // the next button. This allows the infinite pagination to work.\n            getNextButton(root).click();\n        }\n\n        adjustPagingBarSize(root);\n    };\n\n    return {\n        init: init,\n        disableNextControlButtons: disableNextControlButtons,\n        enableNextControlButtons: enableNextControlButtons,\n        disablePreviousControlButtons: disablePreviousControlButtons,\n        enablePreviousControlButtons: enablePreviousControlButtons,\n        showPage: showPage,\n        rootSelector: SELECTORS.ROOT,\n    };\n});\n"],"names":["define","$","CustomEvents","PagedContentEvents","Str","PubSub","Pending","SELECTORS","getPageByNumber","root","pageNumber","find","setLastPageNumber","number","attr","getLastPageNumber","parseInt","getActivePageNumber","setActivePageNumber","getPageNumber","page","undefined","activePageNumber","lastPage","show","removeClass","hide","addClass","disableNextControlButtons","nextButton","lastButton","enableNextControlButtons","removeAttr","disablePreviousControlButtons","previousButton","firstButton","adjustPagingBarSize","lastPageNumber","dotsButtons","beginningDotsButton","endingDotsButton","pages","barSize","minpage","Math","max","round","maxpage","each","index","enablePreviousControlButtons","showPage","id","pendingPromise","isSamePage","limit","getLimit","offset","pageAriaLabelComponents","split","map","component","trim","getPageAriaLabelComponents","activePageAriaLabelComponents","getActivePageAriaLabelComponents","pageItems","stringRequests","toArray","key","param","get_strings","then","strings","string","catch","generateAriaLabels","publish","SHOW_PAGES","resolve","init","items","item","hasClass","generatePageNumbers","ignoreControlWhileLoading","loading","events","activate","on","e","data","originalEvent","preventDefault","stopPropagation","target","closest","subscribe","ALL_ITEMS_LOADED","currentLastPage","PAGES_SHOWN","SET_ITEMS_PER_PAGE_LIMIT","setLimit","registerEventListeners","isNaN","hasActivePageNumber","click","getNextButton","rootSelector"],"mappings":"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"}