3

I have a <ul> element with <li> inside of it. The list items either have a:

<li class="folder"> 
<!-- or... -->
<li class="file">

Nested inside each of the folder's, there's a color-label.

<li class="folder">
    Folder 1 
    <i class="blue"></i>
</li>

I need to use jQuery to dynamically look inside all of the <li class="folder"> list items and find the <i class="color"> labels, then apply the class to each of the <li class="file"> siblings until the next folder color label it finds, and repeat the process until all <li>'s have the correct colors depending on the folder's color-label class.

Here's an example of what it would look like:

enter image description here

I've attempted to use the .nextUntil() jquery method, but haven't had the best results. Here's my code:

https://jsfiddle.net/5c11sqL5/

<nav class="directory">
    <h1 class="title">Directory</h1>
    <ul class="container">
        <!-- Folder 1 -->  
        <li class="folder">Folder 1 <i class="blue"></i></li>
        <li class="file">File 1</li>
        <li class="file">File 2</li>
        <li class="file">File 3</li>

        <!-- Folder 2 -->  
        <li class="folder">Folder 2 <i class="green"></i></li>
        <li class="file">File 1</li>
        <li class="file">File 2</li>
        <li class="file">File 3</li>

        <!-- Folder 3 -->  
        <li class="folder">Folder 3 <i class="gray"></i></li>
        <li class="file">File 1</li>
        <li class="file">File 2</li>
        <li class="file">File 3</li>
    </ul>
</nav>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Courier New", Courier, monospace;
}

/* Directory */

.directory {
    display: flex;
    flex-direction: column;
    background: #ccc;
    width: 240px;
    height: 100vh;
}

.directory .title {
    letter-spacing: 3px;
    text-transform: uppercase;
    opacity: .07;
    text-align: center;
    margin: 1rem 0 0;
}

.directory .container {
    list-style: none;
}

/* Folder and Files */

.folder {
    font-weight: bold;
    font-size: 1rem;
    position: relative;
    padding: 0 0 0 1rem;
    margin: 1rem 0 0;
}

.file {
    font-size: .8rem;
    padding: 0 0 0 1rem;
}

/* Colors */

.blue,
.green,
.gray {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 5px;
    display: block;
}

.blue {
    background: rgba(0, 194, 224, 1);
}

.green {
    background: rgba(81, 232, 152, 1);
}

.gray {
    background: rgba(131, 140, 145, 1);
}
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Oneezy
  • 4,881
  • 7
  • 44
  • 73
  • Rory McCrossan's solution is right. If I were you, I would change the layout of HTML so `li.folder` has nested `
      ` with nested `li.file` so you could easily select folder files like `$('li.folder').each(function(folder) { var files = $('li.file', folder), className = $('i', folder).prop('class'); files.addClass(className) })`
    – Rudolf Gröhling May 26 '16 at 11:12
  • I completely agree! The only problem is that the html is being written dynamically for a Trello extension I'm making. The "trello list" is the directory and the "trello cards" are either the folders or files: http://oneezy.com/www/gtd/trello-directory.png . The cards are drag n' droppable, and has lots of "trello" stuff tied to them, so i've got to be very careful on on how much DOM manipulating I do. – Oneezy May 26 '16 at 11:28

1 Answers1

5

You can achieve this by looping over each i element then copying it's class name to each following .file, something like this:

$('.directory .folder i').each(function() {
    var className = $(this).prop('class');
    $(this).closest('li').nextUntil('.folder').addClass(className);
})

Also note that you would need to amend the classes you have defined so that the position: absolute rules only apply to the i elements, like this:

i.blue,
i.green,
i.gray {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 5px;
    display: block;
}
i.blue {
    background: rgba(0, 194, 224, 1);
}
i.green {
    background: rgba(81, 232, 152, 1);
}
i.gray {
    background: rgba(131, 140, 145, 1);
}

.file.blue {
    color: rgba(0, 194, 224, 1);
}
.file.green {
    color: rgba(81, 232, 152, 1);
}
.file.gray {
    color: rgba(131, 140, 145, 1);
}

Updated fiddle

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339