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"
]
}
]
}
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>