Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * Add search filtering of capabilities
18
 *
19
 * @module      tool_capability/search
20
 * @copyright   2023 Paul Holden <paulh@moodle.com>
21
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
 
24
import Pending from 'core/pending';
25
import {debounce} from 'core/utils';
26
 
27
const Selectors = {
28
    capabilityOverviewForm: '#capability-overview-form',
29
    capabilitySelect: '[data-search="capability"]',
30
    capabilitySearch: '[data-action="search"]',
31
};
32
 
33
const debounceTimer = 250;
34
 
35
/**
36
 * Initialize module
37
 */
38
export const init = () => {
39
    const capabilityOverviewForm = document.querySelector(Selectors.capabilityOverviewForm);
40
    if (!capabilityOverviewForm) {
41
        return;
42
    }
43
 
44
    const capabilitySelect = capabilityOverviewForm.querySelector(Selectors.capabilitySelect);
45
    const capabilitySearch = capabilityOverviewForm.querySelector(Selectors.capabilitySearch);
46
 
47
    const capabilitySelectFilter = searchTerm => {
48
        const pendingPromise = new Pending('tool_capability/search:filter');
49
 
50
        // Remove existing options, remembering which were previously selected.
51
        let capabilitySelected = [];
52
        capabilitySelect.querySelectorAll('option').forEach(option => {
53
            if (option.selected) {
54
                capabilitySelected.push(option.value);
55
            }
56
            option.remove();
57
        });
58
 
59
        // Filter for matching capabilities.
60
        const availableCapabilities = JSON.parse(capabilitySelect.dataset.availableCapabilities);
61
        const filteredCapabilities = Object.keys(availableCapabilities).reduce((matches, capability) => {
62
            if (availableCapabilities[capability].toLowerCase().includes(searchTerm)) {
63
                matches[capability] = availableCapabilities[capability];
64
            }
65
            return matches;
66
        }, []);
67
 
68
        // Re-create filtered options.
69
        Object.entries(filteredCapabilities).forEach(([capability, capabilityText]) => {
70
            const option = document.createElement('option');
71
            option.value = capability;
72
            option.innerText = capabilityText;
73
            option.selected = capabilitySelected.indexOf(capability) > -1;
74
            capabilitySelect.append(option);
75
        });
76
 
77
        pendingPromise.resolve();
78
    };
79
 
80
    // Cache initial capability options.
81
    const availableCapabilities = {};
82
    capabilitySelect.querySelectorAll('option').forEach(option => {
83
        availableCapabilities[option.value] = option.text;
84
    });
85
    capabilitySelect.dataset.availableCapabilities = JSON.stringify(availableCapabilities);
86
 
87
    // Debounce the event listener on the search element to allow user to finish typing.
88
    const capabilitySearchDebounce = debounce(capabilitySelectFilter, debounceTimer);
89
    capabilitySearch.addEventListener('keyup', event => {
90
        const pendingPromise = new Pending('tool_capability/search:keyup');
91
 
92
        capabilitySearchDebounce(event.target.value.toLowerCase());
93
        setTimeout(() => {
94
            pendingPromise.resolve();
95
        }, debounceTimer);
96
    });
97
 
98
    // Ensure filter is applied on form load.
99
    if (capabilitySearch.value !== '') {
100
        capabilitySelectFilter(capabilitySearch.value.toLowerCase());
101
    }
102
};