Javascript: Unexpected Token [ on line 92 - javascript

I am having trouble with my html page here. On the console it shows me that there is 1 error on line 92 due to an unexpected token. Im trying to drag the image on the page to a designated box. Once dragged it should stay in the box. When I click on the image i should be able to drag it out of the box. I am not sure where i went wrong, but its completely not working at this point. All help is appreciated.
$(document).ready(function() {
var pictureIds = 20;
var Size = 400;
var table = $('#results').DataTable();
$.get("https://unsplash.it/list", function(Res) {
for (var i = 0; i < pictureIds; pictureIds++) {
var randomNumber = Math.floor(Math.random() * pictureIds.length)
$('.left').append($("<img>", {
src: "https://picsum.photos/" + Size + "/" + Size + "?image" + Res[randomNumber].id,
id: randomNumber,
class: "leftImg"
}));
}
(".leftImg").draggable({
revert: "invalid"
});
$("#right").droppable({
accept: ".leftImg",
drop: function(event, ui) {
ui.draggable.attr("id"),
$(ui.draggable).detach().css({
top: 2,
left: 0
}).appendTo($(this));
window.alert("Dropped image with an ID of " + ui.draggable.attr('id'));
//Create rows
var rowNode = table.row.add({
Res[image id].id,
Res[image id].filename,
Res[image id].author,
Res[image id].post_url
}).draw()
.node();
table.row.add({
Res[image id].id,
Res[image id].filename,
Res[image id].author,
Res[image id].post_url
}).draw();
$(rowNode).addClass(ui.draggable.attr('id'));
}
})
});
});
.left {
padding: 20px;
order: solid #000000 2px;
height: 50%;
width: 90%;
}
#right {
width: 30%;
border: solid #000000 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
float: right;
min-height: 400px;
}
<html>
<head>
<!-- head stuff goes here -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" />
</head>
<body>
<!-- HTML content goes here -->
<div class="left">
<img class="leftImg" src="https://source.unsplash.com/random/200x200" id="102" />
<div id="right">
</div>
</div>
<table id="results" style="width:100%">
<thead>
<tr>
<th>id</th>
<th>filename</th>
<th>author</th>
<th>url</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</html>

I think you just got a little overzealous with some editing... A few typo's and I think you're good:
Missing the $ on the line " (".leftImg").draggable({"
The line var randomNumber = Math.floor(Math.random() * pictureIds.length) needs to have pictureIds.length changed to pictureIds as it is an int not an array.
Your loop is on the variable i but you incremented pictureId's instead of i.
The part where you are doing table.row.add had Res[image id] and I am not sure what is supposed to be in place if image id but Res[image id] is not valid. I commented that out in the code below but what I have edited below is draggable into the box.
$(document).ready(function() {
var pictureIds = 20;
var Size = 400;
var table = $('#results').DataTable();
$.get("https://unsplash.it/list", function(Res) {
for (var i = 0; i < pictureIds; i++) {
var randomNumber = Math.floor(Math.random() * pictureIds);
$('.left').append($("<img>", {
src: "https://picsum.photos/" + Size + "/" + Size + "?image" + Res[randomNumber].id,
id: randomNumber,
class: "leftImg"
}));
}
$(".leftImg").draggable({
revert: "invalid"
});
$("#right").droppable({
accept: ".leftImg",
drop: function(event, ui) {
ui.draggable.attr("id"),
$(ui.draggable).detach().css({
top: 2,
left: 0
}).appendTo($(this));
window.alert("Dropped image with an ID of " + ui.draggable.attr('id'));
//Create rows
/*
var rowNode = table.row.add({
Res[randomNumber].id,
Res[randomNumber].filename,
Res[randomNumber].author,
Res[randomNumber].post_url
}).draw()
.node();
table.row.add({
Res[randomNumber].id,
Res[randomNumber].filename,
Res[randomNumber].author,
Res[randomNumber].post_url
}).draw();
*/
$(rowNode).addClass(ui.draggable.attr('id'));
}
})
});
});

Related

How to make dynamically created elements draggable with gridstack?

In my project I'm using this drag and drop library called gridstack. You can see their documentation on github here. When you hardcode elements inside the dom and initialize the gridstack, those elements are draggable. But when the elements are created dynamically with a forloop, they are not draggable even if they have the proper draggable classes. How can I make this work?
//initialize grid stack
var grid = GridStack.init({
minRow: 5, // don't collapse when empty
cellHeight: 70,
acceptWidgets: true,// acceptWidgets - accept widgets dragged from other grids or from outside (default: false).
dragIn: '.newWidget', // class that can be dragged from outside
dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper:'clone' }, // clone or can be your function
removable: '#trash', // drag-out delete class
});
//gridstack on change
grid.on('added removed change', function(e, items) {
let str = '';
items.forEach(function(item) { str += ' (x,y)=' + item.x + ',' + item.y; });
console.log(e.type + ' ' + items.length + ' items:' + str );
});
//dynamic elemenets
const arr = ["Bruh cant drag me!", "Nope me neither", "Me too mouhahaha"];
//loop
for (let i = 0; i < arr.length; i++) {
var div = document.createElement('div');
var el = "<div class='newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide'> <div class='grid-stack-item-content' style='padding: 5px;'> "+arr[i]+"</div></div>";
div.innerHTML = el;
$('.dynamic').append(div);
}
.grid-stack-item-removing {
opacity: 0.8;
filter: blur(5px);
}
#trash {
background: rgba(255, 0, 0, 0.4);
padding: 5px;
text-align: center;
}
.grid-stack-item{
background: whitesmoke;
width: 50%;
border: 1px dashed grey;
}
.grid-stack {
background : #F0FFC0;
}
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- gridstack-->
<link rel="stylesheet" href="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-extra.min.css"/>
<script src="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-h5.js"></script>
<!-- body-->
<body>
<div id="trash"><span>drop here to remove</span> </div>
<br>
<div class="dynamic"></div>
<div class="newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide">
<div class="grid-stack-item-content" style="padding: 5px;">
<div>
</div>
<div>
<span>I'm original domster! Drag and drop me!</span>
</div>
</div>
</div>
<br>
<div class="grid-stack"></div>
</body>
This issue was raised here. The grid does not automatically track external changes so the grid needs to be re-initialize for the dragIn option to notice the new dynamic widgets
GridStack.setupDragIn()
Full code
//initialize grid stack
var grid = GridStack.init({
minRow: 5, // don't collapse when empty
cellHeight: 70,
acceptWidgets: true,// acceptWidgets - accept widgets dragged from other grids or from outside (default: false).
dragIn: '.newWidget', // class that can be dragged from outside
dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper:'clone' }, // clone or can be your function
removable: '#trash', // drag-out delete class
});
//gridstack on change
grid.on('added removed change', function(e, items) {
let str = '';
items.forEach(function(item) { str += ' (x,y)=' + item.x + ',' + item.y; });
console.log(e.type + ' ' + items.length + ' items:' + str );
});
//dynamic elemenets
const arr = ["Bruh cant drag me!", "Nope me neither", "Me too mouhahaha"];
//loop
for (let i = 0; i < arr.length; i++) {
var div = document.createElement('div');
var el = "<div class='newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide'> <div class='grid-stack-item-content' style='padding: 5px;'> "+arr[i]+"</div></div>";
div.innerHTML = el;
$('.dynamic').append(div);
}
GridStack.setupDragIn(
'.newWidget',
);
.grid-stack-item-removing {
opacity: 0.8;
filter: blur(5px);
}
#trash {
background: rgba(255, 0, 0, 0.4);
padding: 5px;
text-align: center;
}
.grid-stack-item{
background: whitesmoke;
width: 50%;
border: 1px dashed grey;
}
.grid-stack {
background : #F0FFC0;
}
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- gridstack-->
<link rel="stylesheet" href="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-extra.min.css"/>
<script src="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-h5.js"></script>
<!-- body-->
<body>
<div id="trash"><span>drop here to remove</span> </div>
<br>
<div class="dynamic"></div>
<div class="newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide">
<div class="grid-stack-item-content" style="padding: 5px;">
<div>
</div>
<div>
<span>I'm original domster! Drag and drop me!</span>
</div>
</div>
</div>
<br>
<div class="grid-stack"></div>
</body>

How to pause and start gif using jQuery AJAX

I am a student and I am trying to start, pause and start a gif when a user clicks the gif, however I am stuck on how to add in this click function. I know that the the gif version of the object is .images.fixed_height.url and the still image is .images.fixed_height_still.url . If I try to append like below $(this) I get that images is undefined. How would I go by doing this? Currently 10 gifs show when you click the category. Thank you for any help in advance.
Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Giphy</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<style>
body {
background-image: url('http://www.efoza.com/postpic/2011/04/elegant-blue-wallpaper-designs_154158.jpg');
width: 100%;
}
button {
padding: 0 2%;
margin: 0 2%;
}
h4 {
font-size: 165%;
font-weight: bold;
color: white;
}
.container {
background-color: rgba(0, 0, 0, 0.2);
max-width: 1000px;
width: 100%;
}
.btn {
margin-top: 2%;
margin-bottom: 2%;
font-size: 125%;
font-weight: bold;
}
.guide {
padding: 3% 0 0 0;
}
.tag-row {
padding: 3% 0 0 0;
}
.category-row {
padding: 3% 0 ;
}
#photo {
padding-bottom: 3%;
}
</style>
</head>
<body>
<div class="container">
<div class="row text-center guide"><h4>Click a category and see the current top 10 most popular giphy's of that category!</h4></div>
<div class="row text-center tag-row" id="tags"></div>
<div class="row text-center category-row">
<input type="" name="" id="category"><button class="btn btn-secondary" id="addTag">Add Category</button>
</div>
</div>
<div class="container">
<div id="photo"></div>
</div>
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script type="text/javascript">
var tags = ["dog", "dolphin", "whale", "cat", "elephant", "otter"];
// Function for displaying movie data
function renderButtons() {
$("#tags").empty();
for (var i = 0; i < tags.length; i++) {
$("#tags").append('<button class="tag-buttons btn btn-primary">' + tags[i] + '</button>');
}
}
// Add tags function //
$(document).on('click', '#addTag', function(event) {
event.preventDefault();
var newTag = $("#category").val().trim();
tags.push(newTag);
$("#tags").append('<button class="tag-buttons btn btn-primary">' + newTag + '</button>');
});
// Tag button function //
$(document).on('click', '.tag-buttons', function(event) {
// Keeps page from reloading //
event.preventDefault();
var type = this.innerText;
console.log(this.innerText);
var queryURL = "http://api.giphy.com/v1/gifs/search?q=" + window.encodeURI(type) + "&limit=10&api_key=dc6zaTOxFJmzC";
$.ajax({
url: queryURL,
method: "GET"
}).done(function(response) {
for (var i = 0; i < response.data.length; i++) {
$("#photo").append('<img src="' + response.data[i].images.fixed_height_still.url + '" class="animate">');
$('.animate').on('click', function() {
$(this).remove().append('<img src="' + response.data[i].images.fixed_height.url + '" class="animate">');
console.log($(this));
});
}
});
$("#photo").empty();
});
renderButtons();
</script>
</body>
</html>
The difference between fixed_height and fixed_height_still will solve the problem. if you look closely the urls differ only by name_s.gif and name.gif.
So you can simply swap the two images to create a player. This will act like a play and stop. Not play and pause. But in a small gif I don't think pause really matter, stop and pause will look similar.
adding class name to the #photo
$("#photo").append('<img class="gif" src="' + response.data[i].images.fixed_height_still.url + '">');
event handler which will control play and stop
$('body').on('click', '.gif', function() {
var src = $(this).attr("src");
if($(this).hasClass('playing')){
//stop
$(this).attr('src', src.replace(/\.gif/i, "_s.gif"))
$(this).removeClass('playing');
} else {
//play
$(this).addClass('playing');
$(this).attr('src', src.replace(/\_s.gif/i, ".gif"))
}
});
jsfiddle demo
https://jsfiddle.net/karthick6891/L9t0t1r2/
you can use this jquery plugin http://rubentd.com/gifplayer/
<img class="gifplayer" src="media/banana.png" />
<script>
$('.gifplayer').gifplayer();
</script>
you can control like this
Use these methods to play and stop the player programatically
$('#banana').gifplayer('play');
$('#banana').gifplayer('stop');
youll find more details here https://github.com/rubentd/gifplayer

Complete function not forcing jquery to wait for end of animation

