Arranging HTML elements with jQuery - the existing script flips back and forth

I have created a code snippet on CodePen that showcases a feature of the website I am currently developing: http://codepen.io/barrychapman/pen/BzJGbg?editors=1010

Upon loading the page, you will notice 6 boxes. The first box is active, while the remaining 5 are disabled. By clicking the Add to Metric 2 button, you can enable the second box.

After enabling, click the Resort button to observe what happens. The field headers remain unlabeled to show you the behavior firsthand. The fields will now be rearranged as follows: [1,2,6,5,4,3].

Repeating the click on Resort will correctly sort the fields as [1,2,3,4,5,6]. Another click reverses the order back to the initial state. Here is the specific code segment responsible for this functionality:

$('#target_metrics > div.disabled').each(
  function() {
    var $this = $(this);
    $('#target_metrics').find('div.metric-template:not(.disabled)').last().after($this);
  }
);

I am facing a challenge here. My goal is to maintain the field order consistent after any modifications such as adding/enabling/disabling/removing a field. This consistency is crucial due to various data elements associated with these nodes.

Update

To demonstrate an undesired behavior, follow these steps:

  • Click Resort
  • Click Add to Metric 2
  • Click Resort

    Observe that Metric 2 appears at the end of the row.

  • Click Resort

    Now, Metric 2 is in the correct position.

  • Click Resort once more.

    The other fields have now been resorted.

Answer №1

It appears that you are indicating a preference for having it as an array of `[1,2,3,4,5,6]`, which implies that the state of being disabled is not a concern. In any case, you can simplify this process by utilizing `Array.prototype.sort` on the elements.

It is advisable to minimize consecutive DOM modifications whenever feasible (such as during iteration over an array-like object) - retrieve the data, perform the necessary operations, and then reinsert it.

If your intention is to group them based on their disabled status while still sorting them, you could initially sort all the elements, subsequently segregate them into two distinct arrays based on their disablement, and display these on the page.

Make sure to refer to the MDN's Array.sort() documentation if you haven't done so already.

JS (non-grouped)

// true === Descending order
var direction = false;

function reorderNodes( dir ) {
  var $target = $('#target_metrics');
  var $metricDivs = Array.prototype.sort.call($target.children('div').detach(), function ( a, b ) {
    var _a = a.querySelector('.idx');
    var _b = b.querySelector('.idx');
    if ( _a && _b ) {
      if ( _a.innerHTML > _b.innerHTML ) {
        return dir ? 1 : -1;
      }
      if ( _a.innerHTML < _b.innerHTML ) {
        return dir ? -1 : 1;
      }
    }
    return 0;
  });
  $target.append($metricDivs);
}

Invoke this function on each button click (if you wish to allow toggling between ascending and descending order upon each click - otherwise maintain the same direction)

reorderNodes(direction);
direction = !direction;

http://codepen.io/dhenson02/pen/WxdLwA

For the grouped version, refer to this modified version:

http://codepen.io/dhenson02/pen/ZOvVpJ

Answer №2

When rearranging your DOM elements for display purposes, consider using the CSS order property on flex items instead of manually sorting them.

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

Discovering Ajax-powered websites Here are some tips on identifying websites

My goal is to determine if a webpage makes AJAX calls. If the webpage is AJAX-based, I will wait for a few seconds to retrieve the content. If it's not AJAX-based, then I won't wait. I attempted the code below, but it didn't yield any resul ...

using jQuery to show a block element

I'm attempting to determine whether a div with the style display as block then perform an action. Here is an example: This is just an idea I'm trying to implement using jQuery. if ($("#toshow").css("display") == "block"){ }else{ } ...

Having trouble converting a string to an array in JS? Splitting doesn't seem to be doing

I encountered an issue where I am reading data from a CSV file, storing the innerHTML to a variable (named content), which the browser recognizes as a string. However, when attempting to convert it to an array, I am facing difficulties. I attempted to use ...

What was the reasoning behind Mozilla's decision to implement a conditional catch clause?

Discover the unique Conditional Catch Clauses from Mozilla Delve into this question out of pure curiosity - why would Mozilla venture beyond standard structures with this innovative feature? What specific challenges or issues is it designed to address? W ...

Using Angular 5 to link date input to form field (reactive approach)

I'm encountering an issue with the input type date. I am trying to bind data from a component. Below is my field: <div class="col-md-6"> <label for="dateOfReport">Data zgłoszenia błędu:</label> <input type="date" formC ...

Discover the optimal approach for merging two jQuery functions effortlessly

The initial function (which can be accessed at ) is as follows: $('#confirm').confirm( { msg: 'Before deleting a gallery and all associated images, are you sure?<br>', buttons: { separator: ' - ' } } ); ...

Ways to store data in the localStorage directly from a server

I'm facing an issue - how can I store data in localStorage that was received from the server? Should I use localStorage.setItem for this purpose? And how do I handle storing an array in localStorage? Or am I missing something here? import { HttpCli ...

Multi selection dropdown feature in Angular failing to populate the options

I am working on a small Angular controller that manages a dropdown menu, with the second dropdown menu populating based on the selection made in the first one. Despite my best efforts, I can't seem to populate the dropdown menus with any content from ...

Vue - the <script setup> element is unable to execute scripts

I have a functional widget from Atlassian that works as expected when used in an HTML file: <html lang="en"> <head> <script data-jsd-embedded data-key=<key> data-base-url=https://jsd-widget.atlassian.com src=https://jsd-w ...

Problem with overlapping numbers in the Vis network

I am currently working on a project using Angular 8 and Visnetwork. Everything is going well, but I am facing an issue with overlapping numbers on lines. Is there a way to adjust the position of the numbers on one line without separating the lines? Can s ...

What could be the issue with this JSON data?

After referencing this stackoverflow thread on how to return success/error messages for JQuery .ajax() using PHP, I implemented the accepted answer in my PHP script. I am returning the following json with correct headers: Content-type: application/json and ...

The delay in loading HTML content using FOSJsRoutingBundle and Ajax for a specific route parameter (ID)

I'm using FOSjSrouting in my symfony2.7 project. This is the code in my html.twig view: <table> <!--table header code ...etc... --> <tbody> {% for currentData in arrayData %} <tr> <td>{{ currentData. ...

Trouble with CSS submenus: Are your lists not appearing as they should? Potential style override

I am encountering an issue with my dropdown mega menu. I have two sets of list items that should be displayed vertically side by side with bullet points in the dropdown, but only one list is appearing despite coding for both. Additionally, the list elemen ...

What could be causing the CSS height percentage to malfunction?

I'm having trouble with some basic CSS that uses percentages. I've labeled everything and checked my code, but it still isn't working properly. Here's the CSS code snippet: .BoxHeight { height: 100%; } #Box { margin-top: 0%; mar ...

Encountering an error: Reading an undefined property - NodeJS, Express, and Mongoose

These are the two functions I have: exports.list = function (req, res){ Material.find(function(err, materials) { res.render('materials/list', {title: 'Pagina Materiali', materials: materials}); }); } exports.modify = function (req ...

jQuery Div Animation with Excluded Text

Currently, as I work on developing a website with Joomla, I have incorporated a jQuery module that adjusts the opacity of the enclosing div upon hovering over it. Unfortunately, this also affects the text within the div and gives it a less desirable appear ...

Javascript - Button animation malfunctioning after first click

One issue I'm facing is with an animation that is triggered using the onmousedown event. Another function is supposed to stop the animation when onmouseup is detected. The problem arises after the first time it works correctly. Subsequent attempts to ...

The functionality of sending form data via Express.js router is restricted

In my current project, I am developing a basic CRUD functionality in express. My goal is to utilize the express.Router() to transmit form data via the HTTP POST method. The form structure on the browser appears as follows: form.png The process was flawle ...

"Sequelize will pause and wait for the loop to finish before executing the

As someone with a background in PHP, I'm finding the concept of callbacks a bit challenging to grasp. Essentially, I need to retrieve some rows and then iterate through them to compare against another model (in a different database). However, I want ...

Javascript's second element does not trigger a click event with similar behavior

I'm currently facing an issue with displaying and hiding notification elements based on user interaction. My goal is to have multiple popup elements appear when the page loads. Then, when a user clicks the ".alert-close" element within one of the popu ...