MDL-32824: Make dragdrop work correctly with section titles/links
Initially, the default section title was swapped within the course format javascript functions. Though some section titles may be custom and does not require swapping, in addition they may have links to single section view. This introduces some callback functions for define what needs to be done in sections libs and js files.
This commit is contained in:
@@ -56,6 +56,21 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
*/
|
||||
abstract protected function page_title();
|
||||
|
||||
/**
|
||||
* Generate the section title
|
||||
*
|
||||
* @param stdClass $section The course_section entry from DB
|
||||
* @param stdClass $course The course entry from DB
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function section_title($section, $course) {
|
||||
$title = get_section_name($course, $section);
|
||||
if ($section->section != 0 && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
|
||||
$title = html_writer::link(course_get_url($course, $section->section), $title);
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the content to displayed on the right part of a section
|
||||
* before course modules are included
|
||||
@@ -106,7 +121,7 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
*
|
||||
* @param stdClass $section The course_section entry from DB
|
||||
* @param stdClass $course The course entry from DB
|
||||
* @param bool $onsectionpage true if being printed on a section page
|
||||
* @param bool $onsectionpage true if being printed on a single-section page
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function section_header($section, $course, $onsectionpage) {
|
||||
@@ -115,7 +130,6 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
$o = '';
|
||||
$currenttext = '';
|
||||
$sectionstyle = '';
|
||||
$linktitle = false;
|
||||
|
||||
if ($section->section != 0) {
|
||||
// Only in the non-general sections.
|
||||
@@ -124,7 +138,6 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
} else if ($course->marker == $section->section) {
|
||||
$sectionstyle = ' current';
|
||||
}
|
||||
$linktitle = ($course->coursedisplay == COURSE_DISPLAY_MULTIPAGE);
|
||||
}
|
||||
|
||||
$o.= html_writer::start_tag('li', array('id' => 'section-'.$section->section,
|
||||
@@ -138,11 +151,7 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
$o.= html_writer::start_tag('div', array('class' => 'content'));
|
||||
|
||||
if (!$onsectionpage) {
|
||||
$title = get_section_name($course, $section);
|
||||
if ($linktitle) {
|
||||
$title = html_writer::link(course_get_url($course, $section->section), $title);
|
||||
}
|
||||
$o.= $this->output->heading($title, 3, 'sectionname');
|
||||
$o.= $this->output->heading($this->section_title($section, $course), 3, 'sectionname');
|
||||
}
|
||||
|
||||
$o.= html_writer::start_tag('div', array('class' => 'summary'));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Javascript functions for course format
|
||||
// Javascript functions for Topics course format
|
||||
|
||||
M.course = M.course || {};
|
||||
|
||||
@@ -36,13 +36,32 @@ M.course.format.get_config = function() {
|
||||
M.course.format.swap_sections = function(Y, node1, node2) {
|
||||
var CSS = {
|
||||
COURSECONTENT : 'course-content',
|
||||
LEFT : 'left',
|
||||
SECTIONADDMENUS : 'section_add_menus'
|
||||
};
|
||||
|
||||
var sectionlist = Y.Node.all('.'+CSS.COURSECONTENT+' '+M.course.format.get_section_selector(Y));
|
||||
// Swap left block
|
||||
sectionlist.item(node1).one('.'+CSS.LEFT).swap(sectionlist.item(node2).one('.'+CSS.LEFT));
|
||||
// Swap menus
|
||||
sectionlist.item(node1).one('.'+CSS.SECTIONADDMENUS).swap(sectionlist.item(node2).one('.'+CSS.SECTIONADDMENUS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sections after ajax response
|
||||
*
|
||||
* @param {YUI} Y YUI3 instance
|
||||
* @param {array} response ajax response
|
||||
* @param {string} sectionfrom first affected section
|
||||
* @param {string} sectionto last affected section
|
||||
* @return void
|
||||
*/
|
||||
M.course.format.process_sections = function(Y, sectionlist, response, sectionfrom, sectionto) {
|
||||
var CSS = {
|
||||
SECTIONNAME : 'sectionname'
|
||||
};
|
||||
|
||||
if (response.action == 'move') {
|
||||
// update titles in all affected sections
|
||||
for (var i = sectionfrom; i <= sectionto; i++) {
|
||||
sectionlist.item(i).one('.'+CSS.SECTIONNAME).setContent(response.sectiontitles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,3 +80,24 @@ function callback_topics_ajax_support() {
|
||||
$ajaxsupport->testedbrowsers = array('MSIE' => 6.0, 'Gecko' => 20061111, 'Safari' => 531, 'Chrome' => 6.0);
|
||||
return $ajaxsupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to do some action after section move
|
||||
*
|
||||
* @param stdClass $course The course entry from DB
|
||||
* @return array This will be passed in ajax respose.
|
||||
*/
|
||||
function callback_topics_ajax_section_move($course) {
|
||||
global $COURSE, $PAGE;
|
||||
|
||||
$titles = array();
|
||||
rebuild_course_cache($course->id);
|
||||
$modinfo = get_fast_modinfo($COURSE);
|
||||
$renderer = $PAGE->get_renderer('format_topics');
|
||||
if ($renderer && ($sections = $modinfo->get_section_info_all())) {
|
||||
foreach ($sections as $number => $section) {
|
||||
$titles[$number] = $renderer->section_title($section, $course);
|
||||
}
|
||||
}
|
||||
return array('sectiontitles' => $titles, 'action' => 'move');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Javascript functions for course format
|
||||
// Javascript functions for Weeks course format
|
||||
|
||||
M.course = M.course || {};
|
||||
|
||||
@@ -36,16 +36,32 @@ M.course.format.get_config = function() {
|
||||
M.course.format.swap_sections = function(Y, node1, node2) {
|
||||
var CSS = {
|
||||
COURSECONTENT : 'course-content',
|
||||
LEFT : 'left',
|
||||
SECTIONADDMENUS : 'section_add_menus',
|
||||
WEEKDATES: 'weekdates'
|
||||
SECTIONADDMENUS : 'section_add_menus'
|
||||
};
|
||||
|
||||
var sectionlist = Y.Node.all('.'+CSS.COURSECONTENT+' '+M.course.format.get_section_selector(Y));
|
||||
// Swap left block
|
||||
sectionlist.item(node1).one('.'+CSS.LEFT).swap(sectionlist.item(node2).one('.'+CSS.LEFT));
|
||||
// Swap menus
|
||||
sectionlist.item(node1).one('.'+CSS.SECTIONADDMENUS).swap(sectionlist.item(node2).one('.'+CSS.SECTIONADDMENUS));
|
||||
// Swap week dates
|
||||
sectionlist.item(node1).one('.'+CSS.WEEKDATES).swap(sectionlist.item(node2).one('.'+CSS.WEEKDATES));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sections after ajax response
|
||||
*
|
||||
* @param {YUI} Y YUI3 instance
|
||||
* @param {array} response ajax response
|
||||
* @param {string} sectionfrom first affected section
|
||||
* @param {string} sectionto last affected section
|
||||
* @return void
|
||||
*/
|
||||
M.course.format.process_sections = function(Y, sectionlist, response, sectionfrom, sectionto) {
|
||||
var CSS = {
|
||||
SECTIONNAME : 'sectionname'
|
||||
};
|
||||
|
||||
if (response.action == 'move') {
|
||||
// update titles in all affected sections
|
||||
for (var i = sectionfrom; i <= sectionto; i++) {
|
||||
sectionlist.item(i).one('.'+CSS.SECTIONNAME).setContent(response.sectiontitles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,3 +102,24 @@ function callback_weeks_ajax_support() {
|
||||
$ajaxsupport->testedbrowsers = array('MSIE' => 6.0, 'Gecko' => 20061111, 'Safari' => 531, 'Chrome' => 6.0);
|
||||
return $ajaxsupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to do some action after section move
|
||||
*
|
||||
* @param stdClass $course The course entry from DB
|
||||
* @return array This will be passed in ajax respose.
|
||||
*/
|
||||
function callback_weeks_ajax_section_move($course) {
|
||||
global $COURSE, $PAGE;
|
||||
|
||||
$titles = array();
|
||||
rebuild_course_cache($course->id);
|
||||
$modinfo = get_fast_modinfo($COURSE);
|
||||
$renderer = $PAGE->get_renderer('format_weeks');
|
||||
if ($renderer && ($sections = $modinfo->get_section_info_all())) {
|
||||
foreach ($sections as $number => $section) {
|
||||
$titles[$number] = $renderer->section_title($section, $course);
|
||||
}
|
||||
}
|
||||
return array('sectiontitles' => $titles, 'action' => 'move');
|
||||
}
|
||||
|
||||
@@ -89,6 +89,15 @@ switch($requestmethod) {
|
||||
|
||||
case 'move':
|
||||
move_section_to($course, $id, $value);
|
||||
// See if format wants to do something about it
|
||||
$libfile = $CFG->dirroot.'/course/format/'.$course->format.'/lib.php';
|
||||
$functionname = 'callback_'.$course->format.'_ajax_section_move';
|
||||
if (!function_exists($functionname) && file_exists($libfile)) {
|
||||
require_once $libfile;
|
||||
}
|
||||
if (function_exists($functionname)) {
|
||||
echo json_encode($functionname($course));
|
||||
}
|
||||
break;
|
||||
}
|
||||
rebuild_course_cache($course->id);
|
||||
|
||||
Vendored
+15
@@ -68,6 +68,21 @@ YUI.add('moodle-course-coursebase', function(Y) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sections after ajax response (should be defined in format.js)
|
||||
* If some response is expected, we pass it over to format, as it knows better
|
||||
* hot to process it.
|
||||
*
|
||||
* @param {YUI} Y YUI3 instance
|
||||
* @param {NodeList} list of sections
|
||||
* @param {array} response ajax response
|
||||
* @param {string} sectionfrom first affected section
|
||||
* @param {string} sectionto last affected section
|
||||
* @return void
|
||||
*/
|
||||
M.course.format.process_sections = M.course.format.process_sections || function(Y, sectionlist, response, sectionfrom, sectionto) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sections config for this format, for examples see function definition
|
||||
|
||||
Vendored
+15
-3
@@ -172,9 +172,16 @@ YUI.add('moodle-course-dragdrop', function(Y) {
|
||||
lightbox.show();
|
||||
},
|
||||
success: function(tid, response) {
|
||||
window.setTimeout(function(e) {
|
||||
lightbox.hide();
|
||||
}, 250);
|
||||
// Update section titles, we can't simply swap them as
|
||||
// they might have custom title
|
||||
try {
|
||||
var responsetext = Y.JSON.parse(response.responseText);
|
||||
if (responsetext.error) {
|
||||
new M.core.ajaxException(responsetext);
|
||||
}
|
||||
M.course.format.process_sections(Y, sectionlist, responsetext, loopstart, loopend);
|
||||
} catch (e) {}
|
||||
|
||||
// Classic bubble sort algorithm is applied to the section
|
||||
// nodes between original drag node location and the new one.
|
||||
do {
|
||||
@@ -193,6 +200,11 @@ YUI.add('moodle-course-dragdrop', function(Y) {
|
||||
}
|
||||
loopend = loopend - 1;
|
||||
} while (swapped);
|
||||
|
||||
// Finally, hide the lightbox
|
||||
window.setTimeout(function(e) {
|
||||
lightbox.hide();
|
||||
}, 250);
|
||||
},
|
||||
failure: function(tid, response) {
|
||||
this.ajax_failure(response);
|
||||
|
||||
Reference in New Issue
Block a user