Viewing File: /usr/local/cpanel/base/cjt/ui/widgets/pager.js

/*
#                                                 Copyright(c) 2020 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

// check to be sure the CPANEL global object already exists
if (typeof(CPANEL) === "undefined" || !CPANEL) {
    alert('You must include the CPANEL global object before including ui/widgits/pager.js!');
} else {

    (function() {

        // Define the namespace for this module
        CPANEL.namespace("CPANEL.ui.widgets");

        /**
    The pager module contains pager related objects used in cPanel.
    @module CPANEL.ui.widgets.pager
    */

        if (typeof(CPANEL.ui.widgets.pager) === 'undefined') {

            /**
        The PageActions enum contains the defined action flags reported to
        various action callbacks used by the PageManager class during events.
        @enum
        @static
        @class PagerActions
        @namespace CPANEL.ui.widgets */
            var PagerActions = {
                /**
            Signals to registered callbacks that this is a page size change event.
            @static
            @class PagerActions
            @property  CHANGE_PAGE_SIZE */
                CHANGE_PAGE_SIZE: 1,
                /**
            Signals to registered callbacks that this is a go to page event.
            @static
            @class PagerActions
            @property  CHANGE_PAGE_SIZE */
                GO_TO_PAGE: 2,
                /**
            Signals to registered callbacks that this is a show all event.
            @static
            @class PagerActions
            @property  CHANGE_PAGE_SIZE */
                SHOW_ALL: 4,
                /**
            Signals to registered callbacks that this is a clear filter event.
            @static
            @class PagerActions
            @property  CHANGE_PAGE_SIZE */
                CLEAR_FILTER: 8,
                /**
            Signals to registered callbacks that this is a clear sort event.
            @static
            @class PagerActions
            @property  CHANGE_PAGE_SIZE */
                CLEAR_SORT: 16,
                /**
            Signals to registered callbacks that this is a change filter event.
            @static
            @class PagerActions
            @property  CHANGE_FILTER */
                CHANGE_FILTER: 32,
                /**
            Signals to registered callbacks that this is a change sort event.
            @static
            @class PagerActions
            @property  CHANGE_SORT */
                CHANGE_SORT: 64
            };

            /**
        This class manages the parameters associated with each pager defined on a page. I is used as part of the
        common pagination system.
        @enum
        @static
        @class PagerManager
        @namespace CPANEL.ui.widgets */
            var PagerManager = function() {
                this.cache = {};
            };

            PagerManager.prototype = {
                /**
                 * Call back called before the manager fires an action.
                 * @class PagerManager
                 * @event
                 * @name beforeAction
                 * @param [String] scope- Unique name of the pager being initilized.
                 * @param [Hash] container - reference to the settings for the current pager.
                 * @param [PagerActions] action
                 */

                /**
                 * Call back called after the manager fires an action.
                 * @class PagerManager
                 * @event
                 * @name afterAction
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Hash] container - reference to the settings for the current pager.
                 * @param [PagerActions] action
                 */

                /**
                 * Initialize the PageManager object for a specific scope
                 * @class PagerManager
                 * @name initialize
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [String] url - Optional alternative url. If same page, leave null.
                 * @param [Hash] params - Initial values for parameters passed to the url.
                 * @param [String] method - Either GET or POST
                 * @param [Hash] callbacks - Hash containing optional callbacks
                 *     Supported eveents include:
                 *     beforeAction - Called before the action triggers
                 *     afterAction - Called after the action triggers
                 */
                initialize: function(scope, url, params, method, callbacks) {
                    var container = {
                        url: url || "",
                        params: params || {},
                        method: method || "GET",
                        callbacks: {}
                    };

                    if (callbacks) {
                        if (callbacks.beforeAction) {
                            container.callback.beforeAction = callbacks.beforeAction;
                        }
                        if (callbacks.afterAction) {
                            container.callback.afterAction = callbacks.afterAction;
                        }
                    }

                    this.cache[scope] = container;
                },

                /**
                 * Sets the callbacks for a specific pager.
                 * @class PagerManager
                 * @name setCallback
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Hash] callbacks - Hash containing optional callbacks
                 *     Supported eveents include:
                 *     beforeAction - Called before the action triggers
                 *     afterAction - Called after the action triggers
                 */
                setCallback: function(scope, callbacks) {
                    var container = this.cache[scope];
                    if (container && callbacks) {
                        if (callbacks.beforeAction) {
                            container.callback.beforeAction = callbacks.beforeAction;
                        }
                        if (callbacks.afterAction) {
                            container.callback.afterAction = callbacks.afterAction;
                        }
                    }
                },

                /**
                 * Sets the parameters for a specific pager.
                 * @class PagerManager
                 * @name setParameters
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Hash] params - Name value pairs that you want to set. Items in the current params cache that are not specified in this argument are not changed or removed.
                 */
                setParameters: function(scope, params) {
                    if (params) {
                        var container = this.cache[scope];
                        for (var p in params) {
                            container.params[p] = params[p];
                        }
                    }
                },

                /**
                 * Gets the parameters for a specific pager.
                 * @class PagerManager
                 * @name getParameters
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Array] params - Names of the paramters you want to get.
                 * @return [Hash] - name value pairs in a hash.
                 */
                getParameters: function(scope, params) {
                    var output = {};
                    if (params) {
                        var container = this.cache[scope];
                        for (var i = 0, l = params.length; i < l; i++) {
                            var key = params[i];
                            output[key] = container.params[key];
                        }
                    }
                    return output;
                },
                /**
                 * Sets the specific parameter to the specific value for a specific pager.
                 * @class PagerManager
                 * @name setParameter
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [String] name - Name of the parameter to set.
                 * @param [String] value - Value of the paramter.
                 */
                setParameter: function(scope, name, value) {
                    var container = this.cache[scope];
                    container.params[name] = value;
                },
                /**
                 * Gets the specific parameter for a specific pager.
                 * @class PagerManager
                 * @name getParameter
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [String] name - Name of the parameter to set.
                 *
                 */
                getParameter: function(scope, name) {
                    var container = this.cache[scope];
                    return container.params[name];
                },
                /**
                 * Fires the go to page event.
                 * @class PagerManager
                 * @name fireGoToPage
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Number] start - Start index of first item on a page...
                 * @param [Number] page - Page to go to.
                 * @param [Number] skip - Number of pages to skip.
                 * @note There is signifigant data redundancy in the current implementation to track
                 * all three of these, likely only one is needed, but there seems to be dependancies
                 * on each in various code modules. Consider refactoring this when we have more time.
                 * @refactor
                 */
                fireGoToPage: function(scope, start, page, skip) {
                    var container = this.cache[scope];
                    container.params["api2_paginate_start"] = start;
                    container.params["page"] = page;
                    container.params["skip"] = skip;
                    return this.fireAction(scope, container, PagerActions.GO_TO_PAGE);
                },
                /**
                 * Fires the change items per page event.
                 * @class PagerManager
                 * @name fireChangePageSize
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Number] itemsperpage - Number of items per page.
                 */
                fireChangePageSize: function(scope, itemsperpage, submit) {
                    var container = this.cache[scope];
                    container.params["itemsperpage"] = itemsperpage;
                    if (submit) {
                        return this.fireAction(scope, container, PagerActions.CHANGE_PAGE_SIZE);
                    }
                    return true;
                },
                /**
                 * Fires the show all pages event.
                 * @class PagerManager
                 * @name fireShowAll
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Boolean] clearFilterSort - If true clear the filter and sort, otherwise, leaves them in tact.
                 *  Must implement this action on the server.
                 */
                fireShowAll: function(scope, clearFilterSort) {
                    var container = this.cache[scope];
                    container.params["viewall"] = clearFilterSort ? "1" : "0";
                    return this.fireAction(scope, container, clearFilterSort ? PagerActions.SHOW_ALL | PagerActions.CLEAR_FILTER | PagerActions.CLEAR_SORT : PagerActions.SHOW_ALL);
                },
                /**
                 * Fires the change page filter event.
                 * @class PagerManager
                 * @name fireChangeFilter
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [String] searchregex - The new search expression.
                 * @param [Hash] params - Additional name/value pairs to add to the request, normally additional or custom filter tags.
                 */
                fireChangeFilter: function(scope, searchregex, params) {
                    var container = this.cache[scope];
                    container.params["searchregex"] = searchregex;
                    // Merge in the additianal parameters
                    for (var p in params) {
                        container.params[p] = params[p];
                    }
                    return this.fireAction(scope, container, PagerActions.CHANGE_FILTER);
                },
                /**
                 * Fires the change page sort event.
                 * @class PagerManager
                 * @name fireChangeSort
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [String] column - The name of the column to sort on.
                 * @param [String] direction - Either 'ascending' or 'descending'.
                 * @param [Hash] params - Additional name/value pairs to add to the request, normally additional or custom filter tags.
                 */
                fireChangeSort: function(scope, column, direction, params) {
                    var container = this.cache[scope];
                    container.params["api2_sort_column"] = column;
                    container.params["api2_sort_reverse"] = direction;
                    // Merge in the additianal parameters
                    for (var p in params) {
                        container.params[p] = params[p];
                    }
                    return this.fireAction(scope, container, PagerActions.CHANGE_SORT);
                },
                /**
                 * Fires the specified event including any optional beforeAction() and afterAction()
                 * handlers.
                 * @class PagerManager
                 * @name fireAction
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @param [Object] container - Container for this scope holding all the arguments for the call
                 * @param [PagerAction] action - Action triggering this event.
                 */
                fireAction: function(scope, container, action) {
                    var cancel = false;

                    // Call the before action handler if its available
                    if (container.callbacks["beforeAction"]) {
                        cancel = container.callbacks["beforeAction"](scope, container, action);
                    }

                    if (cancel) {
                        return false;
                    }

                    var href = container.href || window.location.href.split('?')[0];
                    if (container.method == "GET") {
                        window.location = this._makeQuery(href, this._getQuery(container));
                    } else if (container.method === "POST") {
                        var form = this._buildForm(url, container.params);
                        if (form) {
                            form.submit();
                        }
                    }

                    // Call the after action handler if its available
                    if (container.callbacks["afterAction"]) {
                        container.callbacks["afterAction"](scope, container, action);
                    }
                    return true;
                },
                /**
                 * Converts the cached parameters into a URL querystring.
                 * @class PagerManager
                 * @name getQuery
                 * @param [String] scope - Unique name of the pager being initilized.
                 * @return [String] - Query string generated from the current list of parameters for the specificed pager.
                 */
                getQuery: function(scope) {
                    var container = this.cache[scope];
                    return this._getQuery(container);
                },
                /**
                 * Converts the cached parameters into a URL querystring.
                 * @private
                 * @class PagerManager
                 * @name _getQuery
                 * @param [Object] container - Container with parameters for a given scope.
                 * @return [String] - Query string generated from the current list of parameters for the specificed pager.
                 */
                _getQuery: function(container) {
                    return this._serialize(container.params);
                },
                /**
                 * Builds a complete url for a GET call
                 * @private
                 * @class PagerManager
                 * @name _makeQuery
                 * @param [String] url
                 * @param [String] query
                 * @return [String] full URL.
                 */
                _makeQuery: function(url, query) {
                    return url + (query ? "?" + query : "");
                },
                /**
                 * Builds a complete form to submit via post. First checks to see if
                 * there is an old version of itself and removes it. It the injects the
                 * form into the DOM and returns a reference to it.
                 * @private
                 * @class PagerManager
                 * @name _buildForm
                 * @param [String] url
                 * @param [String] params
                 * @return [HTMLElement] form element generated for the url and parameters.
                 */
                _buildForm: function(url, params) {
                    var form = document.createElement("form");
                    form.href = url;
                    form.method = "POST";
                    form.id = scope + "-page-form";
                    for (var param in params) {
                        if (typeof(param) === "string") {
                            var input = document.createElement("input");
                            input.type = "hidden";
                            input.id = scope + "-page-param-" + param;
                            input.name = param;
                            input.value = params[param];
                            form.appendChild(input);
                        }
                    }

                    // Remove the older version of it so we don't bloat the webpage
                    var oldForm = document.getElementById(form.id);
                    if (oldForm) {
                        this._removeElement(oldForm);
                    }

                    // Inject it into the document so its live
                    document.appendChild(form);
                    return form;
                },
                /**
                 * Converts a hash into a URI compatible query string.
                 * @private
                 * @class PagerManager
                 * @name _serialize
                 * @param [Hash] obj
                 * @return [String] URI compatible querystring.
                 * @source http://stackoverflow.com/questions/1714786/querystring-encoding-of-a-javascript-object
                 */
                _serialize: function(obj) {
                    var str = [];
                    for (var p in obj)
                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                    return str.join("&");
                },
                /**
                 * Removes the element from it parent node if it has a parent.
                 * @private
                 * @class PagerManager
                 * @name _removeElement
                 * @param [HTMLElement] el
                 */
                _removeElement: function(el) {
                    var parent = el.parentNode;
                    if (parent) {
                        parent.removeChild(el);
                    }
                }
            };

            // Exports
            CPANEL.ui.widgets.PagerActions = PagerActions;
            CPANEL.ui.widgets.pager = new PagerManager();
        }

    })();
}
Back to Directory File Manager