Good morning everyone,
I seem to be having a slight problem. I want a div to overlay another div(i.e. be on top) but zIndex is not working. I suspect the cause is the display: inline-block but I need to keep it so that the webpage is displayed properly. How do I make the div overlay the other one?
Here is the jsfiddle explaining the problem:
http://jsfiddle.net/Yf7zD/
Or the code right here:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<script type="text/javascript" src="javascript/cookies.js"></script>
<style>
#gameTable {
font-size: 0;
width: 840px;
height: 240px;
margin-top: 20px;
margin-left: 78px;
position: relative;
}
.iamdroppable {
display: inline-block;
margin: 0;
padding: 0;
border: 3px solid #FFF;
}
</style>
</head>
<body style="background-color: black;">
<div id="container" style="position:relative; border: solid 3px red;">
<div id="gameTable"><p>GameTable</p>
</div>
</div>
</body>
<script>
$(document).ready(function(e) {
var myId;
for(vertical = 0; vertical < 3; vertical++) {
for(horizontal = 1; horizontal <= 12; horizontal++) { //Outer Numbers
if(vertical == 0)
myId = horizontal * 3;
else if(vertical == 1)
myId = horizontal * 3 - 1;
else
myId = horizontal * 3 - 2;
$('<div>', {//Normal numbers
class: 'iamdroppable',
id: '' + myId,
width: '62px',
height: '78px',
}).appendTo('#gameTable');
}
}
$('<div>', {//Quads
class: 'iamdroppable',
id: '1000',
top: '-100px',
width: '100px',
height: '200px',
zIndex: '1000',
position: 'absolute',
}).appendTo('#container');
});
</script>
</html>
Thanks!
var div = $('<div>', {//Quads
class: 'iamdroppable',
id: '1000',
top: '-100px',
width: '100px',
height: '200px',
zIndex: '1000',
position: 'absolute',
}).appendTo('#container');
});
$('body').append(div);
You were adding the CSS styles as attributes, they should all be within the style property:
$(document).ready(function (e) {
var myId;
for (vertical = 0; vertical < 3; vertical++) {
for (horizontal = 1; horizontal <= 12; horizontal++) { //Outer Numbers
if (vertical === 0) myId = horizontal * 3;
else if (vertical == 1) myId = horizontal * 3 - 1;
else myId = horizontal * 3 - 2;
$('<div>', { //Normal numbers
class: 'iamdroppable',
id: '' + myId,
style: 'width:62px;height:78px;'
}).appendTo('#gameTable');
}
}
$('<div>', { //Quads
class: 'iamdroppable',
id: '1000',
style: 'top:-100px;width:100px;height:200px;z-index:1000;position:absolute;'
}).appendTo('#container');
});
On another note, where you're doing this comparison: if (vertical == 0) you should use three === like this: if (vertical === 0)
Related
I am building an interactive graph app where the user would upload a data file. The app would then build the graph from the input file.
I am having problems with making the input work with the cytoscape . More specifically, the file dialog window does not pop up when I include the div. That is, the input button is not responsive unless I comment out the cytoscape .
Please see the code below. I guess, this is not cytoscape specific. However, I could not get to the bottom of this, so I am posting the complete instance of the problem.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<script src="cytoscape.js"></script>
</head>
<style>
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<body>
<form name="uploadForm">
<div>
<input id="uploadInput" type="file" name="myFiles" multiple>
selected files: <span id="fileNum">0</span>;
total size: <span id="fileSize">0</span>
</div>
<div><input type="submit" value="Send file"></div>
</form>
<div>
<h1>This!</h1>
</div>
<div id="cy"></div>
<script>
function updateSize() {
let nBytes = 0,
oFiles = this.files,
nFiles = oFiles.length;
for (let nFileId = 0; nFileId < nFiles; nFileId++) {
nBytes += oFiles[nFileId].size;
}
let sOutput = nBytes + " bytes";
// optional code for multiples approximation
const aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
for (nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
sOutput = nApprox.toFixed(3) + " " + aMultiples[nMultiple] + " (" + nBytes + " bytes)";
}
// end of optional code
document.getElementById("fileNum").innerHTML = nFiles;
document.getElementById("fileSize").innerHTML = sOutput;
console.log("AAAA!")
}
document.getElementById("uploadInput").addEventListener("change", updateSize, false);
</script>
<script>
// https://blog.js.cytoscape.org/2016/05/24/getting-started/
var cy = cytoscape({
container: document.getElementById('cy'),
// ~~~~~~~~~~~~~~~~~~~
elements: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
}],
// ~~~~~~~~~~~~~~~~~~~
style: [
{
selector: 'node',
style: {
shape: 'hexagon',
'background-color': 'red',
label: 'data(id)'
}
}]
});
cy.layout({
name: 'circle'
}).run();
</script>
</body>
</html>
It's related with the z-index of the divs. In your case, because you don't assign z-indexes to the divs and add cy div at the end, it is rendered on top, so you cannot interact with the buttons.
You can assign a z-index to cy div such as -1 to send it to the background:
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
z-index: -1;
}
But in this case you won't be able to interact with the top part of the cy canvas. A better solution is to change the top attribute to some value such as 250px so that cy canvas is started to be rendered below the buttons and texts:
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 250px;
left: 0px;
}
I want to display a loading spinner while a huge graph is loaded and layouted in Cytoscape JS. But the loading spinner disappears even though the layout is not finished. I am wondering if there is a way to listen to a layout finish and show the spinner until the final layout is reached ?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/2.7.14/cytoscape.js"></script>
<title></title>
<style media="screen">
#cy {
position: absolute;
width:100%;
height:100%;
/*height:500px;*/
z-index: 0;
margin-left: auto;
margin-right: auto;
}
#loading {
position: absolute;
background: #ffffff;
display: block;
left: 0;
top: 50%;
width: 100%;
text-align: center;
margin-top: -0.5em;
font-size: 2em;
color: #000;
}
#loading.loaded {
display: none;
}
</style>
</head>
<body>
<div id="cy">
</div>
<div id="loading">
<span class="fa fa-refresh fa-spin"></span>
</div>
<script type="text/javascript">
$(document).ready(function(){
// Create random JSON object
var maximum = 500;
var minimum = 1;
function getRandNumber(){
var min = 1;
var max = 1000;
var randNumber = Math.floor(Math.random() * (max - min + 1)) + min;
return randNumber;
}
nodes = [];
geneIds = [];
edges = [];
for(var i = 0; i < 2000; i++){
var source = getRandNumber();
var target = getRandNumber();
edges.push({"data": {"id":i.toString(),"source":source.toString(),"target":target.toString()}});
if ($.inArray(source, geneIds) === -1) {
nodes.push({"data": {"id":source.toString(),"name":source.toString()}});
geneIds.push(source);
}
if ($.inArray(target, geneIds) === -1) {
nodes.push({"data":{"id":target.toString(),"name":target.toString()}});
geneIds.push(target);
}
}
var networkData = {"nodes":nodes,"edges":edges};
// console.log(networkData);
///////////////// Create the network
var coseLayoutParams = {
name: 'cose',
// padding: 10,
randomize: false,
};
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
// elements: networkData,
minZoom: 0.1,
// maxZoom: 10,
wheelSensitivity: 0.2,
style: [
{
selector: 'node',
style: {
'content': 'data(name)',
'text-valign': 'center',
'text-halign': 'center',
'font-size': 8
}
}],
layout: coseLayoutParams
});
cy.add(networkData);
var layout = cy.makeLayout(coseLayoutParams);
layout.run();
$("#loading").addClass("loaded");
});
</script>
</body>
</html>
You can add a listener to your layout object that waits for 'layoutstop' event to be fired:
layout.on('layoutstop', function() {
//... unload spinner here
});
see here: http://js.cytoscape.org/#layout.on
and here: https://github.com/cytoscape/cytoscape.js/blob/master/documentation/md/events.md
or, you can specify a callback function in layout options, such as
var coseLayoutParams = {
name: 'cose',
// padding: 10,
randomize: false,
// Called on `layoutstop`
stop: function() {
//... unload spinner here
},
};
see here: http://js.cytoscape.org/#layouts/cose
Sorry for the ambiguous title, not sure how to phrase it.
I have an html page that has 2 iframes side by side with 100% height. I'm trying to set the maximum width of the iframe on right.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
</head>
<body>
<div id="content-wrapper">
<div id="content">
<div id="holder_Iframe1">
<iframe id="iframe1" src="https://en.wikipedia.org/wiki/Mercedes-Benz"></iframe>
<div id="drag"></div>
</div>
<div id="holder_Iframe2">
<iframe id="iframe2" src="http://www.dictionary.com/browse/mercedes?s=t"></iframe>
</div>
</div>
</div>
</body>
</html>
Both iframes are wrapped by divs. Hover the mouse between the iframes to be see the re-size cursor.
I'm setting a maximum width of the iframe2 (the one on the right) of 560px, but when resizing, sometimes it passes that maximum width so I can't resize it back. I'm trying to fix that.
function Resize(e) {
var rightPanePx = document.documentElement.clientWidth - parseInt(holder_Iframe1.style.width, 10);
console.log(rightPanePx);
if ((rightPanePx >= 25) && (rightPanePx <= 560)) {
holder_Iframe1.style.width = (e.clientX - holder_Iframe1.offsetLeft) + "px";
iframe1.style.width = Math.max((holder_Iframe1.style.width.replace("px", "") - 4), 0) + "px";
holder_Iframe2.style.width = (document.documentElement.clientWidth - holder_Iframe1.style.width.replace("px", "")) + "px";
iframe2.style.width = holder_Iframe2.style.width;
}
}
I have attached the code that demonstrates my problem.
var iframe1 = document.getElementById("iframe1");
var iframe2 = document.getElementById("iframe2");
var holder_Iframe1 = document.getElementById("holder_Iframe1");
var holder_Iframe2 = document.getElementById("holder_Iframe2");
var dragEl = document.getElementById("drag");
holder_Iframe1.style.width = (Math.max(document.documentElement.clientWidth, window.innerWidth || 0) * 0.8) + "px";
iframe1.style.cssText = 'width:' + ((Math.max(document.documentElement.clientWidth, window.innerWidth || 0) * 0.8) - 5) + 'px;height:100%;';
dragEl.addEventListener('mousedown', function(e) {
//create overlay so we will always get event notification even though the pointer is hovering iframes
var overlay = document.createElement('div');
overlay.id = "overlay";
document.body.insertBefore(overlay, document.body.firstChild);
window.addEventListener('mousemove', Resize, false);
window.addEventListener('mouseup', stopResize, false);
}, false);
function Resize(e) {
var rightPanePx = document.documentElement.clientWidth - parseInt(holder_Iframe1.style.width, 10);
console.log(rightPanePx);
if ((rightPanePx >= 25) && (rightPanePx <= 560)) {
holder_Iframe1.style.width = (e.clientX - holder_Iframe1.offsetLeft) + "px";
iframe1.style.width = Math.max((holder_Iframe1.style.width.replace("px", "") - 4), 0) + "px";
holder_Iframe2.style.width = (document.documentElement.clientWidth - holder_Iframe1.style.width.replace("px", "")) + "px";
iframe2.style.width = holder_Iframe2.style.width;
}
}
function stopResize(e) {
//remove event listeners from improved performance
window.removeEventListener('mousemove', Resize, false);
window.removeEventListener('mouseup', stopResize, false);
//remove fake overlay
document.getElementById("overlay").remove();
}
html {
overflow-y: hidden;
}
body {
width: 100%;
}
iframe,
#holder_Iframe1,
#holder_Iframe2 {
margin: 0;
padding: 0;
border: 0;
}
iframe {
width: 100%;
height: 100%;
min-width: 0;
}
#content-wrapper {
display: table;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
position: absolute;
}
#content {
display: table-row;
}
#holder_Iframe1,
#holder_Iframe2 {
display: table-cell;
min-width: 0 !important;
}
#holder_Iframe1 {
width: 80%;
}
#drag {
height: 100%;
width: 3px;
cursor: col-resize;
background-color: rgb(255, 0, 0);
float: right;
}
#drag:hover {
background-color: rgb(0, 255, 0);
}
#drag:active {
background-color: rgb(0, 0, 255);
}
#overlay {
background-color: rgba(0, 0, 0, 0);
width: 100%;
height: 100%;
z-index: 10;
top: 0;
left: 0;
position: fixed;
cursor: col-resize;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
</head>
<body>
<div id="content-wrapper">
<div id="content">
<div id="holder_Iframe1">
<iframe id="iframe1" src="https://en.wikipedia.org/wiki/Mercedes-Benz"></iframe>
<div id="drag"></div>
</div>
<div id="holder_Iframe2">
<iframe id="iframe2" src="http://www.dictionary.com/browse/mercedes?s=t"></iframe>
</div>
</div>
</div>
</body>
</html>
You need to use cursor's position to detect where the direction is.
By adding e.pageX to your function to determine whether resize it or not.
In your sample this may be if (window_size - e.pageX < 560) go resize it, otherwise don't resize.
I have this HTML code:
<div class="inner">
<div class="nhood">
<div class="image"></div>
</div>
</div>
And this CSS:
.image {
width: 4000px;
height: 4000px;
background: beige;
margin: 150px;
position: absolute;
}
.nhood {
overflow: hidden;
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
background: black;
}
The .image div is filled with 400 divs, all floating left, creating a huge 'chess'-pattern, the code is the following:
.image > div {
border: 1px dotted;
width: 5%;
height: 5%;
float: left;
box-sizing:border-box;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
position: relative;
user-select: none;
}
You are able to click on any cell to show its info, and the whole .image div is draggable. Now if you have selected a cell and you ZOOM (which basically only shrinks/extends the 4000x4000 div to 2000x2000 or the other way round) it zooms in ANYWHERE but I want to keep focus on the cell that was selected earlier.
I have made an image of this:
http://smimoo.lima-city.de/zoom.png
I hope this was any clear...
EDIT:
JS
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 0
});
});
}
function zoomOut() {
$(draggable).animate({
height: '2000',
width: '2000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 1
});
});
EDIT2:
This is my js to center the function (written before Mario helped me out):
function centerField() {
var myObject = $(draggable).find('.selected');
var docWidth = ($(viewport).width() / 2) - (myObject.outerWidth()/2);
var docHeight = ($(viewport).height() / 2) - (myObject.outerWidth()/4);
var myOff = myObject.offset();
var distanceTop = myOff.top - docHeight;
var distanceLeft = myOff.left - docWidth;
var position = $(draggable).position();
var left = position.left;
var top = position.top;
var right = left - $(viewport).width() + draggable.outerWidth(true);
var bottom = top - $(viewport).height() + draggable.outerHeight(true);
if(left - distanceLeft > 0) {
distanceLeft = left;
}
if(right - distanceLeft < 0) {
distanceLeft = right;
}
if(top - distanceTop > 0) {
distanceTop = top;
}
if(bottom - distanceTop < 0) {
distanceTop = bottom;
}
$(draggable).animate({
left: '-=' + distanceLeft,
top: '-=' + distanceTop
}, { duration: 200, queue: false });
}
Assume that the selected div has the class .selected, this function will center the div:
function centerSelected() {
var selectedElement = $('.image .selected');
var p = selectedElement.position();
var w = $('.nhood').width();
var h = $('.nhood').height();
var offsetX = (w/2)-p.left - (selectedElement.width() / 2);
var offsetY = (h/2)-p.top - (selectedElement.height() / 2);
if(offsetX > 0) offsetX = 0;
if(offsetY > 0) offsetY = 0;
$('.image').css('left', offsetX + 'px');
$('.image').css('top', offsetY + 'px');
}
Just call centerSelected after every zoom operation.
Here is a jsfiddle with slightly modified css to get the presentation work:
http://jsfiddle.net/q1r95w3g/3/
Edit
If you want the div to get centered during jQuery animation, you can call centerSelected in the step callback of the animate method, e.g.:
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
},{
duration: 600,
complete: function() {
$divs.animate({
borderWidth: 0
});
},
step: function(now, fx) {
centerSelected();
}
});
}
Ok, I builded a slider in javascript and Jquery (with help of you guys) But now I want to have multiple sliders on 1 page. While using just one javascript. BUT...the slider can be different in width (or number of items): also the name of the slider is different because of the css width.
So How do I use 1 javascript to controle different sliders
Here is my code:
HTML
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<style type="text/css">
#temp{
height: 300px;
}
#container{
width: 500px;
height: 150px;
background:#CDFAA8;
overflow:hidden;
position:absolute;
left: 13px;
}
#slider{
width: 800px;
height: 150px;
background:#063;
position:absolute;
left: 0px;
}
#block1{
width: 100px;
height: 150px;
background:#067;
float: left;
}
#block2{
width: 100px;
height: 150px;
background:#079;
float: left;
}
#move_right{
height: 150px;
width: 20px;
background: #3f3f3f;
position: absolute;
right:0px;
z-index: 200;
opacity: 0.2;
}
#move_left{
height: 150px;
width: 20px;
background: #3f3f3f;
position: absolute;
left:0px;
z-index: 200;
opacity: 0.2;
}
</style>
</head>
<body>
<div id="temp">
<div id="container">
<div id="move_left"><button id="right">«</button></div><div id="move_right"><br><br><button id="left">»</button></div>
<div id="slider">
<div id="block1">1</div>
<div id="block2">2</div>
<div id="block1">3</div>
<div id="block2">4</div>
<div id="block1">5</div>
<div id="block2">6</div>
<div id="block1">7</div>
<div id="block2">8</div>
</div>
</div>
</div>
<div id="slider">
<div id="block1">1</div>
<div id="block2">2</div>
<div id="block1">3</div>
<div id="block2">4</div>
<div id="block1">5</div>
<div id="block2">6</div>
<div id="block1">7</div>
<div id="block2">8</div>
</div>
</div>
</div>
JavaScript
(function($) {
var slider = $('#slider'),
step = 500,
left = parseInt(slider.css('left'), 10),
max = $('#container').width() - slider.width(),
min = 0;
$("#left").click(function() {
if (left > max) {
var newLeft = left - step;
left = (newLeft>max) ? newLeft : max;
$("#slider").animate({
"left": left + 'px'
}, "slow");
}
});
$("#right").click(function() {
if (left < 0) {
var newLeft = left + step;
left = (newLeft<min) ? newLeft : min;
slider.animate({
"left": left + 'px'
}, "slow");
}
});
})(jQuery);
This should be fine:
(function($) {
$('#temp #container').each(function(){
var slider = $(this).find('#slider'),
parent = $(this),
step = 500,
left = parseInt(slider.css('left'), 10),
max = parent.width() - slider.width(),
min = 0;
parent.find("#left").click(function() {
if (left > max) {
var newLeft = left - step;
left = (newLeft>max) ? newLeft : max;
slider.animate({
"left": left + 'px'
}, "slow");
}
});
parent.find("#right").click(function() {
if (left < 0) {
var newLeft = left + step;
left = (newLeft<min) ? newLeft : min;
slider.animate({
"left": left + 'px'
}, "slow");
}
});
});
})(jQuery);
FIDDLE
In theory you could do some code which can take a selector to a wrapper element (which has the required slider elements inside) as some parameter. And then you can from this element create selectors which are more dynamic. I'm not sure where you get "step = 500" from, but that's maybe something you could grab dynamically from some relevant element.