MDL-22067 - modify help popup functionality to use overlay.
authorRossiani Wijaya <rossianiwijaya@gmail.com>
Mon, 3 May 2010 08:44:34 +0000 (08:44 +0000)
committerRossiani Wijaya <rossianiwijaya@gmail.com>
Mon, 3 May 2010 08:44:34 +0000 (08:44 +0000)
lib/formslib.php
lib/javascript-static.js
lib/outputactions.php
lib/outputrenderers.php
lib/outputrequirementslib.php
theme/base/style/core.css

index 0ff5c0f..d3aa51d 100644 (file)
@@ -1354,6 +1354,8 @@ class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless {
             $linktext = isset($buttonargs[3]) ? $buttonargs[3] : false;
 
             $element->_helpbutton = $OUTPUT->old_help_icon($page, $text, $module, $linktext);
+            //$OUTPUT->help_icon($identifier, $component, $linktext);
+            // $OUTPUT->help_icon($elementname, $module); // this is works
 
         } else if (!$suppresscheck) {
             print_error('nonexistentformelements', 'form', '', $elementname);
@@ -1385,8 +1387,8 @@ class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless {
     function addHelpButton($elementname, $identifier, $component = 'moodle', $linktext = '', $suppresscheck = false) {
         global $OUTPUT;
         if (array_key_exists($elementname, $this->_elementIndex)) {
-            $element = $this->_elements[$this->_elementIndex[$elementname]];
-            $element->_helpbutton = $OUTPUT->help_icon($identifier, $component, $linktext);
+            $element = $this->_elements[$this->_elementIndex[$elementname]];            
+            $element->_helpbutton = $OUTPUT->help_icon($identifier, $component, $linktext);            
         } else if (!$suppresscheck) {
             debugging(get_string('nonexistentformelements', 'form', $elementname));
         }
index 3758d0e..dce0f97 100644 (file)
@@ -1220,21 +1220,26 @@ function getElementsByClassName(oElm, strTagName, name) {
 function openpopup(event, args) {
 
     YAHOO.util.Event.preventDefault(event);
-
-    var fullurl = args.url;
-    if (!args.url.match(/https?:\/\//)) {
-        fullurl = M.cfg.wwwroot + args.url;
-    }
-    var windowobj = window.open(fullurl,args.name,args.options);
-    if (!windowobj) {
-        return true;
-    }
-    if (args.fullscreen) {
-        windowobj.moveTo(0,0);
-        windowobj.resizeTo(screen.availWidth,screen.availHeight);
+   
+    if (M.help_content.instance !== null) {       
+        var id = '#' + args.id;        
+        M.help_content.instance.load_from_openpopup(event, args);
+    } else {        
+        var fullurl = args.url;
+        if (!args.url.match(/https?:\/\//)) {
+            fullurl = M.cfg.wwwroot + args.url;
+        }
+        var windowobj = window.open(fullurl,args.name,args.options);
+        if (!windowobj) {
+            return true;
+        }
+        if (args.fullscreen) {
+            windowobj.moveTo(0,0);
+            windowobj.resizeTo(screen.availWidth,screen.availHeight);
+        }
+        windowobj.focus();
+        return false;
     }
-    windowobj.focus();
-    return false;
 }
 
 /* This is only used on a few help pages. */
@@ -1460,3 +1465,133 @@ function hide_item(itemid) {
         item.style.display = "none";
     }
 }
+
+M.help_content = {
+    instance : null,
+    init : function(Y) {                
+        Y.use('overlay', 'io', 'event-mouseenter', 'node', "*", function(Y) {
+
+            var help_content_overlay = {
+                overlay : null,
+                init : function() {
+                    var xy = Y.one('#helpcontent').getXY(); 
+
+                    // Create an overlay from markup
+                    this.overlay = new Y.Overlay({
+                        srcNode : "#helpcontent",
+                        contentBox: '#helpcontent',
+                        width:'400px',
+                        xy:[xy[0] + 200, xy[1] + 300]
+                    });
+                    this.overlay.render();
+                    this.overlay.hide();
+
+                    Y.on("click", Y.bind(this.overlay.show, this.overlay), "#show");
+                    Y.on("click", Y.bind(this.overlay.hide, this.overlay), "#hide");
+                    
+                    var menuButton = Y.one(".helplink"),
+                    overlaycontent = this;
+
+                    var boundingBox = this.overlay.get("boundingBox");
+
+                    //  Hide the menu if the user clicks outside of its content 
+                    boundingBox.get("ownerDocument").on("mousedown", function (event) {
+                        var oTarget = event.target;
+
+                        if (!oTarget.compareTo(menuButton) &&
+                            !menuButton.contains(oTarget) &&
+                            !oTarget.compareTo(boundingBox) &&
+                            !boundingBox.contains(oTarget)) {
+                            overlaycontent.overlay.hide();
+                        }
+                    });                    
+                },
+                
+                load_from_openpopup : function(event, node) {
+                    var spinner = document.createElement('img');
+                    spinner.src = M.cfg.loadingicon;
+                    this.overlay.set('bodyContent', spinner);
+
+                    var positionX = 0;
+                    var positionY = 0;
+
+                    if (event.pageX && !Y.UA.chrome) {
+                        positionX = event.pageX;
+                        positionY = event.pageY;
+                    } else if (event.pageX && !Y.UA.chrome) {
+                        positionX = document.getElementById(node['id']).offsetLeft + 200;
+                        positionY = document.getElementById(node['id']).offsetTop + 500;
+                    } else { //chrome browser
+                        positionX = event.clientX + document.body.scrollLeft ;
+                        positionY = document.body.scrollTop;
+                        if (event.clientX > document.body.scrollTop) {
+                            positionY += event.clientY;
+                        }
+                    }
+
+                    if (Y.UA.chrome) {
+                        positionX = event.clientX + document.body.scrollLeft ;
+                        positionY = document.body.scrollTop;
+                        if (event.clientX > document.body.scrollTop) {
+                            positionY += event.clientY;
+                        }                        
+                    }
+
+                    var contentwidth = parseInt(this.overlay.get('width'));
+                    var overlayalign = 'right';
+                    if (document.getElementById('page').offsetWidth <= (positionX + contentwidth )) {
+                        overlayalign = 'left';                        
+                    }
+
+                    var WidgetPositionAlign = Y.WidgetPositionAlign;
+                    if (overlayalign == 'right') {
+                        this.overlay.set("align", {node:"#" + node['id'],
+                          points:[WidgetPositionAlign.TL, WidgetPositionAlign.RC]});
+                    } else {
+                        this.overlay.set("align", {node:"#" + node['id'],
+                          points:[WidgetPositionAlign.TR, WidgetPositionAlign.LC]});
+                    }
+                    
+                    var fullurl = node.url;
+                    if (!node.url.match(/https?:\/\//)) {
+                        fullurl = M.cfg.wwwroot + node.url;
+                    }
+                    
+                    var ajaxurl = fullurl + '&ajax=1';
+                    thishelpcontent = this;
+                    
+                    var cfg = {
+                        method: 'get',
+                        on: {
+                            success: function(id, o, node) {
+                                thishelpcontent.load_from_openpopup_callback(o.responseText);                                
+                            },
+                            failure: function(id, o, node) {
+                                var debuginfo = o.statusText;
+                                if (M.cfg.developerdebug) {
+                                    o.statusText += ' (' + ajaxurl + ')';
+                                }                                
+                                thishelpcontent.load_from_openpopup_callback('bodyContent',debuginfo);
+                            }
+                        }
+                    };
+                    
+                    var conn = Y.io(ajaxurl, cfg);
+                    this.overlay.show();
+                },
+                
+                load_from_openpopup_callback : function(content) {                                                            
+                    this.overlay.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
+                },
+                
+                hideContent : function() {
+                    help = this;
+                    help.overlay.hide();
+                }                
+            }
+            help_content_overlay.init();
+            M.help_content.instance = help_content_overlay;
+            
+        });
+    }
+}
index e942716..7fbde60 100644 (file)
@@ -122,7 +122,7 @@ class popup_action extends component_action {
      * @param array  $params An array of popup parameters
      * @return void
      */
-    public function __construct($event, $url, $name='popup', $params=array()) {
+    public function __construct($event, $url, $name='popup', $params=array()) {        
         global $CFG;
         $this->name = $name;
 
@@ -143,7 +143,12 @@ class popup_action extends component_action {
                 $this->params[$var] = $params[$var];
             }
         }
-        parent::__construct($event, 'openpopup', array('url' => $url->out(false), 'name' => $name, 'options' => $this->get_js_options($params)));
+        
+        $attributes = array('url' => $url->out(false), 'name' => $name, 'options' => $this->get_js_options($params));
+        if (array_key_exists('id', $params)) {
+            $attributes['id'] = $params['id'];
+        }
+        parent::__construct($event, 'openpopup', $attributes);
     }
 
     /**
index 5f42de2..faf66ee 100644 (file)
@@ -62,7 +62,7 @@ class renderer_base {
      * @return string
      */
     public function render(renderable $widget) {
-        $rendermethod = 'render_'.get_class($widget);
+        $rendermethod = 'render_'.get_class($widget);  
         if (method_exists($this, $rendermethod)) {
             return $this->$rendermethod($widget);
         }
@@ -623,6 +623,10 @@ class core_renderer extends renderer_base {
 
         $output = $this->container_end_all(true);
 
+        $helpcontent_body = html_writer::tag('div',  '<button class="closehelpbutton" type="button" id="hide"><img src="'.$this->pix_url('t/delete').'" alt="close" /></button>', array('class'=>'helpcontent_body'));
+        $output .= html_writer::tag('div', $helpcontent_body, array('id'=>'helpcontent', 'class'=>'yui3-overlay-loading'));       
+        $this->page->requires->js_init_call('M.help_content.init');
+        
         $footer = $this->opencontainers->pop('header/footer');
 
         if (debugging() and $DB and $DB->is_transaction_started()) {
@@ -645,7 +649,7 @@ class core_renderer extends renderer_base {
         $footer = str_replace(self::END_HTML_TOKEN, $this->page->requires->get_end_code(), $footer);
 
         $this->page->set_state(moodle_page::STATE_DONE);
-
+      
 
         return $output . $footer;
     }
@@ -739,7 +743,7 @@ class core_renderer extends renderer_base {
             $output = html_writer::tag('a', get_string('skipa', 'access', $skiptitle), array('href' => '#sb-' . $bc->skipid, 'class' => 'skip-block'));
             $skipdest = html_writer::tag('span', '', array('id' => 'sb-' . $bc->skipid, 'class' => 'skip-block-to'));
         }
-
+        
         $output .= html_writer::start_tag('div', $bc->attributes);
 
         $controlshtml = $this->block_controls($bc->controls);
@@ -1460,9 +1464,9 @@ END;
         $attributes = array('href'=>$url, 'title'=>$title);
         $id = html_writer::random_id('helpicon');
         $attributes['id'] = $id;
-        $this->add_action_handler(new popup_action('click', $url), $id);
+        $this->add_action_handler(new popup_action('click', $url, 'popup', array('id'=>$id)), $id);
         $output = html_writer::tag('a', $output, $attributes);
-
+        
         // and finally span
         return html_writer::tag('span', $output, array('class' => 'helplink'));
     }
@@ -1476,7 +1480,7 @@ END;
      * @return string HTML fragment
      */
     public function help_icon($identifier, $component = 'moodle', $linktext = '') {
-        $icon = new help_icon($identifier, $component);
+        $icon = new help_icon($identifier, $component);        
         $icon->diag_strings();
         if ($linktext === true) {
             $icon->linktext = get_string($icon->identifier, $icon->component);
@@ -1523,7 +1527,7 @@ END;
         $attributes = array('href'=>$url, 'title'=>$title);
         $id = html_writer::random_id('helpicon');
         $attributes['id'] = $id;
-        $this->add_action_handler(new popup_action('click', $url), $id);
+        $this->add_action_handler(new popup_action('click', $url, 'popup', array('id'=>$id)), $id);
         $output = html_writer::tag('a', $output, $attributes);
 
         // and finally span
index 776acab..099fbcd 100644 (file)
@@ -241,7 +241,7 @@ class page_requirements_manager {
         }
 
         // accessibility stuff
-        $this->skip_link_to('maincontent', get_string('tocontent', 'access'));
+        $this->skip_link_to('maincontent', get_string('tocontent', 'access'));        
 
         // to be removed soon
         $this->yui2_lib('dom');        // at least javascript-static.js needs to be migrated to YUI3
@@ -249,8 +249,7 @@ class page_requirements_manager {
         $this->string_for_js('confirmation', 'admin');
         $this->string_for_js('cancel', 'moodle');
         $this->string_for_js('yes', 'moodle');
-        $this->js_init_call('M.util.init_help_icons');
-
+        
         if ($page->pagelayout === 'frametop') {
             $this->js_init_call('M.util.init_frametop');
         }
@@ -715,8 +714,8 @@ class page_requirements_manager {
      * @param string $function The name of the function to call
      * @param array  $arguments An optional array of argument parameters to pass to the function
      * @return void
-     */
-    public function event_handler($selector, $event, $function, array $arguments = null) {
+     */    
+    public function event_handler($selector, $event, $function, array $arguments = null) {        
         $this->eventhandlers[] = array('selector'=>$selector, 'event'=>$event, 'function'=>$function, 'arguments'=>$arguments);
     }
 
@@ -937,13 +936,13 @@ class page_requirements_manager {
      * @return string the HTML code to to at the end of the page.
      */
     public function get_end_code() {
-        global $CFG;
+        global $CFG;        
         // add other requested modules
         $output = $this->get_extra_modules_code();
 
         // add missing YUI2 YUI - to be removed once we convert everything to YUI3!
         $output .= $this->get_yui2lib_code();
-
+        
         // all the other linked scripts - there should be as few as possible
         if ($this->jsincludes['footer']) {
             foreach ($this->jsincludes['footer'] as $url) {
index e56c064..bb4ae93 100644 (file)
@@ -533,3 +533,15 @@ body.tag .managelink {padding: 5px;}
  * Web Service
  */
 #webservice-doc-generator td {text-align: left;border: 0px solid black;}
+
+
+/**
+ * Help Content (pop-up)
+ */
+#helpcontent { background-color: #FFE691; border: 1px solid #848484; z-index: 10; }
+#show { margin-left:5px; padding:0; }
+#hide { float: right; }
+.closehelpbutton { border: none; background: none; }
+.yui3-js-enabled .yui3-overlay-loading { top:-1000em; left:-1000em; position:absolute; display: none; }
+.yui3-widget-bd { float: none; clear: both; margin: 1em;}
+#helpcontent .helpheading {font-size: 1em;}