Eric
Eric

Reputation: 574

How to get count of rows and columns in javascript for flexbox and grid layout?

flexbox like this:

display: flex;
flex-flow: row wrap;

and grid like this:

display: grid;
grid-template-columns: repeat(auto-fill, 20px);

dynamically arrange items, and the counts of rows and columns are not fixed.

I'm not sure it's one problem or two, as there may be different solutions for flexbox and grid. For now I ask in a time anyway.

How can I get the count of rows and columns? And further get item by row index and column index?

See https://jsfiddle.net/w2L8oumw/16/ as an example. Drag the frame border to make the width of the result window change, such that counts of rows and columns change, too.

My idea is to iterate all items and decide their row index and column index according to their position, on initializing, item changing and resizing.

Upvotes: 8

Views: 6888

Answers (3)

knigge
knigge

Reputation: 493

The questions is al little bit older but in case anybody needs this:

If you are working with CSS-Grid you don't need so much calculation. You can get the current template settings e.g. with

getComputedStyle(container).getPropertyValue("grid-template-rows")

in modern Browsers this returns the actual values, not the values from your css, so you get a string like

250px 250px 250px

you can than calculate the current number of rows by splitting the string and counting the elements in the resulting array.

This might work in older IEs as well, I did not test it.

Upvotes: 7

Sachink
Sachink

Reputation: 1530

We need to calculate and find, please find below function function setrIdcId(containerId). Now I am calling on the button click. You can call when you required. (on the scroll or resize). Fiddle updated

var GetItemOfContainer = function (container, rIdx, cIdx) {
	// solution code here
}

function setrIdcId(containerId){
  _el = document.getElementById(containerId);
  _boxes = _el.children;
	var colCnt = Math.floor((_el.offsetWidth)/50); //Number of Column;  50:box width
  var rowCnt = Math.ceil(_boxes.length/colCnt); //Number of Rows
  for(var i = 0; i < _boxes.length; i++) {
    var cIdx = Math.floor(i / colCnt);   // X
    var rIdx = Math.floor(i % colCnt); // Y
    _boxes[i].innerHTML = cIdx +":"+ rIdx;  // Print // 
  }
}
#flexbox{
  display:flex;
  flex-flow: row wrap;
  height:30vh;
  width:30vw;
  background:black;
  padding:5px;
  margin:5px;
}

#flexbox > div{
  height:40px;
  width:40px;
  background:purple;
  margin:5px;
}

#grid{
  display:grid;
  grid-template-columns: repeat(auto-fill, 40px);
  grid-gap: 10px;
  height:30vh;
  width:30vw;
  background:black;
  padding:5px;
  margin:5px;
}

#grid > div{
  height:40px;
  /*width:40px;*/
  background:purple;
}
<div id="grid">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<button onClick="setrIdcId('grid')" type="button">Call
</button>

Upvotes: 0

I. Ahmed
I. Ahmed

Reputation: 2534

One sample solution for calculating the columns is given below for flexbox, for row and grid you have to do similar calculation for row.

You may need to add or remove some calculation.

var getComputedValue = function (container, cssProp) {
   return parseInt(window.getComputedStyle(container, null).getPropertyValue(cssProp).split('px')[0]);
};

var calcColms = function() {
  var container = document.getElementById("flexbox");

  var parentWidth = getComputedValue(container,"width");
  var parentPaddingLeft = getComputedValue(container,"padding-left");
  var parentPaddingRight = getComputedValue(container,"padding-Right");

  var child = container.firstElementChild;
  var childWidth =  getComputedValue(child,"width");
  var childMarginLeft = getComputedValue(child,"margin-left");
  var childMarginRight = getComputedValue(child,"margin-right");

  var parentWidthNoPadding = parentWidth - parentPaddingLeft - parentPaddingRight;

  var childWidthWithMargin = childWidth + childMarginLeft + childMarginRight;
  parentWidthNoPadding = parentWidthNoPadding + childMarginLeft + childMarginRight;
  var noCols = parseInt(parentWidthNoPadding / childWidthWithMargin);
  console.log(noCols);
}

window.onload = function () {
  calcColms();
};

window.onresize = function () {
  calcColms();
};
#flexbox{
  display:flex;
  flex-flow: row wrap;
  height:30vh;
  width:30vw;
  background:black;
  padding:5px;
  margin:5px;
}

#flexbox > div{
  height:40px;
  width:40px;
  background:purple;
  margin:5px;
}

#grid{
  display:grid;
  grid-template-columns: repeat(auto-fill, 40px);
  grid-gap: 10px;
  height:30vh;
  width:30vw;
  background:black;
  padding:5px;
  margin:5px;
}

#grid > div{
  height:40px;
  /*width:40px;*/
  background:purple;
}
<div id="flexbox">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

<div id="grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

Upvotes: 0

Related Questions