Repositioning the li element at the beginning of the list

I'm working on a collapsible Material UI feature and I want to ensure that when a user clicks on an item, it stays at the top of the list.

For example, let's say we have a default list with items First, Second, and Third. When the user expands the Second item, it should move to the top like this:

First (expanded)

Second

Third


Second (expanded)

First

Third


If the user then clicks on the Third item, the list should display as:

Third (expanded)

First

Second


<ul class="collapsible" data-collapsible="accordion">
  <li>
    <div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
    <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
  </li>
  <li>
    <div class="collapsible-header"><i class="material-icons">place</i>Second</div>
    <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
  </li>
  <li>
    <div class="collapsible-header"><i class="material-icons">whatshot</i>Third</div>
    <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
  </li>
</ul>

Answer №1

My approach involves utilizing the index() function, however, I encountered a challenge where the index changes each time we use prepend() on an li element. To address this issue, I decided to assign an id property to each li automatically in order to maintain a fixed index for them.

$("li").each(function(index){
  $(this).prop("id",index);
});

Subsequently, the strategy is to prepend the li elements based on the clicked li, leveraging the assigned id. For instance, clicking on the second li would result in the following sequence:

 if($(this).prop("id")==1){//If it's the second one
   $("ul").prepend($("#2"));
   $("ul").prepend($("#0"));
   $("ul").prepend($("#1"));
 }

Below is a code snippet illustrating how this theory is put into practice:

$("li").each(function(index){
  $(this).prop("id",index);
});

