From 6a14c4ffdd01d6b2069e8c27bb2b7df26dcdbd6a Mon Sep 17 00:00:00 2001 From: Andrew Robert Nicols Date: Thu, 5 Jan 2012 16:53:02 +0000 Subject: [PATCH] MDL-31215 Add the ability to change activity titles using AJAX calls --- course/lib.php | 1 + course/rest.php | 9 ++ course/yui/toolboxes/toolboxes.js | 148 +++++++++++++++++++++++------- lang/en/moodle.php | 1 + pix/t/editstring.gif | Bin 0 -> 64 bytes 5 files changed, 127 insertions(+), 32 deletions(-) create mode 100644 pix/t/editstring.gif diff --git a/course/lib.php b/course/lib.php index ec47540faf9..bb63bd02ca9 100644 --- a/course/lib.php +++ b/course/lib.php @@ -4518,6 +4518,7 @@ function include_course_ajax($course, $modules = array(), $config = null) { 'moveleft', 'deletechecktype', 'deletechecktypename', + 'edittitle', 'show', 'hide', 'groupsnone', diff --git a/course/rest.php b/course/rest.php index ec9956ee2b3..26db6591b2a 100644 --- a/course/rest.php +++ b/course/rest.php @@ -40,6 +40,7 @@ $summary = optional_param('summary', '', PARAM_RAW); $sequence = optional_param('sequence', '', PARAM_SEQUENCE); $visible = optional_param('visible', 0, PARAM_INT); $pageaction = optional_param('action', '', PARAM_ALPHA); // Used to simulate a DELETE command +$title = optional_param('title', '', PARAM_TEXT); $PAGE->set_url('/course/rest.php', array('courseId'=>$courseid,'class'=>$class)); @@ -144,6 +145,14 @@ switch($requestmethod) { moveto_module($cm, $section, $beforemod); break; + case 'updatetitle': + require_capability('moodle/course:manageactivities', $modcontext); + $cm = get_coursemodule_from_id('', $id, 0, false, MUST_EXIST); + $module = new stdClass(); + $module->id = $cm->instance; + $module->name = $title; + $DB->update_record($cm->modname, $module); + break; } rebuild_course_cache($course->id); break; diff --git a/course/yui/toolboxes/toolboxes.js b/course/yui/toolboxes/toolboxes.js index fd67cfec270..d8e7ad3ace2 100644 --- a/course/yui/toolboxes/toolboxes.js +++ b/course/yui/toolboxes/toolboxes.js @@ -216,36 +216,6 @@ YUI.add('moodle-course-toolboxes', function(Y) { */ get_section_id : function(section) { return section.get('id').replace(CSS.SECTIONIDPREFIX, ''); - }, - add_lightbox: function(node) { - node.setStyle('position', 'relative'); - var waiticon = Y.Node.create('') - .setAttrs({ - 'src' : M.util.image_url(WAITICON.pix, WAITICON.component), - 'title' : M.str.moodle.move, - 'hspace' : '3' - }) - .setStyles({ - 'position' : 'relative', - 'top' : '50%' - }); - - var lightbox = Y.Node.create('
') - .setStyles({ - 'opacity' : '.75', - 'position' : 'absolute', - 'width' : '100%', - 'height' : '100%', - 'top' : 0, - 'left' : 0, - 'backgroundColor' : 'white', - 'text-align' : 'center' - }) - .setAttribute('class', 'lightbox') - .hide(); - lightbox.appendChild(waiticon); - node.append(lightbox); - return lightbox; } }, { @@ -330,6 +300,13 @@ YUI.add('moodle-course-toolboxes', function(Y) { groups = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.GROUPSVISIBLE, this.toggle_groupmode); groups.setAttribute('groupmode', this.GROUPS_VISIBLE); + + // Add the edit title button + Y.one(toolboxtarget).all(CSS.ACTIVITYLI).each(function (target) { + if (!target.hasClass(CSS.HASLABEL)) { + this.add_edittitlebutton(target.one(CSS.COMMANDSPAN)); + } + }, this); }, move_left : function(e) { this.move_leftright(e, -1, CSS.MOVELEFT); @@ -503,6 +480,113 @@ YUI.add('moodle-course-toolboxes', function(Y) { anchor.appendChild(newicon); anchor.on('click', this.move_left, this); target.one(CSS.MOVERIGHT).insert(anchor, 'before'); + }, + /** + * Add the edittitlebutton button + * + * @param target The encapsulating
  • element + */ + add_edittitlebutton : function(target) { + var edit_string = M.util.get_string('edittitle', 'moodle'); + var newicon = Y.Node.create('') + .addClass(CSS.GENERICICONCLASS) + .setAttrs({ + 'src' : M.util.image_url('t/editstring', 'moodle'), + 'title' : edit_string, + 'alt' : edit_string + }); + var anchor = new Y.Node.create('') + .setStyle('cursor', 'pointer') + .addClass(CSS.EDITTITLECLASS) + .set('title', edit_string); + anchor.appendChild(newicon); + anchor.on('click', this.edit_resource_title, this); + target.get('firstChild').insert(anchor, 'before'); + }, + /** + * Edit the title for the resource + */ + edit_resource_title : function(e) { + // Get the element we're working on + var element = e.target.ancestor(CSS.ACTIVITYLI); + var instancename = element.one(CSS.INSTANCENAME); + var currenttitle = instancename.get('firstChild'); + var oldtitle = currenttitle.get('data'); + var editbutton = element.one('a.' + CSS.EDITTITLECLASS + ' img'); + + // Disable the current href to prevent redirections when editing + var anchor = instancename.ancestor('a'); + anchor.setAttribute('oldhref', anchor.getAttribute('href')); + anchor.removeAttribute('href'); + + // Create the editor and submit button + var editor = Y.Node.create('') + .setAttrs({ + 'name' : 'title', + 'value' : oldtitle, + 'autocomplete' : 'off' + }); + var editform = Y.Node.create('
    ') + .setStyle('padding', '0') + .setStyle('display', 'inline') + .setAttribute('action', '#'); + + // Clear the existing content and put the editor in + currenttitle.set('data', ''); + editform.appendChild(editor); + instancename.appendChild(editform); + + // Focus and select the editor text + editor.focus().select(); + + // Handle cancellation of the editor + editor.on('blur', function(e) { + // Detach the blur event before removing as some actions trigger multiple blurs in + // some browser + editor.detach('blur'); + editform.remove(); + + // Set the title and anchor back to their previous settings + currenttitle.set('data', oldtitle); + anchor.setAttribute('href', anchor.getAttribute('oldhref')); + anchor.removeAttribute('oldhref'); + }); + + // Handle form submission + editform.on('submit', function(e) { + // We don't actually want to submit anything + e.preventDefault(); + + // Detach the handlers to prevent multiple submissions + editform.detach('submit'); + editor.detach('blur'); + + // We only accept strings which have valid content + var newtitle = Y.Lang.trim(editor.get('value')); + if (newtitle != null && newtitle != "" && newtitle != oldtitle) { + var data = { + 'class' : 'resource', + 'field' : 'updatetitle', + 'title' : newtitle, + 'id' : this.get_element_id(element) + }; + this.send_request(data, editbutton); + currenttitle.set('data', newtitle); + } else { + // Invalid content. Set the title back to it's original contents + currenttitle.set('data', oldtitle); + } + + // Add the anchor back + editform.remove(); + + // We need a timeout here otherwise hitting return to save in some browsers triggers + // the anchor + setTimeout(function(e) { + anchor.setAttribute('href', anchor.getAttribute('oldhref')); + anchor.removeAttribute('oldhref'); + }, 500); + }, this); } }, { NAME : 'course-resource-toolbox', @@ -589,7 +673,7 @@ YUI.add('moodle-course-toolboxes', function(Y) { 'value' : value }; - var lightbox = this.add_lightbox(section); + var lightbox = M.util.add_lightbox(Y, section); lightbox.show(); var response = this.send_request(data, null, lightbox); @@ -658,7 +742,7 @@ YUI.add('moodle-course-toolboxes', function(Y) { 'field' : 'marker', 'value' : value }; - var lightbox = this.add_lightbox(section); + var lightbox = M.util.add_lightbox(Y, section); lightbox.show(); this.send_request(data, null, lightbox); } diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 618e6b15c72..9b8a7908787 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -504,6 +504,7 @@ $string['editorsettings'] = 'Editor settings'; $string['editorshortcutkeys'] = 'Editor shortcut keys'; $string['editsettings'] = 'Edit settings'; $string['editsummary'] = 'Edit summary'; +$string['edittitle'] = 'Edit title'; $string['editthisactivity'] = 'Edit this activity'; $string['editthiscategory'] = 'Edit this category'; $string['edituser'] = 'Edit user accounts'; diff --git a/pix/t/editstring.gif b/pix/t/editstring.gif new file mode 100644 index 0000000000000000000000000000000000000000..2a163d6f72e4c4df6020373ec1697307b3f56508 GIT binary patch literal 64 zcmZ?wbhEHbjEB<6*