I am trying to use a counter in my complete function to make sure the animation of margin-top is completed before moving on. Right now, I have the counter in my MakeList(), and in my Spin() function, I console.log the counter and it doesn't recognize the counter++ because it fires before the animation finishes. Nobody I ask can figure out why.
** Note: I can't use timeOut's because the time is set to random (supposed to look like a slot machine ** Also, I can't find what this test platform is saying is an error, but the code runs on my machine. really the script-2.js is all i need to show to get point across though :)
// ********************************************************
// SLOT MACHINE ICONS. Each array has 3 icons for each slot
// ********************************************************
var array1 = [
'<div data-id="0" style="width:100%; background:#fff; height:150px;"></div>',
'<div data-id="1" style="width:100%; background:#ccc; height:150px;"></div>',
'<div data-id="0" style="width:100%; background:#666; height:150px;"></div>'
]
var array2 = [
'<div data-id="0" style="width:100%; background:#fff; height:150px;"></div>',
'<div data-id="1" style="width:100%; background:#ccc; height:150px;"></div>',
'<div data-id="0" style="width:100%; background:#666; height:150px;"></div>'
]
var array3 = [
'<div data-id="0" style="width:100%; background:#fff; height:150px;"></div>',
'<div data-id="1" style="width:100%; background:#ccc; height:150px;"></div>',
'<div data-id="0" style="width:100%; background:#666; height:150px;"></div>'
]
// Generates random # between 0 and 2. Used for choosing winner and creating random slots
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Generates winning array item between coffee, tea and espresso
function win(whatArray){
var arrayItem = getRandomInt(0,2);
var winItem = whatArray[arrayItem];
return winItem;
}
// Populates each slot with random icons to spin through
var makeList = function(whatArray, whatSlot){
var slotArray = [];
for(i=0; i < 100; i++){
var randNum = getRandomInt(0,2); // Generate random number
var findItem = whatArray[randNum]; // Use random number to find associated array item
var slot = whatSlot; // Set which slot to append array item to (first, second or third)
$('#' + slot).append('<div>'+findItem+'</div>'); // Append icon to HTML
}
var winItem = win(whatArray); // Generate winning icon for slot
console.log("winner " + winItem);
$('#' + slot).append('<div>'+winItem+'</div>'); // Append winning icon to end of list
}
// Spin the slot and win some caffeine!
function Spin(){
window.counter = 0;
// Generate lists for each slot
makeList(array1, 'slot-1');
makeList(array2, 'slot-2');
makeList(array3, 'slot-3');
MoveSlots($('#slot1-wrapper'), 2500);
MoveSlots($('#slot2-wrapper'), 5200);
MoveSlots($('#slot3-wrapper'), 500);
//var running = true;
// console.log(running);
var slot1attr = $('#slot1-wrapper div').children().last().attr('data-id');
var slot2attr = $('#slot2-wrapper div').children().last().attr('data-id');
var slot3attr = $('#slot3-wrapper div').children().last().attr('data-id');
console.log('counter = ' + counter);
if(counter > 0){
if(slot1attr == slot2attr && slot1attr == slot3attr ){
console.log("WIN");
} else {
console.log("LOSE");
}
}
function MoveSlots(el, speed){
var time = speed;
time += Math.round(Math.random()*10000);
el.stop(true,true);
var marginTop = -(100 * 150 ); //change 100 to height placeholder
var running = true;
el.animate({
'margin-top':'+='+marginTop+'px'
}, {
'duration' : time,
'easing' : 'easeInOutQuint',
complete: function(){
console.log('yolo');
//$(this).on('animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd', function(){
counter++;
console.log(counter);
//})
}
});
} // end MoveSlots
} // end Spin
body{
/*background-color:white;*/
padding:50px;
margin:50px;
background: #505f77 !important;
}
#slotWrapper {
width:410px;
height:150px;
margin:50px auto;
overflow: hidden;
position:relative;
border:1px solid #f00;
}
#slot1-wrapper, #slot2-wrapper, #slot3-wrapper {
margin-top:0;
position: relative;
}
.slot {
width:120px;
height:150px;
margin-right:25px;
text-align:center;
float:left;
position: absolute;
}
#slot-3 {
margin-right:0;
}
#slot-1 {
top:0;
left:0;
}
#slot-2 {
top:0;
left:145px;
}
#slot-3 {
top:0;
left:290px;
}
.slot div {
width:120px;
height:150px;
}
.slot div img {
width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<!-- <link rel="stylesheet" type="text/css" href="css/default.css" />
<link rel="stylesheet" type="text/css" href="css/component.css" /> -->
<div style="text-align:center">
<input type="button" value="spin!" onClick="Spin();" style="margin-top:4px;">
</div>
<div id="slotWrapper">
<div id="slot1-wrapper">
<div id="slot-1" class="slot"></div>
</div>
<div id="slot2-wrapper">
<div id="slot-2" class="slot"></div>
</div>
<div id="slot3-wrapper">
<div id="slot-3" class="slot"></div>
</div>
</div>
</body>
</html>
The problem is complete is executed asynchronously, ie the counter condition is executed is before the animations are completed.
You can use the animation promise to solve it
// ********************************************************
// SLOT MACHINE ICONS. Each array has 3 icons for each slot
// ********************************************************
var array1 = [
'<div data-id="0" style="width:100%; background:#fff; height:150px;"></div>',
'<div data-id="1" style="width:100%; background:#ccc; height:150px;"></div>',
'<div data-id="0" style="width:100%; background:#666; height:150px;"></div>'
]
var array2 = [
'<div data-id="0" style="width:100%; background:#fff; height:150px;"></div>',
'<div data-id="1" style="width:100%; background:#ccc; height:150px;"></div>',
'<div data-id="0" style="width:100%; background:#666; height:150px;"></div>'
]
var array3 = [
'<div data-id="0" style="width:100%; background:#fff; height:150px;"></div>',
'<div data-id="1" style="width:100%; background:#ccc; height:150px;"></div>',
'<div data-id="0" style="width:100%; background:#666; height:150px;"></div>'
]
// Generates random # between 0 and 2. Used for choosing winner and creating random slots
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Generates winning array item between coffee, tea and espresso
function win(whatArray) {
var arrayItem = getRandomInt(0, 2);
var winItem = whatArray[arrayItem];
return winItem;
}
// Populates each slot with random icons to spin through
var makeList = function(whatArray, whatSlot) {
var slotArray = [];
for (i = 0; i < 100; i++) {
var randNum = getRandomInt(0, 2); // Generate random number
var findItem = whatArray[randNum]; // Use random number to find associated array item
var slot = whatSlot; // Set which slot to append array item to (first, second or third)
$('#' + slot).append('<div>' + findItem + '</div>'); // Append icon to HTML
}
var winItem = win(whatArray); // Generate winning icon for slot
console.log("winner " + winItem);
$('#' + slot).append('<div>' + winItem + '</div>'); // Append winning icon to end of list
}
// Spin the slot and win some caffeine!
function Spin() {
var counter = 0;
// Generate lists for each slot
makeList(array1, 'slot-1');
makeList(array2, 'slot-2');
makeList(array3, 'slot-3');
var p1 = MoveSlots($('#slot1-wrapper'), 2500);
var p2 = MoveSlots($('#slot2-wrapper'), 5200);
var p3 = MoveSlots($('#slot3-wrapper'), 500);
$.when(p1, p2, p3).then(function() {
//var running = true;
// console.log(running);
var slot1attr = $('#slot1-wrapper div').children().last().attr('data-id');
var slot2attr = $('#slot2-wrapper div').children().last().attr('data-id');
var slot3attr = $('#slot3-wrapper div').children().last().attr('data-id');
console.log('counter = ' + counter);
if (counter > 0) {
if (slot1attr == slot2attr && slot1attr == slot3attr) {
console.log("WIN");
} else {
console.log("LOSE");
}
}
});
function MoveSlots(el, speed) {
var time = speed;
time += Math.round(Math.random() * 10000);
el.stop(true, true);
var marginTop = -(100 * 150); //change 100 to height placeholder
var running = true;
el.animate({
'margin-top': '+=' + marginTop + 'px'
}, {
'duration': time,
'easing': 'easeInOutQuint',
complete: function() {
console.log('yolo');
counter++;
console.log(counter);
}
});
return el.promise();
} // end MoveSlots
} // end Spin
body {
/*background-color:white;*/
padding: 50px;
margin: 50px;
background: #505f77 !important;
}
#slotWrapper {
width: 410px;
height: 150px;
margin: 50px auto;
overflow: hidden;
position: relative;
border: 1px solid #f00;
}
#slot1-wrapper,
#slot2-wrapper,
#slot3-wrapper {
margin-top: 0;
position: relative;
}
.slot {
width: 120px;
height: 150px;
margin-right: 25px;
text-align: center;
float: left;
position: absolute;
}
#slot-3 {
margin-right: 0;
}
#slot-1 {
top: 0;
left: 0;
}
#slot-2 {
top: 0;
left: 145px;
}
#slot-3 {
top: 0;
left: 290px;
}
.slot div {
width: 120px;
height: 150px;
}
.slot div img {
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.css" rel="stylesheet" />
<div style="text-align:center">
<input type="button" value="spin!" onClick="Spin();" style="margin-top:4px;">
</div>
<div id="slotWrapper">
<div id="slot1-wrapper">
<div id="slot-1" class="slot"></div>
</div>
<div id="slot2-wrapper">
<div id="slot-2" class="slot"></div>
</div>
<div id="slot3-wrapper">
<div id="slot-3" class="slot"></div>
</div>
</div>

Allowing different widths of columns in rows

I am trying to get the table columns to have different widths on each row. I'm using an array to get the values which I am turning into width percentages and passing it into the column. The output seems to copy the row above even though it has different widths.
http://jsfiddle.net/0182rutf/2/
HTML
<table border='1' id="table">
JS
var Array = [
[10, 5, 10],
[50, 2, 10]
];
for (var k = 0; k < Array.length; k++)
{
var totalCol = 0;
$.each(Array[k], function (){totalCol += parseInt(this);});
$('#table').append('<tr id="' + k + '"></tr>')
for (var i = 0; i < Array[k][i]; i++)
{
var weight = Array[k][i];
var width = weight * 100 / totalCol;
$('#' + k).append('<td width="' + width + '%">column</td>');
}
}
Any idea how to fix this?
So as a followup for my comment above.
I would suggest going with flexbox here. But since you know the width of every column you want to draw you can also go without it and still keep IE9 support.
What I am doing here is simply having a div#grid acting as a package for your "table". Then with the JS I generate a div.row kind of like you generated the tr elements and in those I generate the div.cell elements like you would have done with the td elements and set the width directly on those "cells".
I changed your snippet to work:
http://jsfiddle.net/0182rutf/5/
CSS:
#grid {
border: 1px solid black;
}
#grid .row {
position: relative;
}
#grid .cell {
display: inline-block;
box-sizing: border-box;
border: 1px solid green;
}
JS:
var Array = [
[10, 5, 10],
[50, 2, 10]
];
for (var k = 0; k < Array.length; k++)
{
var totalCol = 0;
$.each(Array[k], function (){totalCol += parseInt(this);});
$('#grid').append('<div class="row" id="' + k + '"></div>')
for (var i = 0; i < Array[k][i]; i++)
{
var weight = Array[k][i];
var width = weight * 100 / totalCol;
$('#' + k).append('<div class="cell" style="width: ' + width + '%">column</div>');
console.log(weight);
}
}
HTML:
<div id="grid"></div>
Note that with your calculation 50 is a weight that is too much :)
Modify your JS to form a div based table and sample output should be as follows:
HTML
<div id="row1">
<div class="float-left div1">1st </div>
<div class="float-left div2">2st </div>
<div class="float-left div2">3st </div>
<div class="clear-fix"></div>
</div>
<div id="row2">
<div class="float-left div1">1st </div>
<div class="float-left div2">2st </div>
<div class="float-left div2">3st </div>
<div class="clear-fix"></div>
</div>
CSS
.float-left {
float:left;
border: 1px solid #ccc;
}
#row1 .div1 {
width:100px;
}
#row1 .div2 {
width:200px;
}
#row1 .div3 {
width:50px;
}
#row2 .div1 {
width:50px;
}
#row2 .div2 {
width:100px;
}
#row2 .div3 {
width:20px;
}
.clear-fix {
clear:both;
}
I think may be you can use this solution if you are comfortable. I created two tables and assigned a single row.
<table border='1' id="table0"></table>
<table border='1' id="table1"></table>
and script code is
var Array = [
[10, 5, 10],
[50, 2, 10]
];
for (var k = 0; k < Array.length; k++)
{
var totalCol = 0;
$.each(Array[k], function (){
totalCol += parseInt(this);
});
$('#table' + k).append('<tr id="' + k + '"></tr>')
for (var i = 0; i < Array[k].length; i++)
{
var weight = Array[k][i];
var width = weight * 100 / totalCol;
$('#' + k).append
('<td width="' + width + '%" >column</td>');
console.log(weight);
}
}
And fiddle link is here

