Welcome back to this week’s CCB API tutorial.
Picking up from where we ended last week’s tutorial, today’s tutorial works to extend last week’s tutorial that displayed Group Areas, Meeting Days and Meeting Times Values as drop down menus.
Specifically, I’m sharing with you today how to create your very own custom group search display for your church website.
Of course, you can always fall back to CCB’s native group search functionality. However, there is a substantial loss in the ability to customize.
Nevertheless, that’s the very reason I’m sharing today’s tutorial. By the end of this tutorial, you’ll have an interactive group search that displays groups on your website.
And the bonus is that you’ll be able to apply your own CSS styling that matches your website, although custom styling is not covered in this tutorial.
Well, we don’t have time to waste, so let’s get started.
Modifications to Existing Codebase
Keep in mind that you’ll certainly need to review the previous tutorial to understand the inner workings up until now. 😉
As a starting point, open a text editor of your choice, and name and save the following file: display-groups.php.
Now copy the codebase from the previous tutorial, pasting the code into the newly created display-groups.php file.
One of the first modifications we’ll make to the codebase is adding an external link to Google’s Content Delivery Network (CDN) for jQuery 3.1.1.
The following code needs to be added directly below the HTML <title> tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js" defer></script>
Adding jQuery library allows for access to enabling the necessary functionality to provide interactive drop down menus that trigger the group search and display code we’ll soon write.
Next, we’ll add a table header row immediately following the Meeting Time table row cell for the Childcare heading:
<td width="20%">Childcare</td>
Next, you’ll need to create a table row cell the contains the following Childcare drop down menu immediately following the meetingTimeValues table row cell:
<td> <select name="childcare" id="childcare"> <option value="#">Please select one</option> <option value="1">Yes</option> <option value="0">No</option> </select> </td>
To display group search results when triggered by drop down menu selection, create a new table row and cell, specifying the column span value as 4 (since we have 4 header and data columns) and the dom id value of td equal to results (as shown below).
In addition, ensure that the table has a width of 80% and center aligned (see code below in its entirety).
Last but not least, just as you did with adding the Google jQuery external link, add an external link to a javascript file that we’ll soon create: groups-script.js.
The group-script.js file will contain all the brains and heavy-lifting javascript magic to bring group-search.php’s interactive functionality to life.
Notice the source link of the file contains the query parameter that is set equal to use and echo PHP’s built-in rand function.
<script src="groups-script.js?query=<? echo rand(1,250); ?>" defer></script>
The use of the query parameter having a randomly generated number between 1 and 250 always forces javascript to be fresh on ALL page loads instead of using browser cache of file, as it often the case without such functionality.
In addition, take note of the defer attribute set within the script tag, which essentially means that this javascript file will be loaded last and not first.
<?PHP // contains resusable globals and functions include("includes/config.php"); //Area Values $lookupService = 'area_list'; $areaValues = getLookup($lookupService); //Meeting Day $lookupService = 'meet_day_list'; $meetingDayValues = getLookup($lookupService); //Meeting Time $lookupService = 'meet_time_list'; $meetingTimeValues = getLookup($lookupService); function getLookup($tableService){ $apiService = $tableService; // CCB api service $urlData = array_filter( array( 'srv' => "$apiService" ) ); $rss = ccbDetails('get',$urlData); // transform to XML $nodes = $rss->xpath('//items/item'); // xpath for items->item $response_object = '<select name="'.$apiService.'" id="'.$apiService.'">'; $response_object .= '<option value="#">All</option>'; foreach ($nodes as $node) { $response_object .= '<option value="'.$node->id.'">'.$node->name.'</option>'; // now print the item name and it (See CCB API documentation for more $apiService fields) } $response_object .= '</select>'; return $response_object; } ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Group Drop Downs</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js" defer></script> </head> <body> <table width="80%" align="center"> <tr> <td width="20%">Area</td> <td width="20%">Meeting Day</td> <td width="20%">Meeting Time</td> <td width="20%">Childcare</td> </tr> <tr> <td><? echo $areaValues; ?></td> <td><? echo $meetingDayValues; ?></td> <td><? echo $meetingTimeValues; ?></td> <td> <select name="childcare" id="childcare"> <option value="#">Please select one</option> <option value="1">Yes</option> <option value="0">No</option> </select> </td> </tr> <tr> <td id="results" colspan="4"><td> </tr> </table> <script src="groups-script.js?query=<? echo rand(1,250); ?>" defer></script> </body> </html>
Bringing Drop Down Menus to Life With Javascript and jQuery
As mentioned in the previous, you’ll need to name and save the following file: group-script.js.
Currently, the display-groups.php file is nothing but a dull page with 4 drop down menus that don’t do a thing but show selections.
Even once selected, the drop down menus do nothing. But that’s about to change in this section as we complete the necessary javascript and jQuery scripting necessary to bring life to each drop down menu and the page in general as it displays group listings.
To start, ensure that you invoke the document ready or onReady function as provide by jQuery (shown below).
Next, to make it where each drop down triggers a group search upon selection, use jQuery’s built-in .each function.
This nifty function allows for quite a bit of time savings and reduces the number of lines of code we’ll need to write.
Instead of writing 4 different functions, we write one function that is applied to each <select> tag. Within the function, set selectId and selectedId variables as shown below.
The next step is to identify each drop down menu (i.e, <select>) tag’s respective id to apply jQuery’s built-in .change function.
The .change jQuery function when binding to the select menu drop down allows for applying a specific trigger, action, or custom function.
Within the .change jQuery function, now instantiate a function we’ll call compileGroups. The reason we’re using a function is to reduce the amount of code.
Granted, it would be easier to simply place the code within the .change jQuery function and roll with it. However, we must think of reuse and refactoring.
In addition, one thing to think about and consider is that the page doesn’t display groups on page (hint, hint).
For this reason, the compileGroups function now can be used anywhere within the javascript file. 😉
Now close both the .change and .each jQuery functions, and don’t forget to immediately instantiate the compileGroups function so that groups are displayed upon initial page load.
$(document).ready(function() { //javascript logic $("select").each(function(i) { var selectId = $(this).attr('id'); var selectedId = "#"+selectId; $(selectedId).change(function(){ compileGroups(); }); }); compileGroups(); });
Making compileGroups Function execute Group Search
In the last section, the compileGroups function was introduced and instantiated.
It’s good the compileGroups function has been instantiated, yet the function is empty. But no worries, as we’re about to change all of that in this section.
In the same file and immediately following the instantiated compileGroups function, define the compileGroups function.
Within the function, define a resultsDiv and attrValues variables.
The resultsDiv variable should be set equal to the results id using jQuery selector. The resultsDiv variable is referenced later in the tutorial when adding interactive messages and displaying group data.
Speaking of displaying interactive messages, we’ll need to inform the user when a drop down is selected that we are performing a search.
To do so, use the resultsDiv variable binded to the .html jQuery method. Within the .html method, we’ll pass or place within it a HTML data string (as shown) below.
function compileGroups(){ var resultsDiv = $("#results"); resultsDiv.html('<br><br><p>Retrieving groups... please wait...</p>'); });
The attrValues variable should be set equal to an empty array. The attrValues variable is used to capture the selected options of all drop down menus as an array, which we’ll cover next.
function compileGroups(){ var resultsDiv = $("#results"); resultsDiv.html('<br><br><p>Retrieving groups... please wait...</p>'); var attrValues = []; });
Once resultsDiv and attrValues have been defined, it’s time to capture the selected values of each of the drop down menus (i.e. <select>).
To recap, the compileGroups function is instantiated each time a selection is made using a drop menu. And each time this happens, selected values for all drop down menus must be obtain so that the correct groups are displayed.
To capture selected values for each of the drop down menus, use the .each jQuery function for each <select> tag, just like in the previous section.
With the .each function, set a idValue variable that is equal to current drop down menu’s selected value as indicated using the .val .jQuery method.
Next, add or push the idValue variable into the attrValues variable array using the .push method. Now the attrValues variable contains a zero-index array of all the drop menus and their respective values.
function compileGroups(){ var resultsDiv = $("#results"); resultsDiv.html('<br><br><p>Retrieving groups... please wait...</p>'); var attrValues = []; $("select").each(function() { var idValue = $(this).val(); attrValues.push(idValue); }); });
Now, it’s time to prepare an AJAX call to POST the drop down menu data so that a CCB API call can be made to retrieve group data using the group_search CCB API service that’s found in an external PHP file.
But before we do, we need to ensure that our data is passed as JSON using the JSON.stringify method. Simply create a attrArray and set it equal to JSON.stringify method, passing the attrValues as the argument.
Now we ready to create the AJAX call. To instantiate AJAX call to POST data, we’ll use .ajax, a jQuery built-in method. In short, the following is defined to POST the AJAX call:
- method is defined at POST
- url is defined as group-search.php (we’ll cover in the next section)
- data is a JSON string, rather array that binds values to the attrArray variable
In addition, we’ll add both .done and .fail jQuery methods to the .ajax method as a simple level of error checking. Within both .done and .fail jQuery methods, the resultsDiv variable is binded to the .html jQuery method once more (see code below).
Note that both methods pass a msg variable as it function argument that is used within the html of the binded resultsDiv and .html method.
As it pertains to the .done method, the msg variable is actually the group data that is returned from the group-search .php upon success, rather when call is completed.
And believe it or not, this rounds out the compileGroups function.
$(document).ready(function() { //javascript logic $("select").each(function(i) { var selectId = $(this).attr('id'); var selectedId = "#"+selectId; $(selectedId).change(function(){ compileGroups(); }); }); compileGroups(); function compileGroups(){ var resultsDiv = $("#results"); resultsDiv.html('<br><br><p>Retrieving groups... please wait...</p>'); var attrValues = []; $("select").each(function() { var idValue = $(this).val(); attrValues.push(idValue); }); var attrArray = JSON.stringify(attrValues); $.ajax({ method: "POST", url: "group-search.php", data: { values: attrArray } }) .done(function( msg ) { resultsDiv.html(msg); //console.log( "Success: " + msg ); }) .fail(function( msg ) { resultsDiv.html('An error has occurred: <b>'+msg+'</b>. Please contact your Administrator.'); //console.log( "Failure: " + msg ); }); } });
Retrieving Group Search Data via group-search.php
Don’t get weary on me just yet! You’re almost to the finish line to sing and rejoice with a functional group search tool that’ll soon be ready to be customized and styled to look like your website.
At this point in the tutorial, you now have the following:
- A PHP file that displays drop downs and group search results (displays-groups.php)
- A Javascript file that provides interactive triggers for obtaining select menu data and showing groups (groups-script.js)
Now, it’s actually time for the heavy lifting and retrieving CCB group search data via the group_search CCB API service.
Quite honestly, this section is really easy because it’s much like previous tutorials with one to two additional steps.
So with the text editor open, name and save the following file: group-search.php.
From the previous tutorial, copy the code INSIDE of the getLookup function and paste into the group-search.php file as your base code.
BEFORE this code, be sure to include the config.php so that access to the ccbDetails function is possible.
Next, we’ll need to access the JSON data discussed in the previous section.
To do so, set a data variable equal to the $_REQUEST variable accessing the values POST variable encapsulated within PHP built-in methods: stripslashes and json_decode. In short, this creates a zero-indexed PHP array.
Next, ensure that the apiService variable is equal to the group_search CCB API service.
This is where things will change up a bit from our normal tutorial. In previous tutorials, we define the urlData variable, which is an encapsulated key-value pair array, that is passed to the ccbDetails function.
However, we’ll need to assemble the urlData variable’s value based upon the data variable array values. In short, set an empty array variable named servArr.
Next, set an array key that binds servArr to the apiService variable. Following this, the series of if statements must be used to determine when to set the various group_search optional parameters (see CCB documentation for further explanation of optional parameters for group_search API service).
Essentially, if the data variable array value is not equal to the pound or hash (#) sign, then set the following servArr variable array key to its respective data variable array value:
- area_id is equal to 0 index value
- meet_day_id is equal to 1 index value
- meet_time_id is equal to 2 index value
- childcare is equal to 3 index value
Once this is completed, then pass the servArr variable to the PHP built-in array_filter method that is the value of the urlData variable.
Now jump to the first response_object variable and make it an empty variable instead of a string of html text that starts a select drop down menu.
Immediately following the first response_object variable, set i variable to equal 0 (zero). The i variable is used as a counter or increment to determine the number of groups to display per row and that is later discussed.
Next, we need to prepare to display the total number of groups. To do so, create a totalGroups variable and set it equal to PHP’s sizeof method with nodes variable as the argument.
Now change the second concatenated response_object variable from the option all selection HTML string to read the “Total Groups Showing:…” message (see code below).
Okay, before moving onto the foreach statement modifications, we actually need to place the foreach statement inside the else section of the if else statement we’re creating next.
The reason for this if else statement we’re creating is providing a better user experience for when do or do not have groups to display.
In short, if total groups is less than 0 (zero), then show a “No groups available” message. However, if more than 0 (zero) groups, then we execute the normal foreach statement as we have in previous tutorials.
But not so fast there, because the foreach statement will have modifications of its own too.
The first is including a if statement that only focuses on a specific group name. For this tutorial, I’m focusing on returning groups that have a grouping_name equal to Community Groups.
Within the group_name if statement, if statements are implemented to start and end the HTML table rows.
In short, if the i variable is less than 1 (one), then I know that we are starting a new table row.
If the i variable is equal to for 4 (four), then I know that the table row can end and I reset the i variable to 0 (zero), which is indicative to start a new row should their be more groups to iterate in the foreach statement.
And in between those two if statements lies yet another concatenated response_object variable that encapsulates the following fields with HTML:
- name
- grouping_name
- description
- meet_day_name
- meet_time_name
- area_name
- owner_email_primary
Immediately following the the response_object variable is the i variable followed by two plus signs (++), which is indicative of incrementing the variable by 1 (one). This incrementing of the i variable in conjunction with the if statements to compare its value triggers the starting and ending of table rows.
Finally, change the final concatenated response_object variable’s value to be the closing </table> HTML tag, and replace the return with echo and we’re all set to test.
<?PHP // contains resusable globals and functions include("includes/config.php"); $data = json_decode(stripslashes($_REQUEST['values'])); $apiService = 'group_search'; // CCB api service $servArr = array(); $servArr['srv'] = "$apiService"; if($data[0] != "#") $servArr['area_id'] = "$data[0]"; if($data[1] != "#") $servArr['meet_day_id'] = "$data[1]"; if($data[2] != "#") $servArr['meet_time_id'] = "$data[2]"; if($data[3] != "#") $servArr['childcare'] = $data[3]; $urlData = array_filter( $servArr ); $rss = ccbDetails('get',$urlData); // transform to XML $nodes = $rss->xpath('//items/item'); // xpath for items->item $response_object = ''; $i = 0; $totalGroups = sizeof($nodes); $response_object .= '<p> </p><p>Total Groups Showing: <b>'.$totalGroups.'</b></p><table cellpadding="8" cellspacing="4" border="0" width="100%" align="center">'; if($totalGroups < 0){ $response_object .= '<tr>'; $response_object .= '<td>No groups available.</td>'; $response_object .= '</tr>'; } else { foreach ($nodes as $node){ if($node->grouping_name == 'Community Groups'){ if($i < 1) $response_object .= '<tr>'; $response_object .= '<td width="25%" valign="top" style="border: 1px solid #cacaca;"><b>'.$node->name.'</b> ('.$node->grouping_name.')<br>'.$node->description.'<br><br>We meet '.$node->meet_day_name.' '.$node->meet_time_name.'s at '.$node->area_name.'.<br><a href="'.$node->owner_email_primary.'">Email Group Leader</a></td>'; // now print the item name and it (See CCB API documentation for more $apiService fields) $i++; if($i == 4){ $response_object .= '</tr>'; $i = 0; } } } } $response_object .= '</table>'; echo $response_object; ?>
Time to test and hope for the best
Well, you made it. It’s time to check and validate that all of your files contain the code as shown in previous sections. Save all of your files, and simply open the display-groups.php file in a web browser.
Hopefully, your web browser displays something that looks like the image below:
If not, then feel free to drop me a message below and I’ll help you troubleshoot your issue.
Congratulations if you did manage to display your groups with fully functioning drop down menus. You’re one step closer to making your dream come true hosting your very own group search tool via your church’s website.
Truth be told, this tutorial is only the beginning for where you can take it. This group search tool covered in today’s tutorial is a simple feature that has much room for improvement and additional functionality.
For instance, instead of an email link for each group, you could implement your own pop form that sends an email to group leader and places individuals in a Community Groups process and queue to be followed up by the Pastor or team of individuals.
You could also choose to display groups with pictures similar to how our church does.
Then there is an idea around displaying groups via a Google Map, and many more ideas too…
Again, this is only the beginning of where you could take this simple tool.
In addition, the tool stands to improve in terms of the overall look and feel. With a bit of HTML and CSS magic, you could actually make the tool mobile-friendly and identical to your website’s look and feel.
I hope this tutorial helps many churches in their desire and attempt to host their own group search tool via their church website.
If you or your church would like to add greater functionality to this tutorial, then please don’t hesitate to contact and hire us for such a development project.
That’s it for this week! Whew, what a tutorial… See you back soon!