suverenia
suverenia

Reputation: 79

Change display of list element, its child and move element up the list

I hava a list with the list elements styled as inline-block. When each list element is clicked I want to:

  1. change display:inline-block; to display:block; of list element,
  2. change display: none; to display: block; of child div
  3. Move the clicked element to top of list
  4. If more than one element is clicked, all of them do the same and move up the list together.

When clicked again (toggle), I want the list to reverse the above (reverse displays and return to its original position).

So far, I have only managed to change the display of the list element to block, but I can't target the child div with element.children, or move the list element up to the top.

function showCombo(ID) {
  var x = document.getElementById(ID);
  var xshow = getComputedStyle(x, null).display; //

  if (xshow == "inline-block") {
    x.style.display = "block";
  } else {
    x.style.display = "inline-block";
  }
}
li {
  display: inline-block;
  border: 1px solid black;
  border-radius: 3px;
  cursor: pointer;
}

li div {
  display: none;
}
<ul>
  <li ID="1" onclick="showCombo(1)">
    <p>Title 1</p>
    <div>Show content</div>
  </li>
  <li ID="2" onclick="showCombo(2)">
    <p>Title 2</p>
    <div>Show content</div>
  </li>
  <li ID="3" onclick="showCombo(3)">
    <p>Title 3</p>
    <div>Show content</div>
  </li>
  <li ID="4" onclick="showCombo(4)">
    <p>Title 4</p>
    <div>Show content</div>
  </li>
  <li ID="5" onclick="showCombo(5)">
    <p>Title 5</p>
    <div>Show content</div>
  </li>
</ul>

Upvotes: 0

Views: 953

Answers (2)

Taha Halabi
Taha Halabi

Reputation: 171

I created Your idea using javascript with great focus on it, but you can use order in css like the previous answer it will be more easier, if you have a question ask me, and if you want a small edit tell me, I will put the explanation links of some events, functions that I used them in my javascript code in case you don't know them

insertBefore

prepend

classlist

getElementsByClassName

getAttribute

setAttribute

var li = document.getElementsByClassName("li"),
    ul = document.getElementById("ul");

for (let i = 0; i < li.length; i = i + 1) {
  
  li[i].setAttribute("index", i); // Create attribute named index and its value will be the i, this is to know the index of the li, we need it when clicked on it again
  
  li[i].setAttribute("firstclick", "yes"); // This is to know if we clicked at it firsttime or secondtime toggle
  
  li[i].onclick = function () {
   
    if (this.getAttribute("firstclick") == "yes") {
      this.setAttribute("firstclick", "no"); // Change it to no to when clicking it once again read the second case
      
       ul.prepend(this); // Put the clicked li at the top of the li, prepend means to put it the first element
      this.classList.add("displayBlock") // add the class displayBlock check it in the css it contains display: block
            this.getElementsByClassName("content")[0].classList.add("displayBlock"); // Add the displayBlock to the div inside the clicked li to show
    } else {
      this.setAttribute("firstclick", "yes"); // Change it to yes to when clicking it once again read the first case
      
      ul.insertBefore(this, li[parseInt(this.getAttribute("index")) + 1]) // Insert It to its original position
      
     this.classList.remove("displayBlock"); // Remove the display block class
      this.getElementsByClassName("content")[0].classList.remove("displayBlock"); // Remove the display block class
      
      
    }
    
    
  }
}
li {
  display: inline-block;
  border: 1px solid black;
  border-radius: 3px;
  cursor: pointer;
}

li div {
  display: none;
}

.displayBlock {
  display: block;
}
<ul id="ul">
 <li class="li" >
    <p>Title 1</p>
    <div class="content">Show content</div>
  </li>
  <li class="li" >
      <p>Title 2</p>
      <div class="content">Show content</div>
  </li>
  <li class="li" >
      <p>Title 3</p>
      <div class="content">Show content</div>
  </li>
  <li class="li" >
      <p>Title 4</p>
      <div class="content">Show content</div>
  </li>
  <li class="li" >
      <p>Title 5</p>
      <div class="content">Show content</div>
  </li>
</ul>

Upvotes: 2

Temani Afif
Temani Afif

Reputation: 272909

Toggle a class with all the properties and it would be easier:

function showCombo(x) {
  x.classList.toggle('active')
}
li {
  border: 1px solid black;
  margin:2px;
  border-radius: 3px;
  cursor: pointer;
}

li div {
  display: none;
}

ul {
  display:flex;
  flex-wrap:wrap;
  list-style:none;
}
li.active {
   width:100%; /* full width*/
   order:-1; /* move to the top */
}
li.active div {
  display:block; /* show div */
}
<ul>
  <li onclick="showCombo(this)">
    <p>Title 1</p>
    <div>Show content</div>
  </li>
  <li onclick="showCombo(this)">
    <p>Title 2</p>
    <div>Show content</div>
  </li>
  <li  onclick="showCombo(this)">
    <p>Title 3</p>
    <div>Show content</div>
  </li>
  <li  onclick="showCombo(this)">
    <p>Title 4</p>
    <div>Show content</div>
  </li>
  <li onclick="showCombo(this)">
    <p>Title 5</p>
    <div>Show content</div>
  </li>
</ul>

Upvotes: 2

Related Questions