javascript not working when page is loaded qtip2 - javascript

I wrote a nice heatmap in javascript, and that worked pretty nice so far. The heatmap is basically a table with a coloring variation, based on the threshold of the value displayed in the table. I used JavaScript to create the table, and to set up the colors. However, I wanted to show a nice pop up window, so when the user hover over the table's cell, some additional information is displayed. I found this library qTip2
$(document).ready(function(){
$('#mytable td').qtip({
overwrite : false, // make sure it can't be overwritten
content : {
text : function(api){
return "Time spent: " + $(this).html();
}
},
position : {
my : 'top left',
target : 'mouse',
viewport : $(window), //keep it on-screen at all time if possible
adjust : {
x : 10, y : 10
}
},
hide : {
fixed : true // Helps to prevent the tooltip from hiding occassionaly when tracking!
},
style : 'ui-tooltip-tipsy ui-tooltip-shadow'
});
});
This function creates the heatmap:
function makeTable(data)
{
var row = new Array();
var cell = new Array();
var row_num = 26;
var cell_num = 44;
var tab = document.createElement('table');
tab.setAttribute('id', 'mytable');
tab.border = '1px';
var tbo = document.createElement('tbody');
for(var i = 0; i < row_num; i++){
row[i] = document.createElement('tr');
var upper = (i+1)*44;
var lower = i*44;
for(var j = lower; j < upper; j++){
cell[j] = document.createElement('td');
//cell[j].setAttribute('class', 'selector');
if(data[j] != undefined){
var count = document.createTextNode(data[j].diff);
cell[j].appendChild(count);
var index = parseInt(data[j].diff);
/* specify which color better suits the heatmap */
if(index >= 0 && index <= 100){
cell[j].style.backgroundColor = '#00BFFF';
}
else if(index > 100 && index <= 1000){
cell[j].style.backgroundColor = "#6495ED";
}
else if(index > 1000 && index <= 4000){
cell[j].style.backgroundColor = "#4682B4";
}
else if(index > 4000 && index <= 6000){
cell[j].style.backgroundColor = "#0000FF";
}
else{
cell[j].style.backgroundColor = "#00008B";
}
row[i].appendChild(cell[j]);
}
}
tbo.appendChild(row[i]);
}
tab.appendChild(tbo);
document.getElementById('mytable').appendChild(tab);
}
Inside of my <body> tag I have:
<div id="body">
<div id="mytable"></div>
</div>
However, when I load the page, I expect to see the pop up box when I hover the mouse over the table's cell, however something happens. Also, when I execute that $(document).ready part from firebug's terminal, then the program starts to execute as suppose to. I also made sure the library is being loaded into my page before I used it. I also don't see any errors in the firebug's terminal.
<script src="http://localhost/heatmap/javascript/jquery.qtip.js">
Could someone please give me a clue why is this happening?
The main function of my javascript is
function OnLoad() {
$.post('index.php/heatmap/getDatalines',
function(answer){
var data = eval('(' + answer + ')');
var list = [];
makeTable(data);
});
}
Thanks
whis is called on load: google.setOnLoadCallback(OnLoad);

You need to create the qtip after you have loaded the table like this:
function OnLoad() {
$.post('index.php/heatmap/getDatalines',
function(answer){
var data = eval('(' + answer + ')');
var list = [];
makeTable(data);
$('#mytable td').qtip({
overwrite : false, // make sure it can't be overwritten
content : {
text : function(api){
return "Time spent: " + $(this).html();
}
},
position : {
my : 'top left',
target : 'mouse',
viewport : $(window), // keep it on-screen at all time if possible
adjust : {
x : 10, y : 10
}
},
hide : {
fixed : true // Helps to prevent the tooltip from hiding occassionaly when tracking!
},
style : 'ui-tooltip-tipsy ui-tooltip-shadow'
});
});
}

Related

Unable to target ID via Javascript

