2

var data = [
  {
    cid: "59eb15be",
    parentCid: "",
    lv: 1,
    number: "2",
    subject: "Title 2"
  },
  {
    cid: "d7d851ef",
    parentCid: "",
    lv: 1,
    number: "4",
    subject: "Title4"
  },    
  {
    cid: "bd01cc50",
    parentCid: "ae35e67d",
    lv: 2,
    number: "1.1",
    subject: "Title1.1"
  },
  {
    cid: "2d8bd8b0",
    parentCid: "",
    lv: 1,
    number: "3",
    subject: "Title3"
  },
  {
    cid: "7f66a92d",
    parentCid: "ae35e67d",
    lv: 2,
    number: "1.2",
    subject: "Title1.2"
  },
  {
    cid: "ae35e67d",
    parentCid: "",
    lv: 1,
    number: "1",
    subject: "Title1"
  },
  {
    cid: "e7c2dbcc",
    parentCid: "ae35e67d",
    lv: 2,
    number: "1.3",
    subject: "Title1.3"
  },
  {
    cid: "cc784c42",
    parentCid: "ae35e67d",
    lv: 2,
    number: "1.4",
    subject: "Title1.4"
  }
];
 var chapterListDiv = document.getElementById("listSummary");
 var store = document.createDocumentFragment(); //we use this to store temporary orphaned childs
 for(var i=0; i<data.length; i++){
  var node = document.createElement("div");
  node.className = "lv" + (data[i].level || data[i].lv);
        var content = document.createTextNode(data[i].number + "." + " " + data[i].subject);
        node.appendChild(content);  
  node.setAttribute("data-id", data[i].cid); //set a data-id attribute. We need it for the orphaned values.
  node.setAttribute("data-parent-id", data[i].parentCid); //set a data-parent-id attribute. We need it for the orphaned values.
  if (data[i].parentCid == "") //we have a root node
  {
   chapterListDiv.appendChild(node);
  }
  else
  {
   var parent = chapterListDiv.querySelector('div[data-id="'+data[i].parentCid+'"]'); //look for a node with the parent id.
   if (parent) //parent is found
   {
    parent.appendChild(node);
   }
   else
   {
    store.appendChild(node); //temp store the node.
   }
  }
 }
    //final check
    var storeChilds = store.querySelectorAll('div[data-parent-id]');
    if (storeChilds)
    {
        Array.prototype.map.call(storeChilds, function(element){
            var parent = document.querySelector('div[data-id="'+element.getAttribute("data-parent-id")+'"]') ||
                store.querySelector('div[data-id="'+element.getAttribute("data-parent-id")+'"]')
            parent.appendChild(element);
            
        });
    }
.lv1 {
    
}

.lv2{
    padding-left: 30px;    
}

.lv3{
    padding-left: 30px;    
}
<div id="listSummary"></div>

In json data, all item has a "cid" and some of them has "parentCid" which mean it is the child level of it.)

As second level of result

1.3. Title1.3
1.4. Title1.4
1.1. Title1.1
1.2. Title1.2

This is not order because "1.1" and "1.2" cannot find their parent node when access in loop because their parent node is behind them. So that is why "1.3" and "1.4" being append first(parent node is ahead).

Is there any way that can have result correctly like below for second level?

1.1. Title1.1
1.2. Title1.2
1.3. Title1.3
1.4. Title1.4
Dreams
  • 8,288
  • 10
  • 45
  • 71

4 Answers4

0

Just sort the data before processing it

data.sort(function(a, b) {
    if ((a.lv | a.level) > (b.lv | b.level))
        return 1;
    else if ((a.lv | a.level) < (b.lv | b.level))
        return -1;
    else {
        if (Number(a.number) > Number(b.number))
            return 1;
        else 
            return -1;
    }
});

The | a.level is because one of your data points has level instead of lv.

potatopeelings
  • 40,709
  • 7
  • 95
  • 119
0

To order your data by number with hierarchy you should simply use sort function:

data.sort(function(a, b) {
    return a.number > b.number
});

If you keep this element numbering style it is enough to just sort by this property

I recommended to read https://stackoverflow.com/a/979325/4772988

Community
  • 1
  • 1
suvroc
  • 3,058
  • 1
  • 15
  • 29
0

Remove the parent elements. Then sort the second level elements by converting your string number to floats and subtracting them from each other.

var data_sorted = data.filter(function(value, index){
    return value.parentCid != "";
}).sort(function(value1, value2){
    return parseFloat(value1.number) - parseFloat(value2.number);
});

Demo

kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
0

Solution with Array.filter(), Array.sort() and Array.forEach():

var data = [{ cid: "59eb15be", parentCid: "", lv: 1, number: "2", subject: "Title 2" }, { cid: "d7d851ef", parentCid: "", lv: 1, number: "4", subject: "Title4" }, { cid: "bd01cc50", parentCid: "ae35e67d", lv: 2, number: "1.1", subject: "Title1.1" }, { cid: "2d8bd8b0", parentCid: "", lv: 1, number: "3", subject: "Title3" }, { cid: "7f66a92d", parentCid: "ae35e67d", lv: 2, number: "1.2", subject: "Title1.2" }, { cid: "ae35e67d", parentCid: "", lv: 1, number: "1", subject: "Title1" }, { cid: "e7c2dbcc", parentCid: "ae35e67d", lv: 2, number: "1.3", subject: "Title1.3" }, { cid: "cc784c42", parentCid: "ae35e67d", lv: 2, number: "1.4", subject: "Title1.4" }];

// this is the place for your tree generating function
function print(a, l) {
    var ll = l;
    while (ll--) document.write('    ');
    document.write('Computed level: ' + l + '  ');
    Object.keys(a).forEach(function (i) {
        document.write(i + ': ' + a[i] + '  ');
    });
    document.write('\n')
}

function getChildren(parent, level) {
    data.filter(function (a) {
        return a.parentCid === parent;
    }).sort(function (a, b) {
        return a.number.localeCompare(b.number);
    }).forEach(function (a) {
        print(a, level);
        getChildren(a.cid, level + 1);
    });
}
document.write('<pre>');
getChildren('', 0);
document.write('</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392