How to assign DOM created objects unique identifiers?











up vote
0
down vote

favorite












This is my first question, so apologies if it's not specific enough or critical details are lacking.



I'm learning JS through tutorials and applying it to building what equates to a deck builder.



A bunch of cards show up, you choose one and it's added to the deck.
Those cards are turned into objects and added to an array that represents the cards chosen to be in the deck



My issue arrises when multiple of the same cards are put into a deck, and you want to remove just one of them. I cannot target just the one because all my comparison operators pick up both instances.



Here is my repo on Github in case it wasn't explained well enough:
https://github.com/caldwell619/armada-fleet/tree/data-attr



Specifically, here are the snippets I'm struggling with:



Removal of a ship from the array chosenFleet.ships:



for (var i = 0; i < chosenFleet.ships.length; i++) {
if ($(this).data("name") === chosenFleet.ships[i].name) {
chosenFleet.ships.splice(i, 1);


I tried applying a unique identifier to all of the objects, but since my function is based off rewritting the HTML,



 pickedShips.innerHTML = "";
for (let ship of chosenFleet.ships) {
// div creation
const shipSel = shipSelect(ship);
pickedShips.appendChild(shipSel);


All of the unique identifiers end up being the same because every time the event listener fires, HTML elements are rewritten based on the current state of the array ships.



Function that creates the HTML based on which ship is selected:



const shipSelect = (ship) => {
const selectedShipContainer = document.createElement("div");
const shipImgContainer = document.createElement("div");
const shipNameContainer = document.createElement("div");
const shipImg = document.createElement("img");
const shipName = document.createElement("p");
const upgradeBar = document.createElement("div");
const deleteElement = document.createElement("span");
shipImgContainer.className = "span-4-of-12 ship-img";
shipImgContainer.appendChild(shipImg);
shipImg.src = "images/cards/ship/empire/" + ship.imageName;
selectedShipContainer.appendChild(shipImgContainer);
selectedShipContainer.className = "selected-ship-container";
upgradeBar.setAttribute("data-name", ship.name);
//add selected ship to new div
shipNameContainer.className = "span-7-of-12 ship-name";
shipNameContainer.appendChild(shipName);
shipNameContainer.appendChild(deleteElement);
deleteElement.className = "delete ion-trash-a";
deleteElement.setAttribute("data-name", ship.name);
deleteElement.setAttribute("data-points", ship.points);
//using data to make DOM manipulation
selectedShipContainer.setAttribute("data-name", ship.name);

shipName.innerHTML = ship.name;
selectedShipContainer.appendChild(shipNameContainer);
upgradeBar.className = "upgrade-bar";
selectedShipContainer.appendChild(upgradeBar);
const specificUpgrades = Object.keys(ship.upgrades);
for (let up of specificUpgrades) {
const butt = upgradeButtonMake(up);
upgradeBar.appendChild(butt);
}
pickedShips.appendChild(selectedShipContainer);
// return throwaway;
return selectedShipContainer;


};



Again, if this is too long / too short / etc, my apologies. Noob here.










share|improve this question






















  • The best solution here is to not store data in the DOM. The DOM is a display layer, you should store your state in an in-memory object, and update the DOM to reflect mutations to your state
    – meagar
    Nov 20 at 2:19















up vote
0
down vote

favorite












This is my first question, so apologies if it's not specific enough or critical details are lacking.



I'm learning JS through tutorials and applying it to building what equates to a deck builder.



A bunch of cards show up, you choose one and it's added to the deck.
Those cards are turned into objects and added to an array that represents the cards chosen to be in the deck



My issue arrises when multiple of the same cards are put into a deck, and you want to remove just one of them. I cannot target just the one because all my comparison operators pick up both instances.



Here is my repo on Github in case it wasn't explained well enough:
https://github.com/caldwell619/armada-fleet/tree/data-attr



Specifically, here are the snippets I'm struggling with:



Removal of a ship from the array chosenFleet.ships:



for (var i = 0; i < chosenFleet.ships.length; i++) {
if ($(this).data("name") === chosenFleet.ships[i].name) {
chosenFleet.ships.splice(i, 1);


I tried applying a unique identifier to all of the objects, but since my function is based off rewritting the HTML,



 pickedShips.innerHTML = "";
for (let ship of chosenFleet.ships) {
// div creation
const shipSel = shipSelect(ship);
pickedShips.appendChild(shipSel);


All of the unique identifiers end up being the same because every time the event listener fires, HTML elements are rewritten based on the current state of the array ships.



Function that creates the HTML based on which ship is selected:



const shipSelect = (ship) => {
const selectedShipContainer = document.createElement("div");
const shipImgContainer = document.createElement("div");
const shipNameContainer = document.createElement("div");
const shipImg = document.createElement("img");
const shipName = document.createElement("p");
const upgradeBar = document.createElement("div");
const deleteElement = document.createElement("span");
shipImgContainer.className = "span-4-of-12 ship-img";
shipImgContainer.appendChild(shipImg);
shipImg.src = "images/cards/ship/empire/" + ship.imageName;
selectedShipContainer.appendChild(shipImgContainer);
selectedShipContainer.className = "selected-ship-container";
upgradeBar.setAttribute("data-name", ship.name);
//add selected ship to new div
shipNameContainer.className = "span-7-of-12 ship-name";
shipNameContainer.appendChild(shipName);
shipNameContainer.appendChild(deleteElement);
deleteElement.className = "delete ion-trash-a";
deleteElement.setAttribute("data-name", ship.name);
deleteElement.setAttribute("data-points", ship.points);
//using data to make DOM manipulation
selectedShipContainer.setAttribute("data-name", ship.name);

shipName.innerHTML = ship.name;
selectedShipContainer.appendChild(shipNameContainer);
upgradeBar.className = "upgrade-bar";
selectedShipContainer.appendChild(upgradeBar);
const specificUpgrades = Object.keys(ship.upgrades);
for (let up of specificUpgrades) {
const butt = upgradeButtonMake(up);
upgradeBar.appendChild(butt);
}
pickedShips.appendChild(selectedShipContainer);
// return throwaway;
return selectedShipContainer;


};



Again, if this is too long / too short / etc, my apologies. Noob here.










share|improve this question






















  • The best solution here is to not store data in the DOM. The DOM is a display layer, you should store your state in an in-memory object, and update the DOM to reflect mutations to your state
    – meagar
    Nov 20 at 2:19













up vote
0
down vote

favorite









up vote
0
down vote

favorite











This is my first question, so apologies if it's not specific enough or critical details are lacking.



I'm learning JS through tutorials and applying it to building what equates to a deck builder.



A bunch of cards show up, you choose one and it's added to the deck.
Those cards are turned into objects and added to an array that represents the cards chosen to be in the deck



My issue arrises when multiple of the same cards are put into a deck, and you want to remove just one of them. I cannot target just the one because all my comparison operators pick up both instances.



Here is my repo on Github in case it wasn't explained well enough:
https://github.com/caldwell619/armada-fleet/tree/data-attr



Specifically, here are the snippets I'm struggling with:



Removal of a ship from the array chosenFleet.ships:



for (var i = 0; i < chosenFleet.ships.length; i++) {
if ($(this).data("name") === chosenFleet.ships[i].name) {
chosenFleet.ships.splice(i, 1);


I tried applying a unique identifier to all of the objects, but since my function is based off rewritting the HTML,



 pickedShips.innerHTML = "";
for (let ship of chosenFleet.ships) {
// div creation
const shipSel = shipSelect(ship);
pickedShips.appendChild(shipSel);


All of the unique identifiers end up being the same because every time the event listener fires, HTML elements are rewritten based on the current state of the array ships.



Function that creates the HTML based on which ship is selected:



const shipSelect = (ship) => {
const selectedShipContainer = document.createElement("div");
const shipImgContainer = document.createElement("div");
const shipNameContainer = document.createElement("div");
const shipImg = document.createElement("img");
const shipName = document.createElement("p");
const upgradeBar = document.createElement("div");
const deleteElement = document.createElement("span");
shipImgContainer.className = "span-4-of-12 ship-img";
shipImgContainer.appendChild(shipImg);
shipImg.src = "images/cards/ship/empire/" + ship.imageName;
selectedShipContainer.appendChild(shipImgContainer);
selectedShipContainer.className = "selected-ship-container";
upgradeBar.setAttribute("data-name", ship.name);
//add selected ship to new div
shipNameContainer.className = "span-7-of-12 ship-name";
shipNameContainer.appendChild(shipName);
shipNameContainer.appendChild(deleteElement);
deleteElement.className = "delete ion-trash-a";
deleteElement.setAttribute("data-name", ship.name);
deleteElement.setAttribute("data-points", ship.points);
//using data to make DOM manipulation
selectedShipContainer.setAttribute("data-name", ship.name);

shipName.innerHTML = ship.name;
selectedShipContainer.appendChild(shipNameContainer);
upgradeBar.className = "upgrade-bar";
selectedShipContainer.appendChild(upgradeBar);
const specificUpgrades = Object.keys(ship.upgrades);
for (let up of specificUpgrades) {
const butt = upgradeButtonMake(up);
upgradeBar.appendChild(butt);
}
pickedShips.appendChild(selectedShipContainer);
// return throwaway;
return selectedShipContainer;


};



Again, if this is too long / too short / etc, my apologies. Noob here.










share|improve this question













This is my first question, so apologies if it's not specific enough or critical details are lacking.



I'm learning JS through tutorials and applying it to building what equates to a deck builder.



A bunch of cards show up, you choose one and it's added to the deck.
Those cards are turned into objects and added to an array that represents the cards chosen to be in the deck



My issue arrises when multiple of the same cards are put into a deck, and you want to remove just one of them. I cannot target just the one because all my comparison operators pick up both instances.



Here is my repo on Github in case it wasn't explained well enough:
https://github.com/caldwell619/armada-fleet/tree/data-attr



Specifically, here are the snippets I'm struggling with:



Removal of a ship from the array chosenFleet.ships:



for (var i = 0; i < chosenFleet.ships.length; i++) {
if ($(this).data("name") === chosenFleet.ships[i].name) {
chosenFleet.ships.splice(i, 1);


I tried applying a unique identifier to all of the objects, but since my function is based off rewritting the HTML,



 pickedShips.innerHTML = "";
for (let ship of chosenFleet.ships) {
// div creation
const shipSel = shipSelect(ship);
pickedShips.appendChild(shipSel);


All of the unique identifiers end up being the same because every time the event listener fires, HTML elements are rewritten based on the current state of the array ships.



Function that creates the HTML based on which ship is selected:



const shipSelect = (ship) => {
const selectedShipContainer = document.createElement("div");
const shipImgContainer = document.createElement("div");
const shipNameContainer = document.createElement("div");
const shipImg = document.createElement("img");
const shipName = document.createElement("p");
const upgradeBar = document.createElement("div");
const deleteElement = document.createElement("span");
shipImgContainer.className = "span-4-of-12 ship-img";
shipImgContainer.appendChild(shipImg);
shipImg.src = "images/cards/ship/empire/" + ship.imageName;
selectedShipContainer.appendChild(shipImgContainer);
selectedShipContainer.className = "selected-ship-container";
upgradeBar.setAttribute("data-name", ship.name);
//add selected ship to new div
shipNameContainer.className = "span-7-of-12 ship-name";
shipNameContainer.appendChild(shipName);
shipNameContainer.appendChild(deleteElement);
deleteElement.className = "delete ion-trash-a";
deleteElement.setAttribute("data-name", ship.name);
deleteElement.setAttribute("data-points", ship.points);
//using data to make DOM manipulation
selectedShipContainer.setAttribute("data-name", ship.name);

shipName.innerHTML = ship.name;
selectedShipContainer.appendChild(shipNameContainer);
upgradeBar.className = "upgrade-bar";
selectedShipContainer.appendChild(upgradeBar);
const specificUpgrades = Object.keys(ship.upgrades);
for (let up of specificUpgrades) {
const butt = upgradeButtonMake(up);
upgradeBar.appendChild(butt);
}
pickedShips.appendChild(selectedShipContainer);
// return throwaway;
return selectedShipContainer;


};



Again, if this is too long / too short / etc, my apologies. Noob here.







javascript arrays loops object for-loop






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 at 2:05









Christopher Caldwell

12




12












  • The best solution here is to not store data in the DOM. The DOM is a display layer, you should store your state in an in-memory object, and update the DOM to reflect mutations to your state
    – meagar
    Nov 20 at 2:19


















  • The best solution here is to not store data in the DOM. The DOM is a display layer, you should store your state in an in-memory object, and update the DOM to reflect mutations to your state
    – meagar
    Nov 20 at 2:19
















The best solution here is to not store data in the DOM. The DOM is a display layer, you should store your state in an in-memory object, and update the DOM to reflect mutations to your state
– meagar
Nov 20 at 2:19




The best solution here is to not store data in the DOM. The DOM is a display layer, you should store your state in an in-memory object, and update the DOM to reflect mutations to your state
– meagar
Nov 20 at 2:19












2 Answers
2






active

oldest

votes

















up vote
2
down vote













You may create more specific sheep identity
e.g something like



deleteElement.setAttribute("data-id", ship.name + ship.type);


type is whatever attribute that better specifies your ship.



and then compare on this attr



if ($(this).data("id") === chosenFleet.ships[i].name + chosenFleet.ships[i].type) {





share|improve this answer




























    up vote
    0
    down vote













    Create a global object like



    (function (global) {
    global.getUniq = getUniq;
    var id = 0;

    function getUniq() {
    return ++id;
    }
    })(window);


    It's a singleton and each time you call getUniq you get a unique identifier no matter how many clients use it.






    share|improve this answer





















    • "Create a global object--" a lot of people just flipped their tables and wrecked their laptops.
      – Jude Desir
      Nov 20 at 2:45













    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385204%2fhow-to-assign-dom-created-objects-unique-identifiers%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote













    You may create more specific sheep identity
    e.g something like



    deleteElement.setAttribute("data-id", ship.name + ship.type);


    type is whatever attribute that better specifies your ship.



    and then compare on this attr



    if ($(this).data("id") === chosenFleet.ships[i].name + chosenFleet.ships[i].type) {





    share|improve this answer

























      up vote
      2
      down vote













      You may create more specific sheep identity
      e.g something like



      deleteElement.setAttribute("data-id", ship.name + ship.type);


      type is whatever attribute that better specifies your ship.



      and then compare on this attr



      if ($(this).data("id") === chosenFleet.ships[i].name + chosenFleet.ships[i].type) {





      share|improve this answer























        up vote
        2
        down vote










        up vote
        2
        down vote









        You may create more specific sheep identity
        e.g something like



        deleteElement.setAttribute("data-id", ship.name + ship.type);


        type is whatever attribute that better specifies your ship.



        and then compare on this attr



        if ($(this).data("id") === chosenFleet.ships[i].name + chosenFleet.ships[i].type) {





        share|improve this answer












        You may create more specific sheep identity
        e.g something like



        deleteElement.setAttribute("data-id", ship.name + ship.type);


        type is whatever attribute that better specifies your ship.



        and then compare on this attr



        if ($(this).data("id") === chosenFleet.ships[i].name + chosenFleet.ships[i].type) {






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 at 2:27









        Brain Ops

        212




        212
























            up vote
            0
            down vote













            Create a global object like



            (function (global) {
            global.getUniq = getUniq;
            var id = 0;

            function getUniq() {
            return ++id;
            }
            })(window);


            It's a singleton and each time you call getUniq you get a unique identifier no matter how many clients use it.






            share|improve this answer





















            • "Create a global object--" a lot of people just flipped their tables and wrecked their laptops.
              – Jude Desir
              Nov 20 at 2:45

















            up vote
            0
            down vote













            Create a global object like



            (function (global) {
            global.getUniq = getUniq;
            var id = 0;

            function getUniq() {
            return ++id;
            }
            })(window);


            It's a singleton and each time you call getUniq you get a unique identifier no matter how many clients use it.






            share|improve this answer





















            • "Create a global object--" a lot of people just flipped their tables and wrecked their laptops.
              – Jude Desir
              Nov 20 at 2:45















            up vote
            0
            down vote










            up vote
            0
            down vote









            Create a global object like



            (function (global) {
            global.getUniq = getUniq;
            var id = 0;

            function getUniq() {
            return ++id;
            }
            })(window);


            It's a singleton and each time you call getUniq you get a unique identifier no matter how many clients use it.






            share|improve this answer












            Create a global object like



            (function (global) {
            global.getUniq = getUniq;
            var id = 0;

            function getUniq() {
            return ++id;
            }
            })(window);


            It's a singleton and each time you call getUniq you get a unique identifier no matter how many clients use it.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 20 at 2:22









            Dominique Fortin

            1,640816




            1,640816












            • "Create a global object--" a lot of people just flipped their tables and wrecked their laptops.
              – Jude Desir
              Nov 20 at 2:45




















            • "Create a global object--" a lot of people just flipped their tables and wrecked their laptops.
              – Jude Desir
              Nov 20 at 2:45


















            "Create a global object--" a lot of people just flipped their tables and wrecked their laptops.
            – Jude Desir
            Nov 20 at 2:45






            "Create a global object--" a lot of people just flipped their tables and wrecked their laptops.
            – Jude Desir
            Nov 20 at 2:45




















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385204%2fhow-to-assign-dom-created-objects-unique-identifiers%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin