2

I have a html markup for a list

<ul>
    <a id="catalogPlaceholder"></a> <!-- this is the placeholder to append new items -->

    <a class="sidebarListItem" href="#link">        
        <object type="deleteLinkOnHover"><a class="deleteItem" href="javascript:deleteItemFromList()">Delete</a></object>
        <div style="width:30%;float:left; background: none"><img class="rounded-circle" src="#image" alt="Product image" width="100%"></div>
        <div style="float:left;padding-left:10px;width:60%;background: none"><strong class="text-muted d-block mb-2"><h5>#title</h5></strong></div>        
    </a>
    <a class="sidebarListItem" href="#link">        
        <object type="deleteLinkOnHover"><a class="deleteItem" href="javascript:deleteItemFromList()">Delete</a></object>
        <div style="width:30%;float:left; background: none"><img class="rounded-circle" src="#image" alt="Product image" width="100%"></div>
        <div style="float:left;padding-left:10px;width:60%;background: none"><strong class="text-muted d-block mb-2"><h5>#title</h5></strong></div>        
    </a>
    <a class="sidebarListItem" href="#link">        
        <object type="deleteLinkOnHover"><a class="deleteItem" href="javascript:deleteItemFromList()">Delete</a></object>
        <div style="width:30%;float:left; background: none"><img class="rounded-circle" src="#image" alt="Product image" width="100%"></div>
        <div style="float:left;padding-left:10px;width:60%;background: none"><strong class="text-muted d-block mb-2"><h5>#title</h5></strong></div>        
    </a>
</ul>

that looks like this image

and want to add new items using javascript like this

function relateNewCatalog(id, image, title) {
    var a = document.createElement('a');
    a.classname = "sidebarListItem";
    a.id = "sidebarItemCatalog-" + id;
    a.href = "../?module=catalogDetails&idcatalog=" + id;
    a.style = "padding:10px";

    var html = '<object type="deleteLinkOnHover"><a class="deleteItem" href="javascript:deleteItemFromList(\'sidebarItemCatalog-' + id +  '\')">Delete</a></object>';
    html += '<div style="width:30%;float:left; background: none"><img class="rounded-circle" src="../uploads/images/' + image + '" alt="Product image" width="100%"></div>';
    html += '<div style="float:left;padding-left:10px;width:60%;background: none"><strong class="text-muted d-block mb-2"><h5>' + title + '</h5></strong></div>';        

    a.innerHTML = html;
    var placeholder = document.getElementById("catalogPlaceholder");
    placeholder.append(a);
} 

but the markup seems broken when I do so like in this image (see padding and hover effect). I tried clear:both and also with insertBefore instead of appendChild but without success. The more items I add the more they get stacked like in the last image

Thanks for your time!

To the editor Sorry for the rejected edit but its basically wrong. You only use "an" if the following word starts with a,e,i,o or u and "HTML" does NOT!

Kamil Kiełczewski
  • 71,169
  • 26
  • 324
  • 295
MBrain
  • 21
  • 6

1 Answers1

1

You can use <template> and separate data and view as follows

let data = [
  { id: 1, title: 'Product 1', image: "https://picsum.photos/id/10/50" },
  { id: 2, title: 'Product 2', image: "https://picsum.photos/id/20/50" },
  { id: 3, title: 'Product 3', image: "https://picsum.photos/id/30/50" }
]

function refresh() {
  let r='', inj = (str, obj) => str.replace(/\${(.*?)}/g, (x,g)=> obj[g]);
  for(let it of data) r += inj(item.innerHTML,it);
  catalogPlaceholder.innerHTML = r;
}

function relateNewCatalog() {
  data.unshift({
    id: Math.max(...data.map(x=>x.id),0)+1, 
    title: `Product ${data.length+1}`, 
    image: `https://picsum.photos/id/${Math.random()*300|0}/50` 
  });
  refresh();
}

function deleteItemFromList(id) {
  data = data.filter(x=> x.id!=id);
  refresh();
}

refresh();
.sidebarListItem {display: flex}
h5 {margin:0}
<button onclick="relateNewCatalog()">Add</button>
<ul id="catalogPlaceholder" ></ul>

<template id="item" >
  <li>
    <a class="sidebarListItem" href="#link">        
      <object type="deleteLinkOnHover">
        <a class="deleteItem" onclick="deleteItemFromList(${id})">Delete</a>
      </object>
      <div class="imgBox">
        <img class="rounded-circle" src="${image}" alt="Product image" >
      </div>
      <div class="titleBox"><strong class="text-muted d-block mb-2">
        <h5>${title}</h5>
      </strong></div>        
    </a>
  </li>
</template>
Kamil Kiełczewski
  • 71,169
  • 26
  • 324
  • 295
  • Nicely presented! Although, you are rebuilding the whole page every time you add another catalogue. This could slow down the page or cause some flickering when there is a large number of catalogues to list. So, maybe `.appendChild()` might come in as a useful alternative to `innerHTML`? (@MBrain: there is no "an" before "useful" ;-) ) – Carsten Massmann Jun 05 '19 at 05:36
  • @cars10m Do you also know why? Because in this case the "a" is related to "alternative" and not to "useful". And "alternative" starts with a vowal sound. "a" is one of those mysterious 5 ones. But, nice try :P – MBrain Jun 05 '19 at 05:46
  • @cars10m you are right - the solution can be improved to not change old products in html tree. By the way in past I made some tests [here](https://stackoverflow.com/a/55970947/860099) and it looks lie `innerHTML =` (do not confuse with `+=` !) is faster than `.appendChild()` - – Kamil Kiełczewski Jun 05 '19 at 05:52
  • Sorry @MBrain, my wife (English native speaker and professional translator) is looking over my shoulder and is slowly losing the will to live ... The use of "a" or "an" depends solely on the pronunciation of the immediately following word. The word "alternative" is of no relevance here. – Carsten Massmann Jun 05 '19 at 06:00
  • Ever heard about XANAX valium? Maybe they will help your professional native speaking translator wife :P Even if i am wrong the edit was completely useless and thats the reason for my being here, so sorry i dont want to discuss such a topic.. Not right now and not right here. – MBrain Jun 05 '19 at 06:08
  • @MBrain if my answer helps, you can accept it by click on big gray check button on its left side – Kamil Kiełczewski Jun 05 '19 at 06:51
  • 1
    Hi @Kamil, interesting fact about your speed comparison. Will remember that for future projects. You got my +1 already this morning. I hope MBrain is not too cross about my comments and will accept your answer. ;-) – Carsten Massmann Jun 05 '19 at 18:24
  • 1
    Its not what i wanted but of course i accept it, thank you anyways. Now i see i dont even asked my question very well. no idea what your comments @cars10m has to deal with it?! – MBrain Jun 05 '19 at 20:40