javascript MDL-22067 Fixed errors with JavaScript openpopup and help icon popups

This commit is contained in:
Sam Hemelryk
2010-05-04 08:29:05 +00:00
parent 67f3290fcc
commit 2cf81209ff
5 changed files with 125 additions and 224 deletions
+107 -199
View File
@@ -169,67 +169,6 @@ M.util.CollapsibleRegion.prototype.div = null;
*/
M.util.CollapsibleRegion.prototype.icon = null;
/**
* Finds all help icons on the page and initiates YUI tooltips for
* each of them, which load a truncated version of the help's content
* on-the-fly asynchronously
*/
M.util.init_help_icons = function(Y) {
Y.use('io', 'yui2-dom', 'yui2-container', function(Y) {
// remove all titles, they would obscure the YUI tooltip
Y.all('span.helplink a').each(function(node) {
node.set('title', '');
});
var iconspans = YAHOO.util.Dom.getElementsByClassName('helplink', 'span');
var tooltip = new YAHOO.widget.Tooltip('help_icon_tooltip', {
context: iconspans,
showdelay: 1000,
hidedelay: 150,
autodismissdelay: 50000,
underlay: 'none',
zIndex: '1000'
});
tooltip.contextTriggerEvent.subscribe(
function(type, args) {
// Fetch help page contents asynchronously
// Load spinner icon while content is loading
var spinner = document.createElement('img');
spinner.src = M.cfg.loadingicon;
this.cfg.setProperty('text', spinner);
var context = args[0];
var link = context.getElementsByTagName('a')[0];
var thistooltip = this;
var ajaxurl = link.href + '&ajax=1';
var cfg = {
method: 'get',
on: {
success: function(id, o, args) {
thistooltip.cfg.setProperty('text', o.responseText);
},
failure: function(id, o, args) {
var debuginfo = o.statusText;
if (M.cfg.developerdebug) {
o.statusText += ' (' + ajaxurl + ')';
}
thistooltip.cfg.setProperty('text', debuginfo);
}
}
};
var conn = Y.io(ajaxurl, cfg);
}
);
});
};
/**
* Makes a best effort to connect back to Moodle to update a user preference,
* however, there is no mechanism for finding out if the update succeeded.
@@ -1219,27 +1158,25 @@ function getElementsByClassName(oElm, strTagName, name) {
function openpopup(event, args) {
YAHOO.util.Event.preventDefault(event);
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;
if (event) {
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);
}
windowobj.focus();
return false;
}
/* This is only used on a few help pages. */
@@ -1466,132 +1403,103 @@ function hide_item(itemid) {
}
}
M.help_content = {
M.util.help_icon = {
Y : null,
instance : null,
init : function(Y) {
Y.use('overlay', 'io', 'event-mouseenter', 'node', "*", function(Y) {
add : function(Y, properties) {
this.Y = Y;
Y.one('#'+properties.id).on('click', this.display, this, properties);
},
display : function(event, args) {
event.preventDefault();
if (M.util.help_icon.instance === null) {
var Y = M.util.help_icon.Y;
Y.use('overlay', 'io', 'event-mouseenter', 'node', function(Y) {
var help_content_overlay = {
overlay : null,
init : function() {
var help_content_overlay = {
overlay : null,
init : function() {
var xy = Y.one('#helpcontent').getXY();
var closebtn = Y.Node.create('<img src="'+M.util.image_url('t/delete', 'moodle')+'" />');
// 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();
// Create an overlay from markup
this.overlay = new Y.Overlay({
headerContent: closebtn,
bodyContent: '',
width:'400px',
visible : false,
constrain : true
});
this.overlay.render(Y.one(document.body));
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;
closebtn.on('click', this.overlay.hide, this.overlay);
var boundingBox = this.overlay.get("boundingBox");
var boundingBox = this.overlay.get("boundingBox");
boundingBox.addClass('helppopup');
// Hide the menu if the user clicks outside of its content
boundingBox.get("ownerDocument").on("mousedown", function (event) {
var oTarget = event.target;
// Hide the menu if the user clicks outside of its content
boundingBox.get("ownerDocument").on("mousedown", function (event) {
var oTarget = event.target;
var menuButton = Y.one("#"+args.id);
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);
if (!oTarget.compareTo(menuButton) &&
!menuButton.contains(oTarget) &&
!oTarget.compareTo(boundingBox) &&
!boundingBox.contains(oTarget)) {
this.overlay.hide();
}
}, this);
},
display : function(event, args) {
this.overlay.set('bodyContent', Y.Node.create('<img src="'+M.cfg.loadingicon+'" class="spinner" />'));
this.overlay.set("align", {node:"#" + args.id, points:[Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.RC]});
var fullurl = args.url;
if (!args.url.match(/https?:\/\//)) {
fullurl = M.cfg.wwwroot + args.url;
}
};
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;
});
var ajaxurl = fullurl + '&ajax=1';
var cfg = {
method: 'get',
context : this,
on: {
success: function(id, o, node) {
this.display_callback(o.responseText);
},
failure: function(id, o, node) {
var debuginfo = o.statusText;
if (M.cfg.developerdebug) {
o.statusText += ' (' + ajaxurl + ')';
}
this.display_callback('bodyContent',debuginfo);
}
}
};
Y.io(ajaxurl, cfg);
this.overlay.show();
},
display_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.util.help_icon.instance = help_content_overlay;
M.util.help_icon.instance.display(event, args);
});
} else {
M.util.help_icon.instance.display(event, args);
}
},
init : function(Y) {
this.Y = Y;
}
}
+6 -7
View File
@@ -96,6 +96,9 @@ class confirm_action extends component_action {
* @since Moodle 2.0
*/
class popup_action extends component_action {
public $jsfunction = 'openpopup';
/**
* @var array $params An array of parameters that will be passed to the openpopup JS function
*/
@@ -122,7 +125,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;
@@ -145,10 +148,7 @@ class popup_action extends component_action {
}
$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);
parent::__construct($event, $this->jsfunction, $attributes);
}
/**
@@ -172,5 +172,4 @@ class popup_action extends component_action {
return $jsoptions;
}
}
}
+4 -8
View 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);
}
@@ -622,10 +622,6 @@ class core_renderer extends renderer_base {
global $CFG, $DB;
$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');
@@ -649,7 +645,6 @@ 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;
}
@@ -1480,7 +1475,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);
@@ -1527,9 +1522,10 @@ 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, 'popup', array('id'=>$id)), $id);
$output = html_writer::tag('a', $output, $attributes);
$this->page->requires->js_init_call('M.util.help_icon.add', array(array('id'=>$id, 'url'=>$url->out(false))));
// and finally span
return html_writer::tag('span', $output, array('class' => 'helplink'));
}
+3 -3
View 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
@@ -936,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) {
+5 -7
View File
@@ -538,10 +538,8 @@ body.tag .managelink {padding: 5px;}
/**
* 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;}
.helppopup {background-color: #FFE691; border: 1px solid #848484;}
.helppopup .yui3-widget-hd {float:right;margin:3px 3px 0 0;}
.helppopup .yui3-widget-bd {margin:0 1em 1em 1em;border-top:1px solid #FFE691;}
.helppopup .helpheading {font-size: 1em;}
.helppopup .spinner {margin:1em;}