Using jQuery to organize divs into columns

I am working with a parent div that contains 19 child divs all with the same class, structured like this:

<div id="dropdown-content1">
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
    <div class="CatsColumn"></div>
</div>

I am trying to use jQuery to dynamically wrap these child divs into 3 columns with the same class name. I have some familiarity with jQuery and think I could use .wrap(), but I am unsure how to instruct jQuery to select the first 7 child divs, then the next 7, and finally the remaining 5 in order to wrap each group into its own div, effectively creating 3 columns. Any guidance on how to accomplish this would be greatly appreciated!

Answer №1

To achieve this using CSS, one method is to utilize column-count. Check out CSS multi-column layouts.

#dropdown-content1 {
  -moz-column-count: 3;
  -webkit-column-count: 3;
  column-count: 3;
}

#dropdown-content1 {
  -moz-column-count: 3;
  -webkit-column-count: 3;
  column-count: 3;
}
<div id="dropdown-content1">
  <div class="CatsColumn">1</div>
  <div class="CatsColumn">2</div>
  <div class="CatsColumn">3</div>
  <div class="CatsColumn">4</div>
  <div class="CatsColumn">5</div>
  <div class="CatsColumn">6</div>
  <div class="CatsColumn">7</div>
  <div class="CatsColumn">8</div>
  <div class="CatsColumn">9</div>
  <div class="CatsColumn">10</div>
  <div class="CatsColumn">11</div>
  <div class="CatsColumn">12</div>
  <div class="CatsColumn">13</div>
  <div class="CatsColumn">14</div>
  <div class="CatsColumn">15</div>
  <div class="CatsColumn">16</div>
  <div class="CatsColumn">17</div>
  <div class="CatsColumn">18</div>
  <div class="CatsColumn">19</div>
</div>


If it's necessary to add wrappers to the columns, you can create a structure like this to form the DOM:

<div id="dropdown-content1">
    <div class="ColWrapper">
        <div class="CatsColumn"></div>
        ...
    </div>
    <div class="ColWrapper">
        <div class="CatsColumn"></div>
        ...
    </div>
    ...
</div>

let columns = 3;
let elements = 19;

let elementsPerCol = Math.ceil(elements / columns);

let $dropdownContent = $("#dropdown-content1");
var $colWrapper;

var currentCol = -1;
for (var i = 0; i < elements; i++) {
  if (currentCol < Math.floor(i / elementsPerCol)) {
    $colWrapper = $('<div class="ColWrapper"></div>').appendTo($dropdownContent);
    currentCol++;
  }
  
  $colWrapper.append('<div class="CatsColumn">' + i + '</div>');
}
.ColWrapper {
  outline: 1px #AAA solid;
  width: 33%;
  display: inline-block;
  vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropdown-content1">
</div>

Answer №2

A slightly different method is to utilize the slice() function:

(edited after observing the improvements made by others, so I decided to contribute as well:))

len=$('.CatsColumn').length;
cols=3; //desired number of columns
rows=Math.ceil(len/cols);