My mission is to tweak this website https://www.mintpal.com/market/XC/BTC# so it will show a different color for the value if it sees "buy orders" over 2.00000000 BTC.
As an example, you check the image http://i.imgur.com/hZBGiTu.png ( the example worked because i targeted them each one separately with "#buyTotal-0-00126011" and so on.
I only want that td#buyTotal pane to be changed.
I tried to target it with the following:
1 - var cell = $('td') - it works, but it changes the values globally
2 - var cell = $('#buyTotal' + price + value.total) - not working
3 - var cell = $('td#buyTotal') - not working.
The code should look similar to this in the end...
var cell = $('td#buyTotal')
cell.each(function() {
var cell_value = $(this).html();
if ((cell_value >= 0) && (cell_value >=2.00000000)) {
$(this).css({'background' : '#FF0000'});
} else if ((cell_value >= 3) && (cell_value >=5.00000000)) {
$(this).css({'background' : '#FF0000'});
} else if (cell_value >= 8.00000000) {
$(this).css({'background' : '#FF0000'});
}
});
You can also access this as a shortcut ' mintpal.com/assets/js/market.js '
If i omitted something, please let me know. Thanks....
Edit: I'm only playing with the code inspector/console on the website. What i want is extremely simple. It's just that i cannot target the id. I updated the photo also.
This will require regex.
var cells = document.querySelectorAll('*[id^="buyTotal"]');
for(var i = 0; i < cells.length; i++) {
if(cells[i].innerHTML > 2) { cells[i].style.backgroundColor = 'red'; }
}

Text pagination inside a DIV with image

