8
\$\begingroup\$

I'm training my coding and wish you guys to see how my code is. I made a cat clicker based on the MVC pattern.

Basically it shows a list of cats and when you click a cat name it shows an image, and if you click the cat image it increments the number of clicks you made in the image and shows it. By the image there is an admin button, wheren you can edit the information of the cat; for this demo only the name is editable.

How does it look?

/* ======= Model ======= */
var model = {
 currentCat: null,
 adminMode: false,
 cats: [
 {
 clickCount : 0,
 name : 'Tabby',
 imgSrc : 'img/22252709_010df3379e_z.jpg',
 },
 {
 clickCount : 0,
 name : 'Donny',
 imgSrc : 'img/434164568_fea0ad4013_z.jpg',
 },
 {
 clickCount : 0,
 name : 'Sean',
 imgSrc : 'img/1413379559_412a540d29_z.jpg',
 },
 {
 clickCount : 0,
 name : 'Monica',
 imgSrc : 'img/4154543904_6e2428c421_z.jpg',
 },
 {
 clickCount : 0,
 name : 'Santos',
 imgSrc : 'img/9648464288_2516b35537_z.jpg',
 }
 ]
};
/* ======= Octupus ======= */
var octopus = {
 init: function(){
 model.currentCat = model.cats[0];
 viewList.init();
 viewDetailsList.init();
 adminMode.init();
 },
 getCats: function(){
 return model.cats;
 },
 setCat: function(cat){
 model.currentCat = cat;
 viewDetailsList.render();
 },
 catClicks: function(){
 model.currentCat.clickCount++;
 viewDetailsList.render();
 },
 getCurrentCat: function(){
 return model.currentCat;
 },
 setAdminMode: function(isSet){
 model.adminMode = isSet;
 adminMode.render();
 },
 getAdminMode: function(){
 return model.adminMode;
 }
}
/* ======= View List ======= */
var viewList = {
 init: function(){
 this.catList = document.getElementById("cat-list");
 this.render();
 },
 render: function(){
 var cats = octopus.getCats();
 for(var i = 0; i < cats.length; i++){
 var elemLi = document.createElement("li");
 var name = cats[i].name;
 var cat = cats[i];
 this.catList.appendChild(elemLi);
 elemLi.innerHTML = name; 
 elemLi.addEventListener('click', (function(catCopy){
 return function(){
 model.currentCat = catCopy;
 viewDetailsList.render();
 octopus.setAdminMode(false);
 adminMode.render();
 }
 })(cat))
 }
 }
}
/* ======= View List Details ======= */
var viewDetailsList = {
 init: function(){
 this.catName = document.getElementById("cat-name");
 this.catClicks = document.getElementById("cat-count");
 this.catImg = document.getElementById("cat-img");
 this.catImg.addEventListener("click", function(){
 octopus.catClicks(); 
 })
 this.render();
 },
 render: function(){
 var cat = octopus.getCurrentCat();
 this.catName.innerHTML=cat.name;
 this.catClicks.innerHTML=cat.clickCount;
 this.catImg.src= cat.imgSrc;
 }
}
/* ======= View Admin Mode ======= */
var adminMode = {
 init: function(){
 this.isActive = octopus.getAdminMode();
 this.submit =document.getElementById('admin');
 this.submit.addEventListener("click", function(){
 this.cat = octopus.getCurrentCat();
 /*
 create a ID and than give a value to input field
 */
 var adminArea = document.getElementById("admin-area");
 /*I could create a for loop based os the properties that i have 
 in the cats objects and than create the input fields..., 
 but instead i just made this way*/
 //submit button
 var nameSubmit = document.createElement('input');
 nameSubmit.setAttribute('type','button');
 nameSubmit.setAttribute('id','save');
 nameSubmit.setAttribute('value','guardar');
 //cancel button
 var nameCancel = document.createElement('input');
 nameCancel.setAttribute('type','button');
 nameCancel.setAttribute('id','cancel');
 nameCancel.setAttribute('value','cancelar');
 nameSubmit.value="guardar";
 //cat name
 var nameInput = document.createElement('input');
 nameInput.id="catName";
 nameInput.value=this.cat.name;
 //cat count
 var countInput = document.createElement('input');
 countInput.id="catCount";
 countInput.value=this.cat.clickCount;
 //cat url
 var urlInput = document.createElement('input');
 urlInput.id="catUrl";
 urlInput.value=this.cat.imgSrc;
 if (!octopus.getAdminMode()) {
 octopus.setAdminMode(true);
 //Apend inputs to List Admin Mode
 adminArea.appendChild(nameInput);
 adminArea.appendChild(countInput);
 adminArea.appendChild(urlInput);
 adminArea.appendChild(nameSubmit);
 adminArea.appendChild(nameCancel);
 //this.save();
 nameSubmit.addEventListener('click', function(){
 var cat = octopus.getCurrentCat();
 cat.name = nameInput.value;
 });
 }
 })
 this.render();
 },
 render: function(){
 document.getElementById("admin-area").innerHTML = "";
 }
}
octopus.init();
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Cat Clicker</title>
</head>
<body>
 <ul id="cat-list"></ul>
 <div id="cat">
 <h2 id="cat-name"></h2>
 <div id="cat-count"></div>
 <img height="250px" id="cat-img" src="" alt="cute cat">
 </div>
 <input type="submit" id="admin" value="Admin">
 <div id="admin-area">
 </div>
 <script src="js/updateApp.js"></script>
</body>
</html>

Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
asked Nov 12, 2015 at 23:51
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

The code looks okay. The only thing to be aware of is that when event listeners are added to DOM elements, there could be memory leaks if those elements would happen to get removed from the DOM (including re-creation). An alternative approach would be to add an event listener to a parent/root element and delegate function calls based on the type of element that was clicked.

The indentation in adminMode.init() is somewhat inconsistent towards the end.

Semi-colons are added to terminate most all lines, except for the lines that declare objects (e.g. octopus, viewList, etc. but not the first one i.e. model).

These lines in viewDetailsList.init() could be simplified:

 this.catImg.addEventListener("click", function(){
 octopus.catClicks();
 })

to just this:

this.catImg.addEventListener("click", octopus.catClicks)
answered Nov 22, 2019 at 18:51
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.