Jquery combining text from parent li elements on click to get path

Viewed 59

I am struggling with jquery a little. I have an unordered list that looks like this.

<ul>
  <li class="folder">Folder: Test</li>
  <ul>
    <li class="folder">Folder: Archive</li>
    <ul>
      <li class="file">
        <div class="filename">HelloWorld.docx</div>
        <div class="size">11.79kiB</div>
        <div class="date">2021-01-12 09:31:34</div>
      </li>
      <li class="file">
        <div class="filename">HelloWorld1.docx</div>
        <div class="size">12.79kiB</div>
        <div class="date">2021-01-11 09:31:34</div>
      </li>
    </ul>
  </ul>
</ul>

Which looks like this

  • Folder: Test
    • Folder : Archive
      • HelloWorld.docx
        11.79kiB
        2021-01-12 09:31:34
      • HelloWorld1.docx
        12.79kiB
        2021-01-11 09:31:34

When I click on any of the li's with the class of "file" I want to look back and work out what the path structure is by finding the parent li's that have the class "folder".

I have tried various combinations but cannot get it

This is what I am working with at the moment

$(document.body).on('click',"li.file",function (e) {
    console.log("clicked");
    $(this).parents("li.folder").each(function() {
        console.log($(this).text());
    });
});

Ultimately i want to get back a full path with the parent folder and the filename in a variable.

e.g. pathtofile = /Test/Archive/HelloWorld.docx

Here is a jsfiddle https://jsfiddle.net/e5d7bcyz/ Thanks

2 Answers

Well, the LI you're looking for are not really the parents as they're not wrapping the current li.file element.

  <ul>
    <li class="folder">Folder: Archive</li> // You close the LI tag. So it's not a parent of the rest of the code.
    <ul>
      <li class="file">

Try to wrap the rest of the code with the LI tag:

<ul>
  <li class="folder">Folder: Test
    <ul>
      <li class="folder">Folder: Archive
      <ul>
        <li class="file">
          <div class="filename">HelloWorld.docx</div>
          <div class="size">11.79kiB</div>
          <div class="date">2021-01-12 09:31:34</div>
        </li>
        <li class="file">
          <div class="filename">HelloWorld1.docx</div>
          <div class="size">12.79kiB</div>
          <div class="date">2021-01-11 09:31:34</div>
        </li>
      </ul>
     </li> //closing the second parent: Folder: Archive
    </ul>
  </li> //closing the first parent: Folder: test
</ul>

As far as I know it's valid HTML code. And then those li.folder elements would be actually parents.

Before approaching your question you first need to correct the HTML. ul elements cannot be children of other ul elements. You need to wrap the ul within their associated li.

You will also need to wrap the folder names in another element, such as a span, in order for the text to be easily retrievable. This would be possible with your current HTML by trawling through text nodes, however that is messy code to write and very brittle. A simple HTML change is the best approach there.

Finally, you can loop through the parent li elements of the clicked .file and reverse their order to get the path in the right format. From there you can append the filename of the selected file. Try this:

$.fn.reverse = [].reverse;

$(document).on('click', "li.file", function(e) {
  let $file = $(this);
  let $path = $file.parent().parents('li').reverse();
  let path = $path.map((i, el) => $(el).children('span').text().trim()).get();
  path.push($file.children('.filename').text().trim());
  console.log(path.join('/'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="folder">
    <span>Test</span>
    <ul>
      <li class="folder">
        <span>Archive</span>
        <ul>
          <li class="file">
            <div class="filename">HelloWorld.docs</div>
            <div class="size">11.79kiB</div>
            <div class="date">2021-01-12 09:31:34</div>
          </li>
          <li class="file">
            <div class="filename">HelloWorld1.docs</div>
            <div class="size">12.79kiB</div>
            <div class="date">2021-01-11 09:31:34</div>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Related