$("li").on("click",function(){
$(".collapsible-body").hide();
$(this).find(".collapsible-body").show("slow");
 if( $(this).prop("id") == 0 ){//If it's the first one
    $("ul").prepend($("#2"));
    $("ul").prepend($("#1"));
    $("ul").prepend($("#0"));
  }else if($(this).prop("id")==1){//If it's the second one
   $("ul").prepend($("#2"));
   $("ul").prepend($("#0"));
   $("ul").prepend($("#1"));
  }else{//If it's the third one

   $("ul").prepend($("#1"));
   $("ul").prepend($("#0"));
   $("ul").prepend($("#2"));
  }
  
});
.collapsible-body{
display:none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="collapsible" data-collapsible="accordion">
    <li>
      <div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
      <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
    </li>
    <li>
      <div class="collapsible-header"><i class="material-icons">place</i>Second</div>
      <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
    </li>
    <li>
      <div class="collapsible-header"><i class="material-icons">whatshot</i>Third</div>
      <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
    </li>
  </ul>


OPTIMIZATION

Alternatively, you can simplify the process with the following implementation:

$("li").each(function(index){
  $(this).prop("id",index);
});

$("li").on("click",function(){
$(".collapsible-body").hide();
$(this).find(".collapsible-body").show("slow");

for(var i=0;i<$("li").length;i++){
var id="#"+i;
$("ul").append($(id));
}
$("ul").prepend($(this));
});
.collapsible-body{
display:none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="collapsible" data-collapsible="accordion">
    <li>
      <div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
      <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
    </li>
    <li>
      <div class="collapsible-header"><i class="material-icons">place</i>Second</div>
      <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
    </li>
    <li>
      <div class="collapsible-header"><i class="material-icons">whatshot</i>Third</div>
      <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
    </li>
  </ul>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Please add content prior to the <input type="image"> tag

To improve the code for adding a product to the basket, I want to enhance the buy button by incorporating an image or background fill with HTML text on top of it. <input border="0" src="/images/buy.png" type="image" /> ...

Showing a single item from an array using ngFor in Angular 2 is a simple task that can be

When there are multiple elements in an array on my website, the template is structured like this: https://i.sstatic.net/SChtZ.png I need a button to navigate to the next element of the array and display only one set of data at a time. The user should be ...

Numerous sections with tabs on the webpage

I am in need of incorporating multiple tabbed sections on a single page, but unfortunately they are currently interconnected. When one tab is clicked, it impacts the others. To see this issue in action, you can visit: https://jsfiddle.net/pxpsvoc6/ This ...

implement express.bodyParser() alongside passport.js

Currently, I am developing a node server utilizing express.js and passport.js. I have encountered a situation where I need to avoid using the express.bodyParser() prior to app.use(passport.initialize()) and app.use(passport.session()). When I include app.u ...

Encountering a problem while working on a Javascript scaffolding application build utilizing Angular 2

I'm having trouble getting this code to run. 'use strict'; /** * @ngdoc function * @name udaciMealsApp.controller:MenuCtrl * @description * # MenuCtrl * Controller of the udaciMealsApp */ angular.module('udaciMealsApp') .c ...

What is the process for capturing a screenshot of a specific DOM element using Intern JS?

I'm currently utilizing intern.js for testing a web application. It allows me to run tests and generate screenshots in case of failures. My goal is to capture a screenshot of a specific element for conducting CSS regression testing with tools like res ...

How can I use TailwindCSS in NextJS to remove the "gap" className from a component?

Currently, I am working on button components in NextJS with Tailwindcss and I am encountering a problem with some variants. Everything works fine, except when I remove the children (button text), I notice something strange that I can't quite figure ou ...

Trouble arising from Bootstrap 5's float-end on flex items

When I apply the float-end class, it shifts the button to the right, but the div tags next to it appear in front of it. https://i.sstatic.net/Mxu0P.png <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protecti ...

Loading V-Select with Data from JSON Using Vue.js

I tried to populate my v-select multiselect element using a JSON object, but unfortunately it did not work as expected. Here is the result I encountered: https://i.sstatic.net/kd1Gl.png <v-select v-model="serviceValues" :items="serviceO ...

Preventing the flipping effect with jquery flippy

Hey there! I've been using a cool flippy jquery plugin that I found on this website. It's working great, but I have run into an issue. When the element flips, I want to include a button on the flip side that takes the user to a different page. T ...

To combine both jquery-1.min.js and jquery.min.js is essential for achieving optimal functionality

When using these two files, only one of them can work on a page. <script src="jquery.min.js"></script> <script src="jquery-1.min.js"></script>//Only the second one works Alternatively, if the order is changed: <script src="jq ...

Transform the string by eliminating any spaces and new lines before converting it into a JSON object

I need assistance with converting the given string into a JSON object. Here is the string: {\"Warranty\": [ \n { \n \"Name\": \"test\", \n \"Type\": \"test2\", \n \"Months\": ...

Enhance the structure of this array data model

Currently in the process of creating a small script to tag coordinates in an array: var countries = ['spain','australia']; var leftX = ['270','575']; var topY = ['60','220']; When I need to ...

When hovering over a select option, a description and clickable link will be displayed

I need to display a description with a clickable link when hovering over any option in the select tag. <div class="col-lg-4"> <div class="form-group"> <label class="form-label">Goal</label> <select name="semiTaskType ...

Tips on effectively utilizing a value that has been modified by useEffect

Here is my current code: const issues = ['x','y','z']; let allIssueStatus; let selectedIssueStatus = ''; useEffect(() => { const fetchIssueStatus = async() => { const response = await fetch(&ap ...

TypeScript is unaware that a component receives a necessary prop from a Higher Order Component (HOC)

My component export is wrapped with a higher-order component (HOC) that adds a required prop to it, but TypeScript seems unaware that this prop has already been added by the HOC. Here's the Component: import * as React from "react"; import { withTex ...

Exploring the differences between Material-UI's makeStyles and withStyles when it comes to

One thing I've observed is that the naming convention for classes created with makeStyles and hooks looks like this: https://i.stack.imgur.com/HcDUc.jpg On the other hand, classes produced using withStyles and higher order components (HOC) follow a ...

Learn how to smoothly transfer a URL from JavaScript to HTML and initiate the download process

I created a website that solely relies on HTML5, CSS and JavaScript to function. The core functionality of this website involves utilizing YouTube URLs. I have stored the URL of a specific YouTube video as a variable, now I am looking for a way to transfer ...

Using Google Maps to add markers, then filtering them with marker clusters

Seeking assistance with my code. I have a script that downloads and processes a JSON file using $.ajax. Additionally, I utilize the moveToLocation() function for filtering, which works fine except for issues with markerclusters where my points remain clust ...

What is the best way to organize React components/modules in order to effectively separate the UI?

Currently, I have developed three key components for a dashboard UI project in React. These components include a sidebar, top navigation bar, and a content container. As someone who is new to React after working with Angular, I am now seeking advice on how ...