Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript AppendChild Issue

UPDATED WITH FULL CODE

I'm trying to dynamically add a div onto some other DIV's stored in an array

The array which contains DIV's is named categoryData which contains an attribute with its category name

The shop-row div's (categoryData) is empty at the beginning.

I've got another array which contains the product object stored in an array called storeCategoryData The product object is in the following format,

{CategoryName:categoryname,StoreObject:store_clearfix} // store_clearfix is another div

I'm trying to add the StoreObject into the DIV categoryData. Unfortunately some objects get added and not the others. I can figure out what i'm doing wrong here. Any help would be much appreciated. Thanks!

I tried doing everything possible. Still no luck :(

 var store_list = document.getElementsByClassName("shop-list")[0];


if(data['stores']!=null && data['stores'] !== typeof undefined){

    var numstores = Object.keys(data["stores"]).length;
    var count = 0;

    while (count < numstores) {

        var categories = data["stores"][count].Categories;
        var catcount = categories.length;
        var c=0;

        while(c<catcount){
            var cat = categories[c];

            if (!(storeCategories.indexOf(cat) > -1)) {

                var category_element = document.createElement("li");
                if(count==0 && c==0){
                    category_element.className="active";
                }
                var clickable = document.createElement("a");
                clickable.href = "#";
                clickable.innerText = cat;
                clickable.setAttribute("category-data", cat);
                storeCategories.push(cat);
                category_element.appendChild(clickable);
                category_list.appendChild(category_element);


                var div = document.createElement("div");
                div.className = "shop-row";
                div.setAttribute("category-name", cat);
                categoryData.push(div);
            }

            c++;
        }

        count++;
    }

    count = 0;

    while (count < numstores) {

        var StoreId = data["stores"][count].StoreId;
        var WebsiteUrl = data["stores"][count].WebsiteUrl;
        var LogoUrl = data["stores"][count].LogoUrl;
        var categories = data["stores"][count].Categories;


        var store_clearfix = document.createElement("div");
        store_clearfix.className = "single-products-catagory clearfix";

        var store_atag =  document.createElement("a");
        store_atag.className = "home-shop";
        store_atag.href = WebsiteUrl;

        var store_img = document.createElement("img");
        store_img.className = "shop-icon";
        store_img.src = LogoUrl;
        store_img.alt = StoreId;

        store_atag.appendChild(store_img);
        store_clearfix.appendChild(store_atag);


        c=0;
        catcount = categories.length;
        while(c<catcount){
            var categoryname = categories[c];
            var i = 0;
            var datacount = categoryData.length;
            while(i<datacount){

                var datarow = categoryData[i];
                if(categoryname==datarow.getAttribute("category-name")) {
                    var storeObj = {CategoryName:categoryname,StoreObject:store_clearfix};
                    storeCategoryData.push(storeObj);
                    break;
                }

                i++;

            }

            c++;
        }


        count++;

    }


    categories_tab.appendChild(category_list);

    i=0;
    for (i = 0; i < categoryData.length; i++) {
        var div = categoryData[i];
        console.log(div);

        var name = div.getAttribute("category-name");

        var c;
        for (c = 0; c < storeCategoryData.length; c++) {
            console.log(storeCategoryData[c].CategoryName);
            if(storeCategoryData[c].CategoryName==name){
                console.log(storeCategoryData[c].StoreObject);
                div.appendChild(storeCategoryData[c].StoreObject);
           }

        }

        console.log("Finished "+name );
        console.log(div);
        store_list.appendChild(div);

    }

}

Example variable data defined as follows

{
"status": "success",
"stores": [
    {
        "StoreId": "randomStore",
        "WebsiteUrl": "https://abcd.com",
        "LogoUrl": "https://abcd.come",
        "Categories": [
            "ALL",
            "MENS",
            "WOMENS"
        ]
    },
    {
        "StoreId": "someStoreId",
        "WebsiteUrl": "https://someurl.com",
        "LogoUrl": "https://someLogo.com",
        "Categories": [
            "MENS"
        ]
    }
  ] 
}

enter image description here

like image 360
Elinoter99 Avatar asked Apr 02 '19 03:04

Elinoter99


People also ask

What does appendChild mean in JavaScript?

The appendChild() is a method of the Node interface. The appendChild() method allows you to add a node to the end of the list of child nodes of a specified parent node.

Why is appendChild not a function?

The "appendChild is not a function" error occurs for multiple reasons: calling the appendChild() method on a value that is not a DOM element. placing the JS script tag above the code that declares the DOM elements. misspelling appendChild - it's case sensitive.

What is the opposite of appendChild in JavaScript?

The removeChild() method removes an element's child.


1 Answers

The problem you are facing here is caused by the following behavior:

The Node.appendChild() method adds a node to the end of the list of children of a specified parent node. If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new position (MDN: Node.appendChild())

What this means is that appendChild will remove the node if already present in the DOM, which is what we are seeing here. This can be easily solved by creating a deep clone of the node first using cloneNode, before appending it to the target div, as follows:

var clone = storeCategoryData[c].StoreObject.cloneNode(true);
div.appendChild(clone);

You can also refer to the snippet below for a working example:

var categories_tab = document.getElementById('category-tab');
var store_list = document.getElementById('store-list');
var storeCategories = [];
var storeCategoryData = [];
var data = {
  "status": "success",
  "stores": [{
      "StoreId": "randomStore",
      "WebsiteUrl": "https://abcd.com",
      "LogoUrl": "https://abcd.come",
      "Categories": [
        "ALL",
        "MENS",
        "WOMENS"
      ]
    },
    {
      "StoreId": "someStoreId",
      "WebsiteUrl": "https://someurl.com",
      "LogoUrl": "https://someLogo.com",
      "Categories": [
        "MENS"
      ]
    }
  ]
};

var categoryData = [];

var category_list = document.createElement("ul");

if (data['stores'] != null && data['stores'] !== typeof undefined) {

  var numstores = Object.keys(data["stores"]).length;
  var count = 0;

  while (count < numstores) {

    var categories = data["stores"][count].Categories;
    var catcount = categories.length;
    var c = 0;

    while (c < catcount) {
      var cat = categories[c];

      if (!(storeCategories.indexOf(cat) > -1)) {

        var category_element = document.createElement("li");
        if (count == 0 && c == 0) {
          category_element.className = "active";
        }
        var clickable = document.createElement("a");
        clickable.href = "#";
        clickable.innerText = cat;
        clickable.setAttribute("category-data", cat);
        storeCategories.push(cat);
        category_element.appendChild(clickable);
        category_list.appendChild(category_element);


        var div = document.createElement("div");
        div.className = "shop-row";
        div.setAttribute("category-name", cat);
        categoryData.push(div);
      }

      c++;
    }

    count++;
  }

  count = 0;

  while (count < numstores) {

    var StoreId = data["stores"][count].StoreId;
    var WebsiteUrl = data["stores"][count].WebsiteUrl;
    var LogoUrl = data["stores"][count].LogoUrl;
    var categories = data["stores"][count].Categories;


    var store_clearfix = document.createElement("div");
    store_clearfix.className = "single-products-catagory clearfix";

    var store_atag = document.createElement("a");
    store_atag.className = "home-shop";
    store_atag.href = WebsiteUrl;

    var p = document.createElement("p");
    p.className = "shop-icon";
    var t = document.createTextNode(LogoUrl);
    p.appendChild(t)

    store_atag.appendChild(p);
    store_clearfix.appendChild(store_atag);


    c = 0;
    catcount = categories.length;
    while (c < catcount) {
      var categoryname = categories[c];
      var i = 0;
      var datacount = categoryData.length;
      while (i < datacount) {

        var datarow = categoryData[i];
        if (categoryname == datarow.getAttribute("category-name")) {
          var storeObj = {
            CategoryName: categoryname,
            StoreObject: store_clearfix
          };
          storeCategoryData.push(storeObj);
          break;
        }

        i++;

      }

      c++;
    }


    count++;

  }


  categories_tab.appendChild(category_list);

  i = 0;
  for (i = 0; i < categoryData.length; i++) {
    var div = categoryData[i];
    console.log(div);

    var name = div.getAttribute("category-name");

    var c;
    for (c = 0; c < storeCategoryData.length; c++) {
      console.log(storeCategoryData[c].CategoryName);
      if (storeCategoryData[c].CategoryName == name) {
        console.log(storeCategoryData[c].StoreObject);
        var clone = storeCategoryData[c].StoreObject.cloneNode(true);
        div.appendChild(clone);
      }

    }

    console.log("Finished " + name);
    console.log(div);
    store_list.appendChild(div);

  }

}
<div id="category-tab" style="min-height: 20px; border: 1px solid; padding: 10px"></div>
<div id="store-list" style="min-height: 20px; border: 1px solid green; padding: 10px; margin-top: 30px"></div>
like image 93
etarhan Avatar answered Oct 19 '22 19:10

etarhan