A jqueryui dialog is placed at the right edge of window, when I quickly resize the dialog from the left side, the dialog's width was set incorretly. what I mean quickly resize here is, move the mouse fast and then quickly release the mouse, I will explain later the reason of doing this.
To make my word more clearly, I have created a jsfiddle: https://jsfiddle.net/sangelee/hw62erug/6/embedded/result/
You can try yourself what I have done in the jsfiddle, but remember you should first put the dialog at the right edge of the container:http://jqueryui.com/dialog/
In the jqueryui source code, the following snippet is executed when resizing the dialog:
resize: function( event ) {
var woset, hoset, isParent, isOffsetRelative,
that = $( this ).resizable( "instance" ),
o = that.options,
co = that.containerOffset,
cp = that.position,
pRatio = that._aspectRatio || event.shiftKey,
cop = {
top: 0,
left: 0
},
ce = that.containerElement,
continueResize = true;
if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
cop = co;
}
if ( cp.left < ( that._helper ? co.left : 0 ) ) {
that.size.width = that.size.width +
( that._helper ?
( that.position.left - co.left ) :
( that.position.left - cop.left ) );
if ( pRatio ) {
that.size.height = that.size.width / that.aspectRatio;
continueResize = false;
}
that.position.left = o.helper ? co.left : 0;
}
if ( cp.top < ( that._helper ? co.top : 0 ) ) {
that.size.height = that.size.height +
( that._helper ?
( that.position.top - co.top ) :
that.position.top );
if ( pRatio ) {
that.size.width = that.size.height * that.aspectRatio;
continueResize = false;
}
that.position.top = that._helper ? co.top : 0;
}
isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
if ( isParent && isOffsetRelative ) {
that.offset.left = that.parentData.left + that.position.left;
that.offset.top = that.parentData.top + that.position.top;
} else {
that.offset.left = that.element.offset().left;
that.offset.top = that.element.offset().top;
}
woset = Math.abs( that.sizeDiff.width +
(that._helper ?
that.offset.left - cop.left :
(that.offset.left - co.left)) );
hoset = Math.abs( that.sizeDiff.height +
(that._helper ?
that.offset.top - cop.top :
(that.offset.top - co.top)) );
if ( woset + that.size.width >= that.parentData.width ) {
that.size.width = that.parentData.width - woset;
if ( pRatio ) {
that.size.height = that.size.width / that.aspectRatio;
continueResize = false;
}
}
if ( hoset + that.size.height >= that.parentData.height ) {
that.size.height = that.parentData.height - hoset;
if ( pRatio ) {
that.size.width = that.size.height * that.aspectRatio;
continueResize = false;
}
}
if ( !continueResize ) {
that.position.left = that.prevPosition.left;
that.position.top = that.prevPosition.top;
that.size.width = that.prevSize.width;
that.size.height = that.prevSize.height;
}
}
In the code above, there is a conditional statement:
if ( woset + that.size.width >= that.parentData.width ) {
that.size.width = that.parentData.width - woset;
if ( pRatio ) {
that.size.height = that.size.width / that.aspectRatio;
continueResize = false;
}
}
The woset was the element's previous $(element).offset().left, but the that.size.width is the element's current new width, why the woset used the previous value but not the current offset, or just use event.pageX?
I have tried that, if woset was replaced by event.pageX, or remove the statement that.size.width = that.parentData.width - woset;, the flickering of the dialog's right side that I showed in the jsfiddle won't happen, and the dialog's resizing behavior still works well. So why add this conditional statement?
If the dialog was not placed at the right edge of window, the conditional statement will not passed, and the dialog's width won't be reset. It is the reason why only the dialog which is closed to the right edge of the window will have the width not set correctly issue.
Perhaps I didn't make myself clear in the above, so I give another example here.
A dialog was initially placed at the right edge of window, and its offset is left: 1600, top: 0, width: 300. woset + that.size.width == that.parentData.width is true here because the dialog is closed to the right edge of window. The window width is initially set to 1900. To simulate resizing quickly on the left side:
var mouseover_event = new MouseEvent('mouseover', {
bubbles: true,
button: 0,
cancelBubble: false,
cancelable: true,
clientX: 1600,
clientY: 300,
pageX: 1600,
pageY: 300
});
var mousedown_event = new MouseEvent('mousedown', {
bubbles: true,
button: 0,
cancelBubble: false,
cancelable: true,
clientX: 1600,
clientY: 300,
pageX: 1600,
pageY: 300
});
var mousemove_event = new MouseEvent('mousemove', {
bubbles: true,
button: 0,
cancelBubble: false,
cancelable: true,
clientX: 1300,
clientY: 300,
pageX: 1300,
pageY: 300
});
var resize_handler = document.querySelector('.ui-resizable-handle.ui-resizable-w');
resize_handler.dispatchEvent(mouseover_event);
resize_handler.dispatchEvent(mousedown_event);
resize_handler.dispatchEvent(mousemove_event);
After dispatch the events, the dialog's position and width should be: left: 1300; width: 600.
However, when executing the conditional statement above, if ( woset + that.size.width >= that.parentData.width ) {, that.size.width was set to be the new dialog width 600, but the woset was still the initial offset 1600, that.parentData.width is the window's width, 1600 + 600 > 1900, and then the follow statement, that.size.width = that.parentData.width - woset; was executed, which sets the dialog's width to nearly the initial width 300. It seems that the dialog was just been moved, not resized. So I think the dialog's width issue was caused by that statement.
The reason I quickly resize the dialog is that I'm writing a script to sync two same page's events, means when an event happened in one page, sends the event detail to the other same page, and then dispatch the same event, just like element.dispatchEvent(event) above. For the sake of efficiency, when syncing the drag or resize event, just sync the last mousemove event before the mouseup(it is just the same behavior as quickly resize the dialog).
The jqueryui version I used is 1.11.4.
And my questions:
Why to add the conditional statement if ( woset + that.size.width >= that.parentData.width ) { and reset the dialog's width that.size.width = that.parentData.width - woset;, since that.size.width has already been set correctly? And why woset was the 'previous value' but not the 'current value'?
Are there any workarounds to the dialog's width problem?
Related
I'm trying to use a plane seat map generator. What it does is really simple. You insert the passengers for first, business and economy on html inputs. And automatically a chart should appear. This work is perform by javascript. I'm trying to run it but something is going wrong. It just does not work. It shows the table where you should put the inputs and a number 7 under it. I guess that's happening because I am missing some javascript. When you fill the input nothing happens.
To make it easier I put the code on jsfiddle. http://jsfiddle.net/g4kzo4fo/
Because I have to paste code here you have my javascript. I think the problem is somewhere here:
makeRequest(request, id, false);
$('#'+id).dialog({ width: 'auto', height: 'auto', modal: true, resizable: false });
$('#'+id).dialog('open');
}
var AircraftConfigCheck = {
capacity : 200,
business : 0,
economy: 0,
first: 0,
businessFree : 0,
economyFree : 0,
firstFree: 0,
total : function() {
return (parseInt(this.business) || 0) * 2 + (parseInt(this.economy) || 0) + (parseInt(this.first) || 0) * 4;
},
checkBusiness : function() {
if( this.total() > this.capacity ) {
this.business = Math.floor( ( this.capacity - this.economy - this.first * 4 ) / 2 );
}
},
checkEconomy : function() {
if( this.total() > this.capacity ) {
this.economy = this.capacity - this.business * 2 - this.first * 4;
}
},
checkFirst : function() {
if( this.total() > this.capacity ) {
this.first = Math.floor( ( this.capacity - this.economy - this.business * 2 ) / 4 );
}
},
updateCapacity : function() {
this.businessFree = Math.max( 0, Math.floor( ( this.capacity - this.total() ) / 2 ) );
this.firstFree = Math.max( 0, Math.floor( ( this.capacity - this.total() ) / 4 ) );
this.economyFree = Math.max( 0, this.capacity - this.total() );
},
setValues : function() {
$("#business").val( this.business );
$("#economy").val( this.economy );
$("#first").val( this.first );
$("#businessFree").html( this.businessFree );
$("#economyFree").html( this.economyFree );
$("#firstFree").html( this.firstFree );
/*$("#first").val( this.total() ); */
this.render();
},
render : function() {
makeRequest('http://www.fsairlines.net/crewcenter/aircraft_config_ajax.php5?max_pax='+this.capacity+
'&first_seats='+this.first+
'&business_seats='+this.business+
'&economy_seats='+this.economy,
'aircraft',
true
);
}
}
$(function() {
$(".seatInput").keyup(function() {
switch( $(this).attr("id") ) {
case "economy":
AircraftConfigCheck.economy = $("#economy").val();
AircraftConfigCheck.checkEconomy();
AircraftConfigCheck.updateCapacity();
AircraftConfigCheck.setValues();
break;
case "business":
AircraftConfigCheck.business = $("#business").val();
AircraftConfigCheck.checkBusiness();
AircraftConfigCheck.updateCapacity();
AircraftConfigCheck.setValues();
break;
case "first":
AircraftConfigCheck.first = $("#first").val();
AircraftConfigCheck.checkFirst();
AircraftConfigCheck.updateCapacity();
AircraftConfigCheck.setValues();
break;
}
});
});
Thanks in advance!
LASTEST UPDATE: http://jsfiddle.net/g4kzo4fo/4/
You have quite a few syntax errors in your code which is why it isn't running.
This part of the code doesn't make any sense:
makeRequest(request, id, false);
$('#'+id).dialog({ width: 'auto', height: 'auto', modal: true, resizable: false });
$('#'+id).dialog('open');
}
The makeRequest() function doesn't exist so you can't call it. And, there's an extraneous } at the end of this block.
Then, later inside the render function, you try to call makeRequest() again, but it doesn't exist.
The very first thing you should do when running any Javascript code that you've just written is to check the error console or debug console in the browser for errors. Then, anytime that something isn't working properly check the console again. Then, when you're testing your code, check the error console again.
Fiddle - http://liveweave.com/JS9EBN
This is a starter template for web design applications. (well almost except for the drawing problem)
Elements are drawn to the stage like so.
// Handles Drawable Elements
$("#canvas").on('mousedown touchstart', function(e) {
if(drawable) {
drawing = true;
mS.x = e.pageX;
mS.y = e.pageY;
dBox = $("<" + $('.draw-elements input[type=radio]:checked').val() + " class='box' />")
.html("Certains textes");
$(this).append(dBox);
// Do not select text when drawing
return false;
}
});
$(document).on('mousemove touchmove', function(e) {
if(drawing && drawable){
var mPos = {x:e.pageX, y:e.pageY};
var css = {};
css.position = 'absolute';
css.left = (mPos.x > mS.x) ? mS.x : mPos.x;
css.top = (mPos.y > mS.y) ? mS.y : mPos.y;
css.width = Math.abs(mPos.x - mS.x);
css.height = Math.abs(mPos.y - mS.y);
css.border = '1px dotted rgb(0, 34, 102)';
dBox.css(css);
// Do not select text when drawing
return false;
}
}).on('mouseup touchend', function(e) {
drawing = false;
});
As long as my select tool is not called I can draw elements without a problem, but when it is called and I come back to draw a div I can no longer draw elements to my stage.
After some tinkering I noticed the problem resides with my drag function for each element that's selected.
var HandleSelectedElement = function() {
if ($(".select-tool.activetool").is(":visible")) {
if(elmstyle) {
$('#canvas').children().drag("start",function( ev, dd ){
dd.attrc = $( ev.target ).prop("className");
dd.attrd = $( ev.target ).prop("id");
dd.width = $( this ).width();
dd.height = $( this ).height();
})
.drag(function( ev, dd ){
var props = {};
if ( dd.attrc.indexOf("E") > -1 ){
props.width = Math.max( 32, dd.width + dd.deltaX );
}
if ( dd.attrc.indexOf("S") > -1 ){
props.height = Math.max( 32, dd.height + dd.deltaY );
}
if ( dd.attrc.indexOf("W") > -1 ){
props.width = Math.max( 32, dd.width - dd.deltaX );
props.left = dd.originalX + dd.width - props.width;
}
if ( dd.attrc.indexOf("N") > -1 ){
props.height = Math.max( 32, dd.height - dd.deltaY );
props.top = dd.originalY + dd.height - props.height;
}
if ( dd.attrd.indexOf("stylethis") > -1 ){
props.top = dd.offsetY;
props.left = dd.offsetX;
}
$('#stylethis').css( props );
}, {relative:true});
}
};
I don't understand what's wrong.
I couldn't find out how to solve the initial problem. So I decided to do a work around.
Here's the fiddle: http://liveweave.com/g2aKlD
I decided to refresh the canvas each time a tool is clicked. I take the canvas's html and set that as a textarea's value. I then set the textarea's value as the canvas's html.
$("#code").val($("#canvas").html());
$("#canvas").html($("#code").val());
This way whatever called the initial bug is removed completely. However last time I did this all spaces where turned into a otherwise known as a non-breakable space (I've also seen this also add unnecessary line breaks and paragraphs when not needed)
I still don't understand why my draw function did not work when drag was turned off.
I really hate having to do this (being refreshing the canvas) because the more elements that are in there and the more refreshing is done, the more ram it uses which makes the browser work the cpu that much harder.
I hope someone can come across a better solution.
I am using this jquery splitter plugin located here: http://methvin.com/splitter/
It is working fine with the version of jquery I am using until I enable the resizeToWidth property then it is giving me the error: too much recursion.
Here is a link to a demo I created on jsfiddle: http://jsfiddle.net/S97rv/4/
Iv looked at the plugin code but im not a javascript expert and don't want to mess with it to much.
Can anybody see a solution to this error?
Here is the plugin code but probably better just looking at the jsfiddle link:
;(function($){
$.fn.splitter = function(args){
args = args || {};
return this.each(function() {
var zombie; // left-behind splitbar for outline resizes
function startSplitMouse(evt) {
if ( opts.outline )
zombie = zombie || bar.clone(false).insertAfter(A);
panes.css("-webkit-user-select", "none"); // Safari selects A/B text on a move
bar.addClass(opts.activeClass);
A._posSplit = A[0][opts.pxSplit] - evt[opts.eventPos];
$(document)
.bind("mousemove", doSplitMouse)
.bind("mouseup", endSplitMouse);
}
function doSplitMouse(evt) {
var newPos = A._posSplit+evt[opts.eventPos];
if ( opts.outline ) {
newPos = Math.max(0, Math.min(newPos, splitter._DA - bar._DA));
bar.css(opts.origin, newPos);
} else
resplit(newPos);
}
function endSplitMouse(evt) {
bar.removeClass(opts.activeClass);
var newPos = A._posSplit+evt[opts.eventPos];
if ( opts.outline ) {
zombie.remove(); zombie = null;
resplit(newPos);
}
panes.css("-webkit-user-select", "text"); // let Safari select text again
$(document)
.unbind("mousemove", doSplitMouse)
.unbind("mouseup", endSplitMouse);
}
function resplit(newPos) {
// Constrain new splitbar position to fit pane size limits
newPos = Math.max(A._min, splitter._DA - B._max,
Math.min(newPos, A._max, splitter._DA - bar._DA - B._min));
// Resize/position the two panes
bar._DA = bar[0][opts.pxSplit]; // bar size may change during dock
bar.css(opts.origin, newPos).css(opts.fixed, splitter._DF);
A.css(opts.origin, 0).css(opts.split, newPos).css(opts.fixed, splitter._DF);
B.css(opts.origin, newPos+bar._DA)
.css(opts.split, splitter._DA-bar._DA-newPos).css(opts.fixed, splitter._DF);
// IE fires resize for us; all others pay cash
if ( !$.browser.msie )
panes.trigger("resize");
}
function dimSum(jq, dims) {
// Opera returns -1 for missing min/max width, turn into 0
var sum = 0;
for ( var i=1; i < arguments.length; i++ )
sum += Math.max(parseInt(jq.css(arguments[i])) || 0, 0);
return sum;
}
// Determine settings based on incoming opts, element classes, and defaults
var vh = (args.splitHorizontal? 'h' : args.splitVertical? 'v' : args.type) || 'v';
var opts = $.extend({
activeClass: 'active', // class name for active splitter
pxPerKey: 8, // splitter px moved per keypress
tabIndex: 0, // tab order indicator
accessKey: '' // accessKey for splitbar
},{
v: { // Vertical splitters:
keyLeft: 39, keyRight: 37, cursor: "e-resize",
splitbarClass: "vsplitbar", outlineClass: "voutline",
type: 'v', eventPos: "pageX", origin: "left",
split: "width", pxSplit: "offsetWidth", side1: "Left", side2: "Right",
fixed: "height", pxFixed: "offsetHeight", side3: "Top", side4: "Bottom"
},
h: { // Horizontal splitters:
keyTop: 40, keyBottom: 38, cursor: "n-resize",
splitbarClass: "hsplitbar", outlineClass: "houtline",
type: 'h', eventPos: "pageY", origin: "top",
split: "height", pxSplit: "offsetHeight", side1: "Top", side2: "Bottom",
fixed: "width", pxFixed: "offsetWidth", side3: "Left", side4: "Right"
}
}[vh], args);
// Create jQuery object closures for splitter and both panes
var splitter = $(this).css({position: "relative"});
var panes = $(">*", splitter[0]).css({
position: "absolute", // positioned inside splitter container
"z-index": "1", // splitbar is positioned above
"-moz-outline-style": "none" // don't show dotted outline
});
var A = $(panes[0]); // left or top
var B = $(panes[1]); // right or bottom
// Focuser element, provides keyboard support; title is shown by Opera accessKeys
var focuser = $('')
.attr({accessKey: opts.accessKey, tabIndex: opts.tabIndex, title: opts.splitbarClass})
.bind($.browser.opera?"click":"focus", function(){ this.focus(); bar.addClass(opts.activeClass) })
.bind("keydown", function(e){
var key = e.which || e.keyCode;
var dir = key==opts["key"+opts.side1]? 1 : key==opts["key"+opts.side2]? -1 : 0;
if ( dir )
resplit(A[0][opts.pxSplit]+dir*opts.pxPerKey, false);
})
.bind("blur", function(){ bar.removeClass(opts.activeClass) });
// Splitbar element, can be already in the doc or we create one
var bar = $(panes[2] || '<div></div>')
.insertAfter(A).css("z-index", "100").append(focuser)
.attr({"class": opts.splitbarClass, unselectable: "on"})
.css({position: "absolute", "user-select": "none", "-webkit-user-select": "none",
"-khtml-user-select": "none", "-moz-user-select": "none"})
.bind("mousedown", startSplitMouse);
// Use our cursor unless the style specifies a non-default cursor
if ( /^(auto|default|)$/.test(bar.css("cursor")) )
bar.css("cursor", opts.cursor);
// Cache several dimensions for speed, rather than re-querying constantly
bar._DA = bar[0][opts.pxSplit];
splitter._PBF = $.boxModel? dimSum(splitter, "border"+opts.side3+"Width", "border"+opts.side4+"Width") : 0;
splitter._PBA = $.boxModel? dimSum(splitter, "border"+opts.side1+"Width", "border"+opts.side2+"Width") : 0;
A._pane = opts.side1;
B._pane = opts.side2;
$.each([A,B], function(){
this._min = opts["min"+this._pane] || dimSum(this, "min-"+opts.split);
this._max = opts["max"+this._pane] || dimSum(this, "max-"+opts.split) || 9999;
this._init = opts["size"+this._pane]===true ?
parseInt($.curCSS(this[0],opts.split)) : opts["size"+this._pane];
});
// Determine initial position, get from cookie if specified
var initPos = A._init;
if ( !isNaN(B._init) ) // recalc initial B size as an offset from the top or left side
initPos = splitter[0][opts.pxSplit] - splitter._PBA - B._init - bar._DA;
if ( opts.cookie ) {
if ( !$.cookie )
alert('jQuery.splitter(): jQuery cookie plugin required');
var ckpos = parseInt($.cookie(opts.cookie));
if ( !isNaN(ckpos) )
initPos = ckpos;
$(window).bind("unload", function(){
var state = String(bar.css(opts.origin)); // current location of splitbar
$.cookie(opts.cookie, state, {expires: opts.cookieExpires || 365,
path: opts.cookiePath || document.location.pathname});
});
}
if ( isNaN(initPos) ) // King Solomon's algorithm
initPos = Math.round((splitter[0][opts.pxSplit] - splitter._PBA - bar._DA)/2);
// Resize event propagation and splitter sizing
if ( opts.anchorToWindow ) {
// Account for margin or border on the splitter container and enforce min height
splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom");
splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20);
$(window).bind("resize", function(){
var top = splitter.offset().top;
var wh = $(window).height();
splitter.css("height", Math.max(wh-top-splitter._hadjust, splitter._hmin)+"px");
if ( !$.browser.msie ) splitter.trigger("resize");
}).trigger("resize");
}
else if ( opts.resizeToWidth && !$.browser.msie )
$(window).bind("resize", function(){
splitter.trigger("resize");
});
// Resize event handler; triggered immediately to set initial position
splitter.bind("resize", function(e, size){
// Custom events bubble in jQuery 1.3; don't get into a Yo Dawg
if ( e.target != this ) return;
// Determine new width/height of splitter container
splitter._DF = splitter[0][opts.pxFixed] - splitter._PBF;
splitter._DA = splitter[0][opts.pxSplit] - splitter._PBA;
// Bail if splitter isn't visible or content isn't there yet
if ( splitter._DF <= 0 || splitter._DA <= 0 ) return;
// Re-divvy the adjustable dimension; maintain size of the preferred pane
resplit(!isNaN(size)? size : (!(opts.sizeRight||opts.sizeBottom)? A[0][opts.pxSplit] :
splitter._DA-B[0][opts.pxSplit]-bar._DA));
}).trigger("resize" , [initPos]);
});
};
})(jQuery);
The plugin you are using is based on a old jQuery version. For some reason, an infinite recursion was introduced by jQuery 1.6, probably due to event bubbling. It seems like a resize event triggered on a specific DOM element follow the event propagation path, all the way to document.
In the resize event handler, you can add a test to prevent recursion:
$(window).bind("resize", function (e) {
if (e.target === window) { splitter.trigger('resize'); }
});
That works, at least in Chrome and Firefox.
Using jQuery Migrate plugin will allow you to use jQuery 1.9 and even 2.0; but relying on browser specific behavior is generally a bad practice. You may have a look at this splitter.js fork, which already fixes your infinite recursion issue, using the same test as above.
I have an <img> in an MVC 4 Razor Display Template, and I'd like to display a tooltip containing the full sized image when the user hovers over the image.
HTML:
<img height="50" width="50" src="#Model.ImageString" />
#Model.ImageString contains an image data string, which looks like this:
"data:image/*;base64," + Convert.ToBase64String(file.Data)
If you couldn't guess, file.Data is a byte[].
How can I display a full-sized tooltip upon hovering the <img>?
Here is a very quick example: http://jsfiddle.net/bGn96/
This is along the lines of what Shan Robertson is suggesting.
var $tooltip = $('#fullsize');
$('img').on('mouseenter', function() {
var img = this,
$img = $(img),
offset = $img.offset();
$tooltip
.css({
'top': offset.top,
'left': offset.left
})
.append($img.clone())
.removeClass('hidden');
});
$tooltip.on('mouseleave', function() {
$tooltip.empty().addClass('hidden');
});
A library that provides the desired functionality can be found here: http://cssglobe.com/lab/tooltip/02/
var Controls = {
init: function () {
var imgLink = document.getElementById('thumb');
imgLink.addEventListener('mouseover', Controls.mouseOverListener, false );
imgLink.addEventListener('mouseout', Controls.mouseOutListener, false );
},
mouseOverListener: function ( event ) {
Controls.displayTooltip ( this );
},
mouseOutListener: function ( event ) {
Controls.hideTooltip ( this );
},
displayTooltip: function ( imgLink ) {
var tooltip = document.createElement ( "div" );
var fullImg = document.createElement ( "img" );
fullImg.src = imgLink.src;
tooltip.appendChild ( fullImg );
tooltip.className = "imgTooltip";
tooltip.style.top = "60px";
imgLink._tooltip = tooltip;
Controls._tooltip = tooltip;
imgLink.parentNode.appendChild ( tooltip );
imgLink.addEventListener ( "mousemove", Controls.followMouse, false);
},
hideTooltip : function ( imgLink ) {
imgLink.parentNode.removeChild ( imgLink._tooltip );
imgLink._tooltip = null;
Controls._tooltip = null;
},
mouseX: function ( event ) {
if ( !event ) event = window.event;
if ( event.pageX ) return event.pageX;
else if ( event.clientX )
return event.clientX + (document.documentElement.scrollLeft ?
document.documentElement.scrollLeft :
document.body.scrollLeft);
else return 0;
},
mouseY: function ( event ) {
if (!event) event = window.event;
if (event.pageY) return event.pageY;
else if (event.clientY)
return event.clientY + (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop);
else return 0;
},
followMouse: function ( event ) {
var tooltip = Controls._tooltip.style;
var offX = 15, offY = 15;
tooltip.left = (parseInt(Controls.mouseX(event))+offX) + 'px';
tooltip.top = (parseInt(Controls.mouseY(event))+offY) + 'px';
}
};
Controls.init();
EDIT:
Fiddle: http://jsfiddle.net/enzoferber/SyJsF/2/
Now the tooltip will follow the mouse.
mouseX() and mouseY() will return the current [x,y] mouse coords. And the follow listener is made with the 'mousemove' event that is attached after the tooltip is created.
Oh, and yeah, I changed the image. Now everyone can be happy....
Assuming you are using Javascript to do this:
Have a tooltip container ready in the dom
on hover, grab the file href and make a new image tag inside of the tooltip container.
Just make sure to not specify the image dimensions in the tag, or if you do, display the fullsize dimensions not 50x50.
When I click browse server in ckeditor the image browser popup doesnt appear.I am facing problem only in Google Chrome.I am using 18.0.1025.152 m verion of Google Chrome
I have made changes in ckeditor/plugins/popup/plugin.js
try
{
// Chrome 18 is problematic, but it's not really needed here (#8855).
var ua = navigator.userAgent.toLowerCase();
if ( ua.indexOf('chrome/18' ) == -1 )
{
popupWindow.moveTo( left, top );
popupWindow.resizeTo( width, height );
}
popupWindow.focus();
popupWindow.location.href = url;
}
catch ( e )
{
popupWindow = window.open( url, null, options, true );
}
I followed this link enter link description here
But I am unable to resolve the issue.Can anyone help
If you edit the source files you have to repackage them again. It's much simpler to update to CKEditor 3.6.3 and get all the other bug fixes.
I am using opencart 1.5.1.3 ckeditor. I edit the /admin/view/javascript/ckeditor/ckeditor.js and re-align the javascript code with http://jsbeautifier.org/
I have tried with the patch from ckeditor community and little modifications. It works!
http://dev.ckeditor.com/ticket/8855
So if anyone has face the similar issue like me in opencart you can try with below changes.
+++ b/v1.5.1.3/admin/view/javascript/ckeditor/ckeditor.js
## -9190,8 +9190,21 ## For licensing, see LICENSE.html or http://ckeditor.com/license
var s = window.open('', null, p, true);
if (!s) return false;
try {
- s.moveTo(r, q);
- s.resizeTo(n, o);
+ // s.moveTo(r, q);
+ // s.resizeTo(n, o);
+ // Chrome 18 is problematic, but it's not really needed here (#8855).
+ var ua = navigator.userAgent.toLowerCase();
+ var useResize = true;
+ if (ua.indexOf('chrome') > -1) {
+ var chromeVersion = ua.replace(/^.*chrome\/([\d]+).*$/i, '$1')
+ if(chromeVersion >= 18) {
+ useResize = false;
+ }
+ }
+ if (useResize) {
+ s.moveTo( r, q );
+ s.resizeTo( n, o );
+ }
s.focus();
s.location.href = m;
} catch (t) {
I'm using the CKEditor 3.6.2 that comes bundled with primefaces-extensions, so upgrading is not that easy. But executing the following fix against the page also worked. I pasted it in the config file, to be sure that it is fired after the CKEDITOR variable is initialized.
CKEDITOR.editor.prototype['popup'] = function( url, width, height, options ) {
width = width || '80%';
height = height || '70%';
if ( typeof width == 'string' && width.length > 1 && width.substr( width.length - 1, 1 ) == '%' )
width = parseInt( window.screen.width * parseInt( width, 10 ) / 100, 10 );
if ( typeof height == 'string' && height.length > 1 && height.substr( height.length - 1, 1 ) == '%' )
height = parseInt( window.screen.height * parseInt( height, 10 ) / 100, 10 );
if ( width < 640 )
width = 640;
if ( height < 420 )
height = 420;
var top = parseInt( ( window.screen.height - height ) / 2, 10 ),
left = parseInt( ( window.screen.width - width ) / 2, 10 );
options = ( options || 'location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes' ) +
',width=' + width +
',height=' + height +
',top=' + top +
',left=' + left;
var popupWindow = window.open( '', null, options, true );
// Blocked by a popup blocker.
if ( !popupWindow )
return false;
try
{
// Chrome 18 is problematic, but it's not really needed here (#8855).
var ua = navigator.userAgent.toLowerCase();
if ( ua.indexOf( ' chrome/18' ) == -1 )
{
popupWindow.moveTo( left, top );
popupWindow.resizeTo( width, height );
}
popupWindow.focus();
popupWindow.location.href = url;
}
catch ( e )
{
popupWindow = window.open( url, null, options, true );
}
return true;
}
$(document).ready(
function() {
setContentHeight();
makeInstructionsTogglable();
window.onbeforeunload = function() {
if (editor.isDirty()) {
return "Are you sure you want to navigate away? You have unsaved changes."
}
};
}
);
$(window).resize(function() {
setContentHeight();
});