MDL-46570 gradereport_history: Convert to moodle dialogue

Part of MDL-46191
This commit is contained in:
Frederic Massart
2014-08-22 10:34:11 +08:00
committed by Ankit Agarwal
parent 532e3dd7bc
commit 49bcd2dfae
7 changed files with 408 additions and 394 deletions
@@ -51,6 +51,7 @@ $string['revisedonly_help'] = 'Only show grades which have been revised.
This means only entries which result in the grade changing are listed.';
$string['selectuser'] = 'Select user';
$string['selectusers'] = 'Select users';
$string['selectedusers'] = 'Selected users';
$string['source'] = 'Source';
$string['useractivitygrade'] = '{$a} grade';
+1
View File
@@ -677,6 +677,7 @@ class grade_report_history extends grade_report {
$button->strings_for_js(array(
'deselect',
'selectuser',
'selectusers',
'finishselectingusers',
), 'gradereport_history');
$button->strings_for_js(array(
+38 -35
View File
@@ -26,43 +26,46 @@ table#gradestable th.header.selected {
}
/* User Selector */
.user-selector-panel {width:455px;background-color:#666;position:absolute;top:10%;left:10%;border:1px solid #666;border-width:0 5px 5px 0;}
.user-selector-panel.hidden {display:none;}
.user-selector-panel .usp-wrap {margin-top:-5px;margin-left:-5px;background-color:#FFF;border:1px solid #999;height:inherit;}
.yui3-gradereport_history_usp-hidden {display:none;}
.user-selector-panel .usp-header {background-color:#eee;padding:1px;}
.user-selector-panel .usp-header h2 {margin:3px 1em 0.5em 1em;font-size:1em;}
.user-selector-panel .usp-header .close {width:25px;height:15px;position:absolute;top:2px;right:1em;cursor:pointer;background:url([[pix:theme|sprite]]) no-repeat scroll 0 0 transparent; opacity: 1;}
.gradereport_history_usp .usp-ajax-content {
height: 375px;
overflow: auto;
}
.gradereport_history_usp .usp-search-results .totalusers {
text-align: center;
font-size: .8em;
font-weight: bold;
}
.gradereport_history_usp .usp-search-results .user {width:100%;text-align:left;font-size:9pt;border-bottom:1px solid #ddd;border-top:1px solid #eee;}
.gradereport_history_usp .usp-search-results .user:nth-child(odd) {border-bottom:1px solid #ddd;border-top:1px solid #eee;background-color:#f9f9f9;}
.gradereport_history_usp .usp-search-results .user .count {width:20px;float:left;font-size:7pt;line-height:41px;border-right:1px solid #ddd;background-color:#EEE;text-align:right;padding:2px;}
.gradereport_history_usp .usp-search-results .user .picture {width:45px;float:left;margin:3px;}
.gradereport_history_usp .usp-search-results .user .details {width:250px;float:left;margin:3px;}
.gradereport_history_usp .usp-search-results .user .options {padding-right:7px;font-size:8pt;margin:3px;}
.gradereport_history_usp .usp-search-results .user .options .deselect {margin:3px;float:right;cursor:pointer;display: none;}
.gradereport_history_usp .usp-search-results .user .options .select {margin:3px;float:right;cursor:pointer;}
.gradereport_history_usp .usp-search-results .user.selected .count {width:40px;color:#eee;}
.gradereport_history_usp .usp-search-results .user.selected .select { display: none; }
.gradereport_history_usp .usp-search-results .user.selected .deselect { display: block; }
.gradereport_history_usp .usp-search-results .usp-more-results {background-color:#eee;padding:5px;border-top:1px solid #BBB;}
.user-selector-panel .usp-content {text-align:center;position:relative;width:100%;border-top:1px solid #999;border-bottom:1px solid #999;}
.user-selector-panel .usp-content .usp-controls {margin:0;padding:3px;background-color:#ddd;text-align:left;border-bottom:1px solid #BBB;}
.user-selector-panel .usp-content .usp-controls .usp-enrolment-option input {vertical-align:middle;margin-left:1em;}
.user-selector-panel .usp-ajax-content {height:375px;overflow:auto;}
.user-selector-panel .usp-search-results .totalusers {background-color:#eee;padding:5px;border-bottom:1px solid #BBB;font-size:7pt;font-weight: bold;}
.user-selector-panel .usp-search-results .user {width:100%;text-align:left;font-size:9pt;border-bottom:1px solid #ddd;border-top:1px solid #eee;}
.user-selector-panel .usp-search-results .user:nth-child(odd) {border-bottom:1px solid #ddd;border-top:1px solid #eee;background-color:#f9f9f9;}
.user-selector-panel .usp-search-results .user .count {width:20px;float:left;font-size:7pt;line-height:41px;border-right:1px solid #ddd;background-color:#EEE;text-align:right;padding:2px;}
.user-selector-panel .usp-search-results .user .picture {width:45px;float:left;margin:3px;}
.user-selector-panel .usp-search-results .user .details {width:250px;float:left;margin:3px;}
.user-selector-panel .usp-search-results .user .options {padding-right:7px;font-size:8pt;margin:3px;}
.user-selector-panel .usp-search-results .user .options .deselect {margin:3px;float:right;cursor:pointer;display: none;}
.user-selector-panel .usp-search-results .user .options .select {margin:3px;float:right;cursor:pointer;}
.user-selector-panel .usp-search-results .user.selected .count {width:40px;color:#eee;}
.user-selector-panel .usp-search-results .user.selected .select { display: none; }
.user-selector-panel .usp-search-results .user.selected .deselect { display: block; }
.user-selector-panel .usp-search-results .usp-more-results {background-color:#eee;padding:5px;border-top:1px solid #BBB;}
.gradereport_history_usp .usp-loading-lightbox {
text-align: center;
}
.gradereport_history_usp .usp-loading-lightbox .loading-icon {
margin: 2em;
}
.user-selector-panel .usp-loading-lightbox {position:absolute;width:100%;height:100%;top:0;left:0;background-color:#FFF;min-width:50px;min-height:50px;}
.user-selector-panel .usp-loading-lightbox.hidden {display:none;}
.user-selector-panel .usp-loading-lightbox .loading-icon {margin:auto;vertical-align:middle;margin-top:125px;}
.gradereport_history_usp .usp-footer {
padding: 3px;
text-align: center;
}
.gradereport_history_usp .usp-search {margin:3px;}
.gradereport_history_usp .usp-search label {padding-right:8px;}
.gradereport_history_usp .usp-search input {width:50%;}
.gradereport_history_usp .usp-search input.usp-search-btn {width:20%;}
.user-selector-panel .usp-footer {padding:3px;background-color:#ddd;text-align:center;}
.user-selector-panel .usp-search {margin:3px;}
.user-selector-panel .usp-search label {padding-right:8px;}
.user-selector-panel .usp-search input {width:50%;}
.user-selector-panel .usp-search input.usp-search-btn {width:20%;}
.dir-rtl .user-selector-panel .usp-header .close {right: auto;left:1em;}
.dir-rtl .user-selector-panel .usp-search-results .user { text-align: right;}
.dir-rtl .user-selector-panel .usp-content .usp-controls { text-align: right;}
.dir-rtl .gradereport_history_usp .usp-search-results .user { text-align: right;}
.dir-rtl .gradereport_history_usp .usp-content .usp-controls { text-align: right;}
@@ -31,20 +31,20 @@ YUI.add('moodle-gradereport_history-userselector', function (Y, NAME) {
var COMPONENT = 'gradereport_history';
var USP = {
NAME : 'User Selector Manager',
AJAXURL : 'ajaxurl',
BASE : 'base',
COURSEID : 'courseid',
DIALOGUE_PREFIX : 'moodle-dialogue',
NAME : 'gradereport_history_usp',
PAGE : 'page',
PARAMS : 'params',
PERPAGE : 'perPage',
SEARCH : 'search',
SEARCHBTN : 'searchbtn',
PARAMS : 'params',
URL : 'url',
AJAXURL : 'ajaxurl',
PAGE : 'page',
COURSEID : 'courseid',
SELECTEDUSERS : 'selectedusers',
USERFULLNAMES : 'userfullnames',
USERS : 'users',
URL : 'url',
USERCOUNT : 'userCount',
PERPAGE : 'perPage'
USERFULLNAMES : 'userfullnames'
};
var CSS = {
ACCESSHIDE : 'accesshide',
@@ -55,18 +55,14 @@ var CSS = {
COUNT : 'count',
DESELECT : 'deselect',
DETAILS : 'details',
EVEN : 'even',
EXTRAFIELDS : 'extrafields',
FOOTER : 'usp-footer',
FULLNAME : 'fullname',
HEADER : 'usp-header',
HIDDEN : 'hidden',
LIGHTBOX : 'usp-loading-lightbox',
LOADINGICON : 'loading-icon',
MORERESULTS : 'usp-more-results',
ODD : 'odd',
OPTIONS : 'options',
PANEL : 'user-selector-panel',
PICTURE : 'picture',
SEARCH : 'usp-search',
SEARCHBTN : 'usp-search-btn',
@@ -80,13 +76,12 @@ var CSS = {
WRAP : 'usp-wrap'
};
var SELECTORS = {
AJAXCONTENT: '.' + CSS.CONTENT + ' .' + CSS.AJAXCONTENT,
AJAXCONTENT: '.' + CSS.AJAXCONTENT,
DESELECT: '.' + CSS.DESELECT,
FOOTER: '.' + CSS.FOOTER,
FOOTERCLOSE: '.' + CSS.FOOTER + ' .' + CSS.CLOSEBTN + ' input',
FULLNAME: '.' + CSS.FULLNAME,
HEADERCLOSE: '.' + CSS.HEADER + ' .' + CSS.CLOSE,
HEADING: '.' + CSS.HEADER + ' h2',
LIGHTBOX: '.' + CSS.CONTENT + ' .' + CSS.LIGHTBOX,
LIGHTBOX: '.' + CSS.LIGHTBOX,
MORERESULTS: '.' + CSS.MORERESULTS,
OPTIONS: '.' + CSS.OPTIONS,
RESULTSUSERS: '.' + CSS.SEARCHRESULTS + ' .' + CSS.USERS,
@@ -114,25 +109,16 @@ var create = Y.Node.create;
var USERSELECTOR = function() {
USERSELECTOR.superclass.constructor.apply(this, arguments);
};
Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Base, {
Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, M.core.dialogue, {
/**
* The loading node.
* Whether or not this is the first time the user displays the dialogue within that request.
*
* @property _loadingNode
* @type Node
* @property _firstDisplay
* @type {Boolean}
* @private
*/
_loadingNode : null,
/**
* The Escape key close event.
*
* @property _escCloseEvent
* @type Event
* @private
*/
_escCloseEvent : null,
_firstDisplay: true,
/**
* Compiled template function for a user node.
@@ -144,16 +130,14 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
_userTemplate : null,
initializer : function() {
var list,
var bb = this.get('boundingBox'),
content,
list,
params,
tpl;
tpl = Y.Handlebars.compile('<div class="{{CSS.PANEL}} {{CSS.HIDDEN}}">' +
tpl = Y.Handlebars.compile(
'<div class="{{CSS.WRAP}}">' +
'<div class="{{CSS.HEADER}}">' +
'<div class="{{CSS.CLOSE}}"></div>' +
'<h2>{{get_string "selectuser" COMPONENT}}</h2>' +
'</div>' +
'<div class="{{CSS.CONTENT}}">' +
'<div class="{{CSS.AJAXCONTENT}}"></div>' +
'<div class="{{CSS.LIGHTBOX}} {{CSS.HIDDEN}}">' +
@@ -173,20 +157,26 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
'<div class="{{CSS.CLOSEBTN}}">' +
'<input type="button" value="{{get_string "finishselectingusers" COMPONENT}}">' +
'</div>' +
'</div>' +
'</div>' +
'</div>');
'<div>' +
'</div>');
this.set(USP.BASE, create(
content = create(
tpl({
COMPONENT: COMPONENT,
CSS: CSS,
loadingIcon: M.util.image_url('i/loading', 'moodle')
})
));
);
this.set(USP.SEARCH, this.get(USP.BASE).one(SELECTORS.SEARCHFIELD));
this.set(USP.SEARCHBTN, this.get(USP.BASE).one(SELECTORS.SEARCHBTN));
// Set the title and content.
this.getStdModNode(Y.WidgetStdMod.HEADER).prepend(create('<h1>' + this.get('title') + '</h1>'));
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
// Use standard dialogue class name. This removes the default styling of the footer.
this.get('boundingBox').one('.moodle-dialogue-wrap').addClass('moodle-dialogue-content');
this.set(USP.SEARCH, bb.one(SELECTORS.SEARCHFIELD));
this.set(USP.SEARCHBTN, bb.one(SELECTORS.SEARCHBTN));
list = Y.one(SELECTORS.USERIDS).get('value').split(',');
if (list[0] === '') {
list = [];
@@ -203,23 +193,13 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
Y.one(SELECTORS.TRIGGER).on('click', this.show, this);
this.get(USP.BASE).one(SELECTORS.HEADERCLOSE).on('click', this.hide, this);
this.get(USP.BASE).one(SELECTORS.FOOTERCLOSE).on('click', this.hide, this);
this._loadingNode = this.get(USP.BASE).one(SELECTORS.LIGHTBOX);
bb.one(SELECTORS.FOOTERCLOSE).on('click', this.hide, this);
params = this.get(USP.PARAMS);
params.id = this.get(USP.COURSEID);
this.set(USP.PARAMS, params);
Y.on('key', this.preSearch, this.get(USP.SEARCH), 'down:13', this);
this.get(USP.SEARCHBTN).on('click', this.preSearch, this);
Y.one(document.body).append(this.get(USP.BASE));
var base = this.get(USP.BASE);
base.plug(Y.Plugin.Drag);
base.dd.addHandle(SELECTORS.HEADING);
base.one(SELECTORS.HEADING).setStyle('cursor', 'move');
},
/**
@@ -237,36 +217,12 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method show
*/
show : function(e) {
e.preventDefault();
e.halt();
var base = this.get(USP.BASE);
base.removeClass(CSS.HIDDEN);
var x = (base.get('winWidth') - 400)/2;
var y = (parseInt(base.get('winHeight'), 10)-base.get('offsetHeight'))/2 + parseInt(base.get('docScrollY'), 10);
if (y < parseInt(base.get('winHeight'), 10)*0.1) {
y = parseInt(base.get('winHeight'), 10)*0.1;
}
base.setXY([x,y]);
if (this.get(USP.USERS)===null) {
if (this._firstDisplay) {
// Load the default list of users when the dialogue is loaded for the first time.
this._firstDisplay = false;
this.search(e, false);
}
this._escCloseEvent = Y.on('key', this.hide, document.body, 'down:27', this);
},
/**
* Hide the dialogue.
*
* @method hide
*/
hide : function(e) {
if (this._escCloseEvent) {
this._escCloseEvent.detach();
this._escCloseEvent = null;
}
this.get(USP.BASE).addClass(CSS.HIDDEN);
Y.namespace('M.gradereport_history.UserSelector').superclass.show.call(this);
},
/**
@@ -314,7 +270,10 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method displayLoading
*/
displayLoading : function() {
this._loadingNode.removeClass(CSS.HIDDEN);
var bb = this.get('boundingBox');
bb.one(SELECTORS.LIGHTBOX).removeClass(CSS.HIDDEN);
bb.one(SELECTORS.AJAXCONTENT).addClass(CSS.HIDDEN);
bb.one(SELECTORS.FOOTER).addClass(CSS.HIDDEN);
},
/**
@@ -323,7 +282,11 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method removeLoading
*/
removeLoading : function() {
this._loadingNode.addClass(CSS.HIDDEN);
var bb = this.get('boundingBox');
bb.one(SELECTORS.LIGHTBOX).addClass(CSS.HIDDEN);
bb.one(SELECTORS.AJAXCONTENT).removeClass(CSS.HIDDEN);
bb.one(SELECTORS.FOOTER).removeClass(CSS.HIDDEN);
this.centerDialogue();
},
/**
@@ -338,9 +301,6 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
count,
selected,
i,
actionClass,
actionStr,
actionComponent,
node,
usersstr,
content,
@@ -360,7 +320,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
if (!args.append) {
users = create('<div class="'+CSS.USERS+'"></div>');
} else {
users = this.get(USP.BASE).one(SELECTORS.RESULTSUSERS);
users = this.get('boundingBox').one(SELECTORS.RESULTSUSERS);
}
if (!this._userTemplate) {
@@ -426,7 +386,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
Y.delegate("click", this.deselectUser, users, SELECTORS.USERDESELECT, this, args);
} else {
if (result.response.totalusers <= (this.get(USP.PAGE)+1)*this.get(USP.PERPAGE)) {
this.get(USP.BASE).one(SELECTORS.MORERESULTS).remove();
this.get('boundingBox').one(SELECTORS.MORERESULTS).remove();
}
}
},
@@ -490,7 +450,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @param {String} content The content.
*/
setContent: function(content) {
this.get(USP.BASE).one(SELECTORS.AJAXCONTENT).setContent(content);
this.get('boundingBox').one(SELECTORS.AJAXCONTENT).setContent(content);
},
/**
@@ -508,8 +468,47 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
}
}, {
NAME : USP.NAME,
CSS_PREFIX : USP.CSS_PREFIX,
ATTRS : {
extraClasses: {
value: [
'gradereport_history_usp'
]
},
/**
* The header.
*
* @attribute title
* @type String
*/
title: {
validator: Y.Lang.isString,
value: M.util.get_string('selectusers', COMPONENT)
},
/**
* Whether to focus on the target that caused the Widget to be shown.
*
* @attribute focusOnPreviousTargetAfterHide
* @type Node
*/
focusOnPreviousTargetAfterHide: {
value: true
},
/**
*
* Width.
*
* @attribute width
* @type {String|Number}
*/
width: {
value: '500px'
},
/**
* The current page URL.
*
@@ -530,33 +529,6 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
validator : Y.Lang.isString
},
/**
* The dialogue.
*
* @attribute base
* @type Node
*/
base : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(USP.NAME+': invalid base node set');
}
return n;
}
},
/**
* The initial list of users.
*
* @attribute userfullnames
* @type Object
*/
users : {
validator : Y.Lang.isArray,
value : null
},
/**
* IDs of the selected users.
*
@@ -648,9 +620,40 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
value: 25,
Validator: Y.Lang.isNumber
}
}
});
Y.augment(Y.namespace('M.gradereport_history').UserSelector, Y.EventTarget);
// Y.augment(Y.namespace('M.gradereport_history').UserSelector, Y.EventTarget);
Y.Base.modifyAttrs(Y.namespace('M.gradereport_history.UserSelector'), {
/**
* Boolean indicating whether or not the Widget is visible.
*
* @attribute visible
* @default true
* @type Boolean
*/
visible: {
value: false
},
/**
* Whether the widget should be modal or not.
*
* @attribute modal
* @type Boolean
* @default true
*/
modal: {
value: true
},
draggable: {
value: true
}
});
Y.namespace('M.gradereport_history.UserSelector').init = function(cfg) {
return new USERSELECTOR(cfg);
File diff suppressed because one or more lines are too long
@@ -31,20 +31,20 @@ YUI.add('moodle-gradereport_history-userselector', function (Y, NAME) {
var COMPONENT = 'gradereport_history';
var USP = {
NAME : 'User Selector Manager',
AJAXURL : 'ajaxurl',
BASE : 'base',
COURSEID : 'courseid',
DIALOGUE_PREFIX : 'moodle-dialogue',
NAME : 'gradereport_history_usp',
PAGE : 'page',
PARAMS : 'params',
PERPAGE : 'perPage',
SEARCH : 'search',
SEARCHBTN : 'searchbtn',
PARAMS : 'params',
URL : 'url',
AJAXURL : 'ajaxurl',
PAGE : 'page',
COURSEID : 'courseid',
SELECTEDUSERS : 'selectedusers',
USERFULLNAMES : 'userfullnames',
USERS : 'users',
URL : 'url',
USERCOUNT : 'userCount',
PERPAGE : 'perPage'
USERFULLNAMES : 'userfullnames'
};
var CSS = {
ACCESSHIDE : 'accesshide',
@@ -55,18 +55,14 @@ var CSS = {
COUNT : 'count',
DESELECT : 'deselect',
DETAILS : 'details',
EVEN : 'even',
EXTRAFIELDS : 'extrafields',
FOOTER : 'usp-footer',
FULLNAME : 'fullname',
HEADER : 'usp-header',
HIDDEN : 'hidden',
LIGHTBOX : 'usp-loading-lightbox',
LOADINGICON : 'loading-icon',
MORERESULTS : 'usp-more-results',
ODD : 'odd',
OPTIONS : 'options',
PANEL : 'user-selector-panel',
PICTURE : 'picture',
SEARCH : 'usp-search',
SEARCHBTN : 'usp-search-btn',
@@ -80,13 +76,12 @@ var CSS = {
WRAP : 'usp-wrap'
};
var SELECTORS = {
AJAXCONTENT: '.' + CSS.CONTENT + ' .' + CSS.AJAXCONTENT,
AJAXCONTENT: '.' + CSS.AJAXCONTENT,
DESELECT: '.' + CSS.DESELECT,
FOOTER: '.' + CSS.FOOTER,
FOOTERCLOSE: '.' + CSS.FOOTER + ' .' + CSS.CLOSEBTN + ' input',
FULLNAME: '.' + CSS.FULLNAME,
HEADERCLOSE: '.' + CSS.HEADER + ' .' + CSS.CLOSE,
HEADING: '.' + CSS.HEADER + ' h2',
LIGHTBOX: '.' + CSS.CONTENT + ' .' + CSS.LIGHTBOX,
LIGHTBOX: '.' + CSS.LIGHTBOX,
MORERESULTS: '.' + CSS.MORERESULTS,
OPTIONS: '.' + CSS.OPTIONS,
RESULTSUSERS: '.' + CSS.SEARCHRESULTS + ' .' + CSS.USERS,
@@ -114,25 +109,16 @@ var create = Y.Node.create;
var USERSELECTOR = function() {
USERSELECTOR.superclass.constructor.apply(this, arguments);
};
Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Base, {
Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, M.core.dialogue, {
/**
* The loading node.
* Whether or not this is the first time the user displays the dialogue within that request.
*
* @property _loadingNode
* @type Node
* @property _firstDisplay
* @type {Boolean}
* @private
*/
_loadingNode : null,
/**
* The Escape key close event.
*
* @property _escCloseEvent
* @type Event
* @private
*/
_escCloseEvent : null,
_firstDisplay: true,
/**
* Compiled template function for a user node.
@@ -144,16 +130,14 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
_userTemplate : null,
initializer : function() {
var list,
var bb = this.get('boundingBox'),
content,
list,
params,
tpl;
tpl = Y.Handlebars.compile('<div class="{{CSS.PANEL}} {{CSS.HIDDEN}}">' +
tpl = Y.Handlebars.compile(
'<div class="{{CSS.WRAP}}">' +
'<div class="{{CSS.HEADER}}">' +
'<div class="{{CSS.CLOSE}}"></div>' +
'<h2>{{get_string "selectuser" COMPONENT}}</h2>' +
'</div>' +
'<div class="{{CSS.CONTENT}}">' +
'<div class="{{CSS.AJAXCONTENT}}"></div>' +
'<div class="{{CSS.LIGHTBOX}} {{CSS.HIDDEN}}">' +
@@ -173,20 +157,26 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
'<div class="{{CSS.CLOSEBTN}}">' +
'<input type="button" value="{{get_string "finishselectingusers" COMPONENT}}">' +
'</div>' +
'</div>' +
'</div>' +
'</div>');
'<div>' +
'</div>');
this.set(USP.BASE, create(
content = create(
tpl({
COMPONENT: COMPONENT,
CSS: CSS,
loadingIcon: M.util.image_url('i/loading', 'moodle')
})
));
);
this.set(USP.SEARCH, this.get(USP.BASE).one(SELECTORS.SEARCHFIELD));
this.set(USP.SEARCHBTN, this.get(USP.BASE).one(SELECTORS.SEARCHBTN));
// Set the title and content.
this.getStdModNode(Y.WidgetStdMod.HEADER).prepend(create('<h1>' + this.get('title') + '</h1>'));
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
// Use standard dialogue class name. This removes the default styling of the footer.
this.get('boundingBox').one('.moodle-dialogue-wrap').addClass('moodle-dialogue-content');
this.set(USP.SEARCH, bb.one(SELECTORS.SEARCHFIELD));
this.set(USP.SEARCHBTN, bb.one(SELECTORS.SEARCHBTN));
list = Y.one(SELECTORS.USERIDS).get('value').split(',');
if (list[0] === '') {
list = [];
@@ -203,23 +193,13 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
Y.one(SELECTORS.TRIGGER).on('click', this.show, this);
this.get(USP.BASE).one(SELECTORS.HEADERCLOSE).on('click', this.hide, this);
this.get(USP.BASE).one(SELECTORS.FOOTERCLOSE).on('click', this.hide, this);
this._loadingNode = this.get(USP.BASE).one(SELECTORS.LIGHTBOX);
bb.one(SELECTORS.FOOTERCLOSE).on('click', this.hide, this);
params = this.get(USP.PARAMS);
params.id = this.get(USP.COURSEID);
this.set(USP.PARAMS, params);
Y.on('key', this.preSearch, this.get(USP.SEARCH), 'down:13', this);
this.get(USP.SEARCHBTN).on('click', this.preSearch, this);
Y.one(document.body).append(this.get(USP.BASE));
var base = this.get(USP.BASE);
base.plug(Y.Plugin.Drag);
base.dd.addHandle(SELECTORS.HEADING);
base.one(SELECTORS.HEADING).setStyle('cursor', 'move');
},
/**
@@ -237,36 +217,12 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method show
*/
show : function(e) {
e.preventDefault();
e.halt();
var base = this.get(USP.BASE);
base.removeClass(CSS.HIDDEN);
var x = (base.get('winWidth') - 400)/2;
var y = (parseInt(base.get('winHeight'), 10)-base.get('offsetHeight'))/2 + parseInt(base.get('docScrollY'), 10);
if (y < parseInt(base.get('winHeight'), 10)*0.1) {
y = parseInt(base.get('winHeight'), 10)*0.1;
}
base.setXY([x,y]);
if (this.get(USP.USERS)===null) {
if (this._firstDisplay) {
// Load the default list of users when the dialogue is loaded for the first time.
this._firstDisplay = false;
this.search(e, false);
}
this._escCloseEvent = Y.on('key', this.hide, document.body, 'down:27', this);
},
/**
* Hide the dialogue.
*
* @method hide
*/
hide : function(e) {
if (this._escCloseEvent) {
this._escCloseEvent.detach();
this._escCloseEvent = null;
}
this.get(USP.BASE).addClass(CSS.HIDDEN);
Y.namespace('M.gradereport_history.UserSelector').superclass.show.call(this);
},
/**
@@ -314,7 +270,10 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method displayLoading
*/
displayLoading : function() {
this._loadingNode.removeClass(CSS.HIDDEN);
var bb = this.get('boundingBox');
bb.one(SELECTORS.LIGHTBOX).removeClass(CSS.HIDDEN);
bb.one(SELECTORS.AJAXCONTENT).addClass(CSS.HIDDEN);
bb.one(SELECTORS.FOOTER).addClass(CSS.HIDDEN);
},
/**
@@ -323,7 +282,11 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method removeLoading
*/
removeLoading : function() {
this._loadingNode.addClass(CSS.HIDDEN);
var bb = this.get('boundingBox');
bb.one(SELECTORS.LIGHTBOX).addClass(CSS.HIDDEN);
bb.one(SELECTORS.AJAXCONTENT).removeClass(CSS.HIDDEN);
bb.one(SELECTORS.FOOTER).removeClass(CSS.HIDDEN);
this.centerDialogue();
},
/**
@@ -338,9 +301,6 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
count,
selected,
i,
actionClass,
actionStr,
actionComponent,
node,
usersstr,
content,
@@ -360,7 +320,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
if (!args.append) {
users = create('<div class="'+CSS.USERS+'"></div>');
} else {
users = this.get(USP.BASE).one(SELECTORS.RESULTSUSERS);
users = this.get('boundingBox').one(SELECTORS.RESULTSUSERS);
}
if (!this._userTemplate) {
@@ -426,7 +386,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
Y.delegate("click", this.deselectUser, users, SELECTORS.USERDESELECT, this, args);
} else {
if (result.response.totalusers <= (this.get(USP.PAGE)+1)*this.get(USP.PERPAGE)) {
this.get(USP.BASE).one(SELECTORS.MORERESULTS).remove();
this.get('boundingBox').one(SELECTORS.MORERESULTS).remove();
}
}
},
@@ -490,7 +450,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @param {String} content The content.
*/
setContent: function(content) {
this.get(USP.BASE).one(SELECTORS.AJAXCONTENT).setContent(content);
this.get('boundingBox').one(SELECTORS.AJAXCONTENT).setContent(content);
},
/**
@@ -508,8 +468,47 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
}
}, {
NAME : USP.NAME,
CSS_PREFIX : USP.CSS_PREFIX,
ATTRS : {
extraClasses: {
value: [
'gradereport_history_usp'
]
},
/**
* The header.
*
* @attribute title
* @type String
*/
title: {
validator: Y.Lang.isString,
value: M.util.get_string('selectusers', COMPONENT)
},
/**
* Whether to focus on the target that caused the Widget to be shown.
*
* @attribute focusOnPreviousTargetAfterHide
* @type Node
*/
focusOnPreviousTargetAfterHide: {
value: true
},
/**
*
* Width.
*
* @attribute width
* @type {String|Number}
*/
width: {
value: '500px'
},
/**
* The current page URL.
*
@@ -530,33 +529,6 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
validator : Y.Lang.isString
},
/**
* The dialogue.
*
* @attribute base
* @type Node
*/
base : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(USP.NAME+': invalid base node set');
}
return n;
}
},
/**
* The initial list of users.
*
* @attribute userfullnames
* @type Object
*/
users : {
validator : Y.Lang.isArray,
value : null
},
/**
* IDs of the selected users.
*
@@ -648,9 +620,40 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
value: 25,
Validator: Y.Lang.isNumber
}
}
});
Y.augment(Y.namespace('M.gradereport_history').UserSelector, Y.EventTarget);
// Y.augment(Y.namespace('M.gradereport_history').UserSelector, Y.EventTarget);
Y.Base.modifyAttrs(Y.namespace('M.gradereport_history.UserSelector'), {
/**
* Boolean indicating whether or not the Widget is visible.
*
* @attribute visible
* @default true
* @type Boolean
*/
visible: {
value: false
},
/**
* Whether the widget should be modal or not.
*
* @attribute modal
* @type Boolean
* @default true
*/
modal: {
value: true
},
draggable: {
value: true
}
});
Y.namespace('M.gradereport_history.UserSelector').init = function(cfg) {
return new USERSELECTOR(cfg);
+122 -119
View File
@@ -29,20 +29,20 @@
var COMPONENT = 'gradereport_history';
var USP = {
NAME : 'User Selector Manager',
AJAXURL : 'ajaxurl',
BASE : 'base',
COURSEID : 'courseid',
DIALOGUE_PREFIX : 'moodle-dialogue',
NAME : 'gradereport_history_usp',
PAGE : 'page',
PARAMS : 'params',
PERPAGE : 'perPage',
SEARCH : 'search',
SEARCHBTN : 'searchbtn',
PARAMS : 'params',
URL : 'url',
AJAXURL : 'ajaxurl',
PAGE : 'page',
COURSEID : 'courseid',
SELECTEDUSERS : 'selectedusers',
USERFULLNAMES : 'userfullnames',
USERS : 'users',
URL : 'url',
USERCOUNT : 'userCount',
PERPAGE : 'perPage'
USERFULLNAMES : 'userfullnames'
};
var CSS = {
ACCESSHIDE : 'accesshide',
@@ -53,18 +53,14 @@ var CSS = {
COUNT : 'count',
DESELECT : 'deselect',
DETAILS : 'details',
EVEN : 'even',
EXTRAFIELDS : 'extrafields',
FOOTER : 'usp-footer',
FULLNAME : 'fullname',
HEADER : 'usp-header',
HIDDEN : 'hidden',
LIGHTBOX : 'usp-loading-lightbox',
LOADINGICON : 'loading-icon',
MORERESULTS : 'usp-more-results',
ODD : 'odd',
OPTIONS : 'options',
PANEL : 'user-selector-panel',
PICTURE : 'picture',
SEARCH : 'usp-search',
SEARCHBTN : 'usp-search-btn',
@@ -78,13 +74,12 @@ var CSS = {
WRAP : 'usp-wrap'
};
var SELECTORS = {
AJAXCONTENT: '.' + CSS.CONTENT + ' .' + CSS.AJAXCONTENT,
AJAXCONTENT: '.' + CSS.AJAXCONTENT,
DESELECT: '.' + CSS.DESELECT,
FOOTER: '.' + CSS.FOOTER,
FOOTERCLOSE: '.' + CSS.FOOTER + ' .' + CSS.CLOSEBTN + ' input',
FULLNAME: '.' + CSS.FULLNAME,
HEADERCLOSE: '.' + CSS.HEADER + ' .' + CSS.CLOSE,
HEADING: '.' + CSS.HEADER + ' h2',
LIGHTBOX: '.' + CSS.CONTENT + ' .' + CSS.LIGHTBOX,
LIGHTBOX: '.' + CSS.LIGHTBOX,
MORERESULTS: '.' + CSS.MORERESULTS,
OPTIONS: '.' + CSS.OPTIONS,
RESULTSUSERS: '.' + CSS.SEARCHRESULTS + ' .' + CSS.USERS,
@@ -112,25 +107,16 @@ var create = Y.Node.create;
var USERSELECTOR = function() {
USERSELECTOR.superclass.constructor.apply(this, arguments);
};
Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Base, {
Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, M.core.dialogue, {
/**
* The loading node.
* Whether or not this is the first time the user displays the dialogue within that request.
*
* @property _loadingNode
* @type Node
* @property _firstDisplay
* @type {Boolean}
* @private
*/
_loadingNode : null,
/**
* The Escape key close event.
*
* @property _escCloseEvent
* @type Event
* @private
*/
_escCloseEvent : null,
_firstDisplay: true,
/**
* Compiled template function for a user node.
@@ -142,16 +128,14 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
_userTemplate : null,
initializer : function() {
var list,
var bb = this.get('boundingBox'),
content,
list,
params,
tpl;
tpl = Y.Handlebars.compile('<div class="{{CSS.PANEL}} {{CSS.HIDDEN}}">' +
tpl = Y.Handlebars.compile(
'<div class="{{CSS.WRAP}}">' +
'<div class="{{CSS.HEADER}}">' +
'<div class="{{CSS.CLOSE}}"></div>' +
'<h2>{{get_string "selectuser" COMPONENT}}</h2>' +
'</div>' +
'<div class="{{CSS.CONTENT}}">' +
'<div class="{{CSS.AJAXCONTENT}}"></div>' +
'<div class="{{CSS.LIGHTBOX}} {{CSS.HIDDEN}}">' +
@@ -171,20 +155,26 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
'<div class="{{CSS.CLOSEBTN}}">' +
'<input type="button" value="{{get_string "finishselectingusers" COMPONENT}}">' +
'</div>' +
'</div>' +
'</div>' +
'</div>');
'<div>' +
'</div>');
this.set(USP.BASE, create(
content = create(
tpl({
COMPONENT: COMPONENT,
CSS: CSS,
loadingIcon: M.util.image_url('i/loading', 'moodle')
})
));
);
this.set(USP.SEARCH, this.get(USP.BASE).one(SELECTORS.SEARCHFIELD));
this.set(USP.SEARCHBTN, this.get(USP.BASE).one(SELECTORS.SEARCHBTN));
// Set the title and content.
this.getStdModNode(Y.WidgetStdMod.HEADER).prepend(create('<h1>' + this.get('title') + '</h1>'));
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
// Use standard dialogue class name. This removes the default styling of the footer.
this.get('boundingBox').one('.moodle-dialogue-wrap').addClass('moodle-dialogue-content');
this.set(USP.SEARCH, bb.one(SELECTORS.SEARCHFIELD));
this.set(USP.SEARCHBTN, bb.one(SELECTORS.SEARCHBTN));
list = Y.one(SELECTORS.USERIDS).get('value').split(',');
if (list[0] === '') {
list = [];
@@ -201,23 +191,13 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
Y.one(SELECTORS.TRIGGER).on('click', this.show, this);
this.get(USP.BASE).one(SELECTORS.HEADERCLOSE).on('click', this.hide, this);
this.get(USP.BASE).one(SELECTORS.FOOTERCLOSE).on('click', this.hide, this);
this._loadingNode = this.get(USP.BASE).one(SELECTORS.LIGHTBOX);
bb.one(SELECTORS.FOOTERCLOSE).on('click', this.hide, this);
params = this.get(USP.PARAMS);
params.id = this.get(USP.COURSEID);
this.set(USP.PARAMS, params);
Y.on('key', this.preSearch, this.get(USP.SEARCH), 'down:13', this);
this.get(USP.SEARCHBTN).on('click', this.preSearch, this);
Y.one(document.body).append(this.get(USP.BASE));
var base = this.get(USP.BASE);
base.plug(Y.Plugin.Drag);
base.dd.addHandle(SELECTORS.HEADING);
base.one(SELECTORS.HEADING).setStyle('cursor', 'move');
},
/**
@@ -235,36 +215,12 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method show
*/
show : function(e) {
e.preventDefault();
e.halt();
var base = this.get(USP.BASE);
base.removeClass(CSS.HIDDEN);
var x = (base.get('winWidth') - 400)/2;
var y = (parseInt(base.get('winHeight'), 10)-base.get('offsetHeight'))/2 + parseInt(base.get('docScrollY'), 10);
if (y < parseInt(base.get('winHeight'), 10)*0.1) {
y = parseInt(base.get('winHeight'), 10)*0.1;
}
base.setXY([x,y]);
if (this.get(USP.USERS)===null) {
if (this._firstDisplay) {
// Load the default list of users when the dialogue is loaded for the first time.
this._firstDisplay = false;
this.search(e, false);
}
this._escCloseEvent = Y.on('key', this.hide, document.body, 'down:27', this);
},
/**
* Hide the dialogue.
*
* @method hide
*/
hide : function(e) {
if (this._escCloseEvent) {
this._escCloseEvent.detach();
this._escCloseEvent = null;
}
this.get(USP.BASE).addClass(CSS.HIDDEN);
Y.namespace('M.gradereport_history.UserSelector').superclass.show.call(this);
},
/**
@@ -312,7 +268,10 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method displayLoading
*/
displayLoading : function() {
this._loadingNode.removeClass(CSS.HIDDEN);
var bb = this.get('boundingBox');
bb.one(SELECTORS.LIGHTBOX).removeClass(CSS.HIDDEN);
bb.one(SELECTORS.AJAXCONTENT).addClass(CSS.HIDDEN);
bb.one(SELECTORS.FOOTER).addClass(CSS.HIDDEN);
},
/**
@@ -321,7 +280,11 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @method removeLoading
*/
removeLoading : function() {
this._loadingNode.addClass(CSS.HIDDEN);
var bb = this.get('boundingBox');
bb.one(SELECTORS.LIGHTBOX).addClass(CSS.HIDDEN);
bb.one(SELECTORS.AJAXCONTENT).removeClass(CSS.HIDDEN);
bb.one(SELECTORS.FOOTER).removeClass(CSS.HIDDEN);
this.centerDialogue();
},
/**
@@ -336,9 +299,6 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
count,
selected,
i,
actionClass,
actionStr,
actionComponent,
node,
usersstr,
content,
@@ -358,7 +318,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
if (!args.append) {
users = create('<div class="'+CSS.USERS+'"></div>');
} else {
users = this.get(USP.BASE).one(SELECTORS.RESULTSUSERS);
users = this.get('boundingBox').one(SELECTORS.RESULTSUSERS);
}
if (!this._userTemplate) {
@@ -424,7 +384,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
Y.delegate("click", this.deselectUser, users, SELECTORS.USERDESELECT, this, args);
} else {
if (result.response.totalusers <= (this.get(USP.PAGE)+1)*this.get(USP.PERPAGE)) {
this.get(USP.BASE).one(SELECTORS.MORERESULTS).remove();
this.get('boundingBox').one(SELECTORS.MORERESULTS).remove();
}
}
},
@@ -488,7 +448,7 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
* @param {String} content The content.
*/
setContent: function(content) {
this.get(USP.BASE).one(SELECTORS.AJAXCONTENT).setContent(content);
this.get('boundingBox').one(SELECTORS.AJAXCONTENT).setContent(content);
},
/**
@@ -506,8 +466,47 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
}
}, {
NAME : USP.NAME,
CSS_PREFIX : USP.CSS_PREFIX,
ATTRS : {
extraClasses: {
value: [
'gradereport_history_usp'
]
},
/**
* The header.
*
* @attribute title
* @type String
*/
title: {
validator: Y.Lang.isString,
value: M.util.get_string('selectusers', COMPONENT)
},
/**
* Whether to focus on the target that caused the Widget to be shown.
*
* @attribute focusOnPreviousTargetAfterHide
* @type Node
*/
focusOnPreviousTargetAfterHide: {
value: true
},
/**
*
* Width.
*
* @attribute width
* @type {String|Number}
*/
width: {
value: '500px'
},
/**
* The current page URL.
*
@@ -528,33 +527,6 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
validator : Y.Lang.isString
},
/**
* The dialogue.
*
* @attribute base
* @type Node
*/
base : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(USP.NAME+': invalid base node set');
}
return n;
}
},
/**
* The initial list of users.
*
* @attribute userfullnames
* @type Object
*/
users : {
validator : Y.Lang.isArray,
value : null
},
/**
* IDs of the selected users.
*
@@ -646,9 +618,40 @@ Y.namespace('M.gradereport_history').UserSelector = Y.extend(USERSELECTOR, Y.Bas
value: 25,
Validator: Y.Lang.isNumber
}
}
});
Y.augment(Y.namespace('M.gradereport_history').UserSelector, Y.EventTarget);
// Y.augment(Y.namespace('M.gradereport_history').UserSelector, Y.EventTarget);
Y.Base.modifyAttrs(Y.namespace('M.gradereport_history.UserSelector'), {
/**
* Boolean indicating whether or not the Widget is visible.
*
* @attribute visible
* @default true
* @type Boolean
*/
visible: {
value: false
},
/**
* Whether the widget should be modal or not.
*
* @attribute modal
* @type Boolean
* @default true
*/
modal: {
value: true
},
draggable: {
value: true
}
});
Y.namespace('M.gradereport_history.UserSelector').init = function(cfg) {
return new USERSELECTOR(cfg);