Getting values from a <ul>, <li> tree format

Viewed 97

I've the folloing tree view:

ul {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />

<ul id="myTreeSelector" onClick="getPath()">
  <li>
    <span class="caret folder-selector"><i class="fa fa-folder"></i> first_folder</span>
    <ul class="nested">
      <li class="file"><i class="fa fa-file"></i> app1.dat</li>
      <li class="file"><i class="fa fa-file"></i> app2.dat</li>
      <li>
        <span class="caret folder-selector"><i class="fa fa-folder"></i> second_folder</span>
        <ul class="nested">
          <li class="file"><i class="fa fa-file"></i> ret.dat</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Which generates a folder tree like this:

enter image description here

What I'm loking for is that when I click on any file or folder, get the "full file/folder path". This means:

  • If I click in app1.dat, my desired output is: first_folder/app1.dat
  • If I click in second_folder, my desired output is: first_folder/second_folder
  • If I click in ret.dat, my desired output is: first_folder/second_folder/ret.dat

How can I archieve this? I tried with no luck to get the value:

function getPath() {
    var value = $("#myTreeSelector").val()
    console.log(value)
}

EDIT: The tree can have more than 2 levels, this is just a minified example.

1 Answers

Here is generic code, all you need to do is add event to li (using event delegation) and use parents to the li elements that are parents of selected li element.

$(function() {
  $('#myTreeSelector').on('click', 'li', function() {
     var item = $(this);
     var path = [];
     if (item.is('.file')) {
        path.push(item.text().trim());
     } else {
        path.push(item.find('> .folder-selector').text().trim() + '/');
     }
     var parents = item.parents('#myTreeSelector li');
     path = parents.map(function() {
        return $(this).find('> .folder-selector').text().trim();
     }).get().reverse().concat(path);
     console.log(path.join('/'));
     return false;
  });
});
     
ul {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />

<ul id="myTreeSelector">
  <li>
    <span class="caret folder-selector"><i class="fa fa-folder"></i> first_folder</span>
    <ul class="nested">
      <li class="file"><i class="fa fa-file"></i> app1.dat</li>
      <li class="file"><i class="fa fa-file"></i> app2.dat</li>
      <li>
        <span class="caret folder-selector"><i class="fa fa-folder"></i> second_folder</span>
        <ul class="nested">
          <li class="file"><i class="fa fa-file"></i> ret.dat</li>
          <li><span class="caret folder-selector"><i class="fa fa-folder"></i> third_folder</span></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Related