for(i=0;i<len;i+=rows) {

$('.CatsColumn').slice(i,i+rows).wrapAll("<div class='column'>");

}
.column {
  display:inline-block;
  border:1px solid red;
  vertical-align:top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropdown-content1">
    <div class="CatsColumn">1</div>
    <div class="CatsColumn">2</div>
    <div class="CatsColumn">3</div>
    <div class="CatsColumn">4</div>
    <div class="CatsColumn">5</div>
    <div class="CatsColumn">6</div>
    <div class="CatsColumn">7</div>
    <div class="CatsColumn">8</div>
    <div class="CatsColumn">9</div>
    <div class="CatsColumn">10</div>
    <div class="CatsColumn">11</div>
    <div class="CatsColumn">12</div>
    <div class="CatsColumn">13</div>
    <div class="CatsColumn">14</div>
    <div class="CatsColumn">15</div>
    <div class="CatsColumn">16</div>
    <div class="CatsColumn">17</div>
    <div class="CatsColumn">18</div>
    <div class="CatsColumn">19</div>
</div>

Answer №3

If you need to accomplish this task, you have the option to develop a jQuery plugin!

A simple function has been included to specify the desired number of columns and the class name to be used.

/* Implementing a jQuery Plugin */
(function($) {
  $.fn.columnize = function(config) {
    var defaults = {
      colCount       : 3,
      wrapperElement : $('<div class="wrapper-element">'),
      transpose      : false
    };
    config = $.extend(defaults, config || {}); // Applying defaults 
    var perColumn    = Math.ceil(this.children().size() / config.colCount);
    var colWidth     = (100 / config.colCount).toFixed(3) + '%';
    var $columns     = [];
    for (var col = 0; col < config.colCount; col++) {
      $columns.push(config.wrapperElement.clone().css({
        display : 'inline-block',
        width   : colWidth
      }));
    }
    this.children().each(function(index, child) {
      $(child).appendTo($columns[
        config.transpose !== false
          ? (index % config.colCount)     // Items added Left to Right
          : Math.floor(index / perColumn) // Items added Top to Bottom
      ]);
    });
    return this.empty().append($columns);
  };
})(jQuery);

$(function() {
  // Transforming the existing list into columns! Default is already set to 3.
  $('#dropdown-content1').columnize({
    wrapperElement : $('<div>').addClass('ColWrapper') // Overriding default wrapper.
  });
});
.ColWrapper {
  outline: 1px #DDD solid;
  vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropdown-content1">
  <div class="CatsColumn">1</div>
  <div class="CatsColumn">2</div>
  <div class="CatsColumn">3</div>
  <div class="CatsColumn">4</div>
  <div class="CatsColumn">5</div>
  <div class="CatsColumn">6</div>
  <div class="CatsColumn">7</div>
  <div class="CatsColumn">8</div>
  <div class="CatsColumn">9</div>
  <div class="CatsColumn">10</div>
  <div class="CatsColumn">11</div>
  <div class="CatsColumn">12</div>
  <div class="CatsColumn">13</div>
  <div class="CatsColumn">14</div>
  <div class="CatsColumn">15</div>
  <div class="CatsColumn">16</div>
  <div class="CatsColumn">17</div>
  <div class="CatsColumn">18</div>
  <div class="CatsColumn">19</div>
</div>

If you prefer, $.fn.wrapAll could be utilized to simplify this process. This eliminates the need for creating an array.

var childSelector = '.CatsColumn';

for (var col = 0; col < config.colCount; col++) {
  var startIndex = (col * (perColumn - 1)) + col;
  var endIndex   = startIndex + perColumn;

  $(childSelector).slice(startIndex, endIndex).wrapAll(config.wrapperElement.clone().css({
    display : 'inline-block',
    width   : colWidth
  }));
}

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

Creating a seamless design with a navigation brand and login button on the same row within a navbar

I am trying to create a fixed navbar at the top of my webpage. The goal is to have the company's logo and name on the left side, with a log-in button on the right side. After reviewing multiple examples online, I found that most of them use a navbar- ...

Automatically populate fields in WordPress using jQuery

I have a jQuery script that populates a text input field in a customized Wordpress search. The current code looks like this: $(window).load(function(){ var availableTags = [ "Option A", "Option B", "Option C", "Option D" ]; $( "#option_field" ).autocomple ...

What is the best way to show hidden content within a masked div, similar to a tooltip?

In an icon-based menu, a grid consists of several <div> elements. Each element is empty with general CSS styling and inline CSS to set the mask effect. The purpose of using images as masks is to allow the icons to be colored in different ways by cha ...

Adjusting the height of a table column to accommodate lengthy text without disrupting the layout of adjacent columns

I am encountering an issue while creating an invoice using an HTML table. The problem arises when the customer address value is too long, causing the sold by column to shift downwards. I need a way to break the customer address value when it reaches the ma ...

Navigate the page by scrolling the absolute positioned div

Is it possible to make the fancybox modal scroll with the page using fancybox 2? I want it to move along with the content rather than being fixed in the center with a max-height restriction. How can I achieve this? $('.fancybox-open').fancybox({ ...

The tag <li> is not allowing enough room for the content to expand as needed

I am trying to create a list using ul li elements. When the content inside the li exceeds the width, a scrollbar appears. However, I am encountering an issue where the li tag does not cover the entire width and spills outside. .container{ b ...

Guidance on incorporating static files with Spring MVC and Thymeleaf

I'm seeking guidance on how to properly incorporate static files such as CSS and images in my Spring MVC application using Thymeleaf. Despite researching extensively on this topic, I have not found a solution that works for me. Based on the recommenda ...

What is the best way to limit the dimension of uploaded images to a specific height and width?

function validateImageDimensions(input) { if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function(e) { $('#uploadForm + img').remove(); var img = $('<img> ...

Enhancing the appearance of the content editor with a personalized touch

I am working with a standard content editor that utilizes an iFrame as the text area. Upon changing dropdown options, it triggers the following command: idContent.document.execCommand(cmd,"",opt); Where "idContent" refers to the iFrame. One of the dropd ...

Submit Button in CKEditor Not Working Without Ajax Submission

Having an issue with the ckeditor. Downloaded the latest version and integrated it into my form like this: <form action="/news.php?frame=edit&amp;id=185" enctype="multipart/form-data" method="post" accept-charset="utf-8"> <textarea class="edi ...

Challenges with the height of the calendar component in Vuetify

I need assistance with preventing the appearance of two scroll bars while working with Vuetify's sheet and calendar components. https://i.stack.imgur.com/yBfhj.png Below is my code snippet: <template> <v-app> <v-main> & ...

In a multidimensional array, locate the key corresponding to the specified value

I am facing an issue with my code that involves an array containing various fruits with product ID and price as keys for different values. While I am able to retrieve the correct price, I am struggling to get the name of the chosen product. For instance, ...

Struggling to keep navbar fixed with a blur effect without it colliding with body content as you scroll?

I'm looking to create a sticky navbar with a blur effect similar to the one seen on (try scrolling to see the blur effect on the nav). I want it to have the following structure: My HTML code is as follows: <header class="sticky z-10 top-10"> ...

A guide on accessing information from a post form using an express.js server

Issue: Whenever the client submits a form using a post request to the server, the express server receives an empty body (req.body = {}). Objective: My goal is to retrieve req.body.username and req.body.password on a post request from the client (using the ...

Troubleshooting issue with jQuery subtraction not functioning as expected

Everything seems to be functioning correctly except for the subtraction operation. function add_culture(ele) { total=parseInt($('#total_price').val()); culture_price=parseInt($('#culture_price').val()); $(& ...

How can you remove the border when an input is in focus on Chrome or Microsoft Edge?

I need to style an input field in a way that removes the black borders/frame that appear around it when clicked on in Chrome and MS Edge. Strangely, Firefox does not display this frame/border. How can I achieve this consistent styling across all browsers? ...

CSS Menu Not Functioning Properly on iPad While Scrolling is Required

My CSS dropdown menu has mouseout and mouseover events but I'm experiencing issues on iPads and iPhones. The menu automatically closes when scrolling, making it difficult to open any links unless the menu is short enough to avoid scrolling. Does anyon ...

Update Button Colour upon clicking the Button

I have multiple buttons lined up in a row on my webpage. I want the button's color to change when I click on them. Below is a snippet of my code: $( "button.change" ).click(function() { $(this).toggleClass( "selected" ); }); .Button { font-fa ...

Adjusting iframe height based on its source URL using JQuery

Currently, I have implemented a script to adjust the height of YouTube iframes in order to maintain a 16:9 aspect ratio while keeping the width at 100% of the container. The challenge I am facing is ensuring that the script only affects YouTube videos and ...

Experiencing Difficulty Retaining Checkbox State Using LocalStorage Upon Page Reload

At the moment, I have a script that automatically clicks on a random checkbox whenever the page loads or refreshes. Through localStorage, I can also view the value of the input assigned to the randomly selected checkbox. However, I'm facing an issue ...