From f2eb500238614fc5c0a5fb4d18f91b4318d0226a Mon Sep 17 00:00:00 2001 From: tjhunt Date: Mon, 3 Nov 2008 05:04:23 +0000 Subject: [PATCH] weblib: MDL-17085 a function to print a collapsible region of the UI, with the collapsed state stored in a user_perference. --- lang/en_utf8/moodle.php | 3 +- lib/ajax/ajaxlib.php | 5 ++ lib/javascript-static.js | 125 ++++++++++++++++++++++++++++++- lib/moodlelib.php | 4 + lib/weblib.php | 53 +++++++++++++ pix/t/collapsed.png | Bin 0 -> 175 bytes pix/t/expanded.png | Bin 0 -> 172 bytes theme/standard/styles_layout.css | 8 ++ user/selector/test.php | 2 + 9 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 pix/t/collapsed.png create mode 100644 pix/t/expanded.png diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index 450055ece1..7a5d54f6f9 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -234,8 +234,9 @@ $string['clamquarantinedirfailed'] = 'Could not move the file into your specifie $string['clamunknownerror'] = 'There was an unknown error with clam.'; $string['cleaningtempdata'] = 'Cleaning temp data'; $string['clear'] = 'Clear'; -$string['clicktochange'] = 'Click to change'; $string['clickhere'] = 'Click here ...'; +$string['clicktochange'] = 'Click to change'; +$string['clicktohideshow'] = 'Click to expand or collapse'; $string['closewindow'] = 'Close this window'; $string['comparelanguage'] = 'Compare and edit current language'; $string['complete'] = 'Complete'; diff --git a/lib/ajax/ajaxlib.php b/lib/ajax/ajaxlib.php index b692ceeebf..af1aacd095 100644 --- a/lib/ajax/ajaxlib.php +++ b/lib/ajax/ajaxlib.php @@ -75,6 +75,11 @@ function ajax_get_lib($libname) { $libpath = $wwwroot . $translatelist[$libname]; } + // If we are in developer debug mode, use the non-compressed version of YUI for easier debugging. + if (debugging('', DEBUG_DEVELOPER)) { + $libpath = str_replace('-min.js', '.js', $libpath); + } + } else if (preg_match('/^https?:/', $libname)) { $libpath = $libname; diff --git a/lib/javascript-static.js b/lib/javascript-static.js index 257a895ddf..af83e02313 100644 --- a/lib/javascript-static.js +++ b/lib/javascript-static.js @@ -592,4 +592,127 @@ function set_user_preference(name, value) { function moodle_initialise_body() { document.body.className += ' jsenabled'; -} \ No newline at end of file +} + +/** + * Oject to handle a collapsible region, see print_collapsible_region in weblib.php + * @constructor + * @param String id the HTML id for the div. + * @param String userpref the user preference that records the state of this box. false if none. + * @param Boolean startcollapsed whether the box should start collapsed. + */ +function collapsible_region(id, userpref, strtooltip) { + // Record the pref name + this.userpref = userpref; + + // Find the divs in the document. + this.div = document.getElementById(id); + this.innerdiv = document.getElementById(id + '_inner'); + this.caption = document.getElementById(id + '_caption'); + this.caption.title = strtooltip; + + // Put the contents of caption in an to make it focussable. + var a = document.createElement('a'); + while (e = this.caption.firstChild) { + a.appendChild(e); + } + a.href = '#'; + this.caption.appendChild(a); + + // Create the animation. + this.animation = new YAHOO.util.Anim(this.div, {}, 0.3, YAHOO.util.Easing.easeBoth); + + // Get to the right initial state. + if (this.div.className.match(/\bcollapsed\b/)) { + this.collapsed = true; + var region = YAHOO.util.Region.getRegion(this.caption); + this.div.style.height = (region.bottom - region.top) + 'px'; + } + + // Add the appropriate image. + this.icon = document.createElement('img'); + this.icon.id = id + '_icon'; + this.icon.alt = ''; + if (this.collapsed) { + this.icon.src = moodle_cfg.pixpath + '/t/collapsed.png'; + } else { + this.icon.src = moodle_cfg.pixpath + '/t/expanded.png'; + } + this.caption.appendChild(this.icon); + + // Hook up the event handler. + self = this; + YAHOO.util.Event.addListener(this.caption, 'click', function(e) {self.handle_click(e);}); + YAHOO.util.Event.addListener(a, 'click', function(e) {self.handle_click(e);}); +} + +/** + * The user preference that stores the state of this box. + * @property userpref, innerdiv, captiondiv + * @type String + */ +collapsible_region.prototype.userpref = null; + +/** + * The key divs that make up this + * @property div, innerdiv, captiondiv + * @type HTMLDivElement + */ +collapsible_region.prototype.div = null; +collapsible_region.prototype.innerdiv = null; +collapsible_region.prototype.captiondiv = null; + +/** + * The key divs that make up this + * @property icon + * @type HTMLImageElement + */ +collapsible_region.prototype.icon = null; + +/** + * Whether the region is currently collapsed. + * @property collapsed + * @type Boolean + */ +collapsible_region.prototype.collapsed = false; + +/** + * @property animation + * @type YAHOO.util.Anim + */ +collapsible_region.prototype.animation = null; + +collapsible_region.prototype.handle_click = function(e) { + // Toggle the state. + this.collapsed = !this.collapsed; + + // Stop the click following the link. + YAHOO.util.Event.stopEvent(e); + + // Animate to the appropriate size. + if (this.animation.isAnimated()) { + this.animation.stop(); + } + if (this.collapsed) { + var targetel = this.caption; + this.div.className += ' collapsed'; + } else { + var targetel = this.innerdiv; + this.div.className = this.div.className.replace(/\s*\bcollapsed\b\s*/, ' '); + } + var region = YAHOO.util.Region.getRegion(targetel); + this.animation.attributes.height = { to: region.bottom - region.top, unit: 'px' }; + this.animation.animate(); + + // Set the appropriate icon. + if (this.collapsed) { + this.icon.src = moodle_cfg.pixpath + '/t/collapsed.png'; + } else { + this.icon.src = moodle_cfg.pixpath + '/t/expanded.png'; + } + + // Update the user preference. + if (this.userpref) { + set_user_preference(this.userpref, this.collapsed); + } +} diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 6fc69f94e0..f3af61186b 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -1115,7 +1115,11 @@ function get_user_preferences($name=NULL, $default=NULL, $otheruserid=NULL) { */ function user_preference_allow_ajax_update($name, $paramtype) { global $USER; + + // Make sure that the required JavaScript libraries are loaded. require_js(array('yui_yahoo', 'yui_connection')); + + // Record in the session that this user_preference is allowed to updated remotely. $USER->ajax_updatable_user_prefs[$name] = $paramtype; } diff --git a/lib/weblib.php b/lib/weblib.php index b80cc12c68..1ab65731d0 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -4088,6 +4088,58 @@ function print_box_end($return=false) { return print_container_end($return); } +function print_collapsible_region($contents, $classes, $id, $caption, $userpref = '', $default = false, $return = false) { + $output = print_collapsible_region_start($classes, $id, $caption, $userpref, true); + $output .= $contents; + $output .= print_collapsible_region_end(true); + + if ($return) { + return $output; + } else { + echo $output; + } +} + +function print_collapsible_region_start($classes, $id, $caption, $userpref = false, $default = false, $return = false) { + global $CFG; + + // Include required JavaScript libraries. + require_js(array('yui_yahoo', 'yui_dom-event', 'yui_event', 'yui_animation')); + + // Work out the initial state. + if (is_string($userpref)) { + user_preference_allow_ajax_update($userpref, PARAM_BOOL); + $collapsed = get_user_preferences($userpref, $default); + } else { + $collapsed = $default; + $userpref = false; + } + + $output = ''; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= $caption . ' '; + $output .= "
\n"; + $output .= print_js_call('new collapsible_region', array($id, $userpref, get_string('clicktohideshow')), true); + + if ($return) { + return $output; + } else { + echo $output; + } +} + +function print_collapsible_region_end($return = false) { + $output = '
'; + + if ($return) { + return $output; + } else { + echo $output; + } +} + /** * Print a message in a standard themed container. * @@ -4101,6 +4153,7 @@ function print_box_end($return=false) { function print_container($message, $clearfix=false, $classes='', $idbase='', $return=false) { $output = print_container_start($clearfix, $classes, $idbase, true); + $output .= $message; $output .= print_container_end(true); if ($return) { diff --git a/pix/t/collapsed.png b/pix/t/collapsed.png new file mode 100644 index 0000000000000000000000000000000000000000..6a5665563d45987a2343294bd2aa7141a74f6d73 GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-z3?wHfJxv8tjKx9jP7LeL$-D$|*aCb)Tr)B< z{{R0kw(esWNIJ>e-G!lpRn`N@;VkfoEC%Wq24O~qS#ugTe~DWM4f2VyOA literal 0 HcmV?d00001 diff --git a/pix/t/expanded.png b/pix/t/expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..e867e87a78d4b89aa62da5fe07fb076c531cdf75 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-z3?wHfJxv8tjKx9jP7LeL$-D$|*aCb)Tr)B< z{{R0kw(esWNIJ>e-G!lpRn`N@;VkfoEC%Wq24O~qS#uFVdQ I&MBb@0H+Ksj{pDw literal 0 HcmV?d00001 diff --git a/theme/standard/styles_layout.css b/theme/standard/styles_layout.css index 4d084c36a3..5fb92317a1 100644 --- a/theme/standard/styles_layout.css +++ b/theme/standard/styles_layout.css @@ -215,6 +215,14 @@ div.groupselector { text-align:center } +.collapsibleregion { + overflow: hidden; +} +div.collapsibleregion div.collapsibleregioncaption a { + color: inherit; + text-decoration: none; +} + .noticebox { border-width:1px; border-style:solid; diff --git a/user/selector/test.php b/user/selector/test.php index dfbc5fd7c7..bfb0da066a 100644 --- a/user/selector/test.php +++ b/user/selector/test.php @@ -57,6 +57,8 @@ if (!empty($users)) { echo ''; } +print_collapsible_region('Blah, blah, blah', '', 'mybox', 'Click me!', 'testbox'); + echo '
'; $userselector->display(); echo '

'; -- 2.39.5