How to copy one image using JavaScript for one HTML5 animation,? - javascript

I have this simple code for one graphic in real time, where I can easily copy this "animation canvas" from HTML5 (id="smoothchartshowAnalisys") to a new < DIV > (id="placeholder"),
This is my goal!
And, I would like it to be automated**!
But, when I put the code into the $(function() the following error appears in my console browser's inspector:
jikken.html:264 Uncaught TypeError: Cannot read property 'getContext'
of null
(in this line var context = smoothchartshowAnalisys.getContext('2d');)
PLEASE thake a look at this jsfidle example the buttons are not working well here, but localy they are OK...
<html>
 <meta charset="utf-8">
<script language="javascript" type="text/javascript" src="./assets/js/jquery.js"></script>
<script language="javascript" type="text/javascript" src="./assets/js/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="./assets/js/jquery.flot.symbol.js"></script>
<body>
<div id="frame01" class="frame01" >
<div id="graph001" class="graph001" >
<div id="placeholder" class="flot-base" style='height:230px; width: 800px;'>
</div >
</div>
<button onclick="analysis()" class="btn btn-success" style='position:absolute; left:700px; top:226px; backgroundd:#01DF01; colorr:white'> <!-- i class="fa fa-forward"></i --> analysis </button>
<canvas id="smoothchartshowTimeLine01" style='position:absolute; left:404px; top: 100px; border:solid 1px orange; padding:0px; margin:0px; ' width="800" height="250"></canvas>
</div>
<script>
$(function() {
// Grid Lines
function seriesData1GridLines() {
if (data1.length > 0)
data1 = data1.slice(1);
// Zip the generated y values with the x values
var res = [];
for (var i = 0; i < data1.length; ++i) {
res.push([i, data1[i]])
}
return res;
}
// Heart beat wave
function seriesData2HeartBet() {
if (data2.length > 0)
data2 = data2.slice(1);
while (data2.length < totalPoints) {
// Heart beat wave
waveHeartBeatNormal();
totalPointsCtrl++
if(totalPointsCtrl>50){//784
totalPointsCtrl=1
}
}
// Zip the generated y values with the x values
var res = [];
for (var i = 0; i < data2.length; ++i) {
res.push([i, data2[i]])
}
return res;
}
// FLAG wave
function seriesData3Flag() {
if (data3.length > 0)
data3 = data3.slice(1);
if (data3b.length > 0)
data3b = data3b.slice(1);
// Zip the generated y values with the x values
var res = [];
for (var i = 0; i < data3.length; ++i) {
res.push([i, data3[i], data3b[i],])
}
return res;
}
var plot = $.plot("#placeholder", [
{data: seriesData1GridLines()},
{data: seriesData2HeartBet(),},
{data: seriesData3Flag(),},
], {
});
// the code for copy the image
// this one is NOT working !!
var smoothchartshowAnalisys = document.querySelector('#smoothchartshowAnalisys');
var smoothchartshowTimeLine01 = document.querySelector('#smoothchartshowTimeLine01');
var context = smoothchartshowAnalisys.getContext('2d');
var image = context.getImageData(0, 0, smoothchartshowAnalisys.width, smoothchartshowAnalisys.height);
smoothchartshowTimeLine01.getContext('2d').putImageData(image, 0, 0);
//
//
function update() {
plot.setData([
{data: seriesData1GridLines(), points: {show: false}, lines: {show: true},},
{data: seriesData2HeartBet(), points: {show: false}, lines: {show: true},},
{data: seriesData3Flag(), points: {show: true}, lines: {show: true},}
]);
plot.draw();
realTime = setTimeout(update, updateInterval);
}
update();
});
//
// copying the image from canvas when press a button
// this one is working !!
function analysis() {
var placeholder = document.querySelector('.flot-base');
var smoothchartshowAnalisys = document.querySelector('#smoothchartshowAnalisys');
var context = placeholder.getContext('2d');
var image = context.getImageData(0, 0, placeholder.width, placeholder.height);
smoothchartshowAnalisys.getContext('2d').putImageData(image, 0, 0);
}
//
// the waves
//
function waveHeartBeatNormal() {
// heart beat wave
}
</script>
</body>
</html>*
So, My question is:
how to make that < div > always up to date? automaticaly?
thanks

Related

JQuery/JS script not running in html (works in Codepen)

I'm trying to make a decoding effect and I have found useful stack overflow questions to help with that but I am facing a weird problem. I have an example that I got from a stack overflow link(answer by Flambino) and it works perfectly fine. However, when I put it in my html files and test it locally, it doesn't do anything(no decoding effect). My local code from these html files are below.
html,
head,
body {
width: 100%;
margin: 0;
background-color: rgb(38, 64, 185);
}
* {
font-family: 'Whitney', sans-serif;
box-sizing: border-box;
}
div.mainContent {
margin-top: 100px;
}
span.morphText {
color: white;
}
.code {
color: red;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/mainStyles.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght#0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<meta charset="utf-8">
<script type="text/javascript">
jQuery.fn.decodeEffect = (function($) {
var defaultOptions = {
duration: 3000,
stepsPerGlyph: 10,
codeGlyphs: "ABCDEFGHIJKLMNOPQRSTUWVXYZ1234567890",
className: "code"
};
// get a random string from the given set,
// or from the 33 - 125 ASCII range
function randomString(set, length) {
console.log("ues");
var string = "",
i, glyph;
for (i = 0; i < length; i++) {
console.log("ues");
glyph = Math.random() * set.length;
string += set[glyph | 0];
}
return string;
}
// this function starts the animation. Basically a closure
// over the relevant vars. It creates a new separate span
// for the code text, and a stepper function that performs
// the animation itself
function animate(element, options) {
var text = element.text(),
span = $("<span/>").addClass(options.className).insertAfter(element),
interval = options.duration / (text.length * options.stepsPerGlyph),
step = 0,
length = 0,
stepper = function() {
if (++step % options.stepsPerGlyph === 0) {
length++;
element.text(text.slice(0, length));
}
if (length <= text.length) {
span.text(randomString(options.codeGlyphs, text.length - length));
setTimeout(stepper, interval);
} else {
span.remove();
}
};
element.text("");
stepper();
}
// Basic jQuery plugin pattern
return function(options) {
options = $.extend({}, defaultOptions, (options || {}));
return this.each(function() {
animate($(this), options);
});
};
}(jQuery));
$("#sometext").decodeEffect();
</script>
</head>
<body>
<div class="mainContent">
<span id="sometext" class="morphText">
Hello, world
</span>
</div>
</body>
</html>
You should wrap your js code in $(document).ready so your code will run as soon as DOM becomes safe for manipilation (check this in documentation - https://api.jquery.com/ready/).
so your code will be next:
$( document ).ready(function() {
jQuery.fn.decodeEffect = (function($) {
var defaultOptions = {
duration: 3000,
stepsPerGlyph: 10,
codeGlyphs: "ABCDEFGHIJKLMNOPQRSTUWVXYZ1234567890",
className: "code"
};
// get a random string from the given set,
// or from the 33 - 125 ASCII range
function randomString(set, length) {
console.log("ues");
var string = "",
i, glyph;
for (i = 0; i < length; i++) {
console.log("ues");
glyph = Math.random() * set.length;
string += set[glyph | 0];
}
return string;
}
// this function starts the animation. Basically a closure
// over the relevant vars. It creates a new separate span
// for the code text, and a stepper function that performs
// the animation itself
function animate(element, options) {
var text = element.text(),
span = $("<span/>").addClass(options.className).insertAfter(element),
interval = options.duration / (text.length * options.stepsPerGlyph),
step = 0,
length = 0,
stepper = function() {
if (++step % options.stepsPerGlyph === 0) {
length++;
element.text(text.slice(0, length));
}
if (length <= text.length) {
span.text(randomString(options.codeGlyphs, text.length - length));
setTimeout(stepper, interval);
} else {
span.remove();
}
};
element.text("");
stepper();
}
// Basic jQuery plugin pattern
return function(options) {
options = $.extend({}, defaultOptions, (options || {}));
return this.each(function() {
animate($(this), options);
});
};
}(jQuery));
$("#sometext").decodeEffect();
});
when you call it in head element $("#sometext") is not yet available, move it to the bottom of body
<body>
<div class="mainContent">
<span id="sometext" class="morphText">
Hello, world
</span>
</div>
<script>
$("#sometext").decodeEffect();
</script>
</body>

How should I refer back to the an element before (in a different function), and modify it in a new function?

How do I make reference to the specific dashes I created, and add a
specific letter to them. Read the comments and code to get a better
context. Thanks for any help in advance!!
<!Doctype html>
<html lang="en">
<head>
<style>
ul {
display: inline;
list-style-type: none;
}
.boxes {
font-size:1.6em;
text-align:center;
width: 10px;
border-bottom: 3px solid black;
margin: 5px;
padding: 10px;
display: inline;
}
.hidden {
visibility: hidden;
}
.visible {
visibility: visible;
}
</style>
</head>
<body>
<script>
var possibleWord = ["COW", "BETTER", "HARDER", "JUSTIFY", "CONDEMN",
"CONTROL", "HELLO", "UNDERSTAND", "LIFE", "INSIGHT","DATE",
"RIGHTEOUSNESS"];
var hangmanWord = possibleWord[Math.floor(Math.random() *
possibleWord.length)];
var underlineHelp;
var space;
var guess;
var guesses = [];
var placement;
var underscores = [];
var character = [];
var textNodes = [];
window.onload = function () {
placement = document.getElementById('hold');
underlineHelp = document.createElement('ul');
placement.appendChild(underlineHelp);
for (i = 0; i < hangmanWord.length; i++) {
underscores = document.createElement('li');
underscores.setAttribute('class', 'boxes');
guesses.push(underscores);
underlineHelp.appendChild(underscores);
character = document.createElement('span');
character.appendChild(document.createTextNode(hangmanWord[i]));
character.classList.add('hidden');
underscores.appendChild(character);
}
This is the area I want to refer to later.
for(x=1;x<=26;x++){
document.getElementById("test").innerHTML = hangmanWord;
var btn = document.createElement("BUTTON");
var myP = document.createElement("br");
var letter = String.fromCharCode(x+64);
var t = document.createTextNode(letter);
btn.appendChild(t);
btn.id = letter;
Just creating buttons. This is important when I say 'this.id' down below.
btn.addEventListener("click", checkLetter);
document.body.appendChild(btn);
//add a line break 'myP' after 3 buttons
if (x%10==0) {
document.body.appendChild(myP);
}
}
}
function checkLetter(){
//this refers to the object that called this function
document.getElementById("p1").innerHTML += this.id;
for (i = 0; i < hangmanWord.length; i++) {
guess = hangmanWord[i];
if (this.id == guess) {
character[i] = hangmanWord[i];
character.appendChild(document.createTextNode(hangmanWord[i]));
character.classList.add('visible');
}
}
}
Here is where I am in trouble. If I do this (the code I wrote after the if statement) the letters will be added on the end of the string. I Want to have it on the specific dashes that I created earlier. How can I manage to do that? Do I have to do something called "object passing." I am relatively new to js (high school student) and I am keen on any insight! Once again thanks for the help in advance!
</script>
</head>
<body>
<p>Click the button to make a BUTTON element with text.</p>
<div id = "contents">
<div id = "hold"></div>
</div>
<p id ="p1"> Letters picked: </p>
<div id= "picBox"></div>
<div id = "test"></div>
</div>
</body>
You could store the guessing word and the guessed characters in an object and just output the replaced result of such instead. Seems easier to me.
<html>
<head>
<script>
//The hangman object
var Hangman = {
wordToGuess: 'RIGHTEOUSNESS', //The word to guess. Just one for my example
guessedLetters: [] //The guessed characters
};
window.onload = function(){
//Creating the buttons
for(var tF=document.createDocumentFragment(), x=1; x<=26; x++){
var tLetter = String.fromCharCode(x+64),
tButton = tF.appendChild(document.createElement("button"));
tButton.id = tLetter;
tButton.addEventListener("click", checkLetter);
tButton.appendChild(document.createTextNode(tLetter));
(x%10 === 0) && tF.appendChild(document.createElement('br'))
};
document.body.appendChild(tF);
startTheGame()
};
//Starts a game of hangman
function startTheGame(){
var tWord = Hangman.wordToGuess,
tPlacement = document.getElementById('hold');
document.getElementById('test').innerHTML = tWord;
//Resetting the guesses
Hangman.guessedLetters = [];
//Creating dashes for all letters in our word
for(var i=0, j=tWord.length; i<j; i++){
tPlacement.appendChild(document.createTextNode('_'))
}
}
function checkLetter(){
var tButton = this,
tLetter = tButton.id,
tWord = Hangman.wordToGuess,
tPlacement = document.getElementById('hold');
//Make a guess
document.getElementById('p1').innerHTML += tLetter;
(Hangman.guessedLetters.indexOf(tLetter) === -1) && Hangman.guessedLetters.push(tLetter.toLowerCase());
//Clear the current word
while(tPlacement.firstChild) tPlacement.removeChild(tPlacement.firstChild);
//Now we reverse replace the hangman word by the guessed characters
for(var i=0, j=tWord.length; i<j; i++){
tPlacement.appendChild(document.createTextNode(
(Hangman.guessedLetters.indexOf(tWord[i].toLowerCase()) === -1) ? '_' : tWord[i]
))
}
}
</script>
</head>
<body>
<p>Click the button to make a BUTTON element with text.</p>
<div id = 'contents'>
<div id = 'hold'></div>
</div>
<p id = 'p1'> Letters picked: </p>
<div id= "picBox"></div>
<div id = "test"></div>
<!-- This one seems to be too much
</div>
-->
</body>
</html>
https://jsfiddle.net/zk0uhetz/
Update
Made a version with propert object handling, separating the actual hangman logic from the interface.
<html>
<head>
<style>
button{
margin: 1px;
min-width: 30px
}
button[disabled]{
background: #777;
color: #fff
}
</style>
<script>
//Handles the hangman game itself
;(function(ns){
'use strict';
var _listOfWord = ['COW', 'BETTER', 'HARDER', 'JUSTIFY', 'CONDEMN', 'CONTROL', 'HELLO', 'UNDERSTAND', 'LIFE', 'INSIGHT','DATE', 'RIGHTEOUSNESS'],
_wordToGuess = null, //The word to guess. Just one for my example
_guessedLetters = [] //The guessed characters
ns.Hangman = {
//Returns the current obstructed word
getCurrentObstructedWord: function(){
var tWord = []; //The current state of the game
if(_wordToGuess){
//Now we reverse replace the hangman word by the guessed characters
for(var i=0, j=_wordToGuess.length; i<j; i++){
tWord.push(
(_guessedLetters.indexOf(_wordToGuess[i].toLowerCase()) === -1) ? '_' : _wordToGuess[i]
)
}
};
return tWord
},
//Make a guess at the current game
Guess: function(letter){
//Add the guess to the list of guesses, unless already guessed
(_guessedLetters.indexOf(letter) === -1) && _guessedLetters.push(letter.toLowerCase());
return this.getCurrentObstructedWord()
},
isComplete: function(){
return !!(this.getCurrentObstructedWord().indexOf('_') === -1)
},
//Starts a new game
Start: function(){
_guessedLetters = []; //Resetting the guesses
_wordToGuess = _listOfWord[Math.floor(Math.random() * _listOfWord.length)];
return _wordToGuess
}
}
}(window._ = window._ || {}));
//Creates the buttons for hangman
function createButtons(){
var tContainer = document.querySelector('#buttons');
while(tContainer.firstChild) tContainer.removeChild(tContainer.firstChild);
//Creating the buttons
for(var tF=document.createDocumentFragment(), x=1; x<=26; x++){
var tLetter = String.fromCharCode(x+64),
tButton = tF.appendChild(document.createElement('button'));
tButton.id = tLetter;
tButton.addEventListener('click', makeAGuess);
tButton.appendChild(document.createTextNode(tLetter));
(x%10 === 0) && tF.appendChild(document.createElement('br'))
};
tContainer.appendChild(tF)
};
//Makes a guess
function makeAGuess(){
var tButton = this,
tLetter = tButton.id;
//Disable the button
tButton.setAttribute('disabled', 'disabled');
//Make a guess
var tElement = document.getElementById('hold');
tElement.textContent = _.Hangman.Guess(tLetter).join('');
//Check if finished
if(_.Hangman.isComplete()){
tElement.style.color = 'limegreen'
}
};
//Starts a new game of hangman
function Reset(){
createButtons(); //Recreated the buttons
_.Hangman.Start(); //Starting a game of hangman
var tElement = document.getElementById('hold');
tElement.textContent = _.Hangman.getCurrentObstructedWord().join('');
tElement.style.color = ''
};
window.onload = function(){
Reset()
};
</script>
</head>
<body>
<div id = 'hold'></div>
<p id = 'p1'>Make a guess:</p>
<div id = 'buttons'></div>
<br /><br />
<button onclick = 'Reset()'>Start a new game</button>
</body>
</html>
https://jsfiddle.net/mm6pLfze/

how to load multiple image one by one on canvas? using loop

var ImgCanvas = new fabric.Canvas("mycanvas");
var json = {};
var IdStore = [];
var retval = [];
var retvalsrc = [];
function sava(){
//push to array for loop
$('.Jicon').each(function(){
retval.push($(this).attr('id'));
retvalsrc.push($(this).attr('src'));
})
var className = $(".Jicon");
var classnameCount = className.length;
//loop classname
for(var d = 0; d < classnameCount; d++){
updateCanvas(retval[d], retvalsrc[d]);
}
}
//change main image
function updateCanvas(_id, _src)
{
ImgCanvas.clear();
// var oImg = new fabric.Image(_src, {
fabric.Image.fromURL(_src, function(oImg) {
oImg.setWidth(500);
oImg.setHeight(400);
oImg.left = ((ImgCanvas.width/2)-(oImg.width/2));
oImg.top = 50;
oImg.selectable = false;
ImgCanvas.add(oImg);
ImgCanvas.renderAll();
});
}
i have a mutiplete Image which i wanna to load them to canvas one by one using loop , how do i achieve that ? so when i press sava the image will show one by one on the canvas.i tried to use for but it load all those image together.
can anyone give me a help here~ thank apreciate.
Demo
Let the end of the imageFromURL call the next load, and refactor the code for use a settimeout, otherwise everything will be very fast.
The images before appeared all togheter because the load is async. So with the for loop you were
rapidly starting the loading in sequence of 4 images
immediately clear 4 times a canvas that is still empty
every image will then finish loading and appear on the canvas on random order.
var ImgCanvas = new fabric.Canvas("mycanvas");
var json = {};
var IdStore = [];
var retval = [];
var retvalsrc = [];
function sava(){
$('.Jicon').each(function(){
retval.push($(this).attr('id'));
retvalsrc.push($(this).attr('src'));
})
updateCanvas();
}
//change main image
function updateCanvas() {
ImgCanvas.clear();
var _src = retvalsrc.pop();
fabric.Image.fromURL(_src, function(oImg) {
oImg.setWidth(500);
oImg.setHeight(400);
oImg.left = ((ImgCanvas.width/2)-(oImg.width/2));
oImg.top = 50;
oImg.selectable = false;
ImgCanvas.add(oImg);
ImgCanvas.renderAll();
if (retvalsrc.length > 0) {
setTimeout(updateCanvas, 1000);
}
});
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div>
<img name="001.png" class="Jicon" id="displayImage1" src="http://i795.photobucket.com/albums/yy232/PixKaruumi/Pokemon%20Pixels/077.png" onclick="updateCanvas(this.src);">
<img name="002.png" class="Jicon" id="displayImag2" src="http://i795.photobucket.com/albums/yy232/PixKaruumi/Pokemon%20Pixels/076.png" onclick="updateCanvas(this.src);">
<img name="003.png" class="Jicon" id="displayImage3" src="http://rs795.pbsrc.com/albums/yy232/PixKaruumi/Pokemon%20Pixels/071.png~c100" onclick="updateCanvas(this.src);">
<img name="004.png" class="Jicon" id="displayImag4" src="http://rs795.pbsrc.com/albums/yy232/PixKaruumi/Pokemon%20Pixels/072.png~c100" onclick="updateCanvas(this.src);">
</div>
<button onclick="sava();">sava</button>
<div id="warpper">
<canvas id="mycanvas" width="380" height="500" style="border:1px solid #000;"></canvas>
</div><!-- end of div -->
</body>

FlotChart Real-time load from JSON do not render

I found real-time chart (flotcharts.org). Now I tried implemented load of data from JSON file.
Data in the file are (for y axis).
{
"data":[["1","3","5","7","9","11","2","8","6","15","3","18","14","9","51","13","6","18","16","3","15","32","17","11","1","23","5","17","9","1"]]
}
HTML and jQuery function are from example. I tried edit for ajax. Data for x axis I want to generate using variable i (below in the code).
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Real-time updates</title>
<link href="http://www.ondrej-vasko.cz/realtime/css/examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="http://www.ondrej-vasko.cz/realtime/js/jquery.js"></script>
<script language="javascript" type="text/javascript" src="http://www.ondrej-vasko.cz/realtime/js/jquery.flot.js"></script>
<script type="text/javascript">
$(function() {
// We use an inline data source in the example, usually data would
// be fetched from a server
var data = [],
totalPoints = 300;
function getRandomData() {
$.ajax({
url: "http://www.ondrej-vasko.cz/realtime/js/data_2.json",
type: "POST",
dataType: "json"
}).success(function(data){
//$('#placeholder').append(JSON.stringify(data) + '</br>');
data.push(data);
});
return false;
// if (data.length > 0)
// data = data.slice(1);
// Do a random walk
// while (data.length < totalPoints) {
// var prev = data.length > 0 ? data[data.length - 1] : 50,
// y = prev + Math.random() * 10 - 5;
//
// if (y < 0) {
// y = 0;
// } else if (y > 100) {
// y = 100;
// }
// data.push(y);
// }
// Zip the generated y values with the x values
var res = [];
for (var i = 0; i < data.length; ++i) {
res.push([i, data[i]])
}
return res;
}
// Set up the control widget
var updateInterval = 30;
$("#updateInterval").val(updateInterval).change(function () {
var v = $(this).val();
if (v && !isNaN(+v)) {
updateInterval = +v;
if (updateInterval < 1) {
updateInterval = 1;
} else if (updateInterval > 2000) {
updateInterval = 2000;
}
$(this).val("" + updateInterval);
}
});
var plot = $.plot("#placeholder", [ getRandomData() ], {
series: {
shadowSize: 0 // Drawing is faster without shadows
},
yaxis: {
min: 0,
max: 100
},
xaxis: {
show: false
}
});
function update() {
plot.setData([getRandomData()]);
// Since the axes don't change, we don't need to call plot.setupGrid()
plot.draw();
setTimeout(update, updateInterval);
}
update();
// Add the Flot version string to the footer
$("#footer").prepend("Flot " + $.plot.version + " – ");
});
</script>
<div id="header">
<h2>Real-time updates</h2>
</div>
<div id="content">
<div class="demo-container">
<div id="placeholder" class="demo-placeholder"></div>
</div>
<p>You can update a chart periodically to get a real-time effect by using a timer to insert the new data in the plot and redraw it.</p>
<p>Time between updates: <input id="updateInterval" type="text" value="" style="text-align: right; width:5em"> milliseconds</p>
</div>
<div id="footer">
Copyright © 2007 - 2013 IOLA and Ole Laursen
</div>
After my editing do not work drawing data to graph. Can ask for help? Thanks
I think the problem might be when you are pushing the data after the ajax call. Put an alert in the loop that returns "res" and make sure the data is in the correct format.
var res = [];
for (var i = 0; i < data.length; ++i) {
res.push([i, data[i]])
*add Alert Here*
}
Have a look at this example. http://jsfiddle.net/grgesxbt/3/
Numerous problems at a quick glance:
1.) This:
var res = [];
for (var i = 0; i < data.length; ++i) {
res.push([i, data[i]])
}
Needs to be in the .success callback function. The way you have it now it'll execute before the AJAX call completes and data will still be []. Actually, you have a random return false; in there, so you never even hit the above code.
2.) Your AJAX return is an object with a "data" property that's an array of array of strings. You then push this into another array. Very convoluted. Rewrite the .success callback to be something like this:
.success(function(data){
var array = data['data'][0];
var res = [];
for (var i = 0; i < array .length; ++i) {
res.push([i, parseFloat(array[i])])
}
return res;
});
3.) Notice the parseFloat above, that's important. Your numbers are strings and flot won't like that. That converts them to numeric data. It would be better to fix your JSON file, then get rid of the parseFloat. Actually if you can edit the JSON file, you can make it simply:
[1,3,5,7,9,11,2,8,6,15,3,18,14,9,51,13,6,18,16,3,15,32,17,11,1,23,5,17,9,1]
Then your .success callback becomes:
.success(function(data){
var res = [];
for (var i = 0; i < data.length; ++i) {
res.push([i, data[i]])
}
return res;
});

Clone HTML elements with JS

Trying to set up a Tic-Tac-Toe board based on JS input with an alert. The alert never shows up, and the HTML is never rendered... what am I missing?
ALL HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tic Tac Toe! (and more...)</title>
<meta name="description" content="Tic Tac Toe">
<meta name="author" content="SinSysOnline">
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js.js"></script>
<style>
body{
font-family:"Lucida Console", Monaco, monospace;
}
td{
border-right:1px solid #000;
border-bottom:1px solid #000;
width:100px;
height:100px;
text-align:center;
font-size:72px;
}
td:last-child{
border-right:none;
border-bottom:1px solid #000;
}
tr:last-child td{
border-bottom:none;
}
</style>
</head>
<body>
<div id="dashboard">
<input type="text" value="How large is your grid? (default 3)" size="35" />
</div>
<table id="board">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</body>
</html>
ALL JS (minus jQuery)
/* Sadly, there is a very well known algorithm to ensure one NEVER loses at
tic-tac-toe. Ties, perhaps, but if you play right you can NEVER LOSE.
I will not institue this cheap shot into my program, and this will be
a computer vs you. I will add in potential moves :-) */
(function($) {
function create(x){
var board = [];
for(var i=0;i<x;i++){
var tempArr = [];
for(var j=0;j<x;j++){ tempArr[j] = ""; }
board.push(tempArr);
}
$('#board tr').clone(x);
return board;
}
var x = prompt("How large would you like your grid? (3-10)");
var board = create(x);
})(jQuery);
I've tried adding the JS to the bottom of my body... just kind of confused here. I know JS inside and out... except for DOM manipulation...
you didn't do any thing with your cloned element!
if you want to dynamically generate a table
the code should be like this
var $board = $('#board');
var td = "<td></td>", $tr = $("<tr></tr>");
function create(x) {
$board.empty();
var arr = [];
for(var i = 0; i < x; i++) {
arr.push(td);
}
var $trCloned = $tr.clone().append(arr.join(''));
for(var j = 0; j < x; j++) {
$board.append($trCloned);
}
}
Here is the fiddle
// JQuery
function create(board, x)
{
var row = $("<tr></tr>");
var i;
for (i = 0; i != x; i++) row.append ($("<td>x</td>")); // create a row
for (i = 0; i != x; i++) $('#'+board).append(row.clone()); // then the board
}
// sample use
var x = window.prompt ("How much, boss?");
create('board', x);
// html
<table id='board' />
I've put an 'x' inside the cells so that the board is visible
As Fiddle works, this No-Prompt problem is more like an environment/compatibility/typo issue. The problem can be solved progressively.
There is a misuse of jQuery's clone() function, the clone() function accepts boolean type (http://api.jquery.com/clone/) , which means whether or not event handlers will be copied. From the code I guess this is not what you want. Please correct it and try again.
On which browser did you test? Does this issue happen on one specific browser, or happens on all browsers in your computer? If it is the latter one, then copy your code (copy the files, not re-type) to someone else' computer and try again.
Simplify the JS code and test step by step. First, just leave the prompt() line and delete all else, will it work? Then, add an empty create() function and try again. Then, add something more. Sooner or later, you will find the line which causes the problem.
Please let us know if you deliver the above experiment and find something new.
EDITS
I'll never stop if I don't stop now. I'm stuck anyway. Hope this helps you on your way. Still needs some work (undefined references) but is functional if my fanciness didn't distract me so much:
JS Fiddle Demo (not working)
Javascript:
(function (window, document, $) {
var $board = $('#board');
var x = parseInt(prompt("How large would you like your grid? (3-10)"), 10);
var taken = [];
create(x);
function create(x) {
var tmp;
var $tr = $('<tr/>');
var $td = $('<td/><td/><td/>');
if (x <= 10 && x >= 3 && typeof x === 'number') {
for (var i = 0; i < x; i++) {
tmp = $tr.append($td);
tmp.clone().appendTo($board);
}
$('#board').on('click', 'td', function (evt) {
var e = evt || window.event;
var y = $(this).index();
var z = $(this).parent('tr').index();
taken = (!taken) ? [y, z] : taken;
userChoice(y, z, x, this);
});
} else {
alert('You entered an incorrect value. Try again!');
return false;
}
}
function userChoice(y, z, x, el) {
//if($(el).text() !== "") {
console.log(taken);
for (var d = 0; d < (x - 1); d++) {
for (var o = 0, n = 0; o < 3; o++) {
if ((taken[n].indexOf(y) && taken[n].indexOf(z)) || (taken[n].indexOf(y) && taken[n].indexOf(z))) {
alert('Already played that spot. Nice try.');
return false;
}
n++;
}
}
taken.push([y, z]);
$(el).text('O');
console.log(taken);
if ((taken.length * taken[taken.length].length) / (x - 1) === 3) {
alert('No more spaces! Game over!');
return false;
}
compChoice(x);
}
function compChoice(x) {
console.log(taken);
var a = Math.floor(Math.random(10) * x);
var b = Math.floor(Math.random(10) * x);
for (var d = 0; d < (x-1); d++) {
for (var o = 0, n = 0; o < 3; o++) {
if ((taken[n].indexOf(a) && taken[n].indexOf(b)) || (taken[n].indexOf(a) && taken[n].indexOf(b))) {
compChoice(x);
}
n++;
}
}
taken.push([a,b]);
console.log(taken);
$board.find('tr:nth-of-type(' + a + ')').find('td:nth-of-type(' + b + ')').text('X');
if ((taken.length * taken[taken.length].length) === x) {
alert('No more spaces! Game over!');
return false;
}
}
})(this, this.document, jQuery, undefined);
HTML:
<div id="dashboard">
<noscript>
<input type="text" value="How large is your grid? (default 3)" size="35" />
</noscript>
</div>
<table id="board"></table>

Categories