JavaScript Conflict with Canvas font element and Local Storage display - javascript

I have a function that runs with windows onload to display a list of scores that are stored in local storage. Even if the list is empty it will display as it would when loading in a new browser.
function scoresListDisplay(){
storedEntries = [];
storedEntries = JSON.parse(localStorage.getItem("localstoragekey"));
highScoreList = game.querySelector("section#game ol.high-scores");
for(var i = 0; i < 10; i++){
var st = storedEntries[i];
gamescorelist = document.createElement('li');
gamescorelist.innerHTML = (typeof(st) != "undefined" ? st : "--" );
highScoreList.appendChild(gamescorelist);
}
}
I also have other div tags such as one containing a canvas tag for the font of the page heading or title and other div tags which are used to display a countdown timer and current score.
The list above works fine but the thing is when the list is empty the canvas element with the title at the top of the page disappears and when the list is populated by one or more values (st) the canvas element reappears and is displayed as normal. All other div elements display ok.
I'm not sure but I think the problem may have something to do with the getItem return. Although the console reports this:
TypeError: storedEntries is null
Am I missing something within the function?
If anybody could help with this I would greatly appreciate it.

Well, you see ...
storedEntries = [];
storedEntries = JSON.parse(localStorage.getItem("localstoragekey"));
You are redefining storedEntries, so the first line is useless. When localStorage is empty, JSON.parse will return null, and later you're accessing it as if it were an array.
Do it this way:
storedEntries = JSON.parse(localStorage.getItem("localstoragekey")) || [];
This means, get the value of JSON.parse and, if it is not null, 0, NaN, undefined, false or '' initialise storedEntries with it; otherwise, initialise storedEntries with [].

Related

Setting data info on dynamically created html

