{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/1.2.0/actions/sort/sort.action.js","webpack:///./src/1.2.0/actions/pagination/pagination.action.js","webpack:///./src/1.2.0/controls/base/controls/base.control.js","webpack:///./src/1.2.0/services/deep-links.service.js","webpack:///./src/1.2.0/services/storage.service.js","webpack:///./src/1.2.0/actions/filter/filter.action.js","webpack:///./src/1.2.0/content/content-manager.js","webpack:///./src/1.2.0/controls/base/groups/base-controls-group.js","webpack:///./src/1.2.0/controls/base/controls/sort/base-sort.control.js","webpack:///./src/1.2.0/controls/base/groups/sort/base-sort-controls-group.js","webpack:///./src/1.2.0/controls/sort/hidden-sort/hidden-sort.control.js","webpack:///./src/1.2.0/controls/sort/buttons-sort/buttons-sort.control.js","webpack:///./src/1.2.0/controls/sort/radio-buttons-sort/radio-buttons-sort.control.js","webpack:///./src/1.2.0/controls/sort/checkbox-sort/checkbox-sort.control.js","webpack:///./src/1.2.0/controls/sort/select-sort/select-sort.control.js","webpack:///./src/1.2.0/controls/base/controls/dropdown/base-dropdown.control.js","webpack:///./src/1.2.0/controls/sort/dropdown-sort/dropdown-sort.control.js","webpack:///./src/1.2.0/controls/base/controls/pagination/base-pagination.control.js","webpack:///./src/1.2.0/controls/base/groups/pagination/base-pagination-controls-group.js","webpack:///./src/1.2.0/controls/pagination/pagination.control.js","webpack:///./src/1.2.0/controls/base/controls/filter/base-text-filter.control.js","webpack:///./src/1.2.0/controls/base/groups/filter/base-text-filter-controls-group.js","webpack:///./src/1.2.0/controls/filter/text-filters/textbox-filter/textbox-filter.control.js","webpack:///./src/1.2.0/controls/base/groups/mixins/checkbox.mixin.js","webpack:///./src/1.2.0/controls/filter/text-filters/checkbox-text-filter/checkbox-text-filter.control.js","webpack:///./src/1.2.0/controls/base/groups/mixins/radio-buttons.mixin.js","webpack:///./src/1.2.0/controls/filter/text-filters/radio-buttons-text-filter/radio-buttons-text-filter.control.js","webpack:///./src/1.2.0/controls/base/groups/mixins/buttons.mixin.js","webpack:///./src/1.2.0/controls/filter/text-filters/buttons-text-filter/buttons-text-filter.control.js","webpack:///./src/1.2.0/controls/base/controls/filter/base-path-filter.control.js","webpack:///./src/1.2.0/controls/base/groups/filter/base-path-filter-controls-group.js","webpack:///./src/1.2.0/controls/filter/path-filters/select-filter/select-filter.control.js","webpack:///./src/1.2.0/controls/filter/path-filters/checkbox-path-filter/checkbox-path-filter.control.js","webpack:///./src/1.2.0/controls/filter/path-filters/radio-buttons-path-filter/radio-buttons-path-filter.control.js","webpack:///./src/1.2.0/controls/filter/path-filters/buttons-path-filter/buttons-path-filter.control.js","webpack:///./src/1.2.0/controls/filter/path-filters/dropdown-filter/dropdown-filter.control.js","webpack:///./src/1.2.0/controls/base/controls/filter/base-range-filter.control.js","webpack:///./src/1.2.0/controls/base/groups/filter/base-range-filter-controls-group.js","webpack:///./src/1.2.0/controls/filter/range-filters/buttons-range-filter/buttons-range-filter.control.js","webpack:///./src/1.2.0/controls/base/controls/slider/base-slider.control.js","webpack:///./src/1.2.0/controls/filter/range-filters/slider-range-filter/slider-range-filter.control.js","webpack:///./src/1.2.0/controls/no-results/no-results.control.js","webpack:///./src/1.2.0/controls/layout/layout.control.js","webpack:///./src/1.2.0/controls/reset/reset.control.js","webpack:///./src/1.2.0/controls/counter/counter.control.js","webpack:///./src/1.2.0/index.js","webpack:///./src/1.2.0/jplist.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","SortAction","[object Object]","items","options","length","sort","item1","item2","sortByIndex","sortHelper","optionsIndex","result","option","path","dataType","sortNumbers","order","sortDateTime","dateTimeFormat","sortText","ignoreRegex","el1","querySelector","el2","text1","textContent","trim","toLowerCase","text2","regexExpr","RegExp","replace","localeCompare","number1","number2","parseFloat","isNaN","Number","jplistIndex","months","date1","date2","datetime1","datetime2","getDateFromString","Date","parse","getTime","dateTimeString","year","getDateWildcardValue","day","month","getMonthByWildcard","hour","minute","second","wildcard","datetimeString","regexValue","match","exec","monthNumberOrName","monthIndex","findIndex","monthAliasesArray","find","monthAlias","sort_action","pagination_action","currentPage","itemsPerPage","itemsNumber","range","this","isInteger","pagesNumber","Math","ceil","start","end","prevPage","nextPage","halfRange","rangeStart","rangeEnd","min","max","base_control","element","initialHTML","outerHTML","type","getAttribute","group","id","jump","DeepLinksService","param","parts","split","key","hash","hashStart","paramsMap","Map","formattedHash","window","decodeURIComponent","params","currentGroupName","pair","getParam","has","set","groupValues","push","deep_links_service","StorageService","storage","e","deepLink","expiration","cValue","encodeURIComponent","exdate","document","cookie","setMinutes","getMinutes","toUTCString","isSupported","cookies","x","substr","indexOf","y","storage_service","FilterAction","text","mode","filtered","formattedText","item","elements","querySelectorAll","shouldBeAdded","el","elText","startsWith","endsWith","isInverted","isFinite","from","to","itemElements","numbers","num","maxNumber","apply","minNumber","isNumeric","filter_action","content_manager_ContentManager","settings","controls","groups","groupName","target","filters","cGroupName","groupValueArr","baseControlsGroups","collectControlsOptions","itemsBlock","fragment","getItemsFragment","sortOptions","filter","filterName","splitted","splitByLogic","handleFilter","and","orOptionsGroupName","or","paginationOptions","paginationAction","bcg","setPaginationOptions","paginatedItems","slice","root","appendChild","sendStateEvent","deepLinking","updateDeepLink","getDeepLink","storageName","cookiesExpiration","filterType","textFilter","pathFilter","rangeFilter","logic","performFilter","orFiltered","Set","temp","Array","orName","undefined","top","jumpEl","jumpElRect","getBoundingClientRect","width","height","getClientRects","clientTop","body","pageYOffset","scroll","stateEvent","CustomEvent","jplistState","baseControlsGroup","control","dispatchEvent","textFilterOptions","pathFilterOptions","rangeFilterOptions","getSortOptions","concat","getTextFilterOptions","getPathFilterOptions","getRangeFilterOptions","getPaginationOptions","createDocumentFragment","hashStr","location","index","href","substring","history","replaceState","deeplink","keys","deepLinkParts","dl","join","groupsMap","groupElements","groupElement","groupValue","controlInstance","map","arr","deepLinkParams","getUrlParams","deepLinkSavedInStorage","jplist","controlTypes","controlClass","controlGroup","addControl","res","findControls","controlsByGroupNames","findControlGroups","groupControls","sameNameControls","findSameNameControls","values","content_manager","base_controls_group","base_sort_control","super","regex","multipleSortsNumber","getMultipleSortsNumber","pathsNumber","attr","attributes","nodeName","propIndex","baseSortControl","isEqual","props","k","base_sort_controls_group","hidden_sort_control","buttons_sort_control_SELECTED_CLASS","buttons_sort_control","checkboxes","radios","selected","deepLinkParam","handleRadios","handleCheckboxes","addEventListener","preventDefault","forEach","cb","isEqualTo","radio","refresh","classList","add","remove","latestSelectedRadio","getLastSelectedRadio","checked","atLeastOneNotSelectedCheckbox","checkbox","cbArr","str","radioArr","combined","radio_buttons_sort_control_SELECTED_CLASS","radio_buttons_sort_control","checkbox_sort_control_SELECTED_CLASS","checkbox_sort_control","select_sort_control","setAttribute","opt","select","dropdown_base_dropdown_control","panels","openedClass","panel","initialContent","innerHTML","contents","handlePanelsClick","atLeastOnePanelIsOpened","dropdownContent","toggle","contains","close","content","dropdown_sort_control_DropdownSortControl","dropdown","buttons","button","btnSortControl","setSelectedButton","getSelectedButton","deepLinkBtn","btn","btnValue","dropdownBtn","setPanelsContent","dropdown_sort_control","base_pagination_control","disabledClass","selectedClass","base_pagination_controls_group","basePaginationControl","pagination_control_PaginationControl","restoreFromDeepLink","pageButtonsHolder","btnTemplate","firstButtons","lastButtons","prevButtons","nextButtons","bindEventHandler","pageButtonClick","bind","itemsPerPageSelects","updateItemsPerPageSelect","itemsPerPageDD","initCustomDropdowns","selectChange","labels","label","template","selects","toString","dd","selectedButton","firstChild","removeChild","div","createElement","pageButton","setPageAttr","infos","html","info","classesToRemove","className","pageNumber","page","isEnabled","eventName","func","pagination_control","base_text_filter_control","initialText","_text","includeValue","base_text_filter_controls_group","baseTextFilterControl","textbox_filter_control","textChanged","clearButtonID","clearBtn","getElementById","checkbox_mixin","superclass","baseControl","checkbox_text_filter_control","radio_buttons_mixin","radio_buttons_text_filter_control","buttons_mixin","baseButtonControl","buttons_text_filter_control","base_path_filter_control","base_path_filter_controls_group","basePathFilterControl","select_filter_control","selectFilterControl","checkbox_path_filter_control","radio_buttons_path_filter_control","buttons_path_filter_control","dropdown_filter_control_DropdownFilterControl","btnPathFilterControl","dropdown_filter_control","base_range_filter_control","Infinity","base_range_filter_controls_group","baseRangeFilterControl","buttons_range_filter_control","BaseSliderControl","isVertical","value1","value2","callback","handler1","left","handler2","dragging","render","resize","stop","setValues","sendCallback","pos1","getInnerValue","pos2","update","newStart","newEnd","position","getHandlerPos","abs","handler1ZIndex","getComputedStyle","defaultView","getPropertyValue","handler2ZIndex","style","stopPropagation","setZIndex","handler","rect","size","xy","lefttop","getPreviewValue","rangeHeight","v1","v2","point","touches","pageX","clientX","pageY","clientY","vector","sub","slider_base_slider_control","slider_range_filter_control","rangeSliderFilterControl","sliderEl","val1Elements","val2Elements","minElements","maxElements","orientation","slider","round","controlOptions","no_results_control","display","layout_control_SELECTED_CLASS","layout_control_LayoutControl","classNames","selectedClassName","groupClassName","handleSelectedControls","handleClasses","resetAllGroups","getLatestSelectedControl","addClassToGroups","cn","selectedGroupClassName","layout_control","reset_control","resetControls","counter_control_CounterControl","baseFilterControl","getFilteredItems","count","countValue","format","getStaticCounterValue","getDynamicCounterValue","counter_control","event","bubbles","cancelable","detail","evt","createEvent","initCustomEvent","Event","assign","splitByGroupAndName","findGroups","controlIndex","oldElement","newElement","parentNode","replaceChild","splice","init","resetControl"],"mappings":"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","file":"jplist-es6.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/**\n * sort action\n */\nclass SortAction{\n\n /**\n * general multiple sort\n * @param {Array.} items\n * @param {Array.<{path: string, dataType: text|number|datetime, order: asc|desc, ignoreRegex: string, dateTimeFormat: string}>} options\n * if path = 'default' - the original sort should be kept\n * @return {Array.} sorted items\n */\n static sort(items, options){\n\n if(!options || options.length <= 0){\n\n /**\n * if no options - return to the default browser sort order\n */\n items.sort((item1, item2) => {\n return SortAction.sortByIndex(item1, item2);\n });\n\n return items;\n }\n\n items.sort((item1, item2) => {\n\n /**\n * start recursive helper\n */\n return SortAction.sortHelper(item1, item2, options, 0);\n });\n\n return items;\n }\n\n /**\n * recursive sort helper\n * @param {HTMLElement} item1\n * @param {HTMLElement} item2\n * @param {Array.} options - structure: {path: string, dataType: text|number|datetime, order: asc|desc, ignoreRegex: string, dateTimeFormat: string}\n * @param {number} optionsIndex\n * @return {number} - 0 if equal, <0 if item1 < item2, >0 if item1 > item2\n */\n static sortHelper(item1, item2, options, optionsIndex){\n\n if(!options || options.length <= 0 || optionsIndex >= options.length){\n return 0;\n }\n\n let result = 0;\n\n const option = options[optionsIndex];\n\n if(option.path !== 'default'){\n\n switch(option.dataType){\n\n case 'number': {\n result = SortAction.sortNumbers(item1, item2, option.path, option.order);\n break;\n }\n\n case 'datetime': {\n result = SortAction.sortDateTime(item1, item2, option.path, option.order, option.dateTimeFormat);\n break;\n }\n\n default: {\n result = SortAction.sortText(item1, item2, option.path, option.order, option.ignoreRegex);\n break;\n }\n }\n }\n else{\n result = SortAction.sortByIndex(item1, item2);\n }\n\n if(result === 0 && optionsIndex + 1 < options.length){\n\n //get next result recursive\n result = SortAction.sortHelper(item1, item2, options, optionsIndex + 1);\n }\n\n return result;\n }\n\n /**\n * sort texts\n * @param {HTMLElement} item1\n * @param {HTMLElement} item2\n * @param {string=} path - can be any CSS selector - https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors;\n * empty path means the whole element; path shouldn't have 'default' value\n * @param {string=} order - asc or desc\n * @param {string=} ignoreRegex - optional regex that defines charaters that should be ignored before the sorting\n * @return {number} - 0 if equal, <0 if item1 < item2, >0 if item1 > item2\n */\n static sortText(item1, item2, path = '', order = 'asc', ignoreRegex = ''){\n\n if(!item1 || !item2){\n return 0;\n }\n\n //find elements with the content to sort\n const el1 = path ? item1.querySelector(path) : item1;\n const el2 = path ? item2.querySelector(path) : item2;\n\n if(!el1 || !el2){\n return 0;\n }\n\n let text1 = el1.textContent.trim().toLowerCase();\n let text2 = el2.textContent.trim().toLowerCase();\n\n if(ignoreRegex){\n\n //regex expression that is used to remove irrelevant characters\n const regexExpr = new RegExp(ignoreRegex, 'ig');\n text1 = text1.replace(regexExpr, '').trim();\n text2 = text2.replace(regexExpr, '').trim();\n }\n\n if(text1 === text2){\n return 0;\n }\n\n if(!order){\n order = 'asc';\n }\n\n //compare languages other than English\n if(''.localeCompare){\n\n if (order === 'asc') {\n return text1.localeCompare(text2);\n }\n else {\n return text2.localeCompare(text1);\n }\n }\n else{\n if (order === 'asc') {\n return text1 > text2 ? 1 : -1;\n }\n else {\n return text1 < text2 ? 1 : -1;\n }\n }\n }\n\n /**\n * sort numbers\n * @param {HTMLElement} item1\n * @param {HTMLElement} item2\n * @param {string=} path - can be any CSS selector - https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors;\n * empty path means the whole element; path shouldn't have 'default' value\n * @param {string=} order - asc or desc\n * @return {number} - 0 if equal, <0 if item1 < item2, >0 if item1 > item2\n */\n static sortNumbers(item1, item2, path = '', order = 'asc'){\n\n if(!item1 || !item2){\n return 0;\n }\n\n //find elements with the content to sort\n const el1 = path ? item1.querySelector(path) : item1;\n const el2 = path ? item2.querySelector(path) : item2;\n\n if(!el1 || !el2){\n return 0;\n }\n\n let number1 = el1.textContent.trim().toLowerCase();\n let number2 = el2.textContent.trim().toLowerCase();\n\n //remove other characters\n number1 = parseFloat(number1.replace(/[^-0-9.]+/g,''));\n number2 = parseFloat(number2.replace(/[^-0-9.]+/g,''));\n\n if(isNaN(number1) || isNaN(number2)){\n\n if(isNaN(number1) && isNaN(number2)){\n return 0;\n }\n else {\n return isNaN(number1) ? 1 : -1;\n }\n }\n\n if(number1 === number2){\n return 0;\n }\n\n if(!order){\n order = 'asc';\n }\n\n if(order === 'asc'){\n return number1 - number2;\n }\n else{\n return number2 - number1;\n }\n }\n\n\n /**\n * sort by initial element index\n * @param {HTMLElement} item1\n * @param {HTMLElement} item2\n * @return {number} - 0 if equal, <0 if item1 < item2, >0 if item1 > item2\n */\n static sortByIndex(item1, item2){\n\n if(!item1 || !item2){\n return 0;\n }\n\n let number1 = Number(item1.jplistIndex);\n let number2 = Number(item2.jplistIndex);\n\n if(isNaN(number1) || isNaN(number2)){\n return 0;\n }\n\n return number1 - number2;\n }\n\n // ---------------- DATE TIME ------------------------\n\n /**\n * month name that can be used in date time strings\n * from 0 for January to 11 for December\n * @returns {Array.>}\n */\n static get months() {\n\n return [\n ['january', 'jan', 'jan.'],\n ['february', 'feb', 'feb.'],\n ['march', 'mar', 'mar.'],\n ['april', 'apr', 'apr.'],\n ['may'],\n ['june', 'jun.'],\n ['july', 'jul', 'jul.'],\n ['august', 'aug', 'aug.'],\n ['september', 'sep', 'sep.'],\n ['october', 'oct', 'oct.'],\n ['november', 'nov', 'nov.'],\n ['december', 'dec', 'dec.']\n ];\n }\n\n /**\n * sort datetime\n * @param {HTMLElement} item1\n * @param {HTMLElement} item2\n * @param {string=} path - can be any CSS selector - https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors;\n * empty path means the whole element; path shouldn't have 'default' value;\n * @param {string=} order - asc or desc\n * @param {string=} dateTimeFormat - for example, {month}/{day}/{year}\n * @return {number} - 0 if equal, <0 if item1 < item2, >0 if item1 > item2\n */\n static sortDateTime(item1, item2, path = '', order = 'asc', dateTimeFormat = ''){\n\n if(!item1 || !item2){\n return 0;\n }\n\n //find elements with the content to sort\n const el1 = path ? item1.querySelector(path) : item1;\n const el2 = path ? item2.querySelector(path) : item2;\n\n if(!el1 || !el2){\n return 0;\n }\n\n let datetime1 = el1.textContent.trim().toLowerCase();\n let datetime2 = el2.textContent.trim().toLowerCase();\n\n let date1;\n let date2;\n\n dateTimeFormat = dateTimeFormat.trim();\n\n if(!dateTimeFormat){\n\n date1 = new Date(Date.parse(datetime1));\n date2 = new Date(Date.parse(datetime2));\n }\n else{\n date1 = SortAction.getDateFromString(datetime1, dateTimeFormat);\n date2 = SortAction.getDateFromString(datetime2, dateTimeFormat);\n }\n\n if(date1.getTime() === date2.getTime()){\n return 0;\n }\n\n if(!order){\n order = 'asc';\n }\n\n if(order === 'asc'){\n return date1.getTime() > date2.getTime() ? 1 : -1;\n }\n else{\n return date1.getTime() < date2.getTime() ? 1 : -1;\n }\n }\n\n /**\n * get date time from string that contains wildcards like {year}, {month}, {day}, {hour}, {min}, {sec}\n * @param {string} dateTimeString - for example, 01/12/2017\n * @param {string} dateTimeFormat - for example, {month}/{day}/{year}\n * @return {Date}\n */\n static getDateFromString(dateTimeString, dateTimeFormat){\n\n //remove special characters\n dateTimeFormat = dateTimeFormat.replace(/\\./g, '\\\\.');\n dateTimeFormat = dateTimeFormat.replace(/\\(/g, '\\\\(');\n dateTimeFormat = dateTimeFormat.replace(/\\)/g, '\\\\)');\n dateTimeFormat = dateTimeFormat.replace(/\\[/g, '\\\\[');\n dateTimeFormat = dateTimeFormat.replace(/\\]/g, '\\\\]');\n\n //get year\n let year = SortAction.getDateWildcardValue(dateTimeFormat, '{year}', dateTimeString);\n year = Number(year) || 1900;\n\n //get day\n let day = SortAction.getDateWildcardValue(dateTimeFormat, '{day}', dateTimeString);\n day = Number(day) || 1;\n\n //get month: integer value representing the month, beginning with 0 for January to 11 for December\n let month = SortAction.getDateWildcardValue(dateTimeFormat, '{month}', dateTimeString);\n month = SortAction.getMonthByWildcard(month);\n if(month === -1){\n month = 0;\n }\n\n //get hour: (0-23)\n let hour = SortAction.getDateWildcardValue(dateTimeFormat, '{hour}', dateTimeString);\n hour = Number(hour) || 0;\n\n //get minute: (0-59)\n let minute = SortAction.getDateWildcardValue(dateTimeFormat, '{min}', dateTimeString);\n minute = Number(minute) || 0;\n\n //get second: (0-59)\n let second = SortAction.getDateWildcardValue(dateTimeFormat, '{sec}', dateTimeString);\n second = Number(second) || 0;\n\n return new Date(year, month, day, hour, minute, second);\n }\n\n /**\n * get datetime format section/item\n * @param {string} dateTimeFormat - for example, {month}/{day}/{year} or any other string with wildcards; dateTimeFormat should not contain special characters like . ( ) [ ]\n * @param {string} wildcard - {year}|{month}|{day}|{hour}|{min}|{sec}\n * @param {string} datetimeString - for example, 01/15/2017\n * @return {string|null} - returns the specified wildcard value, for example 2017 for {year} wildcard\n */\n static getDateWildcardValue(dateTimeFormat, wildcard, datetimeString){\n\n let result = null;\n\n //replace the specified wildcard with the (.*)\n //for example, for wildcard=year the string can be: '{month}/{day}/{year}' => '{month}/{day}/(.*)'\n let replacedFormat = dateTimeFormat.replace(wildcard, '(.*)');\n\n //replace all other wildcard with .*\n //for example above it will be: '.*/.*/(.*)'\n const regexValue = replacedFormat.replace(/{year}|{month}|{day}|{hour}|{min}|{sec}/g, '.*');\n\n //for example, run '.*/.*/(.*)' regex on 01/15/2017\n const regex = new RegExp(regexValue, 'g');\n const match = regex.exec(datetimeString);\n\n //we get the wildcard value from the given string: 2017 in the example above\n if(match && match.length > 1){\n result = match[1];\n }\n\n return result;\n }\n\n /**\n * get month number by string\n * @param {string} monthNumberOrName - month number or name from date time string\n * @return {number} from 0 for January to 11 for December; -1 if not found;\n */\n static getMonthByWildcard(monthNumberOrName){\n\n monthNumberOrName = monthNumberOrName ? monthNumberOrName.trim().toLowerCase() : '';\n\n let monthIndex = Number(monthNumberOrName);\n\n if(!isNaN(monthIndex)){\n\n if(monthIndex - 1 < 0){\n return -1;\n }\n else {\n return monthIndex - 1;\n }\n }\n\n //find month index by value\n return SortAction.months.findIndex((monthAliasesArray) => {\n\n return monthAliasesArray.find(monthAlias => {\n return monthAlias.trim() === monthNumberOrName;\n });\n });\n }\n}\n\nexport default SortAction;","/**\n * pagination\n */\nclass PaginationAction{\n\n /**\n * Pagination\n * @constructor\n * @param {number} currentPage\n * @param {number} itemsPerPage\n * @param {number} itemsNumber\n * @param {number} range\n */\n constructor(currentPage, itemsPerPage, itemsNumber, range){\n\n this.itemsNumber = Number(itemsNumber) || 0;\n this.itemsPerPage = Number.isInteger(itemsPerPage) ? Number(itemsPerPage) : this.itemsNumber;\n\n if(this.itemsPerPage === 0){\n this.itemsPerPage = itemsNumber;\n }\n\n this.pagesNumber = this.itemsPerPage === 0 ? 0 : Math.ceil(this.itemsNumber/this.itemsPerPage);\n\n //validate current page\n this.currentPage = Number(currentPage) || 0;\n\n if(this.currentPage > this.pagesNumber - 1){\n this.currentPage = 0;\n }\n\n this.start = this.currentPage * this.itemsPerPage;\n this.end = this.start + this.itemsPerPage;\n\n //validate the end\n if(this.end > this.itemsNumber){\n this.end = this.itemsNumber;\n }\n\n this.prevPage = this.currentPage <= 0 ? 0 : this.currentPage - 1;\n this.nextPage = this.pagesNumber === 0 ? 0 : (this.currentPage >= this.pagesNumber - 1 ? this.pagesNumber - 1 : this.currentPage + 1);\n\n this.range = Number(range) || 10;\n\n const halfRange = Math.ceil((this.range - 1) / 2);\n this.rangeStart = this.currentPage - halfRange;\n this.rangeEnd = Math.min(this.rangeStart + this.range - 1, this.pagesNumber - 1);\n\n if(this.rangeStart <= 0){\n this.rangeStart = 0;\n this.rangeEnd = Math.min(this.range - 1, this.pagesNumber - 1);\n }\n\n if(this.rangeEnd >= this.pagesNumber - 1){\n this.rangeStart = Math.max(this.pagesNumber - this.range, 0);\n this.rangeEnd = this.pagesNumber - 1;\n }\n }\n}\n\nexport default PaginationAction;","/**\n * jPList Base Control\n * Each jPList control should extend this base control.\n */\nclass BaseControl{\n\n /**\n * control type defined in data-jplist-control attribute;\n * for example, data-jplist-control=\"hidden-sort\" has type='hidden-sort'\n * @param {HTMLElement} element\n */\n constructor(element){\n\n if(element) {\n\n this.element = element;\n\n /**\n * element initial html\n * @type {string}\n */\n this.element.initialHTML = element.outerHTML;\n\n /**\n * used to define appropriate class for the control\n * @type {string} required\n */\n this.type = (element.getAttribute('data-jplist-control') || '').trim().toLowerCase();\n\n /**\n * used to define the elements group that is influenced by this control\n * @type {string=} optional\n */\n this.group = (element.getAttribute('data-group') || '').trim().toLowerCase();\n\n /**\n * control name\n * @type {string} optional\n */\n this.name = (element.getAttribute('data-name') || element.getAttribute('name') || 'default').trim();\n\n /**\n * deep link parameter name\n * @type {string} optional\n */\n this.id = (element.getAttribute('data-id') || '').trim().toLowerCase();\n\n /**\n * jump to an element after the action;\n * and CSS selector or \"top\" keyword\n * @type {string} optional\n */\n this.jump = (element.getAttribute('data-jump') || '').trim();\n }\n }\n}\n\nexport default BaseControl;","class DeepLinksService{\n\n /**\n * take param1=val1 and return an object of the structure { key: param1, value: val1 }\n * @param param {string}\n * @return {object|null}\n */\n static getParam(param){\n\n if(!param) return null;\n\n const parts = param.split('=');\n\n if(parts.length < 2) return null;\n\n return {\n key: parts[0].trim().toLowerCase(),\n value: parts[1].trim().toLowerCase()\n };\n }\n\n /**\n * get deep link parameters from URL\n * @param {string} hash - window.location.hash value\n * @param {string=} hashStart - optional value of hash start; by default it's '#', but can be changed for example to be '#!'\n * @return {Map} params - structure: [groupName, [{key, value}, ...]], ...\n *\n * URL structure example:\n * https://www.example.com?param1=val1¶m2=val2#group=gr1¶m1=val1¶m2=val2&group=gr2¶m1=val1¶m2=val2...\n */\n static getUrlParams(hash, hashStart = '#'){\n\n const paramsMap = new Map();\n\n if(!hash) return paramsMap;\n\n const formattedHash = window.decodeURIComponent(hash.replace(hashStart, '')).trim().toLowerCase();\n\n if(!formattedHash) return paramsMap;\n\n const params = formattedHash.split('&');\n\n let currentGroupName = '';\n\n for(let pair of params){\n\n const param = DeepLinksService.getParam(pair);\n\n if(!param) continue;\n\n if(param.key === 'group'){\n\n currentGroupName = param.value;\n\n //insert group name if doesn't exist\n if(!paramsMap.has(param.value)){\n\n paramsMap.set(param.value, []);\n }\n }\n else{\n const groupValues = paramsMap.get(currentGroupName);\n\n if(groupValues){\n groupValues.push(param);\n }\n\n paramsMap.set(currentGroupName, groupValues);\n }\n }\n\n return paramsMap;\n }\n}\n\nexport default DeepLinksService;","/**\n * local storage, session storage, cookies\n */\nclass StorageService{\n\n /**\n * is storage supported?\n * @param {string} storage - 'localStorage', 'sessionStorage', 'cookies'\n * @return {boolean}\n */\n static isSupported(storage){\n\n if(storage === 'cookies') return true;\n\n try{\n return storage in window && window[storage] !== null;\n }\n catch(e){\n return false;\n }\n }\n\n /**\n * save to the storage\n * @param {string} deepLink\n * @param {string} storage - 'localStorage', 'sessionStorage', 'cookies'\n * @param {string} key - storage key\n * @param {number} expiration - cookie expiration in minutes (-1 = cookies expire when browser is closed)\n */\n static set(deepLink, storage, key, expiration = -1){\n\n if(storage === 'cookies'){\n\n const cValue = encodeURIComponent(deepLink);\n const exdate = new Date();\n\n expiration = Number(expiration) || -1;\n\n if(expiration === -1){\n document.cookie = name + '=' + cValue + ';path=/;';\n }\n else{\n exdate.setMinutes(exdate.getMinutes() + expiration);\n document.cookie = name + '=' + cValue + ';path=/; expires=' + exdate.toUTCString();\n }\n }\n else{\n if(StorageService.isSupported(storage)) {\n\n //save json in storage\n window[storage][key] = deepLink;\n }\n }\n }\n\n /**\n * get from storage\n * @param {string} storage - 'localStorage', 'sessionStorage', 'cookies'\n * @param {string} key - storage key\n * @return {string} deepLink\n */\n static get(storage, key){\n\n let deepLink = '';\n\n if(storage === 'cookies'){\n\n //get document cookie\n const cookies = document.cookie.split(';');\n\n for (let i=0; i} items\n * @param {string} text\n * @param {string=} path - any CSS selector or empty value meaning the whole element\n * @param {string=} mode - contains (default), startsWith, endsWith, equal\n * @param {string=} ignoreRegex - optional regex that defines what characters should be ignored\n * @return {Array.} filtered items\n */\n static textFilter(items, text, path='', mode = 'contains', ignoreRegex = ''){\n\n const filtered = [];\n\n if(!items) return [];\n\n if(path === 'default') return items;\n\n const formattedText = text.replace(new RegExp(ignoreRegex, 'ig'), '').toLowerCase().trim();\n\n for(let item of items){\n\n const elements = path ? item.querySelectorAll(path) : [item];\n\n if(!elements) continue;\n\n let shouldBeAdded = false;\n\n for(let el of elements){\n\n const elText = el.textContent.replace(new RegExp(ignoreRegex, 'ig'), '').toLowerCase().trim();\n\n switch(mode){\n\n case 'startsWith':{\n\n if(elText.startsWith(formattedText)){\n shouldBeAdded = true;\n }\n\n break;\n }\n\n case 'endsWith':{\n\n if(elText.endsWith(formattedText)){\n shouldBeAdded = true;\n }\n\n break;\n }\n\n case 'equal':{\n\n if(elText === formattedText){\n shouldBeAdded = true;\n }\n break;\n }\n\n default:{\n\n //contains\n if(elText.indexOf(formattedText) !== -1){\n shouldBeAdded = true;\n }\n\n break;\n }\n }\n\n if(shouldBeAdded) break;\n }\n\n if(shouldBeAdded){\n filtered.push(item);\n }\n }\n\n return filtered;\n }\n\n /**\n * path filter\n * only items with the given path are returned\n * @param {Array.} items\n * @param {string=} path - any CSS selector or empty value meaning the whole element\n * @param {boolean} isInverted - if true, return all items that DON'T contain the specified path\n * @return {Array.} filtered items\n */\n static pathFilter(items, path='', isInverted = false){\n\n const filtered = [];\n\n if(!items) return [];\n\n if(path === 'default' || !path) return items;\n\n for(let item of items){\n\n const el = item.querySelector(path);\n\n if(el && !isInverted || !el && isInverted){\n filtered.push(item);\n }\n }\n\n return filtered;\n }\n\n /**\n * check if n is a number\n * @param {*} n\n * @returns {boolean}\n */\n static isNumeric(n)\n {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n /**\n * range filter\n * return only elements that satisfy the following condition:\n * all numbers in the element's content are in the following range: min <= from <= (all numbers in the element) <= to <= max\n * @param {Array.} items\n * @param {string=} path - any CSS selector or empty value meaning the whole element\n * @param {number} from\n * @param {number} to\n * @param {number=} min\n * @param {number=} max\n * @return {Array.} filtered items\n */\n static rangeFilter(items, path='', from, to, min = from, max = to){\n\n const filtered = [];\n\n if(!items) return [];\n\n if(path === 'default') return items;\n\n from = Math.max(from, min);\n to = Math.min(to, max);\n\n for(let item of items){\n\n const itemElements = path ? item.querySelectorAll(path) : [item];\n\n if(!itemElements) continue;\n\n //find all numbers within the element\n const numbers = [];\n\n for(let el of itemElements){\n\n const num = Number(el.textContent.trim().replace(/[^-0-9.]+/g,''));\n\n if(!isNaN(num)){\n numbers.push(num);\n }\n }\n\n if(numbers.length > 0){\n\n //find max and min number of all found within the element numbers\n const maxNumber = Math.max.apply(Math, numbers);\n const minNumber = Math.min.apply(Math, numbers);\n\n let shouldBeAdded = true;\n\n if(FilterAction.isNumeric(from) && from > minNumber){\n shouldBeAdded = false;\n }\n\n if(FilterAction.isNumeric(to) && maxNumber > to){\n shouldBeAdded = false;\n }\n\n if(shouldBeAdded){\n filtered.push(item);\n }\n }\n }\n\n return filtered;\n }\n}\n\nexport default FilterAction;","import SortAction from '../actions/sort/sort.action';\nimport PaginationAction from '../actions/pagination/pagination.action';\nimport BaseControl from '../controls/base/controls/base.control';\nimport DeepLinksService from '../services/deep-links.service';\nimport StorageService from '../services/storage.service';\nimport FilterAction from '../actions/filter/filter.action';\n\n/**\n * content manager\n */\nclass ContentManager{\n\n /**\n * apply controls on the content groups\n * @param {Object} settings\n * @param {Map} controls - controls split by data-group and data-name: [groupName, [BaseControlsGroup1, BaseControlsGroup2, ...]]\n * @param {Map} groups - [groupName, Array.<{root: HTMLElement, items: Array.] groups\n * @param {string=} groupName - optional group name; if group name is empty or not provided -> refresh all groups\n * @param {BaseControl|undefined=} target - the element that triggered the event\n */\n static apply(settings, controls, groups, groupName = '', target = undefined){\n\n if(!controls || !groups) return;\n\n const filters = [\n {\n options: 'pathFilterOptions',\n name: 'pathFilter'\n },\n {\n options: 'rangeFilterOptions',\n name: 'rangeFilter'\n },\n {\n options: 'textFilterOptions',\n name: 'textFilter'\n }\n ];\n\n //group structure is Array.<{root: HTMLElement, items: Array.}>\n for(let [cGroupName, groupValueArr] of groups){\n\n if((groupName && groupName === cGroupName) || !groupName){\n\n //get controls of this group;\n //received controls array [BaseControlsGroup1, BaseControlsGroup2, ...]\n const baseControlsGroups = controls.get(cGroupName);\n\n //collect sort, pagination and filter options from all controls with the same group name\n const options = ContentManager.collectControlsOptions(baseControlsGroups);\n\n //there can be more than one block of items with the same group name\n //each itemsBlock has structure: {root: HTMLElement, items: Array.}\n for(let itemsBlock of groupValueArr){\n\n let itemsNumber = itemsBlock.items.length;\n\n //hide all elements moving them to the document fragment\n let fragment = ContentManager.getItemsFragment(itemsBlock.items);\n\n if(options.sortOptions && options.sortOptions.length > 0) {\n\n //sort the items of the group using sort options of all controls\n SortAction.sort(itemsBlock.items, options.sortOptions);\n fragment = ContentManager.getItemsFragment(itemsBlock.items);\n }\n\n let filtered = itemsBlock.items;\n for(let filter of filters){\n\n //pathFilterOptions, rangeFilterOptions or textFilterOptions\n const filterName = filter.options;\n\n if(options[filterName]){\n\n const splitted = ContentManager.splitByLogic(options[filterName]);\n\n //apply \"AND\" filter\n filtered = ContentManager.handleFilter(filtered, splitted.and, 'and', filter.name);\n\n //apply \"OR\" filters\n for(let orOptionsGroupName in splitted.or){\n filtered = ContentManager.handleFilter(filtered, splitted.or[orOptionsGroupName], 'or', filter.name);\n }\n\n itemsNumber = filtered.length;\n fragment = ContentManager.getItemsFragment(filtered);\n }\n }\n\n if(options.paginationOptions){\n\n const paginationAction = new PaginationAction(\n options.paginationOptions.currentPage,\n options.paginationOptions.itemsPerPage,\n filtered.length,\n options.paginationOptions.range\n );\n\n //setPaginationOptions applies all computed properties of PaginationAction class to the latest pagination control\n if(baseControlsGroups.length > 0){\n\n for(let bcg of baseControlsGroups){\n if(bcg.setPaginationOptions){\n bcg.setPaginationOptions(paginationAction);\n }\n }\n }\n\n const paginatedItems = filtered.slice(paginationAction.start, paginationAction.end);\n itemsNumber = paginatedItems.length;\n fragment = ContentManager.getItemsFragment(paginatedItems);\n }\n\n //return to HTML only relevant items\n itemsBlock.root.appendChild(fragment);\n\n //dispatch the event with different data about state of controls and items\n ContentManager.sendStateEvent(options, itemsNumber, baseControlsGroups, groups, filtered);\n }\n\n //if one of controls has data-jump attribute -> jump to the specified CSS selector or to the top\n ContentManager.jump(baseControlsGroups, target);\n }\n\n }\n\n if(settings.deepLinking) {\n\n //update deep link if it's enabled\n ContentManager.updateDeepLink(ContentManager.getDeepLink(controls, groups), settings.hashStart);\n }\n else{\n if(settings.storage){\n\n //update storage if it's enabled\n StorageService.set(ContentManager.getDeepLink(controls, groups), settings.storage, settings.storageName, settings.cookiesExpiration);\n }\n }\n }\n\n /**\n * perform filter\n * @param {object} option\n * @param {Array.} filtered\n * @param {string} filterType - 'textFilter', 'rangeFilter' or 'pathFilter'\n * @returns {Array.}\n */\n static performFilter(option, filtered, filterType){\n\n switch(filterType){\n\n case 'textFilter' : {\n return FilterAction.textFilter(\n filtered,\n option.text,\n option.path,\n option.mode,\n option.ignoreRegex);\n }\n\n case 'pathFilter' : {\n return FilterAction.pathFilter(filtered,\n option.path,\n option.isInverted);\n }\n\n case 'rangeFilter' : {\n return FilterAction.rangeFilter(filtered,\n option.path,\n option.from,\n option.to,\n option.min,\n option.max);\n }\n }\n\n return filtered;\n }\n\n /**\n * filter text / path / range\n * @param {Array.} filtered\n * @param {Array.} options\n * @param {string} logic - 'or' / 'and'\n * @param {string} filterType - 'textFilter', 'rangeFilter' or 'pathFilter'\n * @returns {Array.}\n */\n static handleFilter(filtered, options, logic, filterType){\n\n if(options.length <= 0) return filtered;\n\n if(logic === 'and'){\n for(let option of options){\n filtered = ContentManager.performFilter(option, filtered, filterType);\n }\n }\n\n if(logic === 'or'){\n\n let orFiltered = new Set();\n\n for(let option of options){\n\n let temp = ContentManager.performFilter(option, filtered, filterType);\n\n orFiltered = new Set([...orFiltered, ...temp]);\n }\n\n filtered = Array.from(orFiltered);\n }\n\n return filtered;\n }\n\n /**\n * split array of options by \"OR\" / \"AND\" logic\n * all options with \"AND\" logic organize 1 group, \"OR\" options can organize multiple groups\n * @param {Array.} options\n * @return {object}, {and: [option1, option2, ...], or: {'name1': [option1, options, ...], 'name2': [option1, options, ...], ...}}\n */\n static splitByLogic(options){\n\n const result = {\n and: [],\n or: {}\n };\n\n for(let option of options){\n\n const orName = option.or;\n\n if(!orName){\n result.and.push(option);\n }\n else{\n if(result.or[orName] === undefined){\n result.or[orName] = [option];\n }\n else{\n result.or[orName].push(option);\n }\n }\n }\n\n return result;\n }\n\n /**\n * if one of controls has data-jump attribute -> jump to the specified CSS selector or to the top\n * data-jump=\"any CSS selector or 'top' keyword\"\n * examples: data-jump=\"header\"\n * data-jump=\".top-bar\"\n * data-jump=\"#main\"\n * data-jump=\"top\"\n * @param {Array.} baseControlsGroups - [BaseControlsGroup1, BaseControlsGroup2, ...]\n * @param {BaseControl|undefined=} target - the element that triggered the event\n * @history\n * - 21/08/2018 - fixed https://github.com/1rosehip/jplist-es6/issues/11\n */\n static jump(baseControlsGroups, target = undefined){\n\n if(!target || !target.jump) return;\n\n //if(!baseControlsGroups || baseControlsGroups.length <= 0) return;\n\n //-1 means no scroll\n let top = -1;\n\n //top is always the upper ))\n if(target.jump === 'top'){\n top = 0;\n }\n else{\n const jumpEl = document.querySelector(target.jump);\n\n if(!jumpEl) return;\n\n const jumpElRect = jumpEl.getBoundingClientRect();\n\n //make sure element is not hidden or disconnected\n if (!jumpEl.width && !jumpEl.height && !jumpEl.getClientRects().length) return;\n\n const clientTop = document.clientTop || document.body.clientTop || 0;\n\n if(top < 0){\n\n //select the first jump path as the default value\n top = jumpElRect.top + window.pageYOffset - clientTop;\n }\n else{\n if(jumpElRect.top + window.pageYOffset - clientTop < top){\n top = jumpElRect.top + window.pageYOffset - clientTop;\n }\n }\n }\n\n if(top >= 0){\n window.scroll(0, top);\n }\n }\n\n /**\n * send jPList general event with different data about state of controls and items\n * @param {object} options\n * @param {number} itemsNumber\n * @param {BaseControlsGroup} baseControlsGroups\n * @param {Map} groups - [groupName, Array.<{root: HTMLElement, items: Array.] groups\n * @param {Array.} filtered\n */\n static sendStateEvent(options, itemsNumber, baseControlsGroups, groups, filtered){\n\n if(!baseControlsGroups) return;\n\n const stateEvent = new CustomEvent('jplist.state');\n\n stateEvent.jplistState = {\n options: options,\n itemsNumber: itemsNumber,\n groups: groups,\n filtered: filtered\n };\n\n for(let baseControlsGroup of baseControlsGroups){\n\n for(let control of baseControlsGroup.controls){\n\n control.element.dispatchEvent(stateEvent);\n }\n }\n }\n\n /**\n * collect sort, pagination and filter options from all controls with the same group name\n * @param {Array.} baseControlsGroups\n * @return {object} sort, pagination and filter objects\n */\n static collectControlsOptions(baseControlsGroups){\n\n const options = {\n\n //there can be multiple sort options\n sortOptions: [],\n\n //there should be only one pagination options object;\n //in case of multiple -> get the latest\n paginationOptions: null,\n\n //there can be multiple filter options\n textFilterOptions: [],\n pathFilterOptions: [],\n rangeFilterOptions: []\n };\n\n if(!baseControlsGroups) return options;\n\n for(let baseControlsGroup of baseControlsGroups){\n\n //get sort options only from sort controls\n if(baseControlsGroup.getSortOptions) {\n\n //add base control group sort options\n options.sortOptions = options.sortOptions.concat(baseControlsGroup.getSortOptions());\n }\n\n //get text filter options only from text filter controls\n if(baseControlsGroup.getTextFilterOptions) {\n\n //add base control group sort options\n options.textFilterOptions = options.textFilterOptions.concat(baseControlsGroup.getTextFilterOptions());\n }\n\n //get path filter options only from text filter controls\n if(baseControlsGroup.getPathFilterOptions) {\n\n //add base control group sort options\n options.pathFilterOptions = options.pathFilterOptions.concat(baseControlsGroup.getPathFilterOptions());\n }\n\n //get range filter options only from range filter controls\n if(baseControlsGroup.getRangeFilterOptions) {\n\n //add base control group sort options\n options.rangeFilterOptions = options.rangeFilterOptions.concat(baseControlsGroup.getRangeFilterOptions());\n }\n\n if(baseControlsGroup.getPaginationOptions) {\n options.paginationOptions = baseControlsGroup.getPaginationOptions();\n }\n }\n\n return options;\n }\n\n /**\n * get document fragment with the specified items\n * @param {Array.} items\n * @return {DocumentFragment}\n */\n static getItemsFragment(items){\n\n const fragment = document.createDocumentFragment();\n\n for(let item of items){\n fragment.appendChild(item);\n }\n\n return fragment;\n }\n\n /**\n * update deep link -> replace it in URL\n * @param {string} deepLink\n * @param {string} hashStart\n */\n static updateDeepLink(deepLink, hashStart = '#'){\n\n let hashStr = deepLink.replace(hashStart, '').trim();\n\n if(hashStr === ''){\n hashStr = hashStart;\n }\n else{\n hashStr = hashStart + hashStr;\n }\n\n if(window.location.hash !== hashStr){\n\n const index = window.location.href.indexOf(hashStart);\n let href;\n\n if(index === -1){\n href = window.location.href + hashStr;\n }\n else{\n href = window.location.href.substring(0, index) + hashStr;\n }\n\n if('replaceState' in window.history){\n window.history.replaceState('', '', href);\n }\n else{\n window.location.replace(href);\n }\n }\n }\n\n /**\n * update deep link URL according to the current controls states\n * @return {string} deep link\n */\n static getDeepLink(controls, groups){\n\n let deeplink = [];\n\n //group structure is Array.<{root: HTMLElement, items: Array.}>\n for(let cGroupName of groups.keys()){\n\n //get controls of this group;\n //received controls array [BaseControlsGroup1, BaseControlsGroup2, ...]\n const baseControlsGroups = controls.get(cGroupName);\n\n const deepLinkParts = [];\n for(let baseControlsGroup of baseControlsGroups){\n\n const dl = baseControlsGroup.getDeepLink();\n\n if(dl){\n deepLinkParts.push(dl);\n }\n }\n\n if(deepLinkParts.length > 0){\n deeplink.push('group=' + cGroupName);\n deeplink = deeplink.concat(deepLinkParts);\n }\n }\n\n return deeplink.join('&');\n }\n\n /**\n * find all groups of elements that should be sorted, filtered, etc.\n * each group defined by data-jplist-group attribute;\n * each element in the group defined by data-jplist-item attribute;\n * @param {HTMLCollection} groups\n * @return {Map} Map[groupName, Array.<{root: HTMLElement, items: Array.] groups\n */\n static findGroups(groups){\n\n const groupsMap = new Map();\n\n if(!groups){\n return groupsMap;\n }\n\n //get all items with data attribute data-jplist-group\n const groupElements = [...groups];\n\n for(let groupElement of groupElements){\n\n const groupName = groupElement.getAttribute('data-jplist-group');\n\n let groupValue = [];\n\n if(groupsMap.has(groupName)){\n groupValue = groupsMap.get(groupName);\n }\n\n groupValue.push({\n\n /**\n * the root element of the group\n */\n root: groupElement,\n\n /**\n * all group elements\n */\n items: [...groupElement.querySelectorAll('[data-jplist-item]')],\n\n /**\n * this fragment used as a container for invisible items\n */\n fragment: document.createDocumentFragment()\n });\n\n groupsMap.set(groupName, groupValue);\n }\n\n return groupsMap;\n }\n\n /**\n * find all controls defined on page by data-jplist-control attribute;\n * control classes should be registered in window.jplist.controlTypes before using this method:\n * window.jplist.controlTypes = new Map([\n * ['hidden-sort', HiddenSortControl],\n * ...\n * ]);\n * @param {HTMLElement} root\n * @return {Array.}\n */\n static findControls(root){\n\n if(!root) return [];\n\n const controls = [];\n\n //find all control\n const elements = root.querySelectorAll('[data-jplist-control]');\n\n if(elements) {\n\n for(let element of elements){\n\n const controlType = element.getAttribute('data-jplist-control');\n\n if(!controlType) continue;\n\n const controlInstance = new BaseControl(element);\n controls.push(controlInstance);\n }\n }\n\n return controls;\n }\n\n /**\n * split control by their data-group property\n * @param {Array.} controls\n * @return {Map} [[groupName, controls array], [...], ...]\n */\n static findControlGroups(controls){\n\n const map = new Map();\n\n if(controls) {\n\n for (let control of controls) {\n\n let arr = [];\n\n if (map.has(control.group)) {\n arr = map.get(control.group);\n }\n\n arr.push(control);\n\n map.set(control.group, arr);\n }\n }\n\n return map;\n }\n\n /**\n * find controls with the same name\n * @param {object} settings\n * @param {Array.} controls\n * @return {Map} [[name, BaseControlsGroup], [...]]\n */\n static findSameNameControls(settings, controls){\n\n const map = new Map();\n\n if(controls){\n\n let deepLinkParams = null;\n\n if(settings.deepLinking){\n deepLinkParams = DeepLinksService.getUrlParams(window.location.hash, settings.hashStart);\n }\n else{\n if(settings.storage){\n\n const deepLinkSavedInStorage = StorageService.get(settings.storage, settings.storageName);\n deepLinkParams = DeepLinksService.getUrlParams(deepLinkSavedInStorage, '');\n }\n }\n\n for(let control of controls){\n\n //control with not defined type should be ignored\n if(!control.type || !window.jplist.controlTypes.has(control.type)) continue;\n\n //check if data-type class defined in window.jplist.controlTypes;\n //it should be defined like this:\n //window.jplist.controlTypes = window.jplist.controlTypes || new Map([\n // ['hidden-sort', HiddenSortControl],\n // ...\n //]);\n const controlClass = window.jplist.controlTypes.get(control.type);\n\n if(controlClass){\n\n let controlGroup = null;\n\n if (map.has(control.name)) {\n controlGroup = map.get(control.name);\n }\n else{\n controlGroup = new controlClass(control.group, control.name, [], deepLinkParams);\n }\n\n controlGroup.addControl(control);\n\n map.set(control.name, controlGroup);\n }\n }\n }\n\n return map;\n }\n\n /**\n * initialize controls and split them by group and name\n * @param {object} settings\n * @param {HTMLElement} root\n * @return {Map} [groupName, [BaseControlsGroup1, BaseControlsGroup2, ...]]\n */\n static splitByGroupAndName(settings, root){\n\n const res = new Map();\n\n if(!root) return res;\n\n //find all controls: received {Array.}\n const controls = ContentManager.findControls(root);\n\n //split controls by their data-group attributes;\n //the received structure is map: [[groupName, controls array], [...], ...]\n const controlsByGroupNames = ContentManager.findControlGroups(controls);\n\n for(let [groupName, groupControls] of controlsByGroupNames){\n\n //received {Map} - [[name, BaseControlsGroup], [...]]\n const sameNameControls = ContentManager.findSameNameControls(settings, groupControls);\n\n let arr = [];\n\n for(let baseControlsGroup of sameNameControls.values()){\n arr.push(baseControlsGroup);\n }\n\n res.set(groupName, arr);\n }\n\n return res;\n }\n}\n\nexport default ContentManager;","/**\n * represents a group of controls with the same data-name and data-group attributes\n */\nclass BaseControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls, deepLinkParams = null){\n\n this.group = (group || '').trim().toLowerCase();\n this.name = (name || 'default').trim();\n this.controls = controls || [];\n\n this.deepLinkParams = [];\n\n if(deepLinkParams && deepLinkParams.has(this.group)){\n\n this.deepLinkParams = deepLinkParams.get(this.group) || [];\n }\n }\n\n /**\n * add control to the group\n * @param {BaseControl} control\n */\n addControl(control){\n if(!control || control.name !== this.name || control.group !== this.group) return;\n\n this.controls.push(control);\n }\n\n /**\n * by default control's deep link is empty\n * @returns {string}\n */\n getDeepLink(){\n return '';\n }\n\n}\n\nexport default BaseControlsGroup;","import BaseControl from '../base.control';\n\n/**\n * base sort control\n */\nclass BaseSortControl extends BaseControl{\n\n /**\n * constructor\n * @param {HTMLElement} element\n */\n constructor(element){\n super(element);\n\n if(element){\n\n /**\n * css selector or 'default' for the browser default order (no sort); if path is empty -> the whole element\n * @type {string}\n */\n this.path = (element.getAttribute('data-path') || '').trim();\n\n /**\n * optional text (default), number or datetime\n * @type {string}\n */\n this.dataType = (element.getAttribute('data-type') || 'text').trim().toLowerCase();\n\n /**\n * optional sort order: asc (default) or desc\n * @type {string}\n */\n this.order = (element.getAttribute('data-order') || 'asc').trim().toLowerCase();\n\n /**\n * optional ignore regex - used to ignore characters before sort\n * @type {string}\n */\n this.regex = element.getAttribute('data-regex') || '';\n\n /**\n * optional datetime format - datetime structure using wilcards {year}|{month}|{day}|{hour}|{min}|{sec}, for example: {month}/{day}/{year}\n * @type {string}\n */\n this.dateTimeFormat = (element.getAttribute('data-date-format') || '').trim().toLowerCase();\n\n /**\n * this property indicates the number of data attribute groups [{data-path, data-order, ...}, {data-path-1, data-order-1,...}, ...]\n * only data-path attribute is required;\n * if multipleSortsNum > 0 => multiple sort\n * @type {number}\n */\n this.multipleSortsNumber = this.getMultipleSortsNumber(element);\n\n for(let index=1; index <= this.multipleSortsNumber; index++){\n this['path' + index] = (element.getAttribute('data-path-' + index) || '').trim();\n this['dataType' + index] = (element.getAttribute('data-type-' + index) || 'text').trim().toLowerCase();\n this['order' + index] = (element.getAttribute('data-order-' + index) || 'asc').trim().toLowerCase();\n this['regex' + index] = element.getAttribute('data-regex-' + index) || '';\n this['dateTimeFormat' + index] = (element.getAttribute('data-date-format-' + index) || '').trim().toLowerCase();\n }\n\n }\n }\n\n /**\n * multiple sort is defined by another sets of data attributes like {data-path-1, data-order-1,...}, {data-path-2, data-order-2,...} etc\n * this method counts the number of such sets (= the number of attributes data-path-1, data-path-2, ...)\n * @param {HTMLElement} element\n * @return {number}\n */\n getMultipleSortsNumber(element){\n\n let pathsNumber = 0;\n\n for(let attr of element.attributes){\n\n let match = null;\n const regex = /^data-path-([0-9]+)$/g;\n\n while (match = regex.exec(attr.nodeName)) {\n\n const propIndex = Number(match[1]);\n\n if(!Number.isInteger(propIndex)) continue;\n pathsNumber++;\n }\n }\n\n return pathsNumber;\n }\n\n /**\n * get sort options used in SortAction.sort method\n * @return {Array.<{path: string, dataType: text|number|datetime, order: asc|desc, ignoreRegex: string, dateTimeFormat: string}>} options\n */\n getSortOptions(){\n\n const options = [];\n\n //initial path is required\n if(this.path){\n\n options.push({\n path: this.path,\n dataType: this.dataType,\n order: this.order,\n ignoreRegex: this.ignoreRegex,\n dateTimeFormat: this.dateTimeFormat\n });\n\n for(let index = 1; index <= this.multipleSortsNumber; index++){\n\n options.push({\n path: this['path' + index],\n dataType: this['dataType' + index],\n order: this['order' + index],\n ignoreRegex: this['ignoreRegex' + index],\n dateTimeFormat: this['dateTimeFormat' + index]\n });\n }\n }\n\n return options;\n }\n\n /**\n * check if current base sort control has the same properties like the specified base sort control\n * @param {BaseSortControl} baseSortControl\n * @return {boolean}\n */\n isEqualTo(baseSortControl){\n\n let isEqual = true;\n\n const props = ['path', 'dataType', 'order', 'regex', 'dateTimeFormat'];\n\n for(let i=0; i} sortOptions\n */\n getSortOptions(){\n\n let sortOptions = [];\n\n for(let control of this.controls){\n sortOptions = sortOptions.concat(control.getSortOptions());\n }\n\n return sortOptions;\n }\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BaseSortControl|null}\n */\n addControl(control){\n\n if(control.name !== this.name || control.group !== this.group){\n return null;\n }\n\n const baseSortControl = new BaseSortControl(control.element);\n\n this.controls.push(baseSortControl);\n\n return baseSortControl;\n }\n}\n\nexport default BaseSortControlsGroup;\n","import BaseSortControlsGroup from '../../base/groups/sort/base-sort-controls-group';\n\n/**\n * hidden sort jPList control\n *\n * HTML structure:\n * ----------------\n * \n * \n *\n * Usage in JS:\n * -------------\n * import HiddenSort from './controls/sort/hidden-sort.control';\n * let control = document.getElementById('my-hidden-sort-control');\n * const hiddenSort = new HiddenSort(control);\n * console.log(hiddenSort.type);\n */\nclass HiddenSortControl extends BaseSortControlsGroup{}\n\nexport default HiddenSortControl;\n","import BaseSortControlsGroup from '../../base/groups/sort/base-sort-controls-group';\n\nconst SELECTED_CLASS = 'jplist-selected';\n\n/**\n * sort buttons jPList control\n *\n * Usage:\n * \n * data-group=\"group1\" \n * data-order=\"asc\" \n * data-type=\"text\" \n * data-name=\"sort1\" \n * data-selected=\"true\" \n * data-datetime-format=\"{month}/{day}/{year}\" \n * data-regex=\"\" \n * data-id=\"deep-link-name1\" \n * data-mode=\"radio\"> \n * Sort by title asc\n * \n *\n * Optional deep link: #deepLinkName1=1&deepLinkName2=1\n * selected value - 1\n * non selected - should not appear in deep link or any value !== 1\n */\nclass ButtonsSortControl extends BaseSortControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.checkboxes = [];\n this.radios = [];\n }\n\n /**\n * add control to the group\n * @param {BaseSortControl} control\n */\n addControl(control){\n\n const baseSortControl = super.addControl(control);\n\n //get additional control properties\n baseSortControl.selected = baseSortControl.element.getAttribute('data-selected') === 'true';\n baseSortControl.mode = baseSortControl.element.getAttribute('data-mode') || 'radio';\n\n //check if control contains a link and it is in the deep links parameters\n if(baseSortControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseSortControl.id);\n\n if(deepLinkParam){\n baseSortControl.selected = deepLinkParam.value === '1';\n }\n }\n\n if(baseSortControl.mode === 'radio'){\n\n this.radios.push(baseSortControl);\n this.handleRadios();\n }\n\n if(baseSortControl.mode === 'checkbox'){\n\n this.checkboxes.push(baseSortControl);\n this.handleCheckboxes();\n }\n\n /**\n * on control click -> change the selected control\n */\n baseSortControl.element.addEventListener('click', e => {\n\n e.preventDefault();\n\n if(baseSortControl.mode === 'checkbox'){\n\n baseSortControl.selected = !baseSortControl.selected;\n\n this.checkboxes.forEach(cb => {\n\n if(cb.isEqualTo(baseSortControl)){\n cb.selected = baseSortControl.selected;\n }\n });\n\n this.handleCheckboxes();\n }\n\n if(baseSortControl.mode === 'radio'){\n\n for (let radio of this.radios) {\n radio.selected = false;\n }\n\n baseSortControl.selected = true;\n\n this.handleRadios();\n }\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseSortControl);\n }\n });\n }\n\n /**\n * handle checkbox mode controls\n */\n handleCheckboxes(){\n\n for(let cb of this.checkboxes){\n\n if(cb.selected){\n cb.element.classList.add(SELECTED_CLASS);\n }\n else{\n cb.element.classList.remove(SELECTED_CLASS);\n }\n }\n }\n\n /**\n * get the latest selected radio\n * @return {BaseSortControl} latestSelectedRadio\n */\n getLastSelectedRadio(){\n\n let latestSelectedRadio = null;\n\n //find the latest selected radio\n for (let radio of this.radios) {\n\n if (radio.selected) {\n latestSelectedRadio = radio;\n }\n }\n\n return latestSelectedRadio;\n }\n\n /**\n * handle radio mode controls\n */\n handleRadios(){\n\n if(this.radios.length > 0) {\n\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n //remove selected from all radios\n for (let radio of this.radios) {\n\n radio.selected = false;\n radio.element.classList.remove(SELECTED_CLASS);\n }\n\n if(latestSelectedRadio) {\n\n this.radios.forEach(radio => {\n\n if(radio.isEqualTo(latestSelectedRadio)){\n radio.selected = true;\n radio.element.checked = true;\n radio.element.classList.add(SELECTED_CLASS);\n }\n });\n }\n }\n }\n\n /**\n * get sort options from all controls in the group\n * @return {Array.} sortOptions\n */\n getSortOptions(){\n\n let sortOptions = [];\n\n let atLeastOneNotSelectedCheckbox = false;\n\n //add all selected checkboxes\n for(let checkbox of this.checkboxes){\n\n if(checkbox.selected) {\n sortOptions = sortOptions.concat(checkbox.getSortOptions());\n }\n else{\n atLeastOneNotSelectedCheckbox = true;\n }\n }\n\n if(atLeastOneNotSelectedCheckbox){\n sortOptions = sortOptions.concat([\n {\n path: 'default'\n }\n ]);\n }\n\n //get options from the latest selected radio if exists\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n if(latestSelectedRadio){\n sortOptions = sortOptions.concat(latestSelectedRadio.getSortOptions());\n }\n\n return sortOptions;\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n const cbArr = this.checkboxes.map(cb => cb.id && cb.selected ? cb.id + '=1' : '').filter(str => str !== '');\n const radioArr = this.radios.map(radio => radio.id && radio.selected ? radio.id + '=1' : '').filter(str => str !== '');\n const combined = cbArr.concat(radioArr);\n const unique = Array.from(new Set(combined));\n return unique.join('&');\n }\n}\n\nexport default ButtonsSortControl;","import BaseSortControlsGroup from '../../base/groups/sort/base-sort-controls-group';\n\nconst SELECTED_CLASS = 'jplist-selected';\n\n/**\n * radio buttons sort control\n *\n * Usage:\n * \n *\n * Optional deep link: #deepLinkName1=1\n * selected value - 1\n * non selected - should not appear in deep link\n */\nclass RadioButtonsSortControl extends BaseSortControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n this.radios = [];\n }\n\n /**\n * add control to the group\n * @param {BaseSortControl} control\n */\n addControl(control){\n\n const baseSortControl = super.addControl(control);\n\n //get additional control properties\n baseSortControl.selected = baseSortControl.element.checked;\n\n //check if control contains a link and it is in the deep links parameters\n if(baseSortControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseSortControl.id);\n\n if(deepLinkParam){\n baseSortControl.selected = deepLinkParam.value === '1';\n }\n }\n\n this.radios.push(baseSortControl);\n this.handleRadios();\n\n /**\n * on control change -> update the selected control\n */\n baseSortControl.element.addEventListener('change', e => {\n\n e.preventDefault();\n\n for (let radio of this.radios) {\n radio.selected = false;\n }\n\n baseSortControl.selected = true;\n\n this.handleRadios();\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseSortControl);\n }\n });\n }\n\n /**\n * get the latest selected radio\n * @return {BaseSortControl} latestSelectedRadio\n */\n getLastSelectedRadio(){\n\n let latestSelectedRadio = null;\n\n //find the latest selected radio\n for (let radio of this.radios) {\n\n if (radio.selected) {\n latestSelectedRadio = radio;\n }\n }\n\n return latestSelectedRadio;\n }\n\n /**\n * handle radio mode controls\n */\n handleRadios(){\n\n if(this.radios.length > 0) {\n\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n //remove selected from all radios\n for (let radio of this.radios) {\n\n radio.selected = false;\n radio.element.classList.remove(SELECTED_CLASS);\n }\n\n if(latestSelectedRadio) {\n\n this.radios.forEach(radio => {\n\n if(radio.isEqualTo(latestSelectedRadio)){\n\n radio.selected = true;\n radio.element.checked = true;\n radio.element.classList.add(SELECTED_CLASS);\n }\n });\n }\n }\n }\n\n /**\n * get sort options from all controls in the group\n * @return {Array.} sortOptions\n */\n getSortOptions(){\n\n let sortOptions = [];\n\n //get options from the latest selected radio if exists\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n if(latestSelectedRadio){\n sortOptions = sortOptions.concat(latestSelectedRadio.getSortOptions());\n }\n\n return sortOptions;\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n const radioArr = this.radios.map(radio => radio.id && radio.selected ? radio.id + '=1' : '').filter(str => str !== '');\n const unique = Array.from(new Set(radioArr));\n return unique.join('&');\n }\n}\n\nexport default RadioButtonsSortControl;","import BaseSortControlsGroup from '../../base/groups/sort/base-sort-controls-group';\n\nconst SELECTED_CLASS = 'jplist-selected';\n\n/**\n * checkbox sort control\n *\n * Usage:\n * \n * Optional deep link: #deepLinkName1=1\n * selected value - 1\n * non selected - 0\n */\nclass CheckboxSortControl extends BaseSortControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.checkboxes = [];\n }\n\n /**\n * add control to the group\n * @param {BaseSortControl} control\n */\n addControl(control){\n\n const baseSortControl = super.addControl(control);\n\n //get additional control properties\n baseSortControl.selected = baseSortControl.element.checked;\n\n //check if control contains a link and it is in the deep links parameters\n if(baseSortControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseSortControl.id);\n\n if(deepLinkParam){\n baseSortControl.selected = deepLinkParam.value === '1';\n }\n }\n\n this.checkboxes.push(baseSortControl);\n this.handleCheckboxes();\n\n /**\n * on control change -> update the selected control\n */\n baseSortControl.element.addEventListener('change', e => {\n\n e.preventDefault();\n\n baseSortControl.selected = !baseSortControl.selected;\n\n this.checkboxes.forEach(cb => {\n\n if(cb.isEqualTo(baseSortControl)){\n cb.selected = baseSortControl.selected;\n }\n });\n\n this.handleCheckboxes();\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseSortControl);\n }\n });\n }\n\n /**\n * handle checkbox mode controls\n */\n handleCheckboxes(){\n\n for(let cb of this.checkboxes){\n\n if(cb.selected){\n cb.element.classList.add(SELECTED_CLASS);\n }\n else{\n cb.element.classList.remove(SELECTED_CLASS);\n }\n\n cb.element.checked = cb.selected;\n }\n }\n\n /**\n * get sort options from all controls in the group\n * @return {Array.} sortOptions\n */\n getSortOptions(){\n\n let sortOptions = [];\n\n let atLeastOneNotSelectedCheckbox = false;\n\n //add all selected checkboxes\n for(let checkbox of this.checkboxes){\n\n if(checkbox.selected) {\n sortOptions = sortOptions.concat(checkbox.getSortOptions());\n }\n else{\n atLeastOneNotSelectedCheckbox = true;\n }\n }\n\n //any number of non selected checkboxes -> 1 default option\n if(atLeastOneNotSelectedCheckbox){\n sortOptions = sortOptions.concat([\n {\n path: 'default'\n }\n ]);\n }\n\n return sortOptions;\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n const cbArr = this.checkboxes.map(cb => {\n\n if(cb.id){\n return cb.selected ? cb.id + '=1' : cb.id + '=0';\n }\n else{\n return '';\n }\n\n }).filter(str => str !== '');\n\n const unique = Array.from(new Set(cbArr));\n return unique.join('&');\n }\n}\n\nexport default CheckboxSortControl;","import BaseSortControlsGroup from '../../base/groups/sort/base-sort-controls-group';\nimport BaseSortControl from '../../base/controls/sort/base-sort.control';\n\n/**\n * select sort control\n * \n *\n * Sort by\n *\n * Title A-Z\n *\n * Title Z-A\n * \n *\n * option may have the following attributes:\n * ------------------------------------------\n * data-path - required CSS path selector\n * data-order - optional, asc (default) / desc\n * data-type=\"text\" - optional, text (default) / number / datetime\n * data-datetime-format=\"{month}/{day}/{year}\" - optional datetime format\n * data-regex - optional ignore regex\n */\nclass SelectSortControl extends BaseSortControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.options = [];\n this.selected = '';\n this.id = '';\n }\n\n /**\n * add control to the group\n * @param {BaseSortControl} control\n */\n addControl(control){\n\n const baseSortControl = super.addControl(control);\n\n let options = baseSortControl.element.querySelectorAll('option');\n\n for(let option of options){\n\n option.setAttribute('data-name', this.name);\n option.setAttribute('data-group', this.group);\n\n if(!this.options.find(opt => opt.element.value === option.value)){\n this.options.push(new BaseSortControl(option));\n }\n }\n\n this.selected = baseSortControl.element.value;\n\n //check if control contains a link and it is in the deep links parameters\n if(baseSortControl.id){\n\n this.id = baseSortControl.id;\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseSortControl.id);\n\n if(deepLinkParam){\n baseSortControl.element.value = deepLinkParam.value;\n this.selected = deepLinkParam.value;\n }\n }\n\n /**\n * on control change -> update the selected control\n */\n baseSortControl.element.addEventListener('change', e => {\n\n e.preventDefault();\n\n this.selected = e.target.value;\n\n for(let select of this.controls){\n select.element.value = this.selected;\n }\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseSortControl);\n }\n });\n }\n\n /**\n * get sort options from all controls in the group\n * @return {Array.} sortOptions\n */\n getSortOptions(){\n\n let selected = this.options.find(opt => opt.element.value === this.selected);\n\n if(selected){\n return selected.getSortOptions();\n }\n\n return [];\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n\n let selected = this.options.find(opt => opt.element.value === this.selected);\n\n if(this.id){\n return this.id + '=' + selected.element.value;\n }\n\n return '';\n }\n}\n\nexport default SelectSortControl;","import './base-dropdown.control.css';\n\n/**\n * base dropdown control\n */\nclass BaseDropdownControl{\n\n\n /**\n * control type defined in data-jplist-control attribute;\n * for example, data-jplist-control=\"hidden-sort\" has type='hidden-sort'\n * @param {HTMLElement} element\n */\n constructor(element){\n\n if(element) {\n\n this.element = element;\n\n if(!this.element) return;\n\n //dropdown panel elements defined by data-type=\"panel\" data attribute; can be multiple;\n this.panels = this.element.querySelectorAll('[data-type=\"panel\"]');\n this.element.openedClass = (this.element.getAttribute('data-opened-class') || 'jplist-dd-opened').trim();\n\n //keep panels initial html\n for(let panel of this.panels){\n panel.initialContent = panel.innerHTML;\n panel.element = element;\n }\n\n //dropdown content elements defined by data-type=\"content\" data attribute; can be multiple;\n this.contents = this.element.querySelectorAll('[data-type=\"content\"]');\n\n //handle panels onclick event\n this.handlePanelsClick();\n }\n }\n\n /**\n * handle panels onclick event\n */\n handlePanelsClick(){\n\n if(!this.panels || this.panels.length <= 0) return;\n\n for(let panel of this.panels){\n\n /**\n * on panel click\n */\n panel.addEventListener('click', e => {\n\n //e.stopPropagation();\n\n let atLeastOnePanelIsOpened = false;\n\n for(let dropdownContent of this.contents){\n\n dropdownContent.classList.toggle(panel.element.openedClass);\n\n if(dropdownContent.classList.contains(panel.element.openedClass)){\n atLeastOnePanelIsOpened = true;\n }\n }\n\n if(atLeastOnePanelIsOpened){\n panel.classList.add(panel.element.openedClass);\n panel.element.classList.add(panel.element.openedClass);\n }\n else{\n panel.classList.remove(panel.element.openedClass);\n panel.element.classList.remove(panel.element.openedClass);\n }\n });\n }\n\n /**\n * close dropdowns on body click\n */\n document.addEventListener('click', e => {\n\n if (!this.element.contains(e.target)) { // or use: event.target.closest(selector) === null\n\n this.close();\n }\n });\n }\n\n /**\n * set panels content\n * @param {string} content\n */\n setPanelsContent(content){\n\n for(let panel of this.panels){\n panel.innerHTML = content;\n }\n }\n\n /**\n * restore panels content\n */\n restorePanelsContent(){\n\n for(let panel of this.panels){\n\n if(panel.initialContent) {\n panel.innerHTML = panel.initialContent;\n }\n }\n }\n\n /**\n * close dropdown\n */\n close(){\n for(let dropdownContent of this.contents){\n\n dropdownContent.classList.remove(this.panels[0].element.openedClass);\n }\n\n for(let panel of this.panels){\n panel.classList.remove(panel.element.openedClass);\n panel.element.classList.remove(panel.element.openedClass);\n }\n }\n}\n\nexport default BaseDropdownControl;","import BaseSortControlsGroup from '../../base/groups/sort/base-sort-controls-group';\nimport BaseSortControl from '../../base/controls/sort/base-sort.control';\nimport BaseDropdownControl from '../../base/controls/dropdown/base-dropdown.control';\n\n/**\n * dropdown sort control\n */\nclass DropdownSortControl extends BaseSortControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n this.selected = null;\n this.id = '';\n }\n\n /**\n * add control to the group\n * @param {BaseSortControl} control\n */\n addControl(control){\n\n //a dropdown has the following custom properties:\n // -- dropdown - custom dropdown behaviour, styles, classes\n // -- buttons - the list of dropdown buttons, each of them is BaseSortControl\n const baseSortControl = super.addControl(control);\n\n //generate dropdown instance for the given control;\n //this instance adds dropdown classes, styles and behaviour\n baseSortControl.dropdown = new BaseDropdownControl(control.element);\n baseSortControl.buttons = [];\n\n //each button inside dropdown is a separate sort control that defined by data-path attribute;\n //they are stored in baseSortControl.buttons array\n let buttons = baseSortControl.element.querySelectorAll('[data-path]');\n\n for(let button of buttons){\n\n //all buttons inherits data-name and data-group attributes of the root dropdown\n button.setAttribute('data-name', this.name);\n button.setAttribute('data-group', this.group);\n button.setAttribute('data-jump', baseSortControl.jump);\n\n let btnSortControl = new BaseSortControl(button);\n\n //save newly created button in the baseSortControl.buttons array\n baseSortControl.buttons.push(btnSortControl);\n\n /**\n * on control button click -> update the selected control\n */\n btnSortControl.element.addEventListener('click', e => {\n\n e.preventDefault();\n\n //clicked button should be the selected one\n this.selected = btnSortControl;\n\n this.setSelectedButton(baseSortControl);\n\n for(let control of this.controls){\n if(control.dropdown){\n control.dropdown.close();\n }\n }\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, btnSortControl);\n }\n });\n }\n\n this.selected = DropdownSortControl.getSelectedButton(baseSortControl.buttons);\n this.setSelectedButton(baseSortControl);\n\n //check if control contains a link and it is in the deep links parameters\n if(baseSortControl.id){\n\n this.id = baseSortControl.id;\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseSortControl.id);\n\n if(deepLinkParam){\n\n const deepLinkBtn = baseSortControl.buttons.find(btn => {\n\n const btnValue = btn.element.getAttribute('data-value');\n return (deepLinkParam.value === btnValue) ? btn : null;\n });\n\n if(deepLinkBtn) {\n this.selected = deepLinkBtn;\n this.setSelectedButton(baseSortControl);\n }\n }\n }\n }\n\n /**\n * get sort options from all controls in the group\n * @return {Array.} sortOptions\n */\n getSortOptions(){\n\n if(this.selected){\n return this.selected.getSortOptions();\n }\n\n return [];\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n\n if(this.id && this.selected){\n return this.id + '=' + this.selected.element.getAttribute('data-value') || '';\n }\n\n return '';\n }\n\n /**\n * get selected button that has data-selected=\"true\" data attribute;\n * if there is no data-selected attribute -> take the first button\n * @param {Array.} buttons\n * @return {BaseSortControl|null}\n */\n static getSelectedButton(buttons){\n\n if(buttons.length <= 0) return null;\n\n for(let button of buttons){\n if(button.element.getAttribute('data-selected') === 'true'){\n return button;\n }\n }\n\n return buttons[0];\n }\n\n /**\n * set selected button\n * @param {BaseSortControl} baseSortControl\n */\n setSelectedButton(baseSortControl){\n\n for(let control of this.controls){\n\n if(!control.dropdown) continue;\n\n //verify that dropdown has such button\n const dropdownBtn = baseSortControl.buttons.find(btn => this.selected.isEqualTo(btn));\n\n if(dropdownBtn){\n\n //update dropdown panels value\n control.dropdown.setPanelsContent(dropdownBtn.element.textContent);\n }\n }\n }\n}\n\nexport default DropdownSortControl;","import BaseControl from '../base.control';\n\n/**\n * base pagination control\n */\nclass BasePaginationControl extends BaseControl{\n\n /**\n * constructor\n * @param {HTMLElement} element\n */\n constructor(element){\n super(element);\n\n if(element){\n\n /**\n * optional, 10 by default\n * the max number of items per page\n */\n this.itemsPerPage = Number(element.getAttribute('data-items-per-page')) || 10;\n\n /**\n * optional, 0 by default\n * the initial page\n */\n this.currentPage = Number(element.getAttribute('data-current-page')) || 0;\n\n /**\n * optional, 10 by default\n * max number of visible pagination button\n */\n this.range = Number(element.getAttribute('data-range')) || 10;\n\n /**\n * CSS class that is used on disabled pagination buttons\n * @type {string|string}\n */\n this.disabledClass = (element.getAttribute('data-disabled-class') || 'jplist-disabled').trim();\n\n /**\n * CSS class that is used on selected pagination buttons\n * @type {string|string}\n */\n this.selectedClass = (element.getAttribute('data-selected-class') || 'jplist-selected').trim();\n }\n }\n\n /**\n * get pagination options\n * @return {object} options\n */\n getPaginationOptions(){\n\n return {\n itemsPerPage: this.itemsPerPage,\n currentPage: this.currentPage,\n range: this.range\n };\n }\n}\n\nexport default BasePaginationControl;\n","import BaseControlsGroup from '../base-controls-group';\nimport BasePaginationControl from '../../controls/pagination/base-pagination.control';\n\n/**\n * represents a group of pagination controls with the same data-name and data-group attributes\n */\nclass BasePaginationControlsGroup extends BaseControlsGroup{\n\n /**\n * there can be only 1 pagination options object;\n * in case of multiple -> get the latest\n * @return {object|null} pagination options\n */\n getPaginationOptions(){\n\n if(this.controls.length > 0){\n return this.controls[this.controls.length - 1].getPaginationOptions();\n }\n\n return null;\n }\n\n /**\n * update controls according to the pagination options calculated using PaginationAction class;\n * @param {PaginationAction} paginationOptions\n */\n setPaginationOptions(paginationOptions){}\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BasePaginationControl|null}\n */\n addControl(control){\n\n if(control.name !== this.name || control.group !== this.group){\n return null;\n }\n\n const basePaginationControl = new BasePaginationControl(control.element);\n\n this.controls.push(basePaginationControl);\n\n return basePaginationControl;\n }\n}\n\nexport default BasePaginationControlsGroup;\n","import BasePaginationControlsGroup from '../base/groups/pagination/base-pagination-controls-group';\nimport BaseDropdownControl from '../base/controls/dropdown/base-dropdown.control';\n\n/**\n * pagination control\n */\nclass PaginationControl extends BasePaginationControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.currentPage = 0;\n this.itemsPerPage = 0;\n this.range = 0;\n this.id = '';\n }\n\n /**\n * add control to the group\n * @param {BasePaginationControl} control\n */\n addControl(control){\n\n const basePaginationControl = super.addControl(control);\n\n //update properties - we take them from the latest pagination control in the group\n this.currentPage = basePaginationControl.currentPage;\n this.itemsPerPage = Number(basePaginationControl.itemsPerPage) || 0;\n this.range = basePaginationControl.range;\n\n //restore control state from the deep link value if needed\n this.restoreFromDeepLink(basePaginationControl);\n\n //this template is used for generating pagination buttons\n basePaginationControl.pageButtonsHolder = basePaginationControl.element.querySelector('[data-type=\"pages\"]');\n\n if(basePaginationControl.pageButtonsHolder){\n basePaginationControl.btnTemplate = basePaginationControl.pageButtonsHolder.innerHTML;\n }\n\n //first, last, next and prev button\n basePaginationControl.firstButtons = basePaginationControl.element.querySelectorAll('[data-type=\"first\"]');\n basePaginationControl.lastButtons = basePaginationControl.element.querySelectorAll('[data-type=\"last\"]');\n basePaginationControl.prevButtons = basePaginationControl.element.querySelectorAll('[data-type=\"prev\"]');\n basePaginationControl.nextButtons = basePaginationControl.element.querySelectorAll('[data-type=\"next\"]');\n\n //event handlers\n PaginationControl.bindEventHandler(basePaginationControl.firstButtons, 'click', this.pageButtonClick.bind(this), basePaginationControl);\n PaginationControl.bindEventHandler(basePaginationControl.lastButtons, 'click', this.pageButtonClick.bind(this), basePaginationControl);\n PaginationControl.bindEventHandler(basePaginationControl.prevButtons, 'click', this.pageButtonClick.bind(this), basePaginationControl);\n PaginationControl.bindEventHandler(basePaginationControl.nextButtons, 'click', this.pageButtonClick.bind(this), basePaginationControl);\n\n //items per page select\n basePaginationControl.itemsPerPageSelects = Array.from(basePaginationControl.element.querySelectorAll('[data-type=\"items-per-page\"]'));\n this.updateItemsPerPageSelect(basePaginationControl.itemsPerPageSelects);\n\n //items per page custom drop downs\n basePaginationControl.itemsPerPageDD = Array.from(basePaginationControl.element.querySelectorAll('[data-type=\"items-per-page-dd\"]'));\n this.initCustomDropdowns(basePaginationControl);\n\n PaginationControl.bindEventHandler(basePaginationControl.itemsPerPageSelects, 'change', this.selectChange.bind(this), basePaginationControl);\n\n //information labels\n basePaginationControl.labels = basePaginationControl.element.querySelectorAll('[data-type=\"info\"]');\n\n if(basePaginationControl.labels) {\n for (let label of basePaginationControl.labels) {\n label.template = label.innerHTML;\n }\n }\n }\n\n /**\n * update items per page value of select group\n * @param {Array.} selects\n */\n updateItemsPerPageSelect(selects){\n\n for(let select of selects){\n\n const option = Array.from(select.options).find(option => option.value === this.itemsPerPage.toString());\n\n if(option) {\n select.value = Number(this.itemsPerPage) || 0;\n }\n else{\n select.value = 0;\n }\n }\n }\n\n /**\n * init custom dropdowns\n * @param {BasePaginationControl} basePaginationControl\n */\n initCustomDropdowns(basePaginationControl){\n\n //@param {HTMLCollection} itemsPerPageDD\n const itemsPerPageDD = basePaginationControl.itemsPerPageDD;\n\n if(!itemsPerPageDD || itemsPerPageDD.length <=0) return;\n\n for(let dd of itemsPerPageDD){\n\n //create dropdown instance for each dd HTML structure;\n //this instance adds dropdown classes, styles and behaviour\n dd.dropdown = new BaseDropdownControl(dd);\n\n //all dropdown buttons are keeps as buttons property\n dd.buttons = Array.from(dd.querySelectorAll('[data-value]'));\n\n for(let button of dd.buttons){\n\n button.addEventListener('click', (e) => {\n\n e.preventDefault();\n\n this.itemsPerPage = Number(button.getAttribute('data-value')) || 0;\n\n //set selected button in all dropdowns for the current this.itemsPerPage value\n this.setSelectedButton();\n\n dd.dropdown.close();\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, basePaginationControl);\n }\n });\n }\n }\n\n //set selected button in all dropdowns for the current this.itemsPerPage value\n this.setSelectedButton();\n }\n\n // --------------------- BUTTONS ---------------------\n\n /**\n * set selected button in all dropdowns for the current this.itemsPerPage value\n */\n setSelectedButton(){\n\n for(let control of this.controls){\n\n if(!control.itemsPerPageDD) continue;\n\n for(let dd of control.itemsPerPageDD){\n\n if(!dd.buttons) continue;\n\n let selectedButton = dd.buttons.find(button => {\n\n const btnValue = Number(button.getAttribute('data-value')) || 0;\n return btnValue === this.itemsPerPage;\n });\n\n if(!selectedButton){\n\n selectedButton = dd.buttons.find(button => {\n const btnValue = Number(button.getAttribute('data-value')) || 0;\n return btnValue === 0;\n });\n }\n\n if(selectedButton){\n\n dd.dropdown.setPanelsContent(selectedButton.textContent);\n }\n }\n }\n }\n\n // --------------------- OPTIONS ---------------------\n\n /**\n * there can be only 1 pagination options object;\n * in case of multiple -> get the latest\n * @return {object} pagination options\n */\n getPaginationOptions(){\n\n return {\n itemsPerPage: this.itemsPerPage,\n currentPage: this.currentPage,\n range: this.range\n };\n }\n\n /**\n * update controls according to the pagination options calculated using PaginationAction class;\n * @param {PaginationAction} paginationOptions\n */\n setPaginationOptions(paginationOptions){\n\n if(!paginationOptions) return;\n\n //update properties\n this.currentPage = paginationOptions.currentPage;\n this.itemsPerPage = paginationOptions.itemsPerPage;\n\n for(let control of this.controls){\n\n if(!control.btnTemplate || !control.pageButtonsHolder) continue;\n\n //remove all old buttons\n while (control.pageButtonsHolder.firstChild) {\n control.pageButtonsHolder.removeChild(control.pageButtonsHolder.firstChild);\n }\n\n //generate new buttons\n for (let i = paginationOptions.rangeStart; i <= paginationOptions.rangeEnd; i++) {\n\n //update button text macros and button attributes\n const div = document.createElement('div');\n div.innerHTML = control.btnTemplate.replace(new RegExp('{pageNumber}', 'g'), (i+1)).trim();\n const pageButton = div.firstChild;\n\n let btn = pageButton.querySelector('[data-type=\"page\"]');\n if(!btn){\n btn = pageButton;\n }\n\n btn.setAttribute('data-page', i.toString());\n\n if(i === this.currentPage){\n\n btn.classList.add(control.selectedClass);\n btn.setAttribute('data-selected', 'true');\n }\n\n //on page button click event handler\n btn.addEventListener('click', (e) => { this.pageButtonClick(e, btn, control); });\n\n //add button to the buttons holder\n control.pageButtonsHolder.appendChild(pageButton);\n }\n\n //update data-page attribute of first, last, prev and next buttons\n PaginationControl.setPageAttr(control.firstButtons, 0, this.currentPage !== 0, control.disabledClass);\n\n PaginationControl.setPageAttr(control.lastButtons,\n paginationOptions.pagesNumber - 1,\n this.currentPage !== paginationOptions.pagesNumber - 1,\n control.disabledClass);\n\n PaginationControl.setPageAttr(control.prevButtons,\n paginationOptions.prevPage,\n this.currentPage !== 0,\n control.disabledClass);\n\n PaginationControl.setPageAttr(control.nextButtons,\n paginationOptions.nextPage,\n this.currentPage !== paginationOptions.pagesNumber - 1,\n control.disabledClass);\n\n const infos = [\n {key: '{pageNumber}', value: paginationOptions.currentPage + 1},\n {key: '{pagesNumber}', value: paginationOptions.pagesNumber},\n {key: '{startItem}', value: paginationOptions.start + 1},\n {key: '{endItem}', value: paginationOptions.end},\n {key: '{itemsNumber}', value: paginationOptions.itemsNumber}\n ];\n\n //update information labels\n if(control.labels) {\n for (let label of control.labels) {\n\n if(!label.template) continue;\n\n let html = label.template;\n\n for(let info of infos){\n html = html.replace(new RegExp(info.key, 'g'), info.value);\n }\n\n label.innerHTML = html;\n }\n }\n\n //update whole control classes\n const classesToRemove = (Array.from(control.element.classList)).filter(className => className.startsWith('jplist-pages-number-') || className.startsWith('jplist-items-number-'));\n\n for(let className of classesToRemove){\n control.element.classList.remove(className);\n }\n\n control.element.classList.add('jplist-pages-number-' + paginationOptions.pagesNumber);\n control.element.classList.add('jplist-items-number-' + paginationOptions.itemsNumber);\n }\n }\n\n // --------------------- EVENT HANDLERS ---------------------\n\n /**\n * page, first, last, prev and next button onclick handler\n * @param {HTMLElement} btn\n * @param {BasePaginationControl} control\n */\n pageButtonClick(e, btn, control){\n\n if(e) {\n e.preventDefault();\n }\n\n const pageNumber = btn ? btn.getAttribute('data-page') : e.target.getAttribute('data-page');\n this.currentPage = Number(pageNumber) || 0;\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, control);\n }\n }\n\n /**\n * on items per page select change\n * @param {object} e\n * @param {HTMLElement} select\n * @param {BasePaginationControl} basePaginationControl\n */\n selectChange(e, select, basePaginationControl){\n\n e.preventDefault();\n\n const itemsPerPage = Number(e.target.value);\n\n if(!isNaN(itemsPerPage)){\n\n this.itemsPerPage = itemsPerPage;\n\n //update the selected values of all controls\n for(let control of this.controls){\n this.updateItemsPerPageSelect(control.itemsPerPageSelects);\n }\n }\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, basePaginationControl);\n }\n }\n\n // --------------------- DEEP LINK ---------------------\n\n /**\n * restore control state from the deep link value\n * @param {BasePaginationControl} basePaginationControl\n */\n restoreFromDeepLink(basePaginationControl){\n\n if(basePaginationControl.id){\n\n this.id = basePaginationControl.id;\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === basePaginationControl.id);\n\n if(deepLinkParam){\n\n const parts = deepLinkParam.value.split('-');\n\n if(parts.length !== 2) return;\n\n const currentPage = Number(parts[0]);\n const itemsPerPage = Number(parts[1]);\n\n if(isNaN(currentPage) || isNaN(itemsPerPage)) return;\n\n this.currentPage = currentPage;\n this.itemsPerPage = itemsPerPage;\n }\n }\n }\n\n /**\n * by default control's deep link is empty\n * @returns {string}\n */\n getDeepLink(){\n\n if(this.id){\n return this.id + '=' + this.currentPage + '-' + this.itemsPerPage;\n }\n\n return '';\n }\n\n // --------------------- HELPERS ---------------------\n\n /**\n * update page button attributes and styles of the elements collection\n * @param {HTMLCollection} items\n * @param {number} page\n * @param {boolean} isEnabled\n * @param {string} disabledClass\n */\n static setPageAttr(items, page, isEnabled, disabledClass){\n\n if(!items) return;\n\n for(let item of items){\n item.setAttribute('data-page', page);\n\n if(isEnabled){\n item.classList.remove(disabledClass);\n }\n else{\n item.classList.add(disabledClass);\n }\n }\n }\n\n /**\n * bind event handler to the items collection\n * @param {HTMLCollection} items\n * @param {string} eventName\n * @param {Function} func\n * @param {BasePaginationControl} basePaginationControl\n */\n static bindEventHandler(items, eventName, func, basePaginationControl){\n\n if(!items) return;\n\n for(let item of items){\n item.addEventListener(eventName, (e) => {func(e, item, basePaginationControl); });\n }\n }\n}\n\nexport default PaginationControl;","import BaseControl from '../base.control';\n\n/**\n * base text filter control\n */\nclass BaseTextFilterControl extends BaseControl{\n\n /**\n * constructor\n * @param {HTMLElement} element\n */\n constructor(element){\n super(element);\n\n if(element){\n\n /**\n * css selector or 'default' for the browser default order (no sort); if path is empty -> the whole element\n * @type {string}\n */\n this.path = (element.getAttribute('data-path') || '').trim();\n\n /**\n * initial text value is used to handle multiple same control in different panels\n * @type {string}\n */\n this.initialText = element.getAttribute('data-text') || element.value || '';\n\n /**\n * trimmed text value items filter by\n * @type {string}\n */\n this._text = (element.getAttribute('data-text') || element.value || '').trim();\n\n /**\n * filter mode - contains (default), startsWith, endsWith, equal\n * @type {string}\n */\n this.mode = (element.getAttribute('data-mode') || 'contains').trim();\n\n /**\n * optional ignore regex - used to ignore characters before sort\n * @type {string}\n */\n this.regex = element.getAttribute('data-regex') || '';\n\n /**\n * optional \"OR\" logic property, used to combine different filter controls with \"OR\" logic instead of \"AND\"\n * @type {string|null}\n */\n this.or = element.getAttribute('data-or') || null;\n }\n }\n\n /**\n * text setter\n * @param {string} value\n */\n set text(value){\n\n this.initialText = value || '';\n this._text = (value || '').trim();\n }\n\n /**\n * text getter\n * @return {string}\n */\n get text(){\n\n return this._text;\n }\n\n\n /**\n * get text filter options used in FilterAction.textFilter method\n * @return {Array.<{object}>} options\n */\n getTextFilterOptions(){\n\n return {\n path: this.path,\n text: this.text,\n mode: this.mode,\n ignoreRegex: this.regex,\n or: this.or\n };\n }\n\n /**\n * check if current control has the same properties like the specified control;\n * the values could be different\n * @param {BaseTextFilterControl} control\n * @param {boolean} includeValue\n * @return {boolean}\n */\n isEqualTo(control, includeValue = true){\n\n let isEqual = this.path === control.path &&\n this.mode === control.mode &&\n this.regex === control.regex;\n\n if(includeValue){\n isEqual = isEqual && this.text === control.text;\n }\n\n return isEqual;\n }\n}\n\nexport default BaseTextFilterControl;","import BaseControlsGroup from '../base-controls-group';\nimport BaseTextFilterControl from '../../controls/filter/base-text-filter.control';\n\n/**\n * represents a group of text filter controls with the same data-name and data-group attributes\n */\nclass BaseTextFilterControlsGroup extends BaseControlsGroup{\n\n /**\n * get text filter options from all controls in the group\n * @return {Array.} text filter options\n */\n getTextFilterOptions(){\n\n let options = [];\n\n for(let control of this.controls){\n options = options.concat(control.getTextFilterOptions());\n }\n\n return options;\n }\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BaseTextFilterControl|null}\n */\n addControl(control){\n\n if(control.name !== this.name || control.group !== this.group){\n return null;\n }\n\n const baseTextFilterControl = new BaseTextFilterControl(control.element);\n\n this.controls.push(baseTextFilterControl);\n\n return baseTextFilterControl;\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n\n const dl = this.controls.map(control => control.id && control.text.trim() !== '' ? (control.id + '=' + control.text.trim()) : '').filter(str => str !== '');\n\n const unique = Array.from(new Set(dl));\n return unique.join('&');\n }\n}\n\nexport default BaseTextFilterControlsGroup;\n","import BaseTextFilterControlsGroup from '../../../base/groups/filter/base-text-filter-controls-group';\n\n/**\n * text box filter control\n */\nclass TextboxFilterControl extends BaseTextFilterControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n }\n\n /**\n * add control to the group\n * @param {BaseTextFilterControl} control\n */\n addControl(control){\n\n const baseTextFilterControl = super.addControl(control);\n\n //check if control contains a link and it is in the deep links parameters\n if(baseTextFilterControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseTextFilterControl.id);\n\n if(deepLinkParam){\n baseTextFilterControl.text = deepLinkParam.value;\n baseTextFilterControl.element.value = deepLinkParam.value;\n }\n }\n\n /**\n * on control event\n */\n baseTextFilterControl.element.addEventListener('keyup', e => {\n\n e.preventDefault();\n\n baseTextFilterControl.text = e.target.value;\n\n this.textChanged(baseTextFilterControl);\n });\n\n //handle clear button\n baseTextFilterControl.clearButtonID = (baseTextFilterControl.element.getAttribute('data-clear-btn-id') || '').trim();\n\n if(baseTextFilterControl.clearButtonID){\n\n const clearBtn = document.getElementById(baseTextFilterControl.clearButtonID);\n\n if(clearBtn){\n\n /**\n * on clear button click\n */\n clearBtn.addEventListener('click', e => {\n\n e.preventDefault();\n\n baseTextFilterControl.text = '';\n\n this.textChanged(baseTextFilterControl);\n });\n }\n }\n }\n\n /**\n * on text change\n */\n textChanged(baseTextFilterControl){\n\n this.controls.forEach(control => {\n\n if(control.isEqualTo(baseTextFilterControl, false)){\n\n control.element.value = baseTextFilterControl.initialText;\n control.text = baseTextFilterControl.initialText;\n }\n });\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseTextFilterControl);\n }\n }\n\n}\n\nexport default TextboxFilterControl;","const SELECTED_CLASS = 'jplist-selected';\n\n/**\n * checkbox mixin\n * used for multiple inheritance\n * usage example:\n * class CheckboxTextFilterControl extends CheckboxMixin(BaseTextFilterControlsGroup)\n * @param {class} superclass\n * @return {class}\n */\nconst CheckboxMixin = superclass => class extends superclass {\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.checkboxes = [];\n }\n\n /**\n * add control to the group\n * @param {BasePathFilterControl} control\n */\n addControl(control){\n\n const baseControl = super.addControl(control);\n\n //get additional control properties\n baseControl.selected = baseControl.element.checked;\n\n //check if control contains a link and it is in the deep links parameters\n if(baseControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseControl.id);\n\n if(deepLinkParam){\n baseControl.selected = deepLinkParam.value === '1';\n }\n }\n\n this.checkboxes.push(baseControl);\n this.handleCheckboxes();\n\n /**\n * on control change -> update the selected control\n */\n baseControl.element.addEventListener('change', e => {\n\n e.preventDefault();\n\n baseControl.selected = !baseControl.selected;\n\n this.checkboxes.forEach(cb => {\n\n if(cb.isEqualTo(baseControl)){\n cb.selected = baseControl.selected;\n }\n });\n\n this.handleCheckboxes();\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseControl);\n }\n });\n }\n\n /**\n * handle checkbox mode controls\n */\n handleCheckboxes(){\n\n for(let cb of this.checkboxes){\n\n if(cb.selected){\n cb.element.classList.add(SELECTED_CLASS);\n }\n else{\n cb.element.classList.remove(SELECTED_CLASS);\n }\n\n cb.element.checked = cb.selected;\n }\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n const cbArr = this.checkboxes.map(cb => {\n\n if(cb.id){\n return cb.selected ? cb.id + '=1' : cb.id + '=0';\n }\n else{\n return '';\n }\n\n }).filter(str => str !== '');\n const unique = Array.from(new Set(cbArr));\n return unique.join('&');\n }\n};\n\nexport default CheckboxMixin;","import BaseTextFilterControlsGroup from '../../../base/groups/filter/base-text-filter-controls-group';\nimport CheckboxMixin from '../../../base/groups/mixins/checkbox.mixin';\n\n/**\n * checkbox text filter control\n */\nclass CheckboxTextFilterControl extends CheckboxMixin(BaseTextFilterControlsGroup){\n\n /**\n * get text filter options from all controls in the group\n * @return {Array.} path filter options\n */\n getTextFilterOptions(){\n\n let options = [];\n\n //add all selected checkboxes\n for(let checkbox of this.checkboxes){\n\n if(checkbox.selected) {\n options = options.concat(checkbox.getTextFilterOptions());\n }\n }\n\n return options;\n }\n}\n\nexport default CheckboxTextFilterControl;","const SELECTED_CLASS = 'jplist-selected';\n\n/**\n * radio buttons mixin\n * used for multiple inheritance\n * usage example:\n * class CheckboxTextFilterControl extends CheckboxMixin(BaseTextFilterControlsGroup)\n * @param {class} superclass\n * @return {class}\n */\nconst RadioButtonsMixin = superclass => class extends superclass {\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.radios = [];\n }\n\n /**\n * add control to the group\n * @param {BasePathFilterControl} control\n */\n addControl(control){\n\n const baseControl = super.addControl(control);\n\n //get additional control properties\n baseControl.selected = baseControl.element.checked;\n\n //check if control contains a link and it is in the deep links parameters\n if(baseControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseControl.id);\n\n if(deepLinkParam){\n baseControl.selected = deepLinkParam.value === '1';\n }\n }\n\n this.radios.push(baseControl);\n this.handleRadios();\n\n /**\n * on control change -> update the selected control\n */\n baseControl.element.addEventListener('change', e => {\n\n e.preventDefault();\n\n for (let radio of this.radios) {\n radio.selected = false;\n }\n\n baseControl.selected = true;\n\n this.handleRadios();\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseControl);\n }\n });\n }\n\n /**\n * get the latest selected radio\n * @return {BasePathFilterControl} latestSelectedRadio\n */\n getLastSelectedRadio(){\n\n let latestSelectedRadio = null;\n\n //find the latest selected radio\n for (let radio of this.radios) {\n\n if (radio.selected) {\n latestSelectedRadio = radio;\n }\n }\n\n return latestSelectedRadio;\n }\n\n /**\n * handle radio buttons\n */\n handleRadios(){\n\n if(this.radios.length > 0) {\n\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n //remove selected from all radios\n for (let radio of this.radios) {\n\n radio.selected = false;\n radio.element.classList.remove(SELECTED_CLASS);\n }\n\n if(latestSelectedRadio) {\n\n this.radios.forEach(radio => {\n\n if(radio.isEqualTo(latestSelectedRadio)){\n radio.selected = true;\n radio.element.checked = true;\n radio.element.classList.add(SELECTED_CLASS);\n }\n });\n }\n }\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n const radioArr = this.radios.map(radio => radio.id && radio.selected ? radio.id + '=1' : '').filter(str => str !== '');\n const unique = Array.from(new Set(radioArr));\n return unique.join('&');\n }\n};\n\nexport default RadioButtonsMixin;","import BaseTextFilterControlsGroup from '../../../base/groups/filter/base-text-filter-controls-group';\nimport RadioButtonsMixin from '../../../base/groups/mixins/radio-buttons.mixin';\n\n/**\n * radio buttons text filter control\n */\nclass RadioButtonsTextFilterControl extends RadioButtonsMixin(BaseTextFilterControlsGroup){\n\n /**\n * get text filter options from all controls in the group\n * @return {Array.} path filter options\n */\n getTextFilterOptions(){\n\n let options = [];\n\n //get options from the latest selected radio if exists\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n if(latestSelectedRadio){\n options = options.concat(latestSelectedRadio.getTextFilterOptions());\n }\n\n return options;\n }\n}\n\nexport default RadioButtonsTextFilterControl;","const SELECTED_CLASS = 'jplist-selected';\n\n/**\n * buttons mixin\n * used for multiple inheritance\n * usage example:\n * class ButtonsTextFilterControl extends ButtonsMixin(BaseTextFilterControlsGroup)\n * @param {class} superclass\n * @return {class}\n */\nconst ButtonsMixin = superclass => class extends superclass {\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.checkboxes = [];\n this.radios = [];\n }\n\n /**\n * add control to the group\n * @param {BasePathFilterControl} control\n */\n addControl(control){\n\n const baseButtonControl = super.addControl(control);\n\n //get additional control properties\n baseButtonControl.selected = baseButtonControl.element.getAttribute('data-selected') === 'true';\n baseButtonControl.mode = baseButtonControl.element.getAttribute('data-mode') || 'radio';\n\n //check if control contains a link and it is in the deep links parameters\n if(baseButtonControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === baseButtonControl.id);\n\n if(deepLinkParam){\n baseButtonControl.selected = deepLinkParam.value === '1';\n }\n }\n\n if(baseButtonControl.mode === 'radio'){\n\n this.radios.push(baseButtonControl);\n this.handleRadios();\n }\n\n if(baseButtonControl.mode === 'checkbox'){\n\n this.checkboxes.push(baseButtonControl);\n this.handleCheckboxes();\n }\n\n /**\n * on control click -> change the selected control\n */\n baseButtonControl.element.addEventListener('click', e => {\n\n e.preventDefault();\n\n if(baseButtonControl.mode === 'checkbox'){\n\n baseButtonControl.selected = !baseButtonControl.selected;\n\n this.checkboxes.forEach(cb => {\n\n if(cb.isEqualTo(baseButtonControl)){\n cb.selected = baseButtonControl.selected;\n }\n });\n\n this.handleCheckboxes();\n }\n\n if(baseButtonControl.mode === 'radio'){\n\n for (let radio of this.radios) {\n radio.selected = false;\n }\n\n baseButtonControl.selected = true;\n\n this.handleRadios();\n }\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, baseButtonControl);\n }\n });\n }\n\n /**\n * handle checkbox mode controls\n */\n handleCheckboxes(){\n\n for(let cb of this.checkboxes){\n\n if(cb.selected){\n cb.element.classList.add(SELECTED_CLASS);\n }\n else{\n cb.element.classList.remove(SELECTED_CLASS);\n }\n\n cb.element.checked = cb.selected;\n }\n }\n\n /**\n * get the latest selected radio\n * @return {BasePathFilterControl} latestSelectedRadio\n */\n getLastSelectedRadio(){\n\n let latestSelectedRadio = null;\n\n //find the latest selected radio\n for (let radio of this.radios) {\n\n if (radio.selected) {\n latestSelectedRadio = radio;\n }\n }\n\n return latestSelectedRadio;\n }\n\n /**\n * handle radio buttons\n */\n handleRadios(){\n\n if(this.radios.length > 0) {\n\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n //remove selected from all radios\n for (let radio of this.radios) {\n\n radio.selected = false;\n radio.element.classList.remove(SELECTED_CLASS);\n }\n\n if(latestSelectedRadio) {\n\n this.radios.forEach(radio => {\n\n if(radio.isEqualTo(latestSelectedRadio)){\n radio.selected = true;\n radio.element.checked = true;\n radio.element.classList.add(SELECTED_CLASS);\n }\n });\n }\n }\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n const cbArr = this.checkboxes.map(cb => {\n\n if(cb.id){\n return cb.selected ? cb.id + '=1' : cb.id + '=0';\n }\n else{\n return '';\n }\n\n }).filter(str => str !== '');\n\n const radioArr = this.radios.map(radio => radio.id && radio.selected ? radio.id + '=1' : '').filter(str => str !== '');\n\n const combined = cbArr.concat(radioArr);\n const unique = Array.from(new Set(combined));\n return unique.join('&');\n }\n};\n\nexport default ButtonsMixin;","import BaseTextFilterControlsGroup from '../../../base/groups/filter/base-text-filter-controls-group';\nimport ButtonsMixin from '../../../base/groups/mixins/buttons.mixin';\n\n/**\n * buttons text filter control\n */\nclass ButtonsTextFilterControl extends ButtonsMixin(BaseTextFilterControlsGroup){\n\n /**\n * get text filter options from all controls in the group\n * @return {Array.} text filter options\n */\n getTextFilterOptions(){\n\n let options = [];\n\n //get options from the latest selected radio if exists\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n if(latestSelectedRadio){\n options = options.concat(latestSelectedRadio.getTextFilterOptions());\n }\n\n //add all selected checkboxes\n for(let checkbox of this.checkboxes){\n\n if(checkbox.selected) {\n options = options.concat(checkbox.getTextFilterOptions());\n }\n }\n\n return options;\n }\n\n}\n\nexport default ButtonsTextFilterControl;","import BaseControl from '../base.control';\n\n/**\n * base path filter control\n */\nclass BasePathFilterControl extends BaseControl{\n\n /**\n * constructor\n * @param {HTMLElement} element\n */\n constructor(element){\n super(element);\n\n if(element){\n\n /**\n * css selector or 'default' for the browser default order (no sort); if path is empty -> the whole element\n * @type {string}\n */\n this.path = (element.getAttribute('data-path') || '').trim();\n\n /**\n * defines if path is inverted; if true, the path filter returns all items that DON'T contain the specified path\n * @type {string}\n */\n this.isInverted = (element.getAttribute('data-inverted') || '').toLowerCase().trim() === 'true';\n\n /**\n * optional \"OR\" logic property, used to combine different filter controls with \"OR\" logic instead of \"AND\"\n * @type {string|null}\n */\n this.or = element.getAttribute('data-or') || null;\n }\n }\n\n /**\n * get path filter options used in FilterAction.pathFilter method\n * @return {Array.<{object}>} options\n */\n getPathFilterOptions(){\n\n return {\n path: this.path,\n isInverted: this.isInverted,\n or: this.or\n };\n }\n\n /**\n * check if current control has the same properties like the specified control\n * @param {BasePathFilterControl} control\n * @return {boolean}\n */\n isEqualTo(control){\n return this.path === control.path && this.isInverted === control.isInverted;\n }\n}\n\nexport default BasePathFilterControl;","import BaseControlsGroup from '../base-controls-group';\nimport BasePathFilterControl from '../../controls/filter/base-path-filter.control';\n\n/**\n * represents a group of path filter controls with the same data-name and data-group attributes\n */\nclass BasePathFilterControlsGroup extends BaseControlsGroup{\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BasePathFilterControl|null}\n */\n addControl(control){\n\n if(control.name !== this.name || control.group !== this.group){\n return null;\n }\n\n const basePathFilterControl = new BasePathFilterControl(control.element);\n\n this.controls.push(basePathFilterControl);\n\n return basePathFilterControl;\n }\n\n /**\n * get path filter options from all controls in the group\n * @return {Array.} path filer options\n */\n getPathFilterOptions(){\n\n let options = [];\n\n for(let control of this.controls){\n options = options.concat(control.getPathFilterOptions());\n }\n\n return options;\n }\n\n}\n\nexport default BasePathFilterControlsGroup;\n","import BasePathFilterControlsGroup from '../../../base/groups/filter/base-path-filter-controls-group';\nimport BasePathFilterControl from '../../../base/controls/filter/base-path-filter.control';\n\n/**\n * select filter control\n */\nclass SelectFilterControl extends BasePathFilterControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.options = [];\n this.selected = '';\n this.id = '';\n }\n\n /**\n * add control to the group\n * @param {BasePathFilterControl} control\n */\n addControl(control){\n\n const selectFilterControl = super.addControl(control);\n\n let options = selectFilterControl.element.querySelectorAll('option');\n\n for(let option of options){\n\n option.setAttribute('data-name', this.name);\n option.setAttribute('data-group', this.group);\n\n if(!this.options.find(opt => opt.element.value === option.value)){\n this.options.push(new BasePathFilterControl(option));\n }\n }\n\n this.selected = selectFilterControl.element.value;\n\n //check if control contains a link and it is in the deep links parameters\n if(selectFilterControl.id){\n\n this.id = selectFilterControl.id;\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === selectFilterControl.id);\n\n if(deepLinkParam){\n selectFilterControl.element.value = deepLinkParam.value;\n this.selected = deepLinkParam.value;\n }\n }\n\n /**\n * on control event\n */\n selectFilterControl.element.addEventListener('change', e => {\n\n e.preventDefault();\n\n this.selected = e.target.value;\n\n for(let select of this.controls){\n select.element.value = this.selected;\n }\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, selectFilterControl);\n }\n });\n }\n\n /**\n * get path filter options from all controls in the group\n * @return {Array.} sortOptions\n */\n getPathFilterOptions(){\n\n let selected = this.options.find(opt => opt.element.value === this.selected);\n\n if(selected){\n return [selected.getPathFilterOptions()];\n }\n\n return [];\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n\n let selected = this.options.find(opt => opt.element.value === this.selected);\n\n if(this.id){\n return this.id + '=' + selected.element.value;\n }\n\n return '';\n }\n\n}\n\nexport default SelectFilterControl;","import BasePathFilterControlsGroup from '../../../base/groups/filter/base-path-filter-controls-group';\nimport CheckboxMixin from '../../../base/groups/mixins/checkbox.mixin';\n\n/**\n * checkbox path filter control\n */\nclass CheckboxPathFilterControl extends CheckboxMixin(BasePathFilterControlsGroup){\n\n /**\n * get path filter options from all controls in the group\n * @return {Array.} path filter options\n */\n getPathFilterOptions(){\n\n let options = [];\n\n //add all selected checkboxes\n for(let checkbox of this.checkboxes){\n\n if(checkbox.selected) {\n options = options.concat(checkbox.getPathFilterOptions());\n }\n }\n\n return options;\n }\n}\n\nexport default CheckboxPathFilterControl;","import BasePathFilterControlsGroup from '../../../base/groups/filter/base-path-filter-controls-group';\nimport RadioButtonsMixin from '../../../base/groups/mixins/radio-buttons.mixin';\n\n/**\n * radio buttons path filter control\n */\nclass RadioButtonsPathFilterControl extends RadioButtonsMixin(BasePathFilterControlsGroup){\n\n /**\n * get path filter options from all controls in the group\n * @return {Array.} path filter options\n */\n getPathFilterOptions(){\n\n let options = [];\n\n //get options from the latest selected radio if exists\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n if(latestSelectedRadio){\n options = options.concat(latestSelectedRadio.getPathFilterOptions());\n }\n\n return options;\n }\n}\n\nexport default RadioButtonsPathFilterControl;","import BasePathFilterControlsGroup from '../../../base/groups/filter/base-path-filter-controls-group';\nimport ButtonsMixin from '../../../base/groups/mixins/buttons.mixin';\n\n/**\n * buttons path filter control\n */\nclass ButtonsPathFilterControl extends ButtonsMixin(BasePathFilterControlsGroup){\n\n /**\n * get path filter options from all controls in the group\n * @return {Array.} path filter options\n */\n getPathFilterOptions(){\n\n let options = [];\n\n //get options from the latest selected radio if exists\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n if(latestSelectedRadio){\n options = options.concat(latestSelectedRadio.getPathFilterOptions());\n }\n\n //add all selected checkboxes\n for(let checkbox of this.checkboxes){\n\n if(checkbox.selected) {\n options = options.concat(checkbox.getPathFilterOptions());\n }\n }\n\n return options;\n }\n}\n\nexport default ButtonsPathFilterControl;","import BasePathFilterControlsGroup from '../../../base/groups/filter/base-path-filter-controls-group';\nimport BasePathFilterControl from '../../../base/controls/filter/base-path-filter.control';\nimport BaseDropdownControl from '../../../base/controls/dropdown/base-dropdown.control';\n\n/**\n * dropdown filter control\n */\nclass DropdownFilterControl extends BasePathFilterControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n this.selected = '';\n this.id = '';\n }\n\n /**\n * add control to the group\n * @param {BasePathFilterControl} control\n */\n addControl(control){\n\n //a dropdown has the following custom properties:\n // -- dropdown - custom dropdown behaviour, styles, classes\n // -- buttons - the list of dropdown buttons, each of them is BaseSortControl\n const basePathFilterControl = super.addControl(control);\n\n //generate dropdown instance for the given control;\n //this instance adds dropdown classes, styles and behaviour\n basePathFilterControl.dropdown = new BaseDropdownControl(control.element);\n basePathFilterControl.buttons = [];\n\n //each button inside dropdown is a separate path filter control that defined by data-path attribute;\n //they are stored in basePathFilterControl.buttons array\n let buttons = basePathFilterControl.element.querySelectorAll('[data-path]');\n\n for(let button of buttons){\n\n button.setAttribute('data-name', this.name);\n button.setAttribute('data-group', this.group);\n button.setAttribute('data-jump', basePathFilterControl.jump);\n\n let btnPathFilterControl = new BasePathFilterControl(button);\n\n //save newly created button in the basePathFilterControl.buttons array\n basePathFilterControl.buttons.push(btnPathFilterControl);\n\n /**\n * on control button click -> update the selected control\n */\n btnPathFilterControl.element.addEventListener('click', e => {\n\n e.preventDefault();\n\n //clicked button should be the selected one\n this.selected = btnPathFilterControl;\n\n this.setSelectedButton(basePathFilterControl);\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, btnPathFilterControl);\n }\n });\n }\n\n this.selected = DropdownFilterControl.getSelectedButton(basePathFilterControl.buttons);\n this.setSelectedButton(basePathFilterControl);\n\n //check if control contains a link and it is in the deep links parameters\n if(basePathFilterControl.id){\n\n this.id = basePathFilterControl.id;\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === basePathFilterControl.id);\n\n if(deepLinkParam){\n\n const deepLinkBtn = basePathFilterControl.buttons.find(btn => {\n\n const btnValue = btn.element.getAttribute('data-value');\n return (deepLinkParam.value === btnValue) ? btn : null;\n });\n\n if(deepLinkBtn) {\n this.selected = deepLinkBtn;\n this.setSelectedButton(basePathFilterControl);\n }\n }\n }\n }\n\n /**\n * get path filter options from all controls in the group\n * @return {Array.} pathFilterOptions\n */\n getPathFilterOptions(){\n\n if(this.selected){\n return [this.selected.getPathFilterOptions()];\n }\n\n return [];\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n\n if(this.id && this.selected){\n return this.id + '=' + this.selected.element.getAttribute('data-value') || '';\n }\n\n return '';\n }\n\n /**\n * get selected button that has data-selected=\"true\" data attribute;\n * if there is no data-selected attribute -> take the first button\n * @param {Array.} buttons\n * @return {BasePathFilterControl|null}\n */\n static getSelectedButton(buttons){\n\n if(buttons.length <= 0) return null;\n\n for(let button of buttons){\n if(button.element.getAttribute('data-selected') === 'true'){\n return button;\n }\n }\n\n return buttons[0];\n }\n\n /**\n * set selected button\n * @param {BasePathFilterControl} basePathFilterControl\n */\n setSelectedButton(basePathFilterControl){\n\n for(let control of this.controls){\n\n if(!control.dropdown) continue;\n\n //verify that dropdown has such button\n const dropdownBtn = basePathFilterControl.buttons.find(btn => this.selected.isEqualTo(btn));\n\n if(dropdownBtn){\n\n //update dropdown panels value\n control.dropdown.setPanelsContent(dropdownBtn.element.textContent);\n }\n\n control.dropdown.close();\n }\n }\n\n}\n\nexport default DropdownFilterControl;","import BaseControl from '../base.control';\n\n/**\n * base range filter control\n */\nclass BaseRangeFilterControl extends BaseControl{\n\n /**\n * constructor\n * @param {HTMLElement} element\n */\n constructor(element){\n super(element);\n\n if(element){\n\n /**\n * css selector or 'default' for the browser initial list; if path is empty -> the whole element\n * @type {string}\n */\n this.path = (element.getAttribute('data-path') || '').trim();\n\n const from = element.getAttribute('data-from');\n\n /**\n * min <= from <= (all numbers in the element) <= to <= max\n * @type {number}\n */\n this.from = from === null ? -Infinity : Number(from);\n\n if(isNaN(this.from)){\n this.from = -Infinity;\n }\n\n const to = element.getAttribute('data-to');\n\n /**\n * min <= from <= (all numbers in the element) <= to <= max\n * @type {number}\n */\n this.to = to === null ? Infinity : Number(to);\n\n if(isNaN(this.to)){\n this.to = Infinity;\n }\n\n const min = element.getAttribute('data-min');\n\n /**\n * min <= from <= (all numbers in the element) <= to <= max\n * @type {number}\n */\n this.min = min === null ? this.from : Number(min);\n\n if(isNaN(this.min)){\n this.min = this.from;\n }\n\n const max = element.getAttribute('data-max');\n\n /**\n * min <= from <= (all numbers in the element) <= to <= max\n * @type {number}\n */\n this.max = max === null ? this.to : Number(max);\n\n if(isNaN(this.max)){\n this.max = this.to;\n }\n\n /**\n * optional \"OR\" logic property, used to combine different filter controls with \"OR\" logic instead of \"AND\"\n * @type {string|null}\n */\n this.or = element.getAttribute('data-or') || null;\n }\n }\n\n /**\n * get range filter options used in FilterAction.rangeFilter method\n * @return {Array.<{object}>} options\n */\n getRangeFilterOptions(){\n\n return {\n path: this.path,\n min: this.min,\n from: this.from,\n to: this.to,\n max: this.max,\n or: this.or\n };\n }\n\n /**\n * check if current control has the same properties like the specified control\n * @param {BaseRangeFilterControl} control\n * @return {boolean}\n */\n isEqualTo(control){\n return this.path === control.path &&\n this.from === control.from &&\n this.to === control.to &&\n this.min === control.min &&\n this.max === control.max;\n }\n}\n\nexport default BaseRangeFilterControl;","import BaseControlsGroup from '../base-controls-group';\nimport BaseRangeFilterControl from '../../controls/filter/base-range-filter.control';\n\n/**\n * represents a group of range filter controls with the same data-name and data-group attributes\n */\nclass BaseRangeFilterControlsGroup extends BaseControlsGroup{\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BaseRangeFilterControl|null}\n */\n addControl(control){\n\n if(control.name !== this.name || control.group !== this.group){\n return null;\n }\n\n const baseRangeFilterControl = new BaseRangeFilterControl(control.element);\n\n this.controls.push(baseRangeFilterControl);\n\n return baseRangeFilterControl;\n }\n\n /**\n * get range filter options from all controls in the group\n * @return {Array.} range filer options\n */\n getRangeFilterOptions(){\n\n let options = [];\n\n for(let control of this.controls){\n options = options.concat(control.getRangeFilterOptions());\n }\n\n return options;\n }\n\n}\n\nexport default BaseRangeFilterControlsGroup;\n","import BaseRangeFilterControlsGroup from '../../../base/groups/filter/base-range-filter-controls-group';\nimport ButtonsMixin from '../../../base/groups/mixins/buttons.mixin';\n\n/**\n * buttons range filter\n */\nclass ButtonsRangeFilter extends ButtonsMixin(BaseRangeFilterControlsGroup){\n\n /**\n * get range filter options from all controls in the group\n * @return {Array.} path filter options\n */\n getRangeFilterOptions(){\n\n let options = [];\n\n //get options from the latest selected radio if exists\n let latestSelectedRadio = this.getLastSelectedRadio();\n\n if(latestSelectedRadio){\n options = options.concat(latestSelectedRadio.getRangeFilterOptions());\n }\n\n //add all selected checkboxes\n for(let checkbox of this.checkboxes){\n\n if(checkbox.selected) {\n options = options.concat(checkbox.getRangeFilterOptions());\n }\n }\n\n return options;\n }\n}\n\nexport default ButtonsRangeFilter;","import './base-slider.control.css';\n\n/**\n * base slider control\n */\nclass BaseSliderControl{\n\n /**\n * control type defined in data-jplist-control attribute;\n * for example, data-jplist-control=\"hidden-sort\" has type='hidden-sort'\n * @param {HTMLElement} element\n * @param {boolean} isVertical\n * @param {number} min\n * @param {number} value1 - initial value 1\n * @param {number} value2 - initial value2\n * @param {number} max\n * @param {Function} callback\n */\n constructor(element, isVertical = false, min = 0, value1 = 0, value2 = 0, max = 0, callback = (value1, value2) => {}){\n\n if(element) {\n\n this.element = element;\n this.element.classList.add('jplist-slider');\n\n if(!this.element) return;\n\n this.isVertical = isVertical;\n this.callback = callback;\n this.min = min;\n this.max = max;\n\n if(isVertical){\n this.element.classList.add('jplist-slider-vertical');\n }\n\n //create and append the first holder\n this.handler1 = document.createElement('span');\n this.handler1.classList.add('jplist-slider-holder-1');\n this.element.appendChild(this.handler1);\n\n //create and append the range element\n this.range = document.createElement('span');\n this.range.classList.add('jplist-slider-range');\n this.element.appendChild(this.range);\n\n //initial value\n this.handler1.left = 0;\n this.handler1.top = 0;\n //this.handler1.value = this.getPreviewValue(0, min, max); //0\n\n //create and append the second holder\n this.handler2 = document.createElement('span');\n this.handler2.classList.add('jplist-slider-holder-2');\n this.element.appendChild(this.handler2);\n\n //initial value\n this.handler2.left = 0;\n this.handler2.top = 0;\n //this.handler2.value = this.getPreviewValue(0, min, max); //0\n\n this.dragging = null;\n\n this.handler1.addEventListener('mousedown', this.start.bind(this));\n this.handler2.addEventListener('mousedown', this.start.bind(this));\n this.handler1.addEventListener('touchstart', this.start.bind(this));\n this.handler2.addEventListener('touchstart', this.start.bind(this));\n\n document.addEventListener('mousemove', this.render.bind(this));\n document.addEventListener('touchmove', this.render.bind(this));\n window.addEventListener('resize', this.resize.bind(this));\n\n document.addEventListener('mouseup', this.stop.bind(this));\n document.addEventListener('touchend', this.stop.bind(this));\n document.body.addEventListener('mouseleave', this.stop.bind(this));\n\n this.element.addEventListener('mousedown', this.jump.bind(this));\n\n //set initial values\n this.setValues(value1, value2);\n }\n }\n\n /**\n * set slider values from outside\n * @param {number} value1\n * @param {number} value2\n * @param {boolean} sendCallback\n */\n setValues(value1, value2, sendCallback = true){\n\n if(value2 < value1){\n value2 = value1;\n }\n\n const pos1 = this.getInnerValue(value1, this.min, this.max);\n const pos2 = this.getInnerValue(value2, this.min, this.max);\n\n this.update({\n x: pos2,\n y: pos2\n }, this.handler2, sendCallback);\n\n this.update({\n x: pos1,\n y: pos1\n }, this.handler1, sendCallback);\n }\n\n /**\n * convert [0, slider-width] range to [min, max] range for the specified value\n * @param {number} value\n * @param {number} min\n * @param {number} max\n * @return {number} mappedValue\n */\n getPreviewValue(value, min, max){\n\n const rect = this.element.getBoundingClientRect();\n const size = this.isVertical? 'height': 'width';\n\n const newStart = min;\n const newEnd = max;\n const originalStart = 0;\n const originalEnd = rect[size];\n\n //return Math.round((newEnd - newStart) * ((value - originalStart) / (originalEnd - originalStart)) + newStart);\n return (newEnd - newStart) * ((value - originalStart) / (originalEnd - originalStart)) + newStart;\n }\n\n /**\n * convert [min, max] range to [0, slider-width] range for the specified value\n * @param {number} value\n * @param {number} min\n * @param {number} max\n * @return {number} mappedValue\n */\n getInnerValue(value, min, max){\n\n const rect = this.element.getBoundingClientRect();\n const size = this.isVertical? 'height': 'width';\n\n const newStart = 0;\n const newEnd = rect[size];\n const originalStart = min;\n const originalEnd = max;\n\n //return Math.round((newEnd - newStart) * ((value - originalStart) / (originalEnd - originalStart)) + newStart);\n return (newEnd - newStart) * ((value - originalStart) / (originalEnd - originalStart)) + newStart;\n }\n\n /**\n * jump to the specified point on the slider\n * @param {Object} e\n */\n jump(e){\n e.preventDefault();\n\n let position = this.getHandlerPos(e);\n\n if(this.isVertical){\n this.dragging = Math.abs(position.y - this.handler1.top) < Math.abs(position.y - this.handler2.top) ? this.handler1 : this.handler2;\n }\n else{\n this.dragging = Math.abs(position.x - this.handler1.left) < Math.abs(position.x - this.handler2.left) ? this.handler1 : this.handler2;\n }\n\n //render the updated state\n this.render(e);\n }\n\n /**\n * update z-index of the active handler\n */\n setZIndex(){\n\n const handler1ZIndex = window.getComputedStyle ? Number(document.defaultView.getComputedStyle(this.handler1, null).getPropertyValue('z-index')) || 200 : 200;\n const handler2ZIndex = window.getComputedStyle ? Number(document.defaultView.getComputedStyle(this.handler2, null).getPropertyValue('z-index')) || 200 : 200;\n\n if(handler1ZIndex === handler2ZIndex){\n this.dragging.style['z-index'] = handler1ZIndex + 1;\n }\n else{\n const max = Math.max(handler1ZIndex, handler2ZIndex);\n const min = Math.min(handler1ZIndex, handler2ZIndex);\n\n this.handler1.style['z-index'] = min;\n this.handler2.style['z-index'] = min;\n this.dragging.style['z-index'] = max;\n }\n }\n\n /**\n * start dragging\n * @param {Object} e\n */\n start(e){\n e.preventDefault();\n e.stopPropagation();\n\n this.dragging = e.target;\n\n //update z-index of the active handler\n this.setZIndex();\n\n //render the updated state\n this.render();\n }\n\n /**\n * stop dragging\n * @param {Object} e\n */\n stop(e){\n //e.preventDefault();\n\n this.dragging = null;\n }\n\n /**\n * on window resize\n * @param {Object} e\n */\n resize(e){\n\n if(this.handler1 && this.handler2){\n\n this.setValues(this.handler1.value, this.handler2.value);\n }\n }\n\n /**\n * render the updated state\n */\n render(e){\n if(e && this.dragging){\n\n this.update(this.getHandlerPos(e), this.dragging);\n }\n }\n\n /**\n * update position and styles\n * @param {object} position\n * @param {element} handler\n * @param {boolean} sendCallback\n */\n update(position, handler, sendCallback = true){\n\n if(handler){\n\n const rect = this.element.getBoundingClientRect();\n\n const size = this.isVertical? 'height': 'width';\n const xy = this.isVertical? 'y': 'x';\n const lefttop = this.isVertical? 'top': 'left';\n\n if(position[xy] < 0){\n position[xy] = 0;\n }\n\n if(position[xy] > rect[size]){\n position[xy] = rect[size];\n }\n\n if(handler === this.handler1 && position[xy] >= this.handler2[lefttop]){\n position[xy] = this.handler2[lefttop];\n }\n\n if(handler === this.handler2 && position[xy] <= this.handler1[lefttop]){\n position[xy] = this.handler1[lefttop];\n }\n\n //save current value\n handler[lefttop] = position[xy];\n //const value = Math.round(position[xy] * 100 / rect[size]); //value in %\n handler.value = this.getPreviewValue(position[xy], this.min, this.max);\n\n handler.style[lefttop] = (position[xy]) + 'px';\n\n //update range element\n this.range.style[lefttop] = this.handler1[lefttop] + 'px';\n\n const rangeHeight = this.handler2[lefttop] - this.handler1[lefttop];\n this.range.style[size] = (rangeHeight >= 0 ? rangeHeight : 0) + 'px';\n\n //call callback function\n if(this.callback && sendCallback){\n\n this.callback(this.handler1.value, this.handler2.value);\n }\n }\n }\n\n /**\n * subtraction of 2 vectors\n * @param {Object} v1 - vector #1\n * @param {Object} v2 - vector #2\n */\n static sub(v1, v2){\n\n return {\n x: v1.x - v2.x,\n y: v1.y - v2.y\n };\n }\n\n /**\n * get handler position from mouse / tap position\n * @param {object} e\n * @return {object} handler position\n */\n getHandlerPos(e){\n\n const rect = this.element.getBoundingClientRect();\n\n const point = {\n x: e.touches && e.touches.length > 0 ? e.touches[0].pageX : e.clientX,\n y: e.touches && e.touches.length > 0 ? e.touches[0].pageY : e.clientY\n };\n\n const vector = {\n x: rect.left,\n y: rect.top\n };\n\n return BaseSliderControl.sub(point, vector);\n }\n\n}\n\nexport default BaseSliderControl;","import BaseRangeFilterControlsGroup from '../../../base/groups/filter/base-range-filter-controls-group';\nimport BaseSliderControl from '../../../base/controls/slider/base-slider.control';\n\n/**\n * range slider filter\n */\nclass SliderRangeFilter extends BaseRangeFilterControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n }\n\n /**\n * add control to the group\n * @param {BaseControl} control\n */\n addControl(control){\n\n const rangeSliderFilterControl = super.addControl(control);\n\n const sliderEl = control.element.querySelector('[data-type=\"slider\"]');\n rangeSliderFilterControl.val1Elements = control.element.querySelectorAll('[data-type=\"value-1\"]');\n rangeSliderFilterControl.val2Elements = control.element.querySelectorAll('[data-type=\"value-2\"]');\n rangeSliderFilterControl.minElements = control.element.querySelectorAll('[data-type=\"min\"]');\n rangeSliderFilterControl.maxElements = control.element.querySelectorAll('[data-type=\"max\"]');\n\n if(!sliderEl) return;\n\n //control properties\n const orientation = control.element.getAttribute('data-orientation') || 'horizontal'; //'vertical'\n\n for(let el of rangeSliderFilterControl.minElements){\n el.textContent = rangeSliderFilterControl.min;\n }\n\n for(let el of rangeSliderFilterControl.maxElements){\n el.textContent = rangeSliderFilterControl.max;\n }\n\n //check if control contains a link and it is in the deep links parameters\n if(rangeSliderFilterControl.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === rangeSliderFilterControl.id);\n\n if(deepLinkParam && deepLinkParam.value){\n const parts = deepLinkParam.value.split('_');\n\n if(parts.length === 2){\n\n rangeSliderFilterControl.from = Number(parts[0]) || 0;\n rangeSliderFilterControl.to = Number(parts[1]) || 0;\n }\n }\n }\n\n rangeSliderFilterControl.slider = new BaseSliderControl(\n sliderEl,\n orientation === 'vertical',\n rangeSliderFilterControl.min,\n rangeSliderFilterControl.from,\n rangeSliderFilterControl.to,\n rangeSliderFilterControl.max,\n (value1, value2) => {\n\n for(let el of rangeSliderFilterControl.val1Elements){\n el.textContent = Math.round(value1);\n }\n\n for(let el of rangeSliderFilterControl.val2Elements){\n el.textContent = Math.round(value2);\n }\n\n for(let control of this.controls){\n\n if(!control.slider) continue;\n\n control.slider.setValues(value1, value2, false);\n }\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, rangeSliderFilterControl);\n }\n });\n }\n\n /**\n * get range filter options from all controls in the group\n * @return {Array.} path filter options\n */\n getRangeFilterOptions(){\n\n let options = [];\n\n for(let control of this.controls){\n\n if(!control.slider || !control.slider.handler1 || !control.slider.handler2) continue;\n\n const controlOptions = control.getRangeFilterOptions();\n controlOptions.from = control.slider.handler1.value;\n controlOptions.to = control.slider.handler2.value;\n\n options = options.concat(controlOptions);\n }\n\n return options;\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n\n const arr = this.controls.map(control => {\n\n if(!control.id || !control.slider || !control.slider.handler1 || !control.slider.handler2) return '';\n\n return control.id + '=' + control.slider.handler1.value + '_' + control.slider.handler2.value;\n }).filter(str => str !== '');\n\n const unique = Array.from(new Set(arr));\n\n return unique.join('&');\n\n }\n}\n\nexport default SliderRangeFilter;","import BaseControlsGroup from '../base/groups/base-controls-group';\n\n/**\n * no results control\n * Example:\n *
No Results Found
\n */\nclass NoResultsControl extends BaseControlsGroup{\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BaseControl|null}\n */\n addControl(control){\n\n super.addControl(control);\n\n control.element.addEventListener('jplist.state', (e) => {\n\n if(!e.jplistState) return;\n\n const itemsNumber = Number(e.jplistState.itemsNumber) || 0;\n control.element.style.display = itemsNumber === 0 ? '' : 'none';\n\n }, false);\n\n }\n}\n\nexport default NoResultsControl;","import BaseControlsGroup from '../base/groups/base-controls-group';\n\nconst SELECTED_CLASS = 'jplist-selected';\n\n/**\n * layout control\n */\nclass LayoutControl extends BaseControlsGroup{\n\n /**\n * constructor\n * @param {string} group\n * @param {string} name\n * @param {Array.=} controls\n * @param {Map|null=} deepLinkParams - structure: [groupName, [{key, value}, ...]], ...\n */\n constructor(group, name, controls = [], deepLinkParams = null){\n super(group, name, controls, deepLinkParams);\n\n this.group = group;\n this.name = name;\n\n this.classNames = new Set();\n this.selectedClassName = '';\n }\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BaseControl|null}\n */\n addControl(control){\n\n super.addControl(control);\n\n control.groupClassName = control.element.getAttribute('data-class') || '';\n control.selected = control.element.getAttribute('data-selected') === 'true';\n\n //check if control contains a link and it is in the deep links parameters\n if(control.id){\n\n const deepLinkParam = this.deepLinkParams.find(param => param.key === control.id);\n\n if(deepLinkParam){\n control.selected = deepLinkParam.value === '1';\n }\n //else{\n //control.selected = false;\n //}\n }\n\n this.classNames.add(control.groupClassName);\n\n /**\n * on button click\n */\n control.element.addEventListener('click', (e) => {\n\n e.preventDefault();\n\n this.handleSelectedControls(control.groupClassName);\n\n this.handleClasses();\n\n if(window.jplist) {\n\n window.jplist.refresh(this.group, control);\n }\n\n }, false);\n\n this.handleClasses();\n }\n\n /**\n * add / remove buttons classes\n */\n handleClasses(){\n\n const groups = document.querySelectorAll('[data-jplist-group=\"' + this.group + '\"]');\n\n //remove classes from all groups\n this.resetAllGroups(groups);\n\n let selected = this.getLatestSelectedControl();\n\n if(!selected) return;\n\n this.handleSelectedControls(selected.groupClassName);\n\n //add specified class name to each group\n LayoutControl.addClassToGroups(selected.groupClassName, groups);\n }\n\n /**\n * get the latest selected control\n * @return {BaseControl} selected control\n */\n getLatestSelectedControl(){\n\n let selected = null;\n\n for(let control of this.controls){\n\n if(control.selected){\n selected = control;\n }\n }\n\n if(!selected && this.controls.length > 0){\n selected = this.controls[0];\n }\n\n return selected;\n }\n\n /**\n * remove classes from all groups\n * @param {NodeList} groups\n */\n resetAllGroups(groups){\n\n for(let group of groups){\n\n //remove all classes\n for(let cn of this.classNames){\n group.classList.remove(cn);\n }\n }\n }\n\n /**\n * handle selected controls\n * @param {string} selectedGroupClassName\n */\n handleSelectedControls(selectedGroupClassName){\n\n for(let control of this.controls){\n\n if(control.groupClassName === selectedGroupClassName){\n control.selected = true;\n control.element.classList.add(SELECTED_CLASS);\n }\n else{\n control.selected = false;\n control.element.classList.remove(SELECTED_CLASS);\n }\n }\n }\n\n /**\n * add specified class name to each group\n * @param {string} groupClassName\n * @param {NodeList} groups\n */\n static addClassToGroups(groupClassName, groups){\n\n for(let group of groups){\n\n //add class if needed\n group.classList.add(groupClassName);\n }\n }\n\n /**\n * get deep link according to the current control states\n * @return {string}\n */\n getDeepLink(){\n const arr = this.controls.map(control => {\n\n if(control.id){\n return control.selected ? control.id + '=1' : control.id + '=0';\n }\n else{\n return '';\n }\n\n }).filter(str => str !== '');\n const unique = Array.from(new Set(arr));\n return unique.join('&');\n }\n}\n\nexport default LayoutControl;","import BaseControlsGroup from '../base/groups/base-controls-group';\n\n/**\n * reset control\n */\nclass ResetControl extends BaseControlsGroup{\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BaseControl|null}\n */\n addControl(control){\n\n super.addControl(control);\n\n /**\n * on button click\n */\n control.element.addEventListener('click', (e) => {\n\n e.preventDefault();\n\n if(window.jplist) {\n\n window.jplist.resetControls(this.group, control);\n }\n\n }, false);\n }\n\n}\n\nexport default ResetControl;","import BaseControlsGroup from '../base/groups/base-controls-group';\nimport FilterAction from \"../../actions/filter/filter.action\";\nimport BasePathFilterControl from \"../base/controls/filter/base-path-filter.control\";\nimport BaseTextFilterControl from \"../base/controls/filter/base-text-filter.control\";\nimport BaseRangeFilterControl from \"../base/controls/filter/base-range-filter.control\";\n\n/**\n * counter control\n * Example:\n * \n */\nclass CounterControl extends BaseControlsGroup{\n\n /**\n * get dynamic counter value\n * @param {Array.} filtered\n * @param {BaseControl} baseFilterControl\n * @param {string} filterType - text, path or range\n * @return {number} count\n */\n static getDynamicCounterValue(baseFilterControl, filterType, filtered){\n\n let count = 0;\n\n filtered = CounterControl.getFilteredItems(baseFilterControl, filterType, filtered);\n\n return filtered.length;\n }\n\n /**\n * get static counter value\n * @param {BaseControl} baseFilterControl\n * @param {string} filterType - text, path or range\n * @param {Array.} group\n * @return {number} count\n */\n static getStaticCounterValue(baseFilterControl, filterType, group){\n\n let count = 0;\n\n //there can be more than one block of items with the same group name\n //each itemsBlock has structure: {root: HTMLElement, items: Array.}\n for(let itemsBlock of group){\n\n let filtered = itemsBlock.items;\n\n filtered = CounterControl.getFilteredItems(baseFilterControl, filterType, filtered);\n\n count += filtered.length;\n }\n\n return count;\n }\n\n /**\n * get filtered items\n * @param {BaseControl} baseFilterControl\n * @param {string} filterType - text, path or range\n * @param {Array.} filtered\n * @return {Array.}\n */\n static getFilteredItems(baseFilterControl, filterType, filtered){\n\n switch(filterType){\n case 'text' : {\n filtered = FilterAction.textFilter(\n filtered,\n baseFilterControl.text,\n baseFilterControl.path,\n baseFilterControl.mode,\n baseFilterControl.regex);\n break;\n }\n\n case 'path' : {\n filtered = FilterAction.pathFilter(filtered,\n baseFilterControl.path,\n baseFilterControl.isInverted);\n break;\n }\n\n case 'range' : {\n filtered = FilterAction.rangeFilter(filtered,\n baseFilterControl.path,\n baseFilterControl.from,\n baseFilterControl.to,\n baseFilterControl.min,\n baseFilterControl.max);\n break;\n }\n }\n\n return filtered;\n }\n\n /**\n * render control HTML\n * @param {number} countValue\n */\n render(countValue){\n\n for(let control of this.controls){\n\n control.element.innerHTML = control.format.replace('{count}', countValue);\n }\n }\n\n /**\n * add control to the group\n * @param {BaseControl} control\n * @return {BaseControl|null}\n */\n addControl(control){\n\n super.addControl(control);\n\n control.filterType = control.element.getAttribute('data-filter-type') || 'path'; //text, path or range\n control.format = control.element.getAttribute('data-format') || '{count}';\n control.mode = control.element.getAttribute('data-mode') || 'dynamic'; //static or dynamic\n\n let baseFilterControl = null;\n\n switch(control.filterType){\n\n case 'text' : {\n\n baseFilterControl = new BaseTextFilterControl(control.element);\n break;\n }\n\n case 'path' : {\n\n baseFilterControl = new BasePathFilterControl(control.element);\n break;\n }\n\n case 'range' : {\n\n baseFilterControl = new BaseRangeFilterControl(control.element);\n break;\n }\n }\n\n control.element.addEventListener('jplist.state', (e) => {\n\n if(!baseFilterControl || !e.jplistState) return;\n\n let count = 0;\n\n if(control.mode === 'static' && e.jplistState.groups && e.jplistState.groups.has(control.group)){\n\n //find group by name\n const group = e.jplistState.groups.get(control.group);\n\n count = CounterControl.getStaticCounterValue(baseFilterControl, control.filterType, group);\n }\n\n if(control.mode === 'dynamic' && e.jplistState.filtered && e.jplistState.filtered.length > 0){\n\n count = CounterControl.getDynamicCounterValue(baseFilterControl, control.filterType, e.jplistState.filtered);\n }\n\n //render counter HTML\n this.render(count);\n\n }, false);\n }\n}\n\nexport default CounterControl;","/*\n\n |----\n | /\n | \\\n |----\n |\n /*\\\n // \\\\\n // \\\\\n //=====\\\\\n // \\\\\n----| |=========| |----\n \\ | | | | /\n / | | [] | | \\\n----| | | |----\n | | [] | |\n /=\\| |/=\\\n //=\\\\ [] //=\\\\\n //===\\\\ //===\\\\\n//=====\\\\ //=====\\\\\n||=====||=====||=====||\n-----------------------\n|||||||||||||||||||||||\n-----------------------\n|| ***** ||\n|| ||||||| ||\n|| || | || ||\n|| || | || ||\n|| || (|) || ||\n|| || | || ||\n|| || | || ||\n**===================**/\n\nimport jPList from './jplist';\n\n//sort\nimport HiddenSortControl from './controls/sort/hidden-sort/hidden-sort.control';\nimport ButtonsSortControl from './controls/sort/buttons-sort/buttons-sort.control';\nimport RadioButtonsSortControl from './controls/sort/radio-buttons-sort/radio-buttons-sort.control';\nimport CheckboxSortControl from './controls/sort/checkbox-sort/checkbox-sort.control';\nimport SelectSortControl from './controls/sort/select-sort/select-sort.control';\nimport DropdownSortControl from './controls/sort/dropdown-sort/dropdown-sort.control';\n\n//pagination\nimport PaginationControl from './controls/pagination/pagination.control';\n\n//text filter\nimport TextboxFilterControl from './controls/filter/text-filters/textbox-filter/textbox-filter.control';\nimport CheckboxTextFilterControl from './controls/filter/text-filters/checkbox-text-filter/checkbox-text-filter.control';\nimport RadioButtonsTextFilterControl from './controls/filter/text-filters/radio-buttons-text-filter/radio-buttons-text-filter.control';\nimport ButtonsTextFilterControl from './controls/filter/text-filters/buttons-text-filter/buttons-text-filter.control';\n\n//path filter\nimport SelectFilterControl from './controls/filter/path-filters/select-filter/select-filter.control';\nimport CheckboxPathFilterControl from './controls/filter/path-filters/checkbox-path-filter/checkbox-path-filter.control';\nimport RadioButtonsPathFilterControl from './controls/filter/path-filters/radio-buttons-path-filter/radio-buttons-path-filter.control';\nimport ButtonsPathFilterControl from './controls/filter/path-filters/buttons-path-filter/buttons-path-filter.control';\nimport DropdownFilterControl from './controls/filter/path-filters/dropdown-filter/dropdown-filter.control';\n\n//range filter\nimport ButtonsRangeFilter from './controls/filter/range-filters/buttons-range-filter/buttons-range-filter.control';\nimport RangeSliderFilter from './controls/filter/range-filters/slider-range-filter/slider-range-filter.control';\n\n//other\nimport NoResultsControl from './controls/no-results/no-results.control';\nimport DropdownControl from './controls/base/controls/dropdown/base-dropdown.control';\nimport LayoutControl from './controls/layout/layout.control';\nimport ResetControl from './controls/reset/reset.control';\nimport CounterControl from './controls/counter/counter.control';\n\n(() => {\n 'use strict';\n\n //custom events polyfill for IE 10+\n //https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent\n if (typeof window.CustomEvent !== 'function' ){\n\n const CustomEvent = (event, params) => {\n params = params || { bubbles: false, cancelable: false, detail: undefined };\n var evt = document.createEvent( 'CustomEvent' );\n evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent;\n }\n\n /**\n * global jplist function, one per page\n */\n window.jplist = window.jplist || {};\n\n /**\n * registered control types\n * @type {Map}\n */\n window.jplist.controlTypes = window.jplist.controlTypes || new Map([\n ['hidden-sort', HiddenSortControl],\n ['sort-buttons', ButtonsSortControl],\n ['radio-buttons-sort', RadioButtonsSortControl],\n ['checkbox-sort', CheckboxSortControl],\n ['select-sort', SelectSortControl],\n ['dropdown-sort', DropdownSortControl],\n\n ['pagination', PaginationControl],\n\n ['textbox-filter', TextboxFilterControl],\n ['checkbox-text-filter', CheckboxTextFilterControl],\n ['radio-buttons-text-filter', RadioButtonsTextFilterControl],\n ['buttons-text-filter', ButtonsTextFilterControl],\n\n ['select-filter', SelectFilterControl],\n ['dropdown-filter', DropdownFilterControl],\n ['checkbox-path-filter', CheckboxPathFilterControl],\n ['radio-buttons-path-filter', RadioButtonsPathFilterControl],\n ['buttons-path-filter', ButtonsPathFilterControl],\n\n ['buttons-range-filter', ButtonsRangeFilter],\n ['slider-range-filter', RangeSliderFilter],\n\n ['no-results', NoResultsControl],\n ['dropdown', DropdownControl],\n ['layout', LayoutControl],\n ['reset', ResetControl],\n ['counter', CounterControl]\n ]);\n\n let jplist = new jPList();\n\n /**\n * external api\n */\n window.jplist.init = jplist.init.bind(jplist);\n window.jplist.refresh = jplist.refresh.bind(jplist);\n window.jplist.resetControls = jplist.resetControls.bind(jplist);\n window.jplist.resetControl = jplist.resetControl.bind(jplist);\n})();","import ContentManager from './content/content-manager';\nimport BaseControl from \"./controls/base/controls/base.control\";\n\n/**\n * the main jPList class\n */\nexport default class jPList{\n\n /**\n * API: initialize jPList controls + elements from outside\n * @param {Object} options\n */\n init(options){\n\n this.settings = Object.assign({}, {\n\n //storage\n storage: '', //'', 'localStorage', 'sessionStorage', 'cookies'\n storageName: 'jplist',\n cookiesExpiration: -1, //cookies expiration in minutes (-1 = cookie expires when browser is closed)\n\n //deep links\n deepLinking: false,\n hashStart: '#' //the start of the hash part, for example it may be '#!key='\n\n }, options);\n\n //find all controls split by data-group and data-name\n this.controls = ContentManager.splitByGroupAndName(this.settings, document.body);\n\n //find all jplist groups\n this.elements = document.querySelectorAll('[data-jplist-group]');\n\n //get from each group the data about its root and items;\n //the received structure is: Map[groupName, Array.<{root: HTMLElement, items: Array.}>]\n this.groups = ContentManager.findGroups(this.elements);\n\n let items = [...document.querySelectorAll('[data-jplist-item]')];\n\n //set jPList index for every element\n //it's used to return to the default browser sorting if needed\n for(let jplistIndex = 0; jplistIndex < items.length; jplistIndex++){\n\n items[jplistIndex].jplistIndex = jplistIndex;\n }\n\n //first refresh\n this.refresh('');\n }\n\n /**\n * API: apply controls on content\n * @param {string=} groupName - optional group name\n * @param {BaseControl|undefined=} target - the element that triggered the event\n */\n refresh(groupName = '', target = undefined){\n ContentManager.apply(this.settings, this.controls, this.groups, groupName, target);\n }\n\n /**\n * API: reset control by CSS selector and apply it on content\n * @param {HTMLElement} element\n */\n resetControl(element){\n\n if(!element) return;\n\n if(this.controls) {\n\n for (let [groupName, groupControls] of this.controls) {\n for (let group of groupControls) {\n let controlIndex = group.controls.findIndex(control => control.element === element);\n\n if(controlIndex >= 0){\n\n //find the control\n const control = group.controls[controlIndex];\n const oldElement = control.element;\n\n //create HTML element from outer HTML string\n const div = document.createElement('div');\n div.innerHTML = oldElement.initialHTML;\n const newElement = div.firstChild;\n\n if(oldElement.parentNode) {\n\n //replace HTML element in the DOM\n oldElement.parentNode.replaceChild(newElement, oldElement);\n\n //replace the control in the group\n group.controls.splice(controlIndex, 1);\n group.addControl(new BaseControl(newElement));\n\n //update state\n this.refresh(groupName);\n }\n\n return;\n }\n }\n }\n }\n }\n\n /**\n * API: reset all jplist controls and apply them on content\n * @param {string=} groupName\n */\n resetControls(groupName = ''){\n\n if(this.controls) {\n\n //this.controls is a Map: [groupName, [BaseControlsGroup1, BaseControlsGroup2, ...]]\n for (let [groupName, groupControls] of this.controls) {\n\n for (let group of groupControls) {\n\n for(let control of group.controls){\n\n if (!control.element || !control.element.initialHTML) continue;\n\n control.element.outerHTML = control.element.initialHTML;\n\n }\n }\n }\n }\n\n //find all controls split by data-group and data-name\n this.controls = ContentManager.splitByGroupAndName(this.settings, document.body);\n\n this.refresh(groupName);\n }\n\n}"],"sourceRoot":""}