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
 * Custom form error event handler to manipulate the bootstrap markup and show
18
 * nicely styled errors in an mform.
19
 *
20
 * @module     theme_monocolor/form-display-errors
21
 * @copyright  2016 Damyon Wiese <damyon@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
define(['jquery', 'core_form/events'], function($, FormEvent) {
25
    return {
26
        /**
27
         * Enhance the supplied element to handle form field errors.
28
         *
29
         * @method
30
         * @param {String} elementid
31
         * @listens event:formFieldValidationFailed
32
         */
33
        enhance: function(elementid) {
34
            var element = document.getElementById(elementid);
35
            if (!element) {
36
                // Some elements (e.g. static) don't have a form field.
37
                // Hence there is no validation. So, no setup required here.
38
                return;
39
            }
40
 
41
            element.addEventListener(FormEvent.eventTypes.formFieldValidationFailed, e => {
42
                const msg = e.detail.message;
43
                e.preventDefault();
44
 
45
                var parent = $(element).closest('.form-group');
46
                var feedback = parent.find('.form-control-feedback');
47
                const feedbackId = feedback.attr('id');
48
 
49
                // Get current aria-describedby value.
50
                let describedBy = $(element).attr('aria-describedby');
51
                if (typeof describedBy === "undefined") {
52
                    describedBy = '';
53
                }
54
                // Split aria-describedby attribute into an array of IDs if necessary.
55
                let describedByIds = [];
56
                if (describedBy.length) {
57
                    describedByIds = describedBy.split(" ");
58
                }
59
                // Find the the feedback container in the aria-describedby attribute.
60
                const feedbackIndex = describedByIds.indexOf(feedbackId);
61
 
62
                // Sometimes (atto) we have a hidden textarea backed by a real contenteditable div.
63
                if (($(element).prop("tagName") == 'TEXTAREA') && parent.find('[contenteditable]').length > 0) {
64
                    element = parent.find('[contenteditable]');
65
                }
66
                if (msg !== '') {
67
                    parent.addClass('has-danger');
68
                    parent.data('client-validation-error', true);
69
                    $(element).addClass('is-invalid');
70
                    // Append the feedback ID to the aria-describedby attribute if it doesn't exist yet.
71
                    if (feedbackIndex === -1) {
72
                        describedByIds.push(feedbackId);
73
                        $(element).attr('aria-describedby', describedByIds.join(" "));
74
                    }
75
                    $(element).attr('aria-invalid', true);
76
                    feedback.attr('tabindex', 0);
77
                    feedback.html(msg);
78
 
79
                    // Only display and focus when the error was not already visible.
80
                    // This is so that, when tabbing around the form, you don't get stuck.
81
                    if (!feedback.is(':visible')) {
82
                        feedback.show();
83
                        feedback.focus();
84
                    }
85
 
86
                } else {
87
                    if (parent.data('client-validation-error') === true) {
88
                        parent.removeClass('has-danger');
89
                        parent.data('client-validation-error', false);
90
                        $(element).removeClass('is-invalid');
91
                        // If the aria-describedby attribute contains the error container's ID, remove it.
92
                        if (feedbackIndex > -1) {
93
                            describedByIds.splice(feedbackIndex, 1);
94
                        }
95
                        // Check the remaining element IDs in the aria-describedby attribute.
96
                        if (describedByIds.length) {
97
                            // If there's at least one, combine them with a blank space and update the aria-describedby attribute.
98
                            describedBy = describedByIds.join(" ");
99
                            // Put back the new describedby attribute.
100
                            $(element).attr('aria-describedby', describedBy);
101
                        } else {
102
                            // If there's none, remove the aria-describedby attribute.
103
                            $(element).removeAttr('aria-describedby');
104
                        }
105
                        $(element).attr('aria-invalid', false);
106
                        feedback.hide();
107
                    }
108
                }
109
            });
110
 
111
            var form = element.closest('form');
112
            if (form && !('boostFormErrorsEnhanced' in form.dataset)) {
113
                form.addEventListener('submit', function() {
114
                    var visibleError = $('.form-control-feedback:visible');
115
                    if (visibleError.length) {
116
                        visibleError[0].focus();
117
                    }
118
                });
119
                form.dataset.boostFormErrorsEnhanced = 1;
120
            }
121
        }
122
    };
123
});