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>

\$\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)
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.