1 |
efrain |
1 |
/**
|
|
|
2 |
* JavaScript for form editing grade conditions.
|
|
|
3 |
*
|
|
|
4 |
* @module moodle-availability_grade-form
|
|
|
5 |
*/
|
|
|
6 |
M.availability_grade = M.availability_grade || {};
|
|
|
7 |
|
|
|
8 |
/**
|
|
|
9 |
* @class M.availability_grade.form
|
|
|
10 |
* @extends M.core_availability.plugin
|
|
|
11 |
*/
|
|
|
12 |
M.availability_grade.form = Y.Object(M.core_availability.plugin);
|
|
|
13 |
|
|
|
14 |
/**
|
|
|
15 |
* Grade items available for selection.
|
|
|
16 |
*
|
|
|
17 |
* @property grades
|
|
|
18 |
* @type Array
|
|
|
19 |
*/
|
|
|
20 |
M.availability_grade.form.grades = null;
|
|
|
21 |
|
|
|
22 |
/**
|
|
|
23 |
* Initialises this plugin.
|
|
|
24 |
*
|
|
|
25 |
* @method initInner
|
|
|
26 |
* @param {Array} grades Array of objects containing gradeid => name
|
|
|
27 |
*/
|
|
|
28 |
M.availability_grade.form.initInner = function(grades) {
|
|
|
29 |
this.grades = grades;
|
|
|
30 |
this.nodesSoFar = 0;
|
|
|
31 |
};
|
|
|
32 |
|
|
|
33 |
M.availability_grade.form.getNode = function(json) {
|
|
|
34 |
// Increment number used for unique ids.
|
|
|
35 |
this.nodesSoFar++;
|
|
|
36 |
|
|
|
37 |
// Create HTML structure.
|
|
|
38 |
var html = '<label class="mb-3"><span class="pr-3">' + M.util.get_string('title', 'availability_grade') + '</span> ' +
|
|
|
39 |
'<span class="availability-group">' +
|
|
|
40 |
'<select name="id" class="custom-select"><option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
|
|
|
41 |
for (var i = 0; i < this.grades.length; i++) {
|
|
|
42 |
var grade = this.grades[i];
|
|
|
43 |
// String has already been escaped using format_string.
|
|
|
44 |
html += '<option value="' + grade.id + '">' + grade.name + '</option>';
|
|
|
45 |
}
|
|
|
46 |
html += '</select></span></label> <br><span class="availability-group mb-3">' +
|
|
|
47 |
'<label><input type="checkbox" class="form-check-input position-static mt-0 mx-1" name="min"/>' +
|
|
|
48 |
M.util.get_string('option_min', 'availability_grade') +
|
|
|
49 |
'</label> <label><span class="accesshide">' + M.util.get_string('label_min', 'availability_grade') +
|
|
|
50 |
'</span><input type="text" class="form-control mx-1" name="minval" title="' +
|
|
|
51 |
M.util.get_string('label_min', 'availability_grade') + '"/></label>%</span><br>' +
|
|
|
52 |
'<span class="availability-group mb-3">' +
|
|
|
53 |
'<label><input type="checkbox" class="form-check-input position-static mt-0 mx-1" name="max"/>' +
|
|
|
54 |
M.util.get_string('option_max', 'availability_grade') +
|
|
|
55 |
'</label> <label><span class="accesshide">' + M.util.get_string('label_max', 'availability_grade') +
|
|
|
56 |
'</span><input type="text" class="form-control mx-1" name="maxval" title="' +
|
|
|
57 |
M.util.get_string('label_max', 'availability_grade') + '"/></label>%</span>';
|
|
|
58 |
var node = Y.Node.create('<div class="d-inline-block d-flex flex-wrap align-items-center">' + html + '</div>');
|
|
|
59 |
|
|
|
60 |
// Set initial values.
|
|
|
61 |
if (json.id !== undefined &&
|
|
|
62 |
node.one('select[name=id] > option[value=' + json.id + ']')) {
|
|
|
63 |
node.one('select[name=id]').set('value', '' + json.id);
|
|
|
64 |
}
|
|
|
65 |
if (json.min !== undefined) {
|
|
|
66 |
node.one('input[name=min]').set('checked', true);
|
|
|
67 |
node.one('input[name=minval]').set('value', json.min);
|
|
|
68 |
}
|
|
|
69 |
if (json.max !== undefined) {
|
|
|
70 |
node.one('input[name=max]').set('checked', true);
|
|
|
71 |
node.one('input[name=maxval]').set('value', json.max);
|
|
|
72 |
}
|
|
|
73 |
|
|
|
74 |
// Disables/enables text input fields depending on checkbox.
|
|
|
75 |
var updateCheckbox = function(check, focus) {
|
|
|
76 |
var input = check.ancestor('label').next('label').one('input');
|
|
|
77 |
var checked = check.get('checked');
|
|
|
78 |
input.set('disabled', !checked);
|
|
|
79 |
if (focus && checked) {
|
|
|
80 |
input.focus();
|
|
|
81 |
}
|
|
|
82 |
return checked;
|
|
|
83 |
};
|
|
|
84 |
node.all('input[type=checkbox]').each(updateCheckbox);
|
|
|
85 |
|
|
|
86 |
// Add event handlers (first time only).
|
|
|
87 |
if (!M.availability_grade.form.addedEvents) {
|
|
|
88 |
M.availability_grade.form.addedEvents = true;
|
|
|
89 |
|
|
|
90 |
var root = Y.one('.availability-field');
|
|
|
91 |
root.delegate('change', function() {
|
|
|
92 |
// For the grade item, just update the form fields.
|
|
|
93 |
M.core_availability.form.update();
|
|
|
94 |
}, '.availability_grade select[name=id]');
|
|
|
95 |
|
|
|
96 |
root.delegate('click', function() {
|
|
|
97 |
updateCheckbox(this, true);
|
|
|
98 |
M.core_availability.form.update();
|
|
|
99 |
}, '.availability_grade input[type=checkbox]');
|
|
|
100 |
|
|
|
101 |
root.delegate('valuechange', function() {
|
|
|
102 |
// For grade values, just update the form fields.
|
|
|
103 |
M.core_availability.form.update();
|
|
|
104 |
}, '.availability_grade input[type=text]');
|
|
|
105 |
}
|
|
|
106 |
|
|
|
107 |
return node;
|
|
|
108 |
};
|
|
|
109 |
|
|
|
110 |
M.availability_grade.form.fillValue = function(value, node) {
|
|
|
111 |
value.id = parseInt(node.one('select[name=id]').get('value'), 10);
|
|
|
112 |
if (node.one('input[name=min]').get('checked')) {
|
|
|
113 |
value.min = this.getValue('minval', node);
|
|
|
114 |
}
|
|
|
115 |
if (node.one('input[name=max]').get('checked')) {
|
|
|
116 |
value.max = this.getValue('maxval', node);
|
|
|
117 |
}
|
|
|
118 |
};
|
|
|
119 |
|
|
|
120 |
/**
|
|
|
121 |
* Gets the numeric value of an input field. Supports decimal points (using
|
|
|
122 |
* dot or comma).
|
|
|
123 |
*
|
|
|
124 |
* @method getValue
|
|
|
125 |
* @return {Number|String} Value of field as number or string if not valid
|
|
|
126 |
*/
|
|
|
127 |
M.availability_grade.form.getValue = function(field, node) {
|
|
|
128 |
// Get field value.
|
|
|
129 |
var value = node.one('input[name=' + field + ']').get('value');
|
|
|
130 |
|
|
|
131 |
// If it is not a valid positive number, return false.
|
|
|
132 |
if (!(/^[0-9]+([.,][0-9]+)?$/.test(value))) {
|
|
|
133 |
return value;
|
|
|
134 |
}
|
|
|
135 |
|
|
|
136 |
// Replace comma with dot and parse as floating-point.
|
|
|
137 |
var result = parseFloat(value.replace(',', '.'));
|
|
|
138 |
if (result < 0 || result > 100) {
|
|
|
139 |
return value;
|
|
|
140 |
} else {
|
|
|
141 |
return result;
|
|
|
142 |
}
|
|
|
143 |
};
|
|
|
144 |
|
|
|
145 |
M.availability_grade.form.fillErrors = function(errors, node) {
|
|
|
146 |
var value = {};
|
|
|
147 |
this.fillValue(value, node);
|
|
|
148 |
|
|
|
149 |
// Check grade item id.
|
|
|
150 |
if (value.id === 0) {
|
|
|
151 |
errors.push('availability_grade:error_selectgradeid');
|
|
|
152 |
}
|
|
|
153 |
|
|
|
154 |
// Check numeric values.
|
|
|
155 |
if ((value.min !== undefined && typeof (value.min) === 'string') ||
|
|
|
156 |
(value.max !== undefined && typeof (value.max) === 'string')) {
|
|
|
157 |
errors.push('availability_grade:error_invalidnumber');
|
|
|
158 |
} else if (value.min !== undefined && value.max !== undefined &&
|
|
|
159 |
value.min >= value.max) {
|
|
|
160 |
errors.push('availability_grade:error_backwardrange');
|
|
|
161 |
}
|
|
|
162 |
};
|