Jump to content

Multiple lists and loops into dynamic reusable piece of code


arjen
 Share

Recommended Posts

$jurisdictionsPageChildren = $pages->get(1011)->children();

// Check whether there are any children before attempting to split them
if($jurisdictionsPageChildren > 0) {

// Some general vars
$rows = 2;
$totalCount = count($jurisdictionsPageChildren);
$rowCount = $totalCount / $rows;
// Creating the seperate list (there has to be an easier way to do this)
$firstList = $jurisdictionsPageChildren->slice(0, $rowCount);
$secondList = $jurisdictionsPageChildren->slice($rowCount, $totalCount)

$mainContent .= "<div class='row jurisdictions-list'>";

// First list of elements
$mainContent .= "<div class='columns six alpha'>";
foreach($firstList as $child) {	
 $mainContent .= "<h2><a$class href='{$child->url}' title='{$child->title}'>{$child->title}</a></h2>";
}
$mainContent .= "</div>";

// Second list of elements
$mainContent .= "<div class='columns six omega'>";
foreach($secondList as $child) {	
 $mainContent .= "<h2><a$class href='{$child->url}' title='{$child->title}'>{$child->title}</a></h2>";
}
$mainContent .= "</div>";

$mainContent .= "</div>"; // Close the row class

}

Okay, here is the deal. I have one list ($jurisdictionsPageChildren) which I want to split into multiple blocks/columns. I would like to adjust this code so I can set the $rows variable to some number.

The condition is that the first block (regardless of the number of blocks) has to have a class 'alpha' and that every last block has to have a class 'omega'.

I was thinking to put a foreach in a foreach, but somewhere things got messed up. If this was JSP it would do it like this:

<c:set var="splittedListHere" value="$(rpfn:splitListFunction(listHere, 2))" />
<c:forEach items="splittedListHere" var="list" varStatus="i">
 <div class="block$(i.first ? ' alpha' :'')$(i.last ? ' omega')">
more foreach stuff
 </div>
</c:forEach>

Any thoughts to make this prettier for a PHP noob are very welcome.

Link to comment
Share on other sites

Sorry, it was late and perhaps I didn't explain myself correctly. I re-edited the post to be more precise.

$jurisdictionsPageChildren = $pages->get(1011)->children();

Gives as a result: 1012,1013,1014,1015,1016,1017,101,1018,1019,1020,1021,1022,1023,1024

I would like to split those into a x amount of columns. For example: if I would set the following variable:

$columnCount = 4;

For example I would like to have 4 columns/blocks.

Column 1: 1012,1013,1014,1015

Column 2: 1016,1017,1018

Column 3: 1019,1020,1021

Column 4: 1022,1023,1024

In this case column 1 (the first) should have an extra class 'alpha' and column 4 (the last) should have an extra class 'omega'.

I already found out that I can slice arrays by using the $a->slice($n, $limit), but I have trouble understanding to iterate over those loops.

I've also tried to use a while loop for the first loop and a foreach inside the while, but I am having trouble to define $n and $limit. As you can see I can set them by hand, but I thought it would be nice to create a function that sorts things out dynamicly.

Can anyone point me in the right direction?

Link to comment
Share on other sites

I don't know how to help you here. But somehow, this should work more or less the same way as pagination does. I wonder if looking into that the module we could find something...

EDIT:

Ok, this as nothing to do with what i said above. I wrote this code on the browser, and didn't test it. So, take it as a proof of concept.

EDIT2: I simplified the code, since the only difference you want is in the class

EDIT3: corrected some more code

$rows = 4;
$totalCount = count($jurisdictionsPageChildren);
$rowCount = $totalCount / $rows;
$firstInRow = 0;
$i = 1;
while ($i <= $rows){
  $mainContent .= "<div class='columns six";
  if($i == 1) $mainContent .= " alpha";
  if($i == $rows) $mainContent .= " omega";
  $mainContent .= "'>";
  $sliced = $jurisdictionsPageChildren->slice($firstInRow, $rowCount);
  $firstInRow+=$rowCount;
  foreach($sliced as $p){
  $mainContent .= "<h2><a$class href='{$p->url}' title='{$p->title}'>{$p->title}</a></h2>";
  }
  $mainContent .= "</div>";
  $i++;
}

EDIT4: Tested the code above and it's working :)

I had to round up the $roundCount because i wasn't getting the last row with less pages. I used ceil() for that. So, final code would be:

$rows = 4;
$totalCount = count($jurisdictionsPageChildren);
$rowCount = ceil($totalCount / $rows); // <- this is what changed
$firstInRow = 0;
$i = 1;
while ($i <= $rows){
  $mainContent .= "<div class='columns six";
  if($i == 1) $mainContent .= " alpha";
  if($i == $rows) $mainContent .= " omega";
  $mainContent .= "'>";
  $sliced = $jurisdictionsPageChildren->slice($firstInRow, $rowCount);
  $firstInRow+=$rowCount;
  foreach($sliced as $p){
  $mainContent .= "<h2><a$class href='{$p->url}' title='{$p->title}'>{$p->title}</a></h2>";
  }
  $mainContent .= "</div>";
  $i++;
}

post-88-0-44366900-1333461055_thumb.png

post-88-0-36363400-1333461065_thumb.png

post-88-0-92673800-1333461210_thumb.png

Link to comment
Share on other sites

Another edit deserves a new post... I noticed that the previous approach didn't work in some situations where last row wouldn't have any page to populate it (on the first screenshot there is an example with 7 rows and 23 pages). I'm not very good at maths, but I thought that, knowing the mod we could distribute the pages in another way. So, here is the new code with the changes commented:

$rows = 7;
$totalCount = count($jurisdictionsPageChildren);
$rowCount = ceil($totalCount / $rows);
$mod = $totalCount % $rows; // this will tell us how many rows will have more pages than the others
$firstInRow = 0;
$i = 1;
while ($i <= $rows){
  $mainContent .= "<div class='columns six";
  if($i == 1) $mainContent .= " alpha";
  if($i == $rows) $mainContent .= " omega";
  $mainContent .= "'>";
  if($i <= $mod){ // do this when we want one more page on the row
     $sliced = $jurisdictionsPageChildren->slice($firstInRow, $rowCount);
     $firstInRow += $rowCount;
  }else{ // do this when we want one less page on the row
     $sliced = $jurisdictionsPageChildren->slice($firstInRow, $rowCount-1);
     $firstInRow += $rowCount-1;
  }
  foreach($sliced as $p){
     $mainContent .= "<h2><a$class href='{$p->url}' title='{$p->title}'>{$p->title}</a></h2>";
  }
  $mainContent .= "</div>";
  $i++;
}

and on the other screenshots, the working version

post-88-0-40363400-1333469971_thumb.png

post-88-0-62810300-1333469978_thumb.png

post-88-0-64356000-1333470236_thumb.png

  • Like 3
Link to comment
Share on other sites

Glad you liked it. I think i'm going to try to make this a module. I got some more ideas like sorting the elements in a horizontal way. I use a lot lists and this seems very reusable. Got to finish this project and then I think I have some spare time to try this.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...