芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/.trash/cepali/lib/form/amd/src/filetypes.js
// This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see
. /** * This module allows to enhance the form elements MoodleQuickForm_filetypes * * @module core_form/filetypes * @package core_form * @copyright 2017 David Mudrak
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since 3.3 */ define(['jquery', 'core/log', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/ajax', 'core/templates', 'core/tree'], function($, Log, Str, ModalFactory, ModalEvents, Ajax, Templates, Tree) { "use strict"; /** * Constructor of the FileTypes instances. * * @constructor * @param {String} elementId The id of the form element to enhance * @param {String} elementLabel The label of the form element used as the modal selector title * @param {String} onlyTypes Limit the list of offered types to this * @param {Bool} allowAll Allow presence of the "All file types" item */ var FileTypes = function(elementId, elementLabel, onlyTypes, allowAll) { this.elementId = elementId; this.elementLabel = elementLabel; this.onlyTypes = onlyTypes; this.allowAll = allowAll; this.inputField = $('#' + elementId); this.wrapperBrowserTrigger = $('[data-filetypesbrowser="' + elementId + '"]'); this.wrapperDescriptions = $('[data-filetypesdescriptions="' + elementId + '"]'); if (!this.wrapperBrowserTrigger.length) { // This is a valid case. Most probably the element is frozen and // the filetypes browser should not be available. return; } if (!this.inputField.length || !this.wrapperDescriptions.length) { Log.error('core_form/filetypes: Unexpected DOM structure, unable to enhance filetypes field ' + elementId); return; } this.prepareBrowserTrigger() .then(function() { return this.prepareBrowserModal(); }.bind(this)) .then(function() { return this.prepareBrowserTree(); }.bind(this)); }; /** * Create and set the browser trigger widget (this.browserTrigger). * * @method prepareBrowserTrigger * @returns {Promise} */ FileTypes.prototype.prepareBrowserTrigger = function() { return Templates.render('core_form/filetypes-trigger', {}) .then(function(html) { this.wrapperBrowserTrigger.html(html); this.browserTrigger = this.wrapperBrowserTrigger.find('[data-filetypeswidget="browsertrigger"]'); }.bind(this)); }; /** * Create and set the modal for displaying the browser (this.browserModal). * * @method prepareBrowserModal * @returns {Promise} */ FileTypes.prototype.prepareBrowserModal = function() { return ModalFactory.create({ type: ModalFactory.types.SAVE_CANCEL, title: this.elementLabel }).then(function(modal) { this.browserModal = modal; }.bind(this)) .then(function() { // Because we have custom conditional modal trigger, we need to // handle the focus after closing ourselves, too. this.browserModal.getRoot().on(ModalEvents.hidden, function() { this.browserTrigger.focus(); }.bind(this)); this.browserModal.getRoot().on(ModalEvents.save, function() { this.saveBrowserModal(); }.bind(this)); }.bind(this)); }; /** * Create and set the tree in the browser modal's body. * * @method prepareBrowserTree * @returns {Promise} */ FileTypes.prototype.prepareBrowserTree = function() { this.browserTrigger.on('click', function(e) { e.preventDefault(); // We want to display the browser modal only when the associated input // field is not frozen (disabled). if (this.inputField.is('[disabled]')) { return; } var bodyContent = this.loadBrowserModalBody(); bodyContent.then(function() { // Turn the list of groups and extensions into the tree. this.browserTree = new Tree(this.browserModal.getBody()); // Override the behaviour of the Enter and Space keys to toggle our checkbox, // rather than toggle the tree node expansion status. this.browserTree.handleKeyDown = function(item, e) { if (e.keyCode == this.browserTree.keys.enter || e.keyCode == this.browserTree.keys.space) { e.preventDefault(); e.stopPropagation(); this.toggleCheckbox(item.attr('data-filetypesbrowserkey')); } else { Tree.prototype.handleKeyDown.call(this.browserTree, item, e); } }.bind(this); if (this.allowAll) { // Hide all other items if "All file types" is enabled. this.hideOrShowItemsDependingOnAllowAll(this.browserModal.getRoot() .find('input[type="checkbox"][data-filetypesbrowserkey="*"]:first')); // And do the same whenever we click that checkbox. this.browserModal.getRoot().on('change', 'input[type="checkbox"][data-filetypesbrowserkey="*"]', function(e) { this.hideOrShowItemsDependingOnAllowAll($(e.currentTarget)); }.bind(this)); } // Synchronize checked status if the file extension is present in multiple groups. this.browserModal.getRoot().on('change', 'input[type="checkbox"][data-filetypesbrowserkey]', function(e) { var checkbox = $(e.currentTarget); var key = checkbox.attr('data-filetypesbrowserkey'); this.browserModal.getRoot().find('input[type="checkbox"][data-filetypesbrowserkey="' + key + '"]') .prop('checked', checkbox.prop('checked')); }.bind(this)); }.bind(this)) .then(function() { this.browserModal.show(); }.bind(this)); this.browserModal.setBody(bodyContent); }.bind(this)); // Return a resolved promise. return $.when(); }; /** * Load the browser modal body contents. * * @returns {Promise} */ FileTypes.prototype.loadBrowserModalBody = function() { var args = { onlytypes: this.onlyTypes.join(), allowall: this.allowAll, current: this.inputField.val() }; return Ajax.call([{ methodname: 'core_form_get_filetypes_browser_data', args: args }])[0].then(function(browserData) { return Templates.render('core_form/filetypes-browser', { elementid: this.elementId, groups: browserData.groups }); }.bind(this)); }; /** * Change the checked status of the given file type (group or extension). * * @method toggleCheckbox * @param {String} key */ FileTypes.prototype.toggleCheckbox = function(key) { var checkbox = this.browserModal.getRoot().find('input[type="checkbox"][data-filetypesbrowserkey="' + key + '"]:first'); checkbox.prop('checked', !checkbox.prop('checked')); }; /** * Update the associated input field with selected file types. * * @method saveBrowserModal */ FileTypes.prototype.saveBrowserModal = function() { // Check the "All file types" first. if (this.allowAll) { var allcheckbox = this.browserModal.getRoot().find('input[type="checkbox"][data-filetypesbrowserkey="*"]'); if (allcheckbox.length && allcheckbox.prop('checked')) { this.inputField.val('*'); this.updateDescriptions(['*']); return; } } // Iterate over all checked boxes and populate the list. var newvalue = []; this.browserModal.getRoot().find('input[type="checkbox"]').each(/** @this represents the checkbox */ function() { var checkbox = $(this); var key = checkbox.attr('data-filetypesbrowserkey'); if (checkbox.prop('checked')) { newvalue.push(key); } }); // Remove duplicates (e.g. file types present in multiple groups). newvalue = newvalue.filter(function(x, i, a) { return a.indexOf(x) == i; }); this.inputField.val(newvalue.join(' ')); this.updateDescriptions(newvalue); }; /** * Describe the selected filetypes in the form when saving the browser. * * @param {Array} keys List of keys to describe * @returns {Promise} */ FileTypes.prototype.updateDescriptions = function(keys) { var descriptions = []; keys.forEach(function(key) { descriptions.push({ description: this.browserModal.getRoot().find('[data-filetypesname="' + key + '"]:first').text().trim(), extensions: this.browserModal.getRoot().find('[data-filetypesextensions="' + key + '"]:first').text().trim() }); }.bind(this)); var templatedata = { hasdescriptions: (descriptions.length > 0), descriptions: descriptions }; return Templates.render('core_form/filetypes-descriptions', templatedata) .then(function(html) { this.wrapperDescriptions.html(html); }.bind(this)); }; /** * If "All file types" is checked, all other browser items are made hidden, and vice versa. * * @param {jQuery} allcheckbox The "All file types" checkbox. */ FileTypes.prototype.hideOrShowItemsDependingOnAllowAll = function(allcheckbox) { var others = this.browserModal.getRoot().find('[role="treeitem"][data-filetypesbrowserkey!="*"]'); if (allcheckbox.prop('checked')) { others.hide(); } else { others.show(); } }; return { init: function(elementId, elementLabel, onlyTypes, allowAll) { new FileTypes(elementId, elementLabel, onlyTypes, allowAll); } }; });