Reputation: 35
I need help with a school project. I have a catClicker app that displays an image of a cat and the number of times the image has been clicked.
Now I have to display the names of five different cats. When a cat's name is clicked, I have to update the image and counter for that cat.
This is what I've done so far:
https://github.com/silvodesigns/catClicker
Upvotes: 0
Views: 1059
Reputation: 12239
The problem you're facing is that when an HTML list item is clicked, the click handler has to figure out which logical cat object it should update.
Here is a simple solution: when you make the list item, add a property that refers to the cat object.
Like this:
var listItem = $('<li>').html(cat.name);
$('#catList').append(listItem);
listItem = listItem[0]; // Extract the DOM element from the jQuery object.
listItem.cat = cat; // Add a reference to the logical cat object.
listItem.onclick = function () {
var cat = this.cat; // When the list item is clicked, get the cat object.
cat.clickCount++; // Increment the counter and update the display.
$('#displayClickedCat').html(
'<p id="counter">' + cat.name + ' has ' + cat.clickCount +
' click' + (cat.clickCount == 1 ? '' : 's') +
'.</p>' + '<img src="' + cat.src + '" class="cat" />');
};
The snippet below demonstrates this approach.
var imageDirectory =
'https://raw.githubusercontent.com/silvodesigns/catClicker/master/img/';
var model = {
startCat: 0,
cats: [
{ name: 'Tabby', src: imageDirectory + 'Cat01.jpg' },
{ name: 'Scaredy', src: imageDirectory + 'Cat02.jpg' },
{ name: 'Sleepy', src: imageDirectory + 'Cat03.jpg' },
{ name: 'Shadow', src: imageDirectory + 'Cat04.jpg' },
{ name: 'Tiger', src: imageDirectory + 'Cat05.jpg' }
]
};
$(document).ready(function () {
var cats = model.cats;
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
cat.clickCount = 0;
var listItem = $('<li>').html(cat.name);
$('#catList').append(listItem);
listItem = listItem[0]; // Extract the DOM element from the jQuery object.
listItem.cat = cat; // Add a reference to the logical cat object.
listItem.onclick = function () {
var cat = this.cat; // When the list item is clicked, get the cat object.
cat.clickCount++; // Increment the counter and update the display.
$('#displayClickedCat').html(
'<p id="counter">' + cat.name + ' has ' + cat.clickCount +
' click' + (cat.clickCount == 1 ? '' : 's') +
'.</p>' + '<img src="' + cat.src + '" class="cat" />');
};
if (i == model.startCat) {
cat.clickCount = -1;
listItem.onclick();
}
}
});
body {
font-family: sans-serif;
padding-left: 10px;
font-size: 18px;
}
img {
}
#catList {
list-style: none;
padding: 0;
}
#catList li {
display: inline;
margin: 5px 10px 5px 0;
padding: 5px 12px;
border: 1px solid #bbb;
border-radius: 5px;
cursor: pointer;
}
#catList li:hover {
border-color: #888;
background: #f4f4f4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="displayNames">
<ul id="catList"></ul>
</div>
<div id="displayClickedCat"></div>
Upvotes: 0
Reputation: 143
There is many solution to do the same. Here is the solution from my side. Your previous code for appending the name is:
for(var i=0; i< catNames.length; i++){
$('#cats').append('<li>'+ catNames[i].name +'</li>');// loop over the names of the cats and create and append it to the ul on Index.html
}
I make a little change. Used data attribute to stored the index for each name (li)
for(var i=0; i< catNames.length; i++){
$('#cats').append('<li data-index="'+i+'" class="names">'+ catNames[i].name +'</li>');// loop over the names of the cats and create and append it to the ul on Index.html
}
and your onclick target is different as previous:
$('.cat').click(function(){// whenever the picture with class .cat is clicked the counter goes up
catNames[model.currentCat].clickCount ++;
var counter = document.getElementById("counter");
counter.innerHTML = catNames[model.currentCat].clickCount;
}
The update version for the click event is like this: ** i used names as class for each li
$('.names').click(function(){
// whenever the picture with class .cat is clicked the counter goes up
var index=parseInt($(this).data("index"));
var image=catNames[index].imgSrc;
//This line count individual click for each
catNames[index].clickCount= catNames[index].clickCount+1
catNames[model.currentCat].clickCount ++;
var counter = document.getElementById("counter");
counter.innerHTML = catNames[model.currentCat].clickCount;
$('.cat').attr('src',image);
}
Upvotes: 0
Reputation: 5186
Change your cats object like this
var cats = {'Tabby' : {'count' : 0, 'src' : 'img/Cat01.jpg'}, 'Tiger' : {'count' : 0, 'src' : 'img/Cat02.jpg'}};
Explanation : We are keeping the cat name as the key to the individual cat properties so we can fetch them using the cat name on click.
For your event handler
$("ul#cats>li").on("click", function(){
var name = $(this).html();
var src = cats[name].src;
$('img.cat').attr('src',src);
cats[name].count = cats[name].count + 1;
});
Explanation :
Jquery is being used as i can see you are using jquery.js.
We fetch the name using html property.
We then pass it as the key to cats object to get the property such as name and count.
Note: I have added only two cats , add more if you have them :D
Upvotes: 2
Reputation: 495
Register a click event handler on the image container (use event delegation).
On each click increment the counter, in that way you can maintain the number of clicks.
On click of name, do the same. Register a click event handler and on click get the image name from the event.target and then change the main image as per it.
Upvotes: 0