I have the below json object and i want to loop through it and display the value in a div.
My json object and the function to run it is below
photos = [{"photo1":"myimage1.jpg",
"photo2":"myimg2.jpg",
"photo3":"myimg3.jpg",
"photo4":"myimg4.jpg",}]
function showPhotoOnLoad(photos,$imgUrl){
var $photoData = photos;
var photoLength = Object.keys($photoData[0]).length;
var i, key;
var $containerWidth = 110;
//alert(photoLength);
if(photoLength >0){
$(".mycarousel-container").show();
for (i in $photoData) {
for (key in $photoData[i]) {
a = $photoData[i][key];
imgsrc = $imgUrl = $imgUrl+a;
var div = $("<div class='mycarousel' style='left:"+left+"px'></div>");
var imgPreview = "<img class='myimg' src="+imgsrc+">";
div = div.append(imgPreview);
$(".carouser-inner").append(div);
left = left+$containerWidth;
}
}
}
//console.log($imgUrl);
}
After i run this function i got 4 div created as expected but only the first child of the div has image shown and the other 3 has broken img, i try to debug and i see var a which is suppose to be the img name like myimg1.jpg and the result i got is
`a=myimg1.jpg` //at first iteration of the for loop which make the img display correctly,
`a=myimg1.jpgmyimg2.jpg` //at the second iteration
`a=myimg1.jpgmyimg2.jpgmyimg3.jpg` //at the third iteration
`a=myimg1.jpgmyimg2.jpgmyimg3.jpgmyimg4.jpg` //at the last iteration
What i want to get is like below so all div created will have the right link to the img
`a=myimg1.jpg` //at the first iteration
`a=myimg2.jpg` //at the second iteration
`a=myimg3.jpg` //at the third iteration
`a=myimg4.jpg //at the last iteration
Problem is with imgsrc = $imgUrl = $imgUrl + a;
Here is the working snippet
var photos = [{"photo1":"myimage1.jpg",
"photo2":"myimg2.jpg",
"photo3":"myimg3.jpg",
"photo4":"myimg4.jpg"}];
showPhotoOnLoad(photos,"imageurl");
function showPhotoOnLoad(photos,$imgUrl){
var $photoData = photos;
var photoLength = Object.keys($photoData[0]).length;
var i, key;
var $containerWidth = 110;
//alert(photoLength);
if(photoLength >0){
$(".mycarousel-container").show();
for (i in $photoData) {
for (key in $photoData[i]) {
a = $photoData[i][key];
imgsrc = "a="+a;
var div = $("<div class='mycarousel' style='left:20px'></div>");
var imgPreview = "<img class='myimg' src="+imgsrc+">";
div = div.append(imgPreview);
$(".carouser-inner").append(div);
console.log(imgsrc);
// left = left+$containerWidth;
}
}
}
//console.log($imgUrl);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am not sure what this line is doing. imgsrc = $imgUrl = $imgUrl + a; you can simply loop over your data like this given your array will have only one object. If it has more you need a for loop wrapping the current loop to get all the objects.
photos = [{"photo1":"myimage1.jpg",
"photo2":"myimg2.jpg",
"photo3":"myimg3.jpg",
"photo4":"myimg4.jpg",}];
function showPhotoOnLoad(photos,$imgUrl){
var $photoData = photos[0];
var $containerWidth = 110;
//alert(photoLength);
if($photoData.length >0){
$(".mycarousel-container").show();
for (var i in $photoData){
imgsrc = $photoData[i];
var div = $("<div class='mycarousel' style='left:"+left+"px'></div>");
var imgPreview = "<img class='myimg' src="+imgsrc+">";
div = div.append(imgPreview);
$(".carouser-inner").append(div);
left = left+$containerWidth;
}
}
}
//console.log($imgUrl);
}
Use Object.keys.length to get the length of the object.
Use for..in to get value of each key
var photos = [{
"photo1": "myimage1.jpg",
"photo2": "myimg2.jpg",
"photo3": "myimg3.jpg",
"photo4": "myimg4.jpg",
}]
var _div = ("<div class='mycarousel' style='left:2px'></div>");
var _divCache = "";
if (Object.keys(photos).length > 0) { // will check if the length is greater than 0
$(".mycarousel-container").show()
// loop through each of the key. 0 since photos is an array of object
for (var keys in photos[0]) {
//photos[0][keys] will return values
var imgPreview = $("<img class='myimg' alt='img' src='" + photos[0][keys] + "'>");
$(".carouser-inner").append($(_div).append((imgPreview)[0]));
}
}
JSFIDDLE
Enjoy ONE-LINE code that replaces almost All your code:
$(photos.map((item)=>
Object.keys(item).map((key)=>
`<div class='mycarousel' style='left:${left}px'>
<img src="${item[key]}" class="myimg" />
</div>`
).join('')
).join('')).appendTo('.carouser-inner')
Known that : $(A).append(B) is the same of $(B).appendTo(A)
DEMO
Related
Im new to programming and trying to make a memory game. First I created 5 different flags in CSS that I would like to "play" with in my game. However
I'm very stuck and have no Ideas how to proceed.
I know that I need some sort of function only allows two flags to be "clicked" at the same time and then another function that check if those two flags matches each other.
Any ideas how I could do that, and again very new to this.
(function() {
'use strict';
var flagTarget1 = document.getElementById('flag1');
var flagTarget2 = document.getElementById('flag2');
var i;
var j;
//function that can shuffle the array
Array.prototype.shuffle = function() {
var input = this;
for (var i = input.length - 1; i >= 0; i--) {
var randomIndex = Math.floor(Math.random() * (i + 1));
var itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
return input;
}
var swedishFlag = '<div class="flag sweden"><div class="vertikal"></div><div class="horisontell"></div></div>';
//var swedishFlag = '<div class="ruta"></div>';
var japanFlag = '<div class="flag japan"><div class="part2"></div></div>';
//var japanFlag = '<div class="ruta"></div>';
var litauenFlag = '<div class="flag litauen"><div class="part1"></div><div class="part2"></div></div>';
//var litauenFlag = '<div class="ruta"></div>';
var elfenbenskustenFlag = '<div class="flag elfenbenskusten"><div class="part1"></div><div class="part2"></div></div>';
//var elfenbenskustenFlag = '<div class="ruta"></div>';
var tysklandFlag = '<div class="flag tyskland"><div class="part1"></div><div class="part2"></div></div>';
//var tysklandFlag = '<div class="ruta"></div>';
var swedishFlag2 = '<div class="flag sweden"><div class="vertikal"></div><div class="horisontell"></div></div>';
//var swedishFlag2 = '<div class="ruta"></div>';
var japanFlag2 = '<div class="flag japan"><div class="part2"></div></div>';
//var japanFlag2 = '<div class="ruta"></div>';
var litauenFlag2 = '<div class="flag litauen"><div class="part1"></div><div class="part2"></div></div>';
//var litauenFlag2 = '<div class="ruta"></div>';
var elfenbenskustenFlag2 = '<div class="flag elfenbenskusten"><div class="part1"></div><div class="part2"></div></div>';
//var elfenbenskustenFlag2 = '<div class="ruta"></div>';
var tysklandFlag2 = '<div class="flag tyskland"><div class="part1"></div><div class="part2"></div></div>';
//var tysklandFlag2 = '<div class="ruta"></div>';
//list with classes
var class1 = ['sweden', 'litauen', 'japan', 'tyskland', 'elfenbenskusten', 'sweden', 'litauen', 'japan', 'tyskland', 'elfenbenskusten']
// List with flags
var flaglist = [swedishFlag, japanFlag, litauenFlag, elfenbenskustenFlag, tysklandFlag, swedishFlag2, japanFlag2, litauenFlag2, elfenbenskustenFlag2, tysklandFlag2];
//shuffles the flaglist
flaglist.shuffle();
class1.shuffle();
//for (var i = 0; i < flaglist.length; i++) {
for (var i = 0; i < 10; i++) {
//document.body.appendChild(flaglist[i]);
if (i < 5) {
//flagTarget1.innerHTML += flaglist[i];
flagTarget1.innerHTML += '<div class="ruta"></div>';
//console.log('ritar ' + flaglist[i]);
} else {
//flagTarget2.innerHTML += flaglist[i];
flagTarget2.innerHTML += '<div class="ruta"></div>';
}
}
var flags = document.getElementsByClassName('ruta');
//loop who adds their own ID to every flag-div.
for (i = 0; i < flags.length; i++) {
flags[i].setAttribute('id', 'flagga' + (i));
}
//loop who changes style.top on the first row of flags och spreads them out
for (i = 0, j = 145; i < 5; i++, j += 200) {
var temp = document.getElementById('flagga' + i);
temp.style.left = j + 'px';
temp.style.top = "50px";
}
//loop who changes style.top on the second row of flags och spreads them out
for (i = 5, j = 145; i <= 9; i++, j += 200) {
var temp = document.getElementById('flagga' + i);
//console.log(temp);
temp.style.left = j + 'px';
temp.style.top = '210px';
}
var boxes = document.getElementsByClassName('ruta');
//console.log('class name boxes ' + boxes[2]);
// the array to hold clicked flag
var flagQueue = [];
function pickFlag(event) { //the event argument gets passed by default
// event.target signifies the target of the event fired
flagQueue.push(event.target.firstChild.className); // push the class string to array
console.log(flagQueue);
if (flagQueue.length == 2) { // if it has 2 elements,
if (flagQueue[0] == flagQueue[1]) { // compare them
console.log('Grattis, du hittade ett matchande par.');
} else {
console.log('Inget matchande par. Försök igen');
}
// whatever happens, reset the flagQueue array
flagQueue.length = 0;
}
}
//loop who adds event for boxes
for (i = 0; i < boxes.length; i++) {
boxes[i].addEventListener('click', function() {
temp = document.getElementById(this.id);
//console.log(temp);
switch (this.id) {
case 'flagga0':
temp.innerHTML = flaglist[0];
break;
case 'flagga1':
temp.innerHTML = flaglist[1];
break;
case 'flagga2':
temp.innerHTML = flaglist[2];
break;
case 'flagga3':
temp.innerHTML = flaglist[3];
break;
case 'flagga4':
temp.innerHTML = flaglist[4];
break;
case 'flagga5':
temp.innerHTML = flaglist[5];
break;
case 'flagga6':
temp.innerHTML = flaglist[6];
break;
case 'flagga7':
temp.innerHTML = flaglist[7];
break;
case 'flagga8':
temp.innerHTML = flaglist[8];
break;
case 'flagga9':
temp.innerHTML = flaglist[9];
break;
default:
}
//console.log('flaggnr ' + this.id);
//console.log(temp);
})
boxes[i].addEventListener('click', pickFlag);
}
})();
Okay, so I used the answer I got here and made it partially work. When I get two of the same it writes out a "congratulation". However I need help to get the cards/tiles to turn back around if they don't match and stay if they match.
Any help would be appreciated.
Edit:
I'm appreciate the help but I need couple of more things before everything works smoothly.
The program thinks that flagQueue[0].className are the same as flagQueue[1].className even though it shouldn't be. I wrote a console.log(flagQueue) to check why and got this
[div#flagga0.ruta.hidden, div#flagga5.ruta.hidden]
Congratulations it's a pair (even though it isn't)
The first thing I do in pickFlag() is to make the flag "hidden", altough it's the first flags thats been pressed. Which If I'm not mistaken makes all the flags I pick "hidden"? Is it possible to compare the hidden flag with the original state of the flag (before the flag have been clicked?)
fiddle: https://jsfiddle.net/b05sdy9o/
Thanks again!
Welcome to Stackoverflow!
Please do consider internationalizing your code. Using variable names formed from English words, as well as using comments in English is helpful for people who try to help you.
I'd go with creating an array to hold the clicked flags.
After you add a flag to it, check if it has 2 elements now.
If it does, compare. If it doesn't, wait for next click.
// the array to hold clicked flag
var flagQueue = [];
function pickFlag(event){ //the event argument gets passed by default
// event.target signifies the target of the event fired
flagQueue.push(event.target.className); // push the class string to array
if(flagQueue.length==2){ // if it has 2 elements,
if(flagQueue[0]==flagQueue[1]){ // compare them
alert('Congratulations');
}
else {
alert('Try again');
}
// whatever happens, reset the flagQueue array
flagQueue.length = 0;
}
}
// Now we select all HTML elements with class flag
var flags = document.querySelectorAll('.flag');
// And we add an eventListener to each of them.
for(var i=0; i<flags.length; i++){
flags[i].addEventListener('click',pickFlag);
}
EDIT
I have made a JSFiddle for you. The css is basic, just so you can see how the script works. If you click 2 of the same flags, you get 'Congratulations'. If you click 2 different flags, you get 'Try again'.
Please note, that JSFiddle runs the JS code after it creates the page itself. So if you wnt to replicate my code in a browser, make sure that the <script> with my JS code is placed right before the </body>, so it starts running after all the elements on the page have been created.
If you want to create the flags in Javascript, use the following snippet should come in handy:
// create array to keep the html elements
var flagElements = [];
// put country names into an array
var countries = ['usa','japan','sweden','finland'];
// create new elements for each of the country names
for(var i=0;i<countries.length;i++){
// first create a div element for the flag
var flag1 = document.createElement('div');
// set the class to 'flag <country>'
flag.className = 'flag '+countries[i];
//push it to the array
flagElements.push(flag1);
//then create a second flag, I will just use the same code
var flag2 = document.createElement('div');
flag2.className = 'flag '+countries[i];
flagElements.push(flag2);
}
// Now you have an array holding all of the divs for you.
// All you need to do is shuffle them and append to DOM.
// You can find info about shuffling on stackoverlow, just implement something
myShufflingAlogirthm(flagElements);
// to append the elements just loop over them and append to body
for(var i=0;i<flagElements.length;i++){
document.body.appendChild(flagElements[i]);
}
Also note, that you can edit your own post to include new informatin or clarify questions your answerers have. You can also add comments to other people's answers. Refer to stackoverflow help pages for more info on how to use the website, inluding asking, answering, reputation and more.
An example of shuffling algortihm
EDIT 2
Check out this fiddle for some ideas on how to implement flags going back to being hidden or leaving them up. I added a css class hidden and I just toggle it. I believe that this kind of thing should be solved by css, not by complicated code.
Also notice, that I changed the eventListener a bit - now it pushes the HTML Element into array, instead of just the className.
I'm trying to use JavaScript to list images 01-40 in order automatically.
Like this:
<img src="01.jpg" />
<img src="02.jpg" />
<img src="03.jpg" />
<img src="04.jpg" />
<img src="05.jpg" />
...
I don't want to write each img src manually, as I want to use this on multiple pages
I'd like the image starting and ending number to be variables that I can edit easily.
You need the parent element for imgs:
for ( var i = FIRST_NUMBER ; i < LAST_NUMBER ; i++ ) {
var elem = document.createElement("img");
if ( i < 10 ) {
elem.setAttribute("src", "0"+i+".jpg");
} else {
elem.setAttribute("src", i+".jpg");
}
document.getElementById(PARENT_ID).appendChild(elem);
}
function img_create(startIndex, endIndex) {
for (i = startIndex; i <= endIndex; i++) {
var oImg=document.createElement("img");
oImg.setAttribute('src', i+".jpg");
//other attributes you need
document.body.appendChild(oImg);
}
}
Working example: http://jsfiddle.net/Lw3bjcx4/1/
function createImages(count, elementId) {
// Get the container element where you want to create the images
var element = document.getElementById(elementId)
// Loop count times over to create count image elements
for (var i = 0 ; i < count ; i++) {
// Create a new image element
var imageElement = document.createElement('img')
// Set the source to index.jpg where index is 0,1,2,3.... count
imageElement.setAttribute('src', i + ".jpg")
// Append the new image element to the choosen container.
element.appendChild(imageElement)
}
}
// Test to create 10 images.
createImages(10,"imgs")
You can use like this:
var imgdiv = document.getElementById('imgdiv');
var img = imgdiv.getElementsByTagName('img');
for(var i=0;i<40;i++){
img[i].src=i+'.jpg';
}
Here is an alternative to all other answers, where you don't need to use an id to put images in. Just paste the script tag where you need to have the images. For example, if you put it in a div, the script will automatically insert the images in place.
<script type="text/javascript">
var thisScriptNode = document.currentScript;
for(var i = 1 ; i <= 40 ; i++) {
var img = document.createElement("img");
img.src = ("00" + i).substr(-2) + ".jpg";
thisScriptNode.parentNode.insertBefore(img, thisScriptNode);
}
</script>
You can easily change the number of leading zeros. For example, to get numbers with three characters, replace "00" with "000" and -2 with -3.
var to = 10;
var from = 0;
for (i = from; i < to; i++){
var elem = new Element('img', { src: i + '.jpg' });
document.body.appendChild(elem);
}
it will append to <body> images with names from 0.jpg to 9.jpg
<div id = "board>
<div>{abc</div>
<div>def</div>
<div>ghi}</div>
</div>
I've already done this by span-wrapping all of the char first before comparing if it is { or }. But that is too slow, i need to reverse the procedure, is it possible to get the char position relative to the parent div?
Intended Output is
<div id = "board>
<div><span>{</span>abc</div>
<div>def</div>
<div>ghi<span>}</span></div>
</div>
how about using contains() and replace()?
You want to use Regular Expressions:
var x = '<div id = "board>' +
'<div>{abc</div>' +
'<div>def</div>' +
'<div>ghi}</div>' +
'</div>'; // or... get element by id 'board'
var rgx1 = /{/;
var rgx2 = /}/;
var y = x.replace(rgx1, "<span>{</span>");
y = y.replace(rgx2, "<span>}</span>");
if you think you have more than 1 occurrence of { or }, you can add "g" to the regex's:
var rgx1 = /{/g;
var rgx2 = /}/g;
Assuming this is the markup:
<div id="board">
<div>{abc</div>
<div>def</div>
<div>ghi}<div>
</div>
And your intended output is:
<div id="board">
<span>abcdefghi</span>
</div>
You can do this using jQuery/javascript like this:
var textNodes = $("#board").find("div");
var text = "";
for(var i=0;i<textNodes.length;i++) {
text = text + textNodes[i].text();
$("#board").remove(textNodes[i]);
}
var spans = text.split("}");
var textToAppend = "";
for(i=0;i<spans.length - 1 ;i++)
textToAppend = textToAppend + "<span>"+spans[i].split("{")[1]+"</span>";
$("#board").append(textToAppend);
Is this the solution you are looking for?
Edit 1:
If you need just the position of lets say b as 2, and d as 4?
Here is the code.
var textNodes = $("#board").find("div");
var text = "";
for(var i=0;i<textNodes.length;i++) {
text = text + textNodes[i].text();
}
var codeBlocks = text.split("}");
var firstBlock = codeBlocks[0];
var getCharPosInBlock = function (character) {
if(character === "}") return firstBlock.length;
return firstBlock.indexOf(character);
}
To get the required result using javascript looping:
var textNodes = $("#board").find("div");
for(var i=0;i<textNodes.length;i++) {
var value = textNodes[i].text()
if(value.indexOf("{") > 0)
textNodes[i].text(value.replace("{", "<span>{</span>"));
if(value.indexOf("}") > 0)
textNodes[i].text(value.replace("{", "<span>}</span>"));
}
I have this code that sends the values a user have typed in... the information and numbers are sent as an array and pushed into another array, I then display the text in a dynamically created list element and number in a span element...
var button = $('#add');
button.click(function()
{
var filmnamn = $('#name');
var filmnamnet = filmnamn.val();
var betyg = $('#star');
var betyget = betyg.val();
betyget = Number(betyget);
if(filmnamnet == 0)
{
$('#name').css('background-color', 'red');
}
if(betyget == 0)
{
$('#star').css('background-color', 'red');
}
if(betyget == 0 || filmnamnet == 0)
{
alert("Vänligen fyll i fälten korrekt");
}
else
{
var array = new Array();
array.unshift(betyget);
array.unshift(filmnamnet);
film_array.unshift(array);
betyg_array.unshift(array);
updateFilmList();
}
});
var film_list = $("#filmlista");
var film_array = new Array();
function updateFilmList()
{
document.getElementById("name").value = '';
document.getElementById("star").value = 0;
var filmen = film_array[0][0];
var grade = film_array[0][1];
var element = '<li class="lista">' + filmen + '<span class="betyg">'+ grade +'</span></li>';
film_list.append(element);
changeNumber();
}
And at last I have the function that i want to change the number in the span element to the amount of stars that the number shows... this works fine but only for the first created list and span element, when I try to add more listelements the number wont show up as stars, can someone tell me why this happens and point me in the direction to fix the problem?
function changeNumber(){
var elements= document.getElementsByClassName("betyg");
for (var i=0; i<elements.length; i++) {
var element = elements[i];
var length = parseInt(element.innerHTML);
var x=Array(length+1).join("*");
element.innerHTML=x;
}
}
for(var i=0; i<myJSONObject.model.length; i++){
var create_div = document.createElement('div');
create_div.id = 'model_id'+i;
create_div.innerHTML = myJSONObject.model[i].model_name;
var assign_innerHTML = create_div.innerHTML;
var create_anchor = document.createElement('a');
document.getElementById('models').appendChild(create_div);
document.getElementById(create_div.id).appendChild(create_anchor);
}
for ex the myJSONObject.model.length is 2
the output is like this
<div id = 'model_id0'>XXXXX<a> </a></div>
<div id = 'model_id1'>XXXXX<a> </a></div> */
but instead of above the output sholud be like this
<div id = model_id0> <a> xxxxxx</a></div>
<div id = model_id1> <a> xxxxxx</a></div>
how to append it inside of the innerhtml
any one plz reply !!!!
two suggestions:
1.) instead of assigning innerHTML to model_idx div assign the model name to its child a. and 2nd instead of appending it to DOM in every loop do it after completing the loop as to minimize frequent the DOM Update ie by:
objContainer = document.createElement('div');
for(....)
{
var create_div = document.createElement('div');
create_div.id = 'model_id'+i;
var create_anchor = document.createElement('a');
create_anchor.innerHTML = myJSONObject.model[i].model_name;
create_div.appendChild(create_anchor);
objContainer.appendChild(create_div);
}
document.getElementById('models').appendChild(objContainer);
I would go along the lines of:
var i = 0,
m = myJSONObject.model,
l = m.length,
models = document.getElementById("models");
for(; i < j; i++) {
var model = m[i];
var create_div = document.createElement("div");
create_div.id = "model_id" + i;
create_div.innerHTML = "<a>" + model.model_name + "</a>";
models.appendChild(create_div);
}
Unless you specifically need to do something to the anchor itself (other than set its innerHTML), there's no need to create a reference to an element for it. If you do need to do something specific to that anchor, then in that case have this, instead:
EDIT: As per your comment, you DO want to do something to the anchor, so go with this (now updated) option - assuming the anchor will always be a child of the div that has the ID you require. The reason "model_id" + i is being put in as a string is because that is exactly what is being passed into the HTML - the document has no clue what "i" is outside of javascript:
var i = 0,
m = myJSONObject.model,
l = m.length,
models = document.getElementById("models");
for(; i < j; i++) {
var model = m[i];
var create_div = document.createElement("div");
var create_anchor = document.createElement("a");
create_div.id = "model_id" + i;
create_anchor.innerHTML = model.model_name;
if(window.addEventListener) {
create_anchor.addEventListener("click", function() {
getModelData(1, this.parentNode.id);
}, false);
} else {
create_anchor.attachEvent("onclick", function() {
getModelData(1, this.parentNode.id);
});
}
create_div.appendChild(create_anchor);
models.appendChild(create_div);
}