Why is my webpage components loading slow?

Here is my webpage with a puzzle game I am making:
http://www.acsu.buffalo.edu/~jamesber/GameOne.html#
If you take a look at it, keep refreshing the page, it takes a second or two for all the components to load.
I thought it was that the ajax was loading slow but I don't think that is it. Someone please help! Thanks!
My javascript code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes /smoothness/jquery-ui.css" />
<style>
#puzzle {
width: 450px;
height: 450px;
outline: 4px solid black;
padding: 0px;
-webkit-padding-start: 0px;
margin-left:440px;
margin-right:auto;
margin-top:-205px;
}
.helper {
width: 200px;
height: 200px;
border: 1px solid black;
margin: 0px;
}
.piece {
float: left;
display: block;
width: 148px;
height: 148px;
border: 1px solid black;
margin: 0px;
background-size: 450px 450px;
background-repeat:no-repeat;
}
.piece span {
display:inline-block;
border:1px solid #FFFFFF;
color: #B80000;
display: none;
}
.ui-dialog .ui-dialog-title {
text-align: center;
width: 100%;
}
</style>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.js"></script>
<script type="text/javascript">
$(function () {
var plant = "";
$.when($.ajax({"url":"http://botanicalapp.com/api/v1/plants/?photo=true"}))
.done(function(fullData){
(function(){
var rand = Math.floor(Math.random()*fullData.length)
plant = fullData[rand].plant.image_default.url;
})()
startGame();
});
function startGame() {
$("#puzzle div").css({'background-image':'url('+ plant +')'});
$("#helper").attr("src",plant);
var puzzle = $("#puzzle");
var pieces = $("#puzzle div");
pieces.sort(function (a, b) {
var temp = parseInt(Math.random() * 100);
var isOddOrEven = temp % 2;
var isPosOrNeg = temp > 5 ? 1 : -1;
return (isOddOrEven * isPosOrNeg);
}).appendTo(puzzle);
var checkDone = false;
var timer;
var secs = 0;
var mins = 0;
var millsecs = 0;
var timeString = document.getElementById("time");
timeString.innerHTML = "00:00:00";
function update(){
if(millsecs > 98) {
secs++;
millsecs = 0;
if(secs > 59){
mins++;
secs = 0;
}
}
else {
millsecs++;
}
if((millsecs<10) && (secs<10) && (mins<10)) {
timeString.innerHTML = '0' + mins + ':0' + secs + ':0' + millsecs;
}
else if ((millsecs<10) && (secs<10)) {
timeString.innerHTML = mins + ':0' + secs + ':0' + millsecs;
}
else if ((millsecs<10) && (mins<10)) {
timeString.innerHTML = '0' + mins + ':' + secs + ':0' + millsecs;
}
else if((secs<10) && (mins<10)){
timeString.innerHTML = '0' + mins + ':0' + secs + ':' + millsecs;
}
else if (millsecs<10) {
timeString.innerHTML = mins + ':' + secs + ':0' + millsecs;
}
else if (secs<10){
timeString.innerHTML = mins + ':0' + secs + ':' + millsecs;
}
else if (mins<10) {
timeString.innerHTML = '0' + mins + ':' + secs + ':' + millsecs;
}
else {
timeString.innerHTML = mins + ':' + secs + ':' + millsecs;
}
}
function start(){
timer = setInterval(function() {update()}, 10);
}
document.getElementById("instr").onclick=function(){ $("#instruct").dialog("open"); };
start();
initSwap();
$("#final").dialog({
autoOpen: false,
modal: true,
width: 900,
resizable: false,
height: 540,
position: [250,75],
dialogClass: "fixed-dialog",
title: "Congratulations Puzzle Solved!",
draggable: false
});
$("#instruct").dialog({
autoOpen: false,
modal: true,
width: 700,
resizable: false,
height: 250,
position: [325,75],
dialogClass: "fixed-dialog",
draggable: false,
title: "Puzzle Instructions",
open: function(ev, ui) { clearTimeout(timer); },
close: function(ev, ui) { if (!checkDone) { start(); } }
});
function initSwap() {
initDroppable($("#puzzle div"));
initDraggable($("#puzzle div"));
}
function initDraggable($elements) {
$elements.draggable({
appendTo: "body",
helper: "clone",
cursor: "move",
revert: "invalid"
});
}
function initDroppable($elements) {
$elements.droppable({
activeClass: "ui-state-default",
hoverClass: "ui-drop-hover",
accept: ":not(.ui-sortable-helper)",
over: function (event, ui) {
var $this = $(this);
},
drop: function (event, ui) {
var $this = $(this);
var linew1 = $(this).after(ui.draggable.clone());
var linew2 = $(ui.draggable).after($(this).clone());
$(ui.draggable).remove();
$(this).remove();
initSwap();
var finished = "1,2,3,4,5,6,7,8,9";
var started = '';
$("#puzzle div").each(function(){
var image = $(this).attr("id");
started += image.replace("recordArr_","")+",";
});
started = started.substr(0,(started.length)-1);
if(started == finished){
checkDone = true;
clearTimeout(timer);
$("#thePlant").attr("src",plant);
$("#final").dialog("open");
}
}
});
}
}
});
</script>
</head>
<body>
<big><big><big><div id="time"></div></big></big></big>
<div id="help"><image id="helper" width="200", height="200"/></div>
<div id="final"><img id="thePlant" width="450", height="450" <p align="top"> Plant Information! </p></div>
<div id="instruct"><p> To begin playing a picture will appear that has been scrambled.
Your job is to drag each piece into the location you think it should be.
When you move all the pieces into their correct locations a window will appearthat will tell you
more about that plant and where to find it when you visit the Botanical Gardens.
If you need help, click on the hints button and numbers will appear in the corners
of the pictures to show you what order the pieces should be in. Good Luck!</p></div>
<div id="maindiv">
<div id="puzzle">
<div id="1" class="piece" style="background-position: -000px -000px;"><b><big><big><span>1</span></big></big></b></div>
<div id="6" class="piece" style="background-position: -301px -151px;"><b><big><big><span>6</span></big></b></big></div>
<div id="9" class="piece" style="background-position: -301px -301px;"><b><big><big><span>9</span></big></big></b></div>
<div id="4" class="piece" style="background-position: -000px -151px;"><b><big><big><span>4</span></big></big></b></div>
<div id="3" class="piece" style="background-position: -301px -000px;"><b><big><big><span>3</span></big></big></b></div>
<div id="7" class="piece" style="background-position: -000px -301px;"><b><big><big><span>7</span></big></big></b></div>
<div id="2" class="piece" style="background-position: -151px -000px;"><b><big><big><span>2</span></big></big></b></div>
<div id="5" class="piece" style="background-position: -151px -151px;"><b><big><big><span>5</span></big></big></b></div>
<div id="8" class="piece" style="background-position: -151px -301px;"><b><big><big><span>8</span></big></big></b></div>
</div>
</div>
Instructions
Toggle Hints
Use Firebug, you can see in the network tab which part is slow.
You should extract your javascript and css in seperate files, they can be compressed then.
As other users suggested - if you are loading 3rd party content from the internet, you have to keep in mind that download times may vary on each page refresh.
Anyway, my advice is to move your custom js code into separate file and minify it when you finish the development process.
And the most important: place that file just before </body> tag.
The reason for doing so is that scripts at the head of a page are blocking the browser. It must stop processing the website until all of the scripts are downloaded and parsed.
A great discussion about that matter is available on stackoverflow, you should go through it here.
A get-request for http://botanicalapp.com/api/v1/plants/?photo=true is taking around 2-3.5 seconds so you're probably not going to be able to process it faster than that.
I would advice you to move the script tag containing your sites javascript to the bottom of the page. It doesn't have to reside in head and putting it right before the closing tag of body allows other external component on the page to download as quickly as possible before the scripts are loaded.
Nothing seems to make it better. I was wondering. Is there a way to put like a smoother looking loading screen to cover it up? Was looking into a js spinner but couldn't get that to work right. But could this be done?

Categories