StuBlackett
StuBlackett

Reputation: 3857

Load an Array ordered by Alphabetical letters

I have an array of users, Like so :

Andrew Smith
Alex Williams    
Sam White
Stuart Smith

I am looking to use iOSList to create a list that would look like so....

A
Andrew Smith
Alex Williams

S
Sam White
Stuart Smith

I have made an attempt at this using a PHP Foreach loop and a break, But each user has a seperate ul each time.

My current code is as follows :

        <?php
        $currentLetter = '';
        foreach($pupils['user'] as $pupil)
        {
            $firstLetter = substr($pupil->profile_name, 0, 1);
        ?>
        <?php
            if ($firstLetter !== $currentLetter) { ?>
                <!-- SHOW FIRST LETTER -->
                    <div class="ioslist-group-container">
                        <div class="ioslist-group-header">
                            <strong>
                                <?php echo $firstLetter; ?>
                            </strong>
                        </div><!-- /.ioslist-group-header -->
                <?php $currentLetter = $firstLetter; ?>
            <?php } ?>
                <ul>
                    <li>
                        <a href="<?php echo base_url('admin/pupil/view'); ?>/<?php echo $pupil->user_id; ?>">
                            <?php echo $pupil->profile_name; ?>
                        </a>
                    </li>
                </ul>
            </div><!-- /.iostlist-group-container -->
        <?php } // END FOREACH  ?>

My HTML is being outputted as this :

<div id="pupil-list">
                                                <!-- SHOW FIRST LETTER -->
                    <div class="ioslist-group-container">
                    <div class="ioslist-group-header">
                        <strong>
                            A                       </strong>
                    </div><!-- /.ioslist-group-header -->
                                                    <ul>
                    <li>
                        <a href="http://local.wld-hub/admin/pupil/view/10">
                            Adam Bragg                      </a>
                    </li>
                </ul>
                </div><!-- /.iostlist-group-container -->
                                                <!-- SHOW FIRST LETTER -->
                    <div class="ioslist-group-container">
                    <div class="ioslist-group-header">
                        <strong>
                            S                       </strong>
                    </div><!-- /.ioslist-group-header -->
                                                    <ul>
                    <li>
                        <a href="http://local.wld-hub/admin/pupil/view/11204">
                            Sam acclaiminapp                        </a>
                    </li>
                </ul>
                </div><!-- /.iostlist-group-container -->
                                            <ul>
                    <li>
                        <a href="http://local.wld-hub/admin/pupil/view/11194">
                            Sam NormalEmail                     </a>
                    </li>
                </ul>
                </div>

The last 2 elements are breaking out of the "pupil-list"

broken menu

Where am I going wrong and how can I correct it?

Cheers

Upvotes: 0

Views: 196

Answers (3)

Ja͢ck
Ja͢ck

Reputation: 173572

The problem seems to be that you're not properly closing your elements at the end of each group; you could check whether $firstLetter is empty and close </div> if it's not (empty); this would have to be repeated at the end as well.

Alternatively, build an intermediate structure:

$tmp = [];
foreach ($pupils['user'] as $pupil) {
    $tmp[$pupil->profile_name[0]][] = $pupil->profile_name);
}

foreach ($tmp as $letter => $names) { ?>
    <div class="ioslist-group-container">
      <div class="ioslist-group-header">
        <strong><?php echo $firstLetter; ?></strong>
      </div>
      <ul>
      <?php foreach ($names as $name) { ?>
        <li>
          <a href="<?php echo base_url('admin/pupil/view') . '/' . $pupil->user_id; ?>"><?php echo $pupil->profile_name; ?></a>
        </li>
      <?php } ?>
      </ul>
    </div>
<?php }

Keep in mind that you should escape your output using either htmlspecialchars() or urlencode() depending on what's being escaped.

Upvotes: 1

Kulvar
Kulvar

Reputation: 1179

You make user list with only one item each time.

<?php
// Display user list
$currentLetter = '';
foreach($pupils['user'] as $pupil)
{
    $firstLetter = $pupil->profile_name[0];
    if($firstLetter !== $currentLetter)
    {
        // If it's not the first loop, we close the list and block containers
        if($currentLetter !== '')
        {
        ?>
            </ul>
        </div>
        <?php
        }
    ?>
        <!-- SHOW FIRST LETTER -->
        <div class="ioslist-group-container">
            <div class="ioslist-group-header">
                <strong><?php echo $firstLetter; ?></strong>
            </div><!-- /.ioslist-group-header -->
            <ul>
    <?php
    }
?>
                <li><?php echo $pupil->profile_name; ?></li>
<?php
}
// Close the last list and block containers
?>
            </ul>
        </div>
<?php
// End of display

Upvotes: 1

KIKO Software
KIKO Software

Reputation: 16688

I don't like the mixing of PHP and HTML in your example. I prefer to go for all PHP code. Your basic idea is correct but it would become:

function showFirstLetter($letter)
{
  echo '<div class="ioslist-group-header"><strong>'.$letter.'</strong></div>';
}

function showPupilName($pupil)
{
  $url = base_url('admin/pupil/view').'/'.$pupil->user_id;
  echo '<li><a href="'.$url.'">'.$pupil->profile_name.'</a></li>';
}

echo '<div class="ioslist-group-container">'; // start container

$currentLetter = '';
foreach($pupils['user'] as $pupil)
{
  $firstLetter = substr($pupil->profile_name,0,1);
  if ($firstLetter !== $currentLetter) 
  { 
    if ($currentLetter != '') echo '</ul>'; // end list
    showFirstLetter($firstLetter);
    $currentLetter = $firstLetter; 
    echo '<ul>'; // start list
  } 
  showPupilName($pupil);
} 

echo '</ul></div>'; // end last list and container

Lots of things can be improved in this code, but when your code is more legible you can see your error much quicker. In this case the ul list tags were the problem.

Upvotes: 2

Related Questions