I want to paginate a text in some div so it will fit the allowed area
Logic is pretty simple:
1. split text into words
2. add word by word into and calculate element height
3. if we exceed the height - create next page
It works quite good
here is JS function i've used:
function paginate() {
var newPage = $('<pre class="text-page" />');
contentBox.empty().append(newPage);
var betterPageText='';
var pageNum = 0;
var isNewPage = false;
var lineHeight = parseInt(contentBox.css('line-height'), 10);
var wantedHeight = contentBox.height() - lineHeight;
for (var i = 0; i < words.length; i++) {
if (isNewPage) {
isNewPage = false;
} else {
betterPageText = betterPageText + ' ' + words[i];
}
newPage.text(betterPageText + ' ...');
if (newPage.height() >= wantedHeight) {
pageNum++;
if (pageNum > 0) {
betterPageText = betterPageText + ' ...';
}
newPage.text(betterPageText);
newPage.clone().insertBefore(newPage)
betterPageText = '...';
isNewPage = true;
} else {
newPage.text(betterPageText);
}
}
contentBox.craftyslide({ height: wantedHeight });
}
But when i add an image it break everything. In this case text overflows 'green' area.
Working fiddle: http://jsfiddle.net/74W4N/7/
Is there a better way to paginate the text and calculate element height?
Except the fact that there are many more variables to calculate,not just only the word width & height, but also new lines,margins paddings and how each browser outputs everything.
Then by adding an image (almost impossible if the image is higher or larger as the max width or height) if it's smaller it also has margins/paddings. and it could start at the end of a line and so break up everything again.basically only on the first page you could add an image simply by calculating it's width+margin and height+margin/lineheight. but that needs alot math to get the wanted result.
Said that i tried some time ago to write a similar script but stopped cause of to many problems and different browser results.
Now reading your question i came across something that i read some time ago:
-webkit-column-count
so i made a different approach of your function that leaves out all this calculations.
don't judge the code as i wrote it just now.(i tested on chrome, other browsers need different prefixes.)
var div=document.getElementsByTagName('div')[0].firstChild,
maxWidth=300,
maxHeigth=200,
div.style.width=maxWidth+'px';
currentHeight=div.offsetHeight;
columns=Math.ceil(currentHeight/maxHeigth);
div.style['-webkit-column-count']=columns;
div.style.width=(maxWidth*columns)+'px';
div.style['-webkit-transition']='all 700ms ease';
div.style['-webkit-column-gap']='0px';
//if you change the column-gap you need to
//add padding before calculating the normal div.
//also the line height should be an integer that
// is divisible of the max height
here is an Example
http://jsfiddle.net/HNF3d/10/
adding an image smaller than the max height & width in the first page would not mess up everything.
and it looks like it's supported by all modern browsers now.(with the correct prefixes)
In my experience, trying to calculate and reposition text in HTML is almost an exercise in futility. There are too many variations among browsers, operating systems, and font issues.
My suggestion would be to take advantage of the overflow CSS property. This, combined with using em sizing for heights, should allow you to define a div block that only shows a defined number of lines (regardless of the size and type of the font). Combine this with a bit of javascript to scroll the containing div element, and you have pagination.
I've hacked together a quick proof of concept in JSFiddle, which you can see here: http://jsfiddle.net/8CMzY/1/
It's missing a previous button and a way of showing the number of pages, but these should be very simple additions.
EDIT: I originally linked to the wrong version for the JSFiddle concept
Solved by using jQuery.clone() method and performing all calculations on hidden copy of original HTML element
function paginate() {
var section = $('.section');
var cloneSection = section.clone().insertAfter(section).css({ position: 'absolute', left: -9999, width: section.width(), zIndex: -999 });
cloneSection.css({ width: section.width() });
var descBox = cloneSection.find('.holder-description').css({ height: 'auto' });
var newPage = $('<pre class="text-page" />');
contentBox.empty();
descBox.empty();
var betterPageText = '';
var pageNum = 0;
var isNewPage = false;
var lineHeight = parseInt(contentBox.css('line-height'), 10);
var wantedHeight = contentBox.height() - lineHeight;
var oldText = '';
for (var i = 0; i < words.length; i++) {
if (isNewPage) {
isNewPage = false;
descBox.empty();
}
betterPageText = betterPageText + ' ' + words[i];
oldText = betterPageText;
descBox.text(betterPageText + ' ...');
if (descBox.height() >= wantedHeight) {
if (i != words.length - 1) {
pageNum++;
if (pageNum > 0) {
betterPageText = betterPageText + ' ...';
}
oldText += ' ... ';
}
newPage.text(oldText);
newPage.clone().appendTo(contentBox);
betterPageText = '... ';
isNewPage = true;
} else {
descBox.text(betterPageText);
if (i == words.length - 1) {
newPage.text(betterPageText).appendTo(contentBox);
}
}
}
if (pageNum > 0) {
contentBox.craftyslide({ height: wantedHeight });
}
cloneSection.remove();
}
live demo: http://jsfiddle.net/74W4N/19/
I actually came to an easier solution based on what #cocco has done, which also works in IE9.
For me it was important to keep the backward compatibility and the animation and so on was irrelevant so I stripped them down. You can see it here: http://jsfiddle.net/HNF3d/63/
heart of it is the fact that I dont limit height and present horizontal pagination as vertical.
var parentDiv = div = document.getElementsByTagName('div')[0];
var div = parentDiv.firstChild,
maxWidth = 300,
maxHeigth = 200,
t = function (e) {
div.style.webkitTransform = 'translate(0,-' + ((e.target.textContent * 1 - 1) * maxHeigth) + 'px)';
div.style["-ms-transform"] = 'translate(0,-' + ((e.target.textContent * 1 - 1) * maxHeigth) + 'px)';
};
div.style.width = maxWidth + 'px';
currentHeight = div.offsetHeight;
columns = Math.ceil(currentHeight / maxHeigth);
links = [];
while (columns--) {
links[columns] = '<span>' + (columns + 1) + '</span>';
}
var l = document.createElement('div');
l.innerHTML = links.join('');
l.onclick = t;
document.body.appendChild(l)

Show/Hide & Mouseover Javascript