I have a JSON response from a server, which returns me a array with 32 objects (in this case). Something like this:
[{object1},{ object2},{ object3}, etc].
Each object have some info that I use to populate an html template. For that, I just use a simple loop:
for(var i = 0; i < api_empresaListar.length; i++)
{
var item = api_empresaListar[i];
var htmls;
htmls = $('...lots of html code');
...
Then it’s just a simple matter of finding/changing the values, and append items on the DOM. Everything works fine. BUT, for some next parts of the code, I would like to access all the info from the object I used to build the html elements (I just show part of the info). So, after searching a lot, I tried to use data, like this:
var tp = htmls.find(".rl_grupo"); // the main div of each html element created in the loop
$(tp).data('key', api_empresaListar[i]); // here, I expected to just insert the object data in each created item.
But when I try it in the console, I got the object info as expected, but always from the last element in the array. Why is that happening? I believe it might be something stupid, but I can’t figure it out.
So, any ideas on how to solve this, or another method to make this work is appreciated. I made it work by setting some "display:none" placeholder html tags and populate those with the info I need later, but looks like a poor solution...
You should not set your htmls variable in the loop. I think that you crush its content every turn, that's why you only have the last item. You should do something like this:
var htmls = $('<div></div>');
for(var i = 0; i < api_empresaListar.length; i++) {
htmls.append($('...lots of html code'));
}
How about setting an index number on each element inside of your html creating code, then iterating over the $('.rl_grupo') elements, like this?
$('.rl_grupo').each(function(){
var index = $(this).data('index');
var currentData = api_empresaListar[index];
$(this).data('key', currentData);
})

javascript div children do not work

With the yrss library, I am loading a RSS feed into my HTML document. This works.
But then I want to access the divs from my JavaScript.
I can lookup the parent node (var test) and put it in the console. But when I want to get the number of child elements, it returns 0.
I'm using the following code:
var test = document.querySelector('#History_0');
console.log("test:");
console.log(test); //Returns <div class="item_trackHistory rss-feed" id="History_0">
console.log("test.childElementCount:");
console.log(test.childElementCount); //Returns 0
However, I can see the child elements I want to access in the inspector.
Why is it that I can see the children of the #History_0-div in Developer Tools, but the attribute childElementCount returns 0?
How can I access an element's children in JavaScript?
Sorry for making mistakes in the way I edited my question the first time.
here is the entire function call. I also entered the suggested solution from below. Unfortunately, it didn't work out.
code
for (var i = 0; i < obj.results.length ; i++ ){
var div = "History_" + i
getRSS(div ,obj.results[i].feedUrl, i);
}
code
this.getRSS = function(div, link, iteration){
$('#'+div+'').yrss(link,{
limit: 50,
dateformat: 'localedate',
tags:'true',
logging:'false'
});
var parent = document.querySelector('#History_'+iteration+'');
var childCount = 0;
if (parent !== null){
var childElements = parent.getElementsByClassName('entry-wrapper');
console.log(childElements);
console.log(childElements.item(0));
if(childElements !== null){
childCount = childElements.length;
console.log(childCount);
}
}
The console.log of ChildElements Returns a HTML Collection, which appears to have 20 entries. But console logging the ChildElement.item(0), it Returns a null.
The console log of childCount Returns 0.
Does anyone have an idea, how it is possible to access the childElements?
Where in my entire js-file should I call a function to Access the divs, that the yrss function creates?
Not the best question as others have pointed out, however, some simple things we can look at. I am unsure if the page loads the RSS feed after the page has loaded or not. I presume not, and will answer it presuming exactly that.
You can see my working code example here:
https://codepen.io/vincentritter/pen/vJmBrd?editors=1010
I've added notes too. Here is the snippet that should be the most important to get you started.
// Grab 'parent' div - History_0 or by class name 'rss-feed'
var parent = document.querySelector('.rss-feed');
var childCount = 0; // Just want to spit this out on the page so you can see.
// Check if parent isn't null
if(parent !== null){
// Get child elements by class name
var childElements = parent.getElementsByClassName('entry-wrapper');
// Check if child elements isn't null...
if(childElements !== null){
// Print results, just so we can look.
childCount = childElements.length;
console.log(childCount);
}
}
I used your images as reference.
To note, I grab stuff by their class name. Just find that easier. But everyone is different, whatever works for you.
That should get you going at least.

Using .each() to create nested Object out of table rows

I am desperately trying to create an Object while using the .each() loop but it doesn't seem to work. Here is the Code:
$("#pdfyap").on("click", function(){
var sonarr = {};
$("#bura tr").each(function(){
var malzemeadi = $(this).find(".maladi").html();
console.log(malzemeadi);
sonarr[malzemeadi] = {};
sonarr[malzemeadi]["malzemekodu"] = $(this).find(".malkodu").html();
sonarr[malzemeadi]["malzemedovizi"] = $(this).find(".doviz").html();
sonarr[malzemeadi]["malzemekdvorani"] = $(this).find(".kdvoranbir").html();
sonarr[malzemeadi]["malzemebirimfiyati"] = $(this).find(".birimfiyat").html();
sonarr[malzemeadi]["malzemebirimkdvmiktari"] = $(this).find(".kdvmikbir").html();
sonarr[malzemeadi]["malzemedovizfiyati"] = $(this).find(".dovfiyat").html();
});
sonarr["nettoplam"] = $("#aratop").html();
sonarr["kdvtoplam"] = $("#kdvtop").html();
sonarr["grosstoplam"] = $("#totaltry").html();
console.log(sonarr);
});
I get all the values right but in the console the object seems to have just the key (malzemeadi) and the value of it is empty and the last three ones are gotten right. long story short: just the nested ones are not being added, although the selector gets the values correct (checked it multiple times). What is it i am missing?
Here is the console log, too:
Object { sdfsadd: Object, fhg: Object, xcvxcv: Object, nettoplam: "6431", kdvtoplam: "245", grosstoplam: "6676" }
Thanks in advance.
I tried your code and it works. The problem is the console will only show the top-level items without expanding the hierarchy. Try clicking the little arrow next to the log to see the expanded hierarchy.
Alternatively, you can convert the object to JSON and log it to the console to see its hierarchy:
console.log(JSON.stringify(sonarr, null, 4));

Displaying images with Javascript based on user input

I have been trying to display image with the following code. The user input is intended to be compared to bring up the right picture.
$(document).ready(function(){
var defaultimg = document.getElementById('image1');
defaultimg.src = pictureImage;
var pictureImage = "images/unknown.png";
if({{messages.get.message}} == "Mewtwo"){
var imgobject = document.getElementById('image1');
imgobject.src = pictureImage;
pictureImage = "images/150.png";
}
if({{messages.get.message}} == "Charmeleon"){
var imgobject2 = document.getElementById('image1');
imgobject2.src = pictureImage;
pictureImage = "images/005.png";
}
if({{messages.get.message}} == "Warturtle"){
var imgobject3 = document.getElementById('image1');
imgobject3.src = pictureImage;
pictureImage = "images/008.png";
}
)}
to the following piece of html
<img id="image1" alt="Pokemon" width="88" height="75"> 
At the moment it only displays an empty box.
Can someone offer advice on whether this approach can be fixed to display the images? Thanks for the time and help.
that's probably a reference loop:
$(document).ready(function(){
var defaultimg = document.getElementById('image1');
// defaultimg now contains image1
// using jQuery and getElementbyId together is weired
defaultimg.src = pictureImage;
// pictureImage is not assigned, so the url is empty
// prob. cause for empty block?
var pictureImage = "images/unknown.png";
// ok, now we assign an url
if({{messages.get.message}} == "Mewtwo"){
// is that path correct?
var imgobject = document.getElementById('image1');
// copy of the empty image from above
imgobject.src = pictureImage;
// we assign an url
pictureImage = "images/150.png";
// new url on pictureImage, unused so far.
}
...
if none of the conditions like if({{messages.get.message}} == "Mewtwo"){
is true, it must show nothing due to defaultimg.src = pictureImage; with unassigned pictureImage variable.
You might want to state with which kind of template engine or the like you work, as "{{messages.get.message}}" wouldn't help you much in vanilla js (though it would be syntactically well formed)
Tip for debugging:
debugger;
in js code starts up the debugger in chrome/firefox(+firebug)/...
otherwise you can also use the console commands, e.g.
console.debug("if 1")
to find out what is happening
also have a look at console output in general, there should be no warnings or errors.
Next:
You're trying to use the probably global (because of missing "var" in front) variable "pictureImage" before you define it. Javascript is run from start to end, from left to right (let's just assume it's that way for easier understanding), top to bottom.
So you try to set the src of an image to something which is undefined at that point, and later on define that variable. There is no such thing as pointers to non-object types in javascript (which string constants are)
To fix your problem you'll probably have to swap some lines in your code, so the used variable gets set, and THEN is used, not the other way around.

How to give each element of a JavaScript array a different 'type'?

I have a JavaScript array which contains a number of images. The images have all been taken from a hidden section in my HTML using lines such as
sources[0] = document.getElementById("building").src
The reason I am getting the images from the HTML rather than directly from the source is because I want to display around 30 of them on an HTML5 canvas, and if I were to load them directly from source into the JavaScript code, the page would take ages to load, so I've 'preloaded' them in a hidden section of my HTML, and then loaded them into the JavaScript code from there.
So, I have created my JavaScript array with the following:
var sources = [];
sources[0] = document.getElementById("building").src,
sources[1] = document.getElementById("chair").src,
....
(There are roughly 30 lines for adding images to the sources array).
The idea is that there will be four or five different 'types' of image (that is, some will be assets, others will be liabilities, etc.), and the user will be required to drag each image to its corresponding description box (also displayed on the canvas).
So what I'd like to do, is put the images into different 'groups' within the one array. I've had a look into it, and my understanding is that the best way to do this is by using associative arrays, so, for example:
var sources = {
name1 : ["name1", "place1", "data1"],
name2 : ["name2", "place2", "data2"],
name3 : ["name3", "place3", "data3"]
};
But I'm not sure how to use this in the context of what I currently have... Would I do something like the following?
var sources = {
asset1 : document.getElementById("building").src,
asset2 : document.getElementById("chair").src,
liability1: document.getElementById("electricity").src,
...
};
How would I then check whether an image belongs to the description box it's been dragged to when the user drags it to the description box they think it belongs to?
The way I intend to check whether an image has been dragged to the correct description box, is to have a Boolean that will be set to "true" when a mousedown event is detected on one of the 'draggable' images, and keep track of the x & y coordinates of the cursor as it moves around the canvas.
Then, when the mouseup event is triggered, I will check what the coordinates of the cursor are at that point. If the cursor has dropped the image to a location at which one of the description boxes are drawn (so for example, x being between 50-100 and y between 150-200 is where the assets description box is, liabilities description box at x 150-200, y 150-200), then I will check which description box is at that location (loop through the array of description box locations, and check which one is at the location of the cursor, if any).
Once I have the name of the description box at that location, I will check to see what 'type' the image that has just been dropped was, and if it matches the box at the location at which it's been dropped, it will disappear from the canvas, if not, it will be drawn back where it was originally 'picked up' by the user.
What I'm not sure about with how to do this, is how do I access the 'type' of image that the user has clicked on from the array?
Edit 2013-03-13T14:15
So I've given the suggested answer a go. However, when I now view my page in the browser, the canvas is not displayed, and I get an "uncaught exception" error in the console. This error message says:
uncaught exception: [Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: file:///M:/year%205/major%20project/development/collision/kinetic.js :: :: line 4250" data: no]
I'm wondering if this is because of the functions I'm calling at the end of this function...? To explain things a bit further, I'm creating and using the sources array inside the window.onload function. It currently looks like this:
window.onload = function(){
var sources = {
assets: [],
liabilities: [],
income: [],
expenditure: []
}
console.log("the code reaches here");
sources.assets[0] = document.getElementById("building").src,
sources.assets[1] = document.getElementById("chair").src,
sources.assets[2] = document.getElementById("drink").src,
sources.assets[3] = document.getElementById("food").src,
sources.assets[4] = document.getElementById("fridge").src,
sources.assets[5] = document.getElementById("land").src,
sources.assets[6] = document.getElementById("money").src,
sources.assets[7] = document.getElementById("oven").src,
sources.assets[8] = document.getElementById("table").src,
sources.assets[9] = document.getElementById("van").src,
sources.liabilities[10] = document.getElementById("burger").src,
sources.liabilities[11] = document.getElementById("chips").src,
/* I have loads of lines like this, adding in roughly 30 images */
/*Maybe create an array of attributes within each position
of this array, so that I have access to all of each
element's attributes. */
/*Create an associative array for the images and their types*/
var imageTypes = new Array();
/*Use a loop to populate the associative array, declare variables for the total number
of items in each group, declare a variable for the item being for example: */
var numAssets = 10;
var numLiabilities = 5;
var numEx = 11;
var numInc = 8;
// Error checking- check total of these numbers adds up to the number elements in sources array.
var j = 0; // This is to indicate the location of the image in sources array
loadImages(sources, drawImage);
drawGameElements();
drawDescriptionBoxes();
//drawBox();
stage.add(imagesLayer);
};
Is the canvas now not showing because of one of the other functions I'm calling at the end of the window.onload function? But these function calls were performing correctly before I changed my sources array, so maybe it something wrong with what I've changed in the sources array?
I'd suggest restructuring your sources object to:
var sources = {
assets: [],
liabilities: []
};
sources.assets[0] = document.getElementById("building").src;
sources.assets[1] = document.getElementById("chair").src;
...
sources.liabilities[0] = document.getElementById("electricity").src;
...
The sources object is optional, you can just have the assets and liabilities arrays.
You can then use this answer:
How to determine if object is in array
to figure out the 'type' of the selected image.
Alternatively, you could add a class to the images depending on their 'type' and then check that when the user selects.

Categories

Resources