help creating a people directory listing

5 posts by 2 authors in: Forums > CMS Builder
Last Post: March 10, 2014   (RSS)

By craig_bcd - February 27, 2014

I am going to be creating a online directory, fundamentally a website membership listing (using the membership module), for a corporate intranet site I am developing.  For this directory listing page, I want to be able to allow people to click on a hyper-linked letter and get to specific names.  For example, if I have "Tom Smith" in the fullname field, I would like someone to be able to click  a hyper-linked "T" and get to people with all the names who start with "T".  I have created categories before using foreach statements to group information on a page but I am not sure if  a) there is a better way and b)how I go about pulling out the first letter of the fullname field to even create a category or what this foreach loop might look like.

Thanks for your help.

By gregThomas - February 27, 2014

Hi Craig,

How do you want the link system to work? Should clicking the link filter the page, so the page refreshes and only those with names that start with T display? Or would all of the names be displayed on the page, and clicking the T would be an internal link that takes the user to all the uses who names start with T?

You could create an array of users broken up by the first letter of their name like this:

   // load records from 'animal_wiki'
  list($animalWiki, $animal_wiki) = getRecords(array(
    'tableName'   => 'animal_wiki',
    'loadUploads' => true,
  ));



function sortByFirstLetter($array, $firstLetterField){

  $returnArray = array();

  //Loop through users
  foreach($array as $key => $item){
    
    //Set the first letter of their name to a field
    if($item[$firstLetterField]){
      $returnArray[$key] = $item;
      $returnArray[$key]['firstLetter'] = substr(strtolower($item[$firstLetterField]),0, 1);
      
    }else{
      break;
    }

  }

  //Sort by the first letter field
  return array_groupBy($returnArray, 'firstLetter', true);

}

$animalWiki = sortByFirstLetter( $animalWiki, 'name');

showme($animalWiki);

This is example code, so you'll have to make a few changes to get it working. You'll have to replace the animalWiki array with your array of users, and the use the fullname field in the sortByFirstLetter function.

So the function I've created will break the users up into sub arrays based on the first letter of their name. You could use a foreach loop to cycle through each letter, then a second loop inside the first to cycle through each user.

Let me know if you have any questions.

Thanks!

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By craig_bcd - March 7, 2014 - edited: March 7, 2014

Greg -

Thanks so much, that was very helpful.  You have been so helpful so far, I need just a little more help:

1 - I am getting an undefined index error on line 37 but yet it works - I see firstLetter and it is sorted correctly I am hoping you can see where that is coming from (I attached the page code) here is the live path: http://www.xanitoshq.com/cd/cd-fn.php

2 - you asked about how i want the nav to work, I think I would like it it to open with the nav and show all the letters (the valid ones) as links and then when you click that letter the page would refresh and only those names with that start with the selected letter would display.  It is currently about 300 records it might go to 500 but probably not much more than that.  if you think an internal link would be more efficient, that could work as well, because it will probably be used heavily on mobile devices I am trying to keep the quantity of data pushed at any one time to a minimum.  I think I can achieve this with foreach loops but i am not totally sure where in the code to put them for it to be most efficient.

Thanks again Greg

ps - did not look like the attachment was coming through here is the code

<?php header('Content-type: text/html; charset=utf-8'); ?>
<?php
  /* STEP 1: LOAD RECORDS - Copy this PHP code block near the TOP of your page */
  
  // load viewer library
  $libraryPath = 'cmsAdmin/lib/viewer_functions.php';
  $dirsToCheck = array('/home/content/76/11867176/html/','','../','../../','../../../');
  foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
  if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }

  // load record from 'cd_first_name'
  list($cd_first_nameRecords, $cd_first_nameMetaData) = getRecords(array(
    'tableName'   => 'cd_first_name',
    'where'       => '', // load first record
    'loadUploads' => true,
    'allowSearch' => false,
    'limit'       => '1',
  ));
  $cd_first_nameRecord = @$cd_first_nameRecords[0]; // get first record
  if (!$cd_first_nameRecord) { dieWith404("Record not found!"); } // show error message if no record found

  // load records from 'members'   
  list($members, $members) = getRecords(array(
  //list($membersRecords, $membersMetaData) = getRecords(array(
    'tableName'   => 'members',
    'loadUploads' => true,
  ));

function sortByFirstLetter($array, $firstLetterField){

  $returnArray = array();

  //Loop through users
  foreach($array as $key => $item){
    
     //Set the first letter of their name to a field
    if($item[$firstLetterField]){
      $returnArray[$key] = $item;
      $returnArray[$key]['firstLetter'] = substr(strtolower($item['username']),0, 1);
    }else{
      break;
    }
  }

  //Sort by the first letter field
  return array_groupBy($returnArray, 'firstLetter', true);

}

$members = sortByFirstLetter( $members, 'username');
$membersRecords = sortByFirstLetter( $members, 'username');

//showme($members);

?><!DOCTYPE html>

By gregThomas - March 7, 2014

Hi Craig,

The reason you're getting the that error is because you're calling the sortByLetter function on an array that has already been sorted. You just need to remove this line:

$membersRecords = sortByFirstLetter( $members, 'username');

I think the easiest method to filter by letter would be to pass the letter you want to filter on in the URL:

cd-fn.php?letter=a

Then add a where statement that will filter on that letter to your getRecords function:

<?php header('Content-type: text/html; charset=utf-8'); ?>
<?php
  /* STEP 1: LOAD RECORDS - Copy this PHP code block near the TOP of your page */
  
  // load viewer library
  $libraryPath = 'cmsAdmin/lib/viewer_functions.php';
  $dirsToCheck = array('/home/content/76/11867176/html/','','../','../../','../../../');
  foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
  if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }

  $where = "";

  // load record from 'cd_first_name'
  list($cd_first_nameRecords, $cd_first_nameMetaData) = getRecords(array(
    'tableName'   => 'cd_first_name',
    'where'       => '', // load first record
    'loadUploads' => true,
    'allowSearch' => false,
    'limit'       => '1',
  ));
  $cd_first_nameRecord = @$cd_first_nameRecords[0]; // get first record
  if (!$cd_first_nameRecord) { dieWith404("Record not found!"); } // show error message if no record found

  if(@$_REQUEST['letter'] && preg_match('/^[a-zA-Z]$/', $_REQUEST['letter'])){
    $where =  "`username` LIKE '".$_REQUEST['letter']."%'",
  }

  // load records from 'members'   
  list($members, $members) = getRecords(array(
  //list($membersRecords, $membersMetaData) = getRecords(array(
    'tableName'   => 'members',
    'loadUploads' => true,
    'where'       => $where,
  ));

function sortByFirstLetter($array, $firstLetterField){

  $returnArray = array();

  //Loop through users
  foreach($array as $key => $item){
    
     //Set the first letter of their name to a field
    if($item[$firstLetterField]){
      $returnArray[$key] = $item;
      $returnArray[$key]['firstLetter'] = substr(strtolower($item['username']),0, 1);
    }else{
      break;
    }
  }

  //Sort by the first letter field
  return array_groupBy($returnArray, 'firstLetter', true);

}

$members = sortByFirstLetter( $members, 'username');
$membersRecords = sortByFirstLetter( $members, 'username');

//showme($members);

?><!DOCTYPE html>

So the above code will check if there is a single letter against the letter variable in the URL, then carry out a search on the username field and only return results that start with that letter.

Thanks!

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By craig_bcd - March 10, 2014 - edited: March 10, 2014

Greg -

You are a genius!  Thanks so much - can't believe I missed the duplicate array statement - too close to it I guess.  Very elegant solution.

Thanks for your help.

Regards,

Craig