Justin Besteman
Justin Besteman

Reputation: 398

JavaScript, Trying to get buttons to move on click

/*
var young_link = {
    power: 30,
    cpower: 20,
    hp: 3,
    image: "../images/young_link.jpg",
};


var young_zelda = {
    power: 30,
    cpower: 20,
    hp: 3,
}


var impa = {
    power: 30,
    cpower: 20,
    hp: 3,
}


var hey = {
    power: 30,
    cpower: 20,
    hp: 3,
}

//$("#test").html(young_link);

console.log(young_link);*/


$(document).ready(function() {

    var hero_image = new Array();
    hero_image[0] = new Image();
    hero_image[0].src = 'assets/images/link.png';
    hero_image[0].id = 'image';

    hero_image[1] = new Image();
    hero_image[1].src = 'assets/images/bongo.png';
    hero_image[1].id = 'image';

    hero_image[2] = new Image();
    hero_image[2].src = 'assets/images/gandondorf.jpg';
    hero_image[2].id = 'image';

    hero_image[3] = new Image();
    hero_image[3].src = 'assets/images/queen.png';
    hero_image[3].id = 'image';


    //var test = "<img src= '../images/young_link.jpg'>";

    //var young_hero = ["young_link","young_zelda","impa", "malon"];
    var young_hero = ["Link", "Bongo Bongo","Gandondorf","Queen Gohma"];
    var health = [100, 70, 120, 50];


    for (var i = 0; i < young_hero.length; i++) {
        var hero_btns = $("<buttons>");

        hero_btns.addClass("hero hero_button");

        hero_btns.attr({"data-name":young_hero[i],"data-health":health[i],"data-image":hero_image[i]});


        hero_btns.text(young_hero[i]);
        hero_btns.append(hero_image[i]);
        hero_btns.append(health[i]);

        $("#buttons").append(hero_btns);
    }   




$(".hero_button").on("click" , function() {

    var battle_ground = $("<div>");

    battle_ground.addClass("hero hero_button");

    battle_ground.text($(this).data("data-name"));

    $("#battle").append(battle_ground);

});

});

The for loop is working and appending the buttons on the screen. But in $(".hero_button").on("click" , function() it is just putting a empty box on the page with a click. So, it is not taking the data that is attached to the button.

Upvotes: 0

Views: 84

Answers (2)

Matt
Matt

Reputation: 4117

Sam answered your question correctly and rightly deserves the accepted answer. But I wanted to give you an insight into how you can do this in a cleaner way, without lots of arrays which must line up. Also without using jQuery at all. Below you can see a more object oriented way to do this.

You can see it in action in this jsFiddle

// Now we have an object which represents a hero. No need to duplicate loads of code.
function Hero(heroData) {
    this.name = heroData.name;
  this.health = heroData.health;

  this.setImage = function() {
    this.image = new Image();
    this.image.src = heroData.imageSrc;
    this.image.id = heroData.imageId;
  }

  this.createHeroButton = function() {
    this.createButtonElement();
    this.addButtonToPage();
    this.attachButtonEvents();
  }

  this.createButtonElement = function() {
    var heroButton = document.createElement('button');
    heroButton.classList.add('hero,hero_button');
    heroButton.setAttribute('name', this.name);
    heroButton.setAttribute('health', this.health);
    heroButton.appendChild(this.image);
    this.button = heroButton;
  }

  this.attachButtonEvents = function() {
    this.button.addEventListener('click', this.addButtonToPage.bind(this));
  }

  this.addButtonToPage = function() {
    var container = document.getElementById('container');
    container.appendChild(this.button);
  }

  this.takeDamage = function(damageValue) {
    this.health -= damageValue;
    this.button.setAttribute('health', this.health);
  }

  this.setImage();
}

// So here we create a Hero instance, in this case Link, we can use now describe links attributes, image, name, health...
var link = new Hero({
    name: 'Link',
  health: 100,
  imageSrc: 'http://orig12.deviantart.net/8bb7/f/2011/276/4/e/four_swords_link_avatar_by_the_missinglink-d4bq8qn.png',
  imageId: 'link-image'
});

var mario = new Hero({
    name: 'Mario',
  health: 100,
  imageSrc: 'http://rs568.pbsrc.com/albums/ss123/stvan000/thumb-super-mario-bros-8bit-Mario.jpg~c200',
  imageId: 'mario-image'
});

// Now we can easily make a button and add it to the page
link.createHeroButton();
mario.createHeroButton();

// Lets try decreasing the health on mario
mario.takeDamage(10);
// Because we have an object reference which handles all of our heros state we can decrease his health and update the buttons data without much trouble.

Upvotes: 2

Sᴀᴍ Onᴇᴌᴀ
Sᴀᴍ Onᴇᴌᴀ

Reputation: 8297

A couple of changes to get the data set and read correctly:

  1. make button tags instead of buttons
  2. use .attr() instead of .data() to get the attributes

See comments inline in the code below.

Also, instead of adding an attribute for the Image object of each item (which will add an attribute like data-image="[Object object]") just add an integer corresponding to the iterator index and use that to reference into the hero_image array when you need to get the corresponding image.

Additionally, you can use Array.forEach() to iterate over the items in the heroes array with a callback function. That way you don't have to worry about updating the iterator variable (i in this case) and indexing into the array. You should take a look at this functional programming guide which has some good exercises.

$(document).ready(function() {

  var hero_image = new Array();
  hero_image[0] = new Image();
  hero_image[0].src = 'assets/images/link.png';
  hero_image[0].id = 'image';

  hero_image[1] = new Image();
  hero_image[1].src = 'assets/images/bongo.png';
  hero_image[1].id = 'image';

  hero_image[2] = new Image();
  hero_image[2].src = 'assets/images/gandondorf.jpg';
  hero_image[2].id = 'image';

  hero_image[3] = new Image();
  hero_image[3].src = 'assets/images/queen.png';
  hero_image[3].id = 'image';

  var young_heroes = ["Link", "Bongo Bongo", "Gandondorf", "Queen Gohma"];
  var health = [100, 70, 120, 50];
  young_heroes.forEach(function(young_hero,i) {
    var hero_btns = $("<button>");
    hero_btns.addClass("hero hero_button");
    hero_btns.attr({
      "data-name": young_hero,
      "data-health": health[i],
      //instead of adding an attribute for the image object, just add an index
      "data-index": i
    });


    hero_btns.text(young_hero);
    hero_btns.append(hero_image[i]);
    hero_btns.append(health[i]);

    $("#buttons").append(hero_btns);
  });

  $(".hero_button").on("click", function() {
    var battle_ground = $("<div>");
    battle_ground.addClass("hero hero_button");
    //use .attr() here instead of .data()
    battle_ground.text($(this).attr("data-name"));

    /** My additions  - 
     * I am not sure exactly how this should be done  
     * so adjust accordingly 
     **/
    //additionally, you can add attributes to the new battle_ground item
    battle_ground.attr('data-health',$(this).attr("data-health"));

    battle_ground.append(hero_image[$(this).attr("data-index")]);
    battle_ground.append($(this).attr("data-health"));
    /** End my additions **/

    $("#battle").append(battle_ground);
  });
});
#battle div {
  border: 1px solid #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="buttons"></div>
Battle ground:
<div id="battle"></div>

Upvotes: 1

Related Questions