0

I am trying to display a series of posts and replies (a typical comment section) using a recursive function. I get it to print out the posts in the right order, but the replies seem to appear inside the comment that follows the one they refer to. In other words, the posts are not printed out on screen in the nested hierarchical order intended.

I tried the insertAfter() function suggested here but it makes no difference. Also tried lots of variations but there is just something I am missing. Or is this entirely the wrong approach to display nested posts? If so, any suggestions (links to) better ways? Thanks in advance!

var box = document.getElementById('commentBox');

function showThreads(sortedArr, respTo, parent = box){
//create two json-encoded arrays with post data
  var selected = getResponsesTo(sortedArr, respTo)[0];
  var remaining = getResponsesTo(sortedArr, respTo)[1];

  //create new div element
  var childDiv = document.createElement('div');

  //append div at the end of last sibling [normal appendChild() doesn't work either]
  parent.insertBefore(childDiv, parent.lastChild.nextSibling);

        for(var i=0; i<selected.length; i++){
          //get the json encoded element
          var pi = selected[i];
        //create new div element for post
        var pDiv = document.createElement('div');
        //add the post to the element, after formatting it in html with makePost function
        pDiv.innerHTML = makePost(pi);
        //add post to current division
        childDiv.appendChild(pDiv);

        //recursively get responses to that post if available
        if(remaining.length>0){
        showThreads(remaining, pi.pID, childDiv);
      }else{
        continue;
      }
      }
    }

dan
  • 11
  • 2

1 Answers1

0

Well there isn't much data to work with so I randomized it. I think you just need to appendChild to a parent which you called recursively and it should work.

Warning: Try to run the snippet a few times it might return: null, tree, list or endless loop.

function showThreads(sortedArr, respTo, parent, level) {
  level = level || 0;
  var [selected, remaining] = getResponsesTo(sortedArr, respTo);

  var childDiv = document.createElement('div');

  parent.append(childDiv, null);

  for (var i = 0; i < selected.length; i++) {
    var pi = selected[i];
    var pDiv = document.createElement('div');
    pDiv.innerHTML = makePost(pi, level);
    childDiv.appendChild(pDiv);

    if (remaining.length > 0) {
      showThreads(remaining, pi.pID, childDiv, level + 1);
    } else {
      continue;
    }
  }
}

var box = document.querySelector('.commentBox');
showThreads([{}], null, box)


function getResponsesTo() {
  return Math.random() < 0.75 ? [
    [{
      pi: 1
    }, {
      pi: 2
    }, {
      pi: 3
    }],
    (Math.random() < 0.5 ? [] : [{
      pi: 4
    }])
  ] : [
    [],
    [{
      pi: 5
    }, {
      pi: 6
    }]
  ];

}


function makePost(pi, level) {
  return "<div style='padding-left: " + (level * 40) + "px'><h" + (level + 1) + ">post</h" + (level + 1) + "><p>body</p></div>";
}
<pre class="commentBox"></pre>
IT goldman
  • 14,885
  • 2
  • 14
  • 28
  • excellent, you are right, thank you! And good tip about adding the comment level.. – dan Jul 31 '22 at 19:36