From 87b4981b4ab4db8bca7261daed59d03958de4559 Mon Sep 17 00:00:00 2001 From: Sam Hemelryk Date: Tue, 21 Sep 2010 06:09:14 +0000 Subject: [PATCH] enrolments MDL-24317 Permission filter now remembers what you type into it. --- admin/roles/lib.php | 3 +- admin/roles/module.js | 244 ++++++++++++++++++++------------- lib/outputrequirementslib.php | 3 +- theme/standard/style/admin.css | 1 + 4 files changed, 151 insertions(+), 100 deletions(-) diff --git a/admin/roles/lib.php b/admin/roles/lib.php index a42e7127ff9..d77694d66fe 100644 --- a/admin/roles/lib.php +++ b/admin/roles/lib.php @@ -85,7 +85,8 @@ abstract class capability_table_base { public function display() { if (count($this->capabilities) > capability_table_base::NUM_CAPS_FOR_SEARCH) { global $PAGE; - $PAGE->requires->js_init_call('M.core_role.init_cap_table_filter', array($this->id, get_string('filter'), get_string('clear'))); + $PAGE->requires->strings_for_js(array('filter','clear'),'moodle'); + $PAGE->requires->js_init_call('M.core_role.init_cap_table_filter', array($this->id, $this->context->id)); } echo '' . "\n\n"; echo ''; diff --git a/admin/roles/module.js b/admin/roles/module.js index 08bec4dcaf6..c306400ac8a 100644 --- a/admin/roles/module.js +++ b/admin/roles/module.js @@ -1,118 +1,166 @@ -/* This class filters the rows of a table like the one on the define or -override roles pages. It adds a search box just above the table, and if -content is typed into that box, it hides any rows in the table where the -capability name does not contain that text. */ +/** + * This class filters the rows of a table like the one on the define or + * override roles pages. It adds a search box just above the table, and if + * content is typed into that box, it hides any rows in the table where the + * capability name does not contain that text. + */ +/** + * Role namespace + */ M.core_role = {}; -M.core_role.init_cap_table_filter = function(Y, tableid, strsearch, strclear) { - var CapTableFilter = function(tableid, strsearch, strclear) { - this.delayhandle = -1, - this.searchdelay = 100, // milliseconds +/** + * @param {YUI} Y + * @param {string} tableid + * @param {int} contextid + */ +M.core_role.init_cap_table_filter = function(Y, tableid, contextid) { - // Find the form controls. - this.table = document.getElementById(tableid); - - // Create a div to hold the search UI. - this.div = document.createElement('div'); - this.div.className = 'capabilitysearchui'; - this.div.style.width = this.table.offsetWidth + 'px'; - - // Create the capability search input. - this.input = document.createElement('input'); - this.input.type = 'text'; - this.input.id = tableid + 'capabilitysearch'; - - // Create a label for the search input. - this.label = document.createElement('label'); - this.label.htmlFor = this.input.id; - this.label.appendChild(document.createTextNode(strsearch + ' ')); - - // Create a clear button to clear the input. - this.button = document.createElement('input'); - this.button.value = strclear; - this.button.type = 'button'; - this.button.disabled = true; - - // Tie it all together - this.div.appendChild(this.label); - this.div.appendChild(this.input); - this.div.appendChild(this.button); - this.table.parentNode.insertBefore(this.div, this.table); - Y.on('keyup', this.change, this.input, this); - Y.on('click', this.clear, this.button, this); - - // Horrible hack! - var hidden = document.createElement('input'); - hidden.type = 'hidden'; - hidden.disabled = true; - this.div.appendChild(hidden); - hidden = document.createElement('input'); - hidden.type = 'hidden'; - hidden.disabled = true; - this.div.appendChild(hidden); + var CapTableFilter = function(tableid) { + this.tableid = tableid; + this.context = contextid; + this.initializer(); }; + CapTableFilter.prototype = { + tableid : null, // ID of the cap table + context : null, // Context ID associated with what ever we are looking at + delayhandle : -1, + searchdelay : 100, // milliseconds + table : null, + div : null, + input : null, + label : null, + button : null, + /** + * Initialises the CapTableFilter object. + * This is called initializer so that a move to convert this to a proper + * YUI module will be easier. + */ + initializer : function() { + // Get any existing filter value + var filtervalue = this.getFilterCookieValue(); - CapTableFilter.prototype.clear = function () { - this.input.value = ''; - if (this.delayhandle != -1) { - clearTimeout(this.delayhandle); - this.delayhandle = -1; - } - this.filter(); - }; + // Find the form controls. + this.table = Y.one('#'+this.tableid); - CapTableFilter.prototype.change = function() { - var self = this; - var handle = setTimeout(function(){self.filter();}, this.searchdelay); - if (this.delayhandle != -1) { - clearTimeout(this.delayhandle); - } - this.delayhandle = handle; - }; + // Create a div to hold the search UI. + this.div = Y.Node.create('
').setStyle('width', this.table.get('offsetWidth')); + // Create the capability search input. + this.input = Y.Node.create(''); + // Create a label for the search input. + this.label = Y.Node.create(''); + // Create a clear button to clear the input. + this.button = Y.Node.create('').set('disabled', filtervalue==''); - CapTableFilter.prototype.set_visible = function(row, visible) { - if (visible) { - Y.one(row).removeClass('hiddenrow'); - } else { - Y.one(row).addClass('hiddenrow'); - } - }; + // Tie it all together + this.div.append(this.label).append(this.input).append(this.button); - CapTableFilter.prototype.filter = function() { - var filtertext = this.input.value.toLowerCase(); - this.button.disabled = (filtertext == ''); - var lastheading = null; - var capssincelastheading = 0; + // Insert it into the div + this.table.ancestor().insert(this.div, this.table); - Y.all('#'+this.table.id+' tr').each(function(row, index, list) { - if (row.hasClass('rolecapheading')) { - if (lastheading) { - this.set_visible(lastheading, capssincelastheading > 0); - } - lastheading = row; - capssincelastheading = 0; + // Wire the events so it actually does something + this.input.on('keyup', this.change, this); + this.button.on('click', this.clear, this); + + if (filtervalue != '') { + this.filter(); } - if (row.hasClass('rolecap')) { - var capname = row.one('.cap-name').get('text') + '|' + row.one('.cap-desc a').get('text').toLowerCase(); - if (capname.indexOf(filtertext) >= 0) { - this.set_visible(row, true); - capssincelastheading += 1; - } else { - this.set_visible(row, false); - } + }, + /** + * Sets a cookie that describes the filter value. + * The cookie stores the context, and the time it was created and upon + * retrieval is checked to ensure that the cookie is for the correct + * context and is no more than an hour old. + */ + setFilterCookieValue : function(value) { + var cookie = { + fltcontext : this.context, + flttime : new Date().getTime(), + fltvalue : value } - }, this); + Y.Cookie.setSubs("captblflt", cookie); + }, + /** + * Gets the existing filter value if there is one. + * The cookie stores the context, and the time it was created and upon + * retrieval is checked to ensure that the cookie is for the correct + * context and is no more than an hour old. + */ + getFilterCookieValue : function() { + var cookie = Y.Cookie.getSubs('captblflt'); + if (cookie.fltcontext && cookie.fltcontext == this.context && parseInt(cookie.flttime) > new Date().getTime()-(60*60*1000)) { + return cookie.fltvalue; + } + return ''; + }, + /** + * Clears the filter value. + */ + clear : function() { + this.input.set('value', ''); + if (this.delayhandle != -1) { + clearTimeout(this.delayhandle); + this.delayhandle = -1; + } + this.filter(); + }, + /** + * Event callback for when the filter value changes + */ + change : function() { + var self = this; + var handle = setTimeout(function(){self.filter();}, this.searchdelay); + if (this.delayhandle != -1) { + clearTimeout(this.delayhandle); + } + this.delayhandle = handle; + }, + /** + * Marks a row as visible or hidden + */ + setVisible : function(row, visible) { + if (visible) { + row.removeClass('hiddenrow'); + } else { + row.addClass('hiddenrow'); + } + }, + /** + * Filters the capability table + */ + filter : function() { + var filtertext = this.input.get('value').toLowerCase(), + lastheading = null; - if (lastheading) { - this.set_visible(lastheading, capssincelastheading > 0); + this.setFilterCookieValue(filtertext); + + this.button.set('disabled', (filtertext == '')); + + this.table.all('tr').each(function(row){ + if (row.hasClass('rolecapheading')) { + this.setVisible(row, false); + lastheading = row; + } + if (row.hasClass('rolecap')) { + var capname = row.one('.cap-name').get('text') + '|' + row.one('.cap-desc a').get('text').toLowerCase(); + if (capname.indexOf(filtertext) >= 0) { + this.setVisible(row, true); + if (lastheading) { + this.setVisible(lastheading, true); + lastheading = null; + } + } else { + this.setVisible(row, false); + } + } + }, this); } - }; + } - new CapTableFilter(tableid, strsearch, strclear); + new CapTableFilter(tableid); }; - M.core_role.init_add_assign_page = function(Y) { var add = Y.one('#add'); var addselect = M.core_user.get_user_selector('addselect'); diff --git a/lib/outputrequirementslib.php b/lib/outputrequirementslib.php index 7b507a0da28..c0b112b64ed 100644 --- a/lib/outputrequirementslib.php +++ b/lib/outputrequirementslib.php @@ -418,7 +418,8 @@ class page_requirements_manager { break; case 'core_role': $module = array('name' => 'core_role', - 'fullpath' => '/admin/roles/module.js'); + 'fullpath' => '/admin/roles/module.js', + 'requires' => array('node', 'cookie')); break; case 'core_completion': $module = array('name' => 'core_completion', diff --git a/theme/standard/style/admin.css b/theme/standard/style/admin.css index f5601c57ca7..e204c1248c9 100644 --- a/theme/standard/style/admin.css +++ b/theme/standard/style/admin.css @@ -56,6 +56,7 @@ #page-admin-uploaduser table#uuresults {font-size: 0.9em;} #page-admin-auth_config .required {background-color:#DDDDDD;} #page-admin-report-unittest-index .sep {color:#AAAAAA;} +.path-admin-roles .capabilitysearchui {text-align:center;margin:0.5em;} .path-admin .rolecap .cap-name, .path-admin .rolecap .note {color: #888;font-size: 0.75em;}
' . get_string('capability','role') . '