I been researching on Show/Hide javascript and pushed it further with a mouseover effect to achieve what I want. I've set up a Fiddle for better accessibility. However, I now want to push it by having up to 4 different text areas ("Click here for more information"), and each text area would have more hover text as I tried to show in the HTML code itself. The javascript that I used and edited now has "ID"s corresponding to "0" and "1" which wouldnt work for my current HTML code as it has funky names like "uu3308-10" (made with Adobe Muse). Now, I'm wonder what variables would I have to change within the Javascript to make it function properly and is there a way to compile this code so it works with at least 11 other "Click here for more information" points?
Note: The current javascript makes showMoreText2 appear under both showMoreText areas (would like to make only one hover text appear at a time).
CLICK HERE FOR THE FIDDLE -- > http://jsfiddle.net/TPLOR/vy6nS/
Thanks, I hope this was helpful enough. =)
kinda hackish: (see http://jsfiddle.net/vy6nS/30/ )
window.onload = function() {
var elems1 = document.getElementsByClassName("expander");
for (i = 0; i < elems1.length; i++) {
elems2 = elems1[i].childNodes;
for (x = 0; x < elems2.length; x++) {
if (elems2[x].className == "toggle") elems2[x].onclick = function() {
showMore(0, this);
};
else if (elems2[x].className == "showMoreText") {
elems2[x].onmouseover = function() {
showChilds("block", this);
};
elems2[x].onmouseout = function() {
showChilds("none", this);
};
}
}
}
};
function get_nextsibling(n) {
x = n.nextSibling;
while (x.nodeType != 1) {
x = x.nextSibling;
}
return x;
}
function showChilds(disp, elem) {
get_nextsibling(elem).style.display = disp;
}
function showMore(disp, elem) {
var children = elem.parentNode.childNodes;
for (i = 0; i < children.length; i++) {
if (disp == 0 && children[i].className == "showMoreText") {
children[i].style.display = children[i].style.display == "none" ? "block" : "none";
}
}
}​

elementFromPoint() full document alternative

I am trying to recover a value from a cookie, which is somewhere on the Y-axis where the user clicked. I then want to find the parent <h2> from that click (if it helps, all the <h2>s are the first child of a <div class="_bdnable_">). Here is what I have so far:
var bookmarkLocation;
function getBookmarkPos() {
if ($.cookie("bookmark-position") !== null) {
$(".bdnable").each(function(i) {
var scrollTopTop = $(this).offset.top;
var scrollTopBottom = $(this).offset.top + $(this).height();
// var screenWidth = parseInt(screen.width/2);
// alert(screenWidth);
// var bookmarkPosition = parseInt($.cookie("bookmark-position"));
// alert(bookmarkPosition);
// var query = document.elementFromPoint(screenWidth, 50).nodeName;
// alert(query);
if ($.cookie("bookmark-position")>=scrollTopTop && $.cookie("bookmark-position")<=scrollTopBottom) {
bookmarkLocation = $(this).closest("div").children(":nth-child(1)").text();
}
});
if (bookmarkLocation == null) {
bookmarkLocation = "Unknown";
}
} else {
bookmarkLocation = "No bookmark set";
}
$("#bookmarklocationspan").html(bookmarkLocation);
}
In the commented out section is where I tried to use getElementFromPoint and then realized that it only checks the visible area. Not good, because the scrollable Y-axis on the page is 1000s of pixels tall.
Any ideas are greatly appreciated!!!
If you already have the y-coordinate of the click from the cookie, why not simply compare all H2's y-position and pick the one which is the next "higher" one? Your approach looks like it's compares whether the user has clicked directly on the H2 instead of the article/button below it?
Just an idea - don't rate it's style, think its prettey messy:
var $myH2 = $('h2');
var clickY = <COOKIE_VALUE>;
var currentY = 0;
var foundH2ID = '';
for (var i = 0; i < $myH2.length; i++) {
var h2Y = $($myH2[i]).position().top;
if (h2Y <= clickY && h2Y > currentY) {
currentY = h2Y;
foundH2ID = $myH2[i].id;
}
}
Or maybe I got you wrong?

Trouble with onclick attribute for img when used in combination with setInterval

I am trying to make images that move around the screen that do something when they are clicked. I am using setInterval to call a function to move the images. Each image has the onclick attribute set. The problem is that the clicks are not registering.
If I take out the setInterval and just keep the images still, then the clicks do register.
My code is here (html, css, JavaScript): https://jsfiddle.net/contini/nLc404x7/4/
The JavaScript is copied here:
var smiley_screen_params = {
smiley_size : 100, // needs to agree with width/height from css file
num_smilies: 20
}
var smiley = {
top_position : 0,
left_position : 0,
jump_speed : 2,
h_direction : 1,
v_direction : 1,
intvl_speed : 10, // advance smiley every x milliseconds
id : "smiley"
}
function randomise_direction(s) {
var hd = parseInt(Math.random()*2);
var vd = parseInt(Math.random()*2);
if (hd === 0)
s.h_direction = -1;
if (vd === 0)
s.v_direction = -1;
}
function plotSmiley(sp /* sp = smiley params */) {
var existing_smiley = document.getElementById(sp.id);
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.setAttribute('onclick', "my_click_count()");
smiley_to_plot.style.position = 'absolute';
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
document.getElementById("smileybox").appendChild(smiley_to_plot);
}
function random_direction_change() {
var r = parseInt(Math.random()*200);
if (r===0)
return true;
else
return false;
}
function moveFace(sp_array /* sp_array = smiley params array */) {
var i;
var sp;
for (i=0; i < sp_array.length; ++i) {
// move ith element
sp = sp_array[i];
if (
(sp.h_direction > 0 && sp.left_position >= smiley_screen_params.width - smiley_screen_params.smiley_size) ||
(sp.h_direction < 0 && sp.left_position <= 0) ||
(random_direction_change())
) {
sp.h_direction = -sp.h_direction; // hit left/right, bounce off (or random direction change)
}
if (
(sp.v_direction > 0 && sp.top_position >= smiley_screen_params.height - smiley_screen_params.smiley_size) ||
(sp.v_direction < 0 && sp.top_position <= 0) ||
(random_direction_change())
) {
sp.v_direction = -sp.v_direction; // hit top/bottom, bounce off (or random direction change)
}
sp.top_position += sp.v_direction * sp.jump_speed;
sp.left_position += sp.h_direction * sp.jump_speed;
plotSmiley(sp);
}
}
if (typeof Object.create !== 'function') {
Object.create = function(o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
function generateFaces() {
var smilies = new Array();
var s;
var i;
var css_smileybox=document.getElementById("smileybox");
var sb_style = getComputedStyle(css_smileybox, null);
// add info to the screen params
smiley_screen_params.width = parseInt(sb_style.width);
smiley_screen_params.height = parseInt(sb_style.height);
// create the smileys
for (i=0; i < smiley_screen_params.num_smilies; ++i) {
s = Object.create(smiley);
s.id = "smiley" + i;
s.top_position = parseInt(Math.random() * (smiley_screen_params.height - smiley_screen_params.smiley_size)),
s.left_position = parseInt(Math.random() * (smiley_screen_params.width - smiley_screen_params.smiley_size)),
randomise_direction(s);
smilies.push(s);
}
setInterval( function(){ moveFace(smilies) }, smiley.intvl_speed );
}
var click_count=0;
function my_click_count() {
++click_count;
document.getElementById("mg").innerHTML = "Number of clicks: " + click_count;
}
generateFaces();
The generateFaces() will generate parameters (for example, coordinates of where they are placed) for a bunch of smiley face images. The setInterval is within this function, and calls the moveFace function to make the smiley faces move at a fixed interval of time. moveFace computes the new coordinates of each smiley face image and then calls plotSmiley to plot each one on the screen in its new location (removing it from the old location). The plotSmiley sets the onclick attribute of each image to call a dummy function just to see if the clicks are registering.
Thanks in advance.
This is not a complete answer but it could give you some perspective to improve your code.
First of all, your idea of deleting the existing img so wrong. If it does exist, all you need is to just change its position so instead of this
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
you should do something like this:
if (existing_smiley !== null)
var smiley_to_plot = existing_smiley;
else {
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.style.position = 'absolute';
document.getElementById("smileybox").appendChild(smiley_to_plot);
smiley_to_plot.addEventListener('click', my_click_count);
}
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
As you can see new image is only being added if it's not already there. Also notice that adding events by using .setAttribute('onclick', "my_click_count()"); is not a good way to do. You should use .addEventListener('click', my_click_count); like I did.
Like I said this is not a complete answer but at least this way they response to the click events now.
FIDDLE UPDATE
Good luck!

Categories