MDL-42299 course: management interface remember categories expanded by AJAX
Categories that have been expanded using AJAX are now remember and expanded again autoamtically when something triggers a page refresh.
This commit is contained in:
@@ -103,6 +103,18 @@ switch ($action) {
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'expandcategory':
|
||||
$categoryid = required_param('categoryid', PARAM_INT);
|
||||
$coursecat = coursecat::get($categoryid);
|
||||
\core_course\management\helper::record_expanded_category($coursecat);
|
||||
$outcome->outcome = true;
|
||||
break;
|
||||
case 'collapsecategory':
|
||||
$categoryid = required_param('categoryid', PARAM_INT);
|
||||
$coursecat = coursecat::get($categoryid);
|
||||
\core_course\management\helper::record_expanded_category($coursecat, false);
|
||||
$outcome->outcome = true;
|
||||
break;
|
||||
case 'getsubcategorieshtml' :
|
||||
$categoryid = required_param('categoryid', PARAM_INT);
|
||||
/* @var core_course_management_renderer $renderer */
|
||||
|
||||
@@ -41,6 +41,13 @@ defined('MOODLE_INTERNAL') || die;
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class helper {
|
||||
|
||||
/**
|
||||
* The expanded category structure if its already being loaded from the cache.
|
||||
* @var null|array
|
||||
*/
|
||||
protected static $expandedcategories = null;
|
||||
|
||||
/**
|
||||
* Returns course details in an array ready to be printed.
|
||||
*
|
||||
@@ -803,4 +810,87 @@ class helper {
|
||||
$params = array('path' => $path);
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records when a category is expanded or collapsed so that when the user
|
||||
*
|
||||
* @param \coursecat $coursecat The category we're working with.
|
||||
* @param bool $expanded True if the category is expanded now.
|
||||
*/
|
||||
public static function record_expanded_category(\coursecat $coursecat, $expanded = true) {
|
||||
// If this ever changes we are going to reset it and reload the categories as required.
|
||||
self::$expandedcategories = null;
|
||||
$categoryid = $coursecat->id;
|
||||
$path = $coursecat->get_parents();
|
||||
/* @var \cache_session $cache */
|
||||
$cache = \cache::make('core', 'coursecat');
|
||||
$categories = $cache->get('managementexpanded');
|
||||
if (!is_array($categories)) {
|
||||
if (!$expanded) {
|
||||
// No categories recorded, nothing to remove.
|
||||
return;
|
||||
}
|
||||
$categories = array();
|
||||
}
|
||||
if ($expanded) {
|
||||
$ref =& $categories;
|
||||
foreach ($coursecat->get_parents() as $path) {
|
||||
if (!isset($ref[$path]) || !is_array($ref[$path])) {
|
||||
$ref[$path] = array();
|
||||
}
|
||||
$ref =& $ref[$path];
|
||||
}
|
||||
if (!isset($ref[$categoryid])) {
|
||||
$ref[$categoryid] = true;
|
||||
}
|
||||
} else {
|
||||
$found = true;
|
||||
$ref =& $categories;
|
||||
foreach ($coursecat->get_parents() as $path) {
|
||||
if (!isset($ref[$path])) {
|
||||
$found = false;
|
||||
break;
|
||||
}
|
||||
$ref =& $ref[$path];
|
||||
}
|
||||
if ($found) {
|
||||
$ref[$categoryid] = null;
|
||||
unset($ref[$categoryid]);
|
||||
}
|
||||
}
|
||||
$cache->set('managementexpanded', $categories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the categories that should be expanded when displaying the interface.
|
||||
*
|
||||
* @param int|null $withpath If specified a path to require as the parent.
|
||||
* @return \coursecat[] An array of Category ID's to expand.
|
||||
*/
|
||||
public static function get_expanded_categories($withpath = null) {
|
||||
if (self::$expandedcategories === null) {
|
||||
/* @var \cache_session $cache */
|
||||
$cache = \cache::make('core', 'coursecat');
|
||||
self::$expandedcategories = $cache->get('managementexpanded');
|
||||
if (self::$expandedcategories === false) {
|
||||
self::$expandedcategories = array();
|
||||
}
|
||||
}
|
||||
if (empty($withpath)) {
|
||||
return array_keys(self::$expandedcategories);
|
||||
}
|
||||
$parents = explode('/', trim($withpath, '/'));
|
||||
$ref =& self::$expandedcategories;
|
||||
foreach ($parents as $parent) {
|
||||
if (!isset($ref[$parent])) {
|
||||
return array();
|
||||
}
|
||||
$ref =& $ref[$parent];
|
||||
}
|
||||
if (is_array($ref)) {
|
||||
return array_keys($ref);
|
||||
} else {
|
||||
return array($parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,9 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
$selectedparents[] = $category->id;
|
||||
$selectedcategory = $category->id;
|
||||
}
|
||||
$catatlevel = array_shift($selectedparents);
|
||||
$catatlevel = \core_course\management\helper::get_expanded_categories('');
|
||||
$catatlevel[] = array_shift($selectedparents);
|
||||
$catatlevel = array_unique($catatlevel);
|
||||
|
||||
$listing = coursecat::get(0)->get_children();
|
||||
|
||||
@@ -135,7 +137,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
foreach ($listing as $listitem) {
|
||||
// Render each category in the listing.
|
||||
$subcategories = array();
|
||||
if ($listitem->id == $catatlevel) {
|
||||
if (in_array($listitem->id, $catatlevel)) {
|
||||
$subcategories = $listitem->get_children();
|
||||
}
|
||||
$html .= $this->category_listitem(
|
||||
@@ -166,6 +168,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
public function category_listitem(coursecat $category, array $subcategories, $totalsubcategories,
|
||||
$selectedcategory = null, $selectedcategories = array()) {
|
||||
|
||||
$isexpandable = ($totalsubcategories > 0);
|
||||
$isexpanded = (!empty($subcategories));
|
||||
$activecategory = ($selectedcategory === $category->id);
|
||||
@@ -224,9 +227,11 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
$html .= html_writer::end_div();
|
||||
if ($isexpanded) {
|
||||
$html .= html_writer::start_tag('ul', array('class' => 'ml', 'role' => 'group'));
|
||||
$catatlevel = array_shift($selectedcategories);
|
||||
$catatlevel = \core_course\management\helper::get_expanded_categories($category->path);
|
||||
$catatlevel[] = array_shift($selectedcategories);
|
||||
$catatlevel = array_unique($catatlevel);
|
||||
foreach ($subcategories as $listitem) {
|
||||
$childcategories = ($listitem->id == $catatlevel) ? $listitem->get_children() : array();
|
||||
$childcategories = (in_array($listitem->id, $catatlevel)) ? $listitem->get_children() : array();
|
||||
$html .= $this->category_listitem(
|
||||
$listitem,
|
||||
$childcategories,
|
||||
|
||||
@@ -693,3 +693,54 @@ Feature: Course category management interface performs as expected
|
||||
# Redirect
|
||||
And I should see "Edit course settings"
|
||||
And I should see "Course 1"
|
||||
|
||||
@javascript
|
||||
Scenario: Test AJAX expanded categories stay open.
|
||||
Given the following "categories" exists:
|
||||
| name | category | idnumber |
|
||||
| Cat 1 | 0 | CAT1 |
|
||||
| Cat 2 | 0 | CAT2 |
|
||||
| Cat 1-1 | CAT1 | CAT3 |
|
||||
| Cat 1-2 | CAT1 | CAT4 |
|
||||
| Cat 1-1-1 | CAT3 | CAT5 |
|
||||
| Cat 1-1-2 | CAT3 | CAT6 |
|
||||
| Cat 2-1 | CAT2 | CAT7 |
|
||||
| Cat 2-1-1 | CAT7 | CAT8 |
|
||||
| Cat 2-1-1-1 | CAT8 | CAT10 |
|
||||
| Cat 2-1-2 | CAT7 | CAT9 |
|
||||
| Cat 2-1-2-1 | CAT9 | CAT11 |
|
||||
|
||||
And I log in as "admin"
|
||||
And I go to the courses management page
|
||||
And I should see the "Course categories" management page
|
||||
And I should see "Cat 1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should not see "Cat 1-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should not see "Cat 1-2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should not see "Cat 2-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I click to expand category "CAT2" in the management interface
|
||||
# AJAX action - no redirect.
|
||||
And I click to expand category "CAT7" in the management interface
|
||||
# AJAX action - no redirect.
|
||||
And I click to expand category "CAT9" in the management interface
|
||||
# AJAX action - no redirect.
|
||||
And I should see "Cat 1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should not see "Cat 1-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should not see "Cat 1-2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1-2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should not see "Cat 2-1-1-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1-2-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I click on "Cat 1" "link"
|
||||
# Redirect.
|
||||
And I should see "Cat 1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 1-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 1-2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1-2" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should not see "Cat 2-1-1-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
And I should see "Cat 2-1-2-1" in the "#course-category-listings ul.ml" "css_element"
|
||||
@@ -423,6 +423,11 @@ Console.prototype = {
|
||||
args.action = action;
|
||||
args.ajax = '1';
|
||||
args.sesskey = M.cfg.sesskey;
|
||||
if (callback === null) {
|
||||
callback = function() {
|
||||
Y.log("'Action '"+action+"' completed", 'debug', 'moodle-course-management');
|
||||
};
|
||||
}
|
||||
io.send(this.get('ajaxurl'), {
|
||||
method : 'POST',
|
||||
on : {
|
||||
@@ -1155,6 +1160,7 @@ Category.prototype = {
|
||||
title : M.util.get_string('collapse', 'moodle'),
|
||||
alt : M.util.get_string('collapse', 'moodle')
|
||||
});
|
||||
this.get('console').performAjaxAction('expandcategory', {categoryid : this.get('categoryid')}, null, this);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1170,6 +1176,7 @@ Category.prototype = {
|
||||
title : M.util.get_string('expand', 'moodle'),
|
||||
alt : M.util.get_string('expand', 'moodle')
|
||||
});
|
||||
this.get('console').performAjaxAction('collapsecategory', {categoryid : this.get('categoryid')}, null, this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -416,6 +416,10 @@ Console.prototype = {
|
||||
args.action = action;
|
||||
args.ajax = '1';
|
||||
args.sesskey = M.cfg.sesskey;
|
||||
if (callback === null) {
|
||||
callback = function() {
|
||||
};
|
||||
}
|
||||
io.send(this.get('ajaxurl'), {
|
||||
method : 'POST',
|
||||
on : {
|
||||
@@ -1130,6 +1134,7 @@ Category.prototype = {
|
||||
title : M.util.get_string('collapse', 'moodle'),
|
||||
alt : M.util.get_string('collapse', 'moodle')
|
||||
});
|
||||
this.get('console').performAjaxAction('expandcategory', {categoryid : this.get('categoryid')}, null, this);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1145,6 +1150,7 @@ Category.prototype = {
|
||||
title : M.util.get_string('expand', 'moodle'),
|
||||
alt : M.util.get_string('expand', 'moodle')
|
||||
});
|
||||
this.get('console').performAjaxAction('collapsecategory', {categoryid : this.get('categoryid')}, null, this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
+2
@@ -155,6 +155,7 @@ Category.prototype = {
|
||||
title : M.util.get_string('collapse', 'moodle'),
|
||||
alt : M.util.get_string('collapse', 'moodle')
|
||||
});
|
||||
this.get('console').performAjaxAction('expandcategory', {categoryid : this.get('categoryid')}, null, this);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -170,6 +171,7 @@ Category.prototype = {
|
||||
title : M.util.get_string('expand', 'moodle'),
|
||||
alt : M.util.get_string('expand', 'moodle')
|
||||
});
|
||||
this.get('console').performAjaxAction('collapsecategory', {categoryid : this.get('categoryid')}, null, this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
+5
@@ -421,6 +421,11 @@ Console.prototype = {
|
||||
args.action = action;
|
||||
args.ajax = '1';
|
||||
args.sesskey = M.cfg.sesskey;
|
||||
if (callback === null) {
|
||||
callback = function() {
|
||||
Y.log("'Action '"+action+"' completed", 'debug', 'moodle-course-management');
|
||||
};
|
||||
}
|
||||
io.send(this.get('ajaxurl'), {
|
||||
method : 'POST',
|
||||
on : {
|
||||
|
||||
Reference in New Issue
Block a user