Added more mapping features and started doing search form
authorChuck Scott <cscott@gaslightmedia.com>
Wed, 18 Mar 2015 21:45:40 +0000 (17:45 -0400)
committerChuck Scott <cscott@gaslightmedia.com>
Wed, 18 Mar 2015 21:45:40 +0000 (17:45 -0400)
classes/data/dataCategories.php
classes/glmPluginSupport.php
config/plugin.ini
controllers/front.php
css/front.css
misc/notes.txt [new file with mode: 0644]
models/front/members/list.php
views/admin/configure/amenities.html
views/front/members/detail.html
views/front/members/list.html

index 83629fa..40db513 100644 (file)
@@ -303,10 +303,9 @@ class GlmDataCategories extends GlmDataAbstract
     public function getListSortedParentChild() {
 
         $categories = $this->getList();
+        $categoriesSorted = $this->sortParentChild($categories);
 
-        $categories = glmMembersAdmin::sortParentChild($categories);
-
-        return $categories;
+        return $categoriesSorted;
 
     }
 
@@ -337,6 +336,56 @@ class GlmDataCategories extends GlmDataAbstract
         return $r;
     }
 
+    /*
+     * Sort a database result array (from DataAbstract.php) by parent, child relationships
+     *
+     * @param array $array Array to be sorted
+     * @param string $name Name of array element that represents the text to sort on
+     * @param string $parent Name of the array element that represents the parent ID to sort on
+     *
+     * @return array Sorted array
+     */
+    public static function sortParentChild($array, $name = 'name', $parent = 'parent')
+    {
+
+        if (!is_array($array) || count($array) == 0) {
+            return false;
+        }
+
+        // Do a sort by custom function with it included in the call
+        // This lets me directly use $name and $parent in the sort function
+        uasort($array, function ($a, $b) use ($name, $parent) {
+
+            // If there's a parent, append the name of this entry to the parent
+            // The '~~~' simply keeps appended strings from any chance of a match with something else
+            if ($a[$parent]['value']) {
+                $aVal = $a[$parent]['name'].'~~~'.$a['name'];
+            } else {
+                // Otheriwse just use the name.
+                $aVal = $a['name'];
+            }
+
+            // Same for b value
+            if ($b[$parent]['value']) {
+                $bVal = $b[$parent]['name'].'~~~'.$b['name'];
+            } else {
+                $bVal = $b['name'];
+            }
+
+            if ($aVal > $bVal) {
+                return 1;
+            }
+
+            if ($aVal < $bVal) {
+                return -1;
+            }
+
+            return 0;
+
+        });
+
+            return $array;
+    }
 
 }
 
index ec9c511..7be41a5 100644 (file)
@@ -113,58 +113,6 @@ class GlmPluginSupport
 
     }
 
-    /*
-     * Sort a database result array (from DataAbstract.php) by parent, child relationships
-     *
-     * @param array $array Array to be sorted
-     * @param string $name Name of array element that represents the text to sort on
-     * @param string $parent Name of the array element that represents the parent ID to sort on
-     *
-     * @return array Sorted array
-     */
-    public static function sortParentChild($array, $name = 'name', $parent = 'parent')
-    {
-
-        if (!is_array($array) || count($array) == 0) {
-            return false;
-        }
-
-        // Do a sort by custom function with it included in the call
-        // This lets me directly use $name and $parent in the sort function
-        uasort($array, function ($a, $b) use ($name, $parent) {
-
-            // If there's a parent, append the name of this entry to the parent
-            // The '~~~' simply keeps appended strings from any chance of a match with something else
-            if ($a[$parent]['value']) {
-                $aVal = $a[$parent]['name'].'~~~'.$a['name'];
-            } else {
-                // Otheriwse just use the name.
-                $aVal = $a['name'];
-            }
-
-            // Same for b value
-            if ($b[$parent]['value']) {
-                $bVal = $b[$parent]['name'].'~~~'.$b['name'];
-            } else {
-                $bVal = $b['name'];
-            }
-
-            if ($aVal > $bVal) {
-                return 1;
-            }
-
-            if ($aVal < $bVal) {
-                return -1;
-            }
-
-            return 0;
-
-        });
-
-        return $array;
-    }
-
-
 }
 
 ?>
\ No newline at end of file
index eaee2ad..685cbac 100644 (file)
@@ -34,13 +34,16 @@ thumb['crop'] = false
 
 [common]
 
+;
+; Site Configuration Options
+;
+
 ; Debug Options
 admin_debug = false
 admin_debug_verbose = false
 front_debug = false
 front_debug_verbose = false
 
-;
 ; Google Maps Browser API Key
 ; Account: cscott.glm@gmail.com
 ; Need to create a new key for each "Project", referrer
@@ -49,12 +52,79 @@ front_debug_verbose = false
 ;
 googleMapsApiKey = 'AIzaSyDWgyf8MeYdxZRHaN73O37vFbkhvPjjNhU'
 
-; General Settings
+; Site Time Zone
 timezone = America/Detroit
+
 ; Default map location is Gaslight Media office
 map_default_lat = 45.3749
 map_default_lon = -84.9592
 
+; Front-end Member Listing - [glm-members-list]
+front-config['list_show_map'] = true
+front-config['list_show_list'] = true
+front-config['list_show_search'] = true
+front-config['list_search_text'] = true
+front-config['list_search_category'] = true
+front-config['list_search_amenities'] = false
+front-config['list_search_alpha'] = false
+;    Front-end Member Listing Options
+front-config['list_show_detaillink'] = true
+front-config['list_show_logo'] = true
+front-config['list_logo_size'] = small
+front-config['list_show_address'] = true
+front-config['list_show_street'] = true
+front-config['list_show_citystatezip'] = true
+front-config['list_show_country'] = false
+front-config['list_show_region'] = true
+front-config['list_show_description'] = true
+front-config['list_show_short_descr'] = false
+front-config['list_show_phone'] = true
+front-config['list_show_tollfree'] = true
+front-config['list_show_url'] = true
+front-config['list_show_categories'] = false
+front-config['list_show_creditcards'] = false
+front-config['list_show_amenities'] = false
+;    Front-end Meber Listing Map Options
+front-config['list_map_show_detaillink'] = true
+front-config['list_map_show_logo'] = true
+front-config['list_map_logo_size'] = thumb
+front-config['list_map_show_description'] = true
+front-config['list_map_show_short_descr'] = false
+front-config['list_map_show_address'] = true
+front-config['list_map_show_street'] = true
+front-config['list_map_show_citystatezip'] = true
+front-config['list_map_show_country'] = true
+front-config['list_map_show_region'] = true
+front-config['list_map_show_phone'] = true
+front-config['list_map_show_tollfree'] = true
+front-config['list_map_show_url'] = true
+front-config['list_map_show_categories'] = true
+front-config['list_map_show_creditcards'] = true
+front-config['list_map_show_amenities'] = false
+;    Front-end Member Detail Options
+front-config['detail_show_map'] = true
+front-config['detail_show_directions'] = true
+front-config['detail_show_detaillink'] = true
+front-config['detail_show_logo'] = true
+front-config['detail_logo_size'] = large
+front-config['detail_show_address'] = true
+front-config['detail_show_street'] = true
+front-config['detail_show_citystatezip'] = true
+front-config['detail_show_country'] = true
+front-config['detail_show_region'] = true
+front-config['detail_show_description'] = true
+front-config['detail_show_short_descr'] = false
+front-config['detail_show_phone'] = true
+front-config['detail_show_tollfree'] = true
+front-config['detail_show_url'] = true
+front-config['detail_show_categories'] = true
+front-config['detail_show_creditcards'] = true
+front-config['detail_show_amenities'] = true
+
+;
+; End of site configuration options
+;
+
 ;
 ; Entry Status Types
 ;
index bffee32..50a0526 100644 (file)
@@ -404,6 +404,7 @@ class glmMembersFront extends GlmPluginSupport
         $smarty->templateAssign ( 'glmPluginName', GLM_MEMBERS_PLUGIN_NAME );
         $smarty->templateAssign ( 'glmPluginMediaURL', GLM_MEMBERS_PLUGIN_MEDIA_URL );
         $smarty->templateAssign ( 'thisYear', date ( 'Y' ) );
+        $smarty->templateAssign ( $this->config['front-config']);
         $smarty->templateAssign ( $this->config['term']);
         $smarty->templateAssign ( $this->config['phrase']);
         $smarty->templateAssign ( 'googleMapsBrowserApiKey', $this->config['googleMapsApiKey']);
index a57a51d..d0d9241 100644 (file)
@@ -3,21 +3,52 @@
     Gaslight Media Members Database Front-End Styles
 
 */
-
 .glm-right {
     float: right;    
 }
 .glm-left {
     float: left;    
 }
+.glm-hidden {
+    display: none;
+}
+.glm-button {  /* Requires default WordPress classes "button" and either "button-primary" or "button-secondary". */
+    margin: 4px !important;
+    padding: .4em !important;
+    cursor: pointer;
+}
+
+/* Input fields */
+.glm-form-bad-input {
+    background: #FFaBa9;
+    padding: .2em;
+}
+.glm-form-text-input {
+    width: 95%;
+}
+.glm-form-text-input-short {
+    width: 15em;
+}
+.glm-form-text-input-medium {
+    width: 30em;
+}
+.glm-form-textarea {
+    width: 90%;
+}
 
-/* Member Containers */
+
+/* Member List */
 .glm-member-list-container {
     border: 1px #ccc solid;
     padding: .4em;
     background: #f8f8f8;
     margin: .4em 0px .4em 0px;
 }
+.glm-member-entry-container {
+    border: 1px #ccc solid;
+    padding: .4em;
+    margin: 1em 0px 1em 0px;
+}
 .glm-member-list-image {
     float: right;
 }
     margin-top: .5em;
 }
 
+/* Member Detail */
+.glm-member-detail-container {
+}
+.glm-member-detail-image {
+    margin-bottom: 1em;
+}
+.glm-member-detail-nameAddress {
+}
+.glm-member-detail-info {
+    clear: both;
+}
+.glm-member-detail-items {
+    margin-top: .5em;
+}
+
 /* Map */
 
 .glm-map { 
     width: 100%; 
     height:400px; 
     border: 2px black solid;
+    margin; 10px 0 10px 0;
 }
 /* overrride whatever was causing the 100% width for images in Google Maps */
 .glm-map img {
 .glm-map-member-name {
     width: 100%;
     font-weight: bold;
-    border-bottom: 2px #ccc solid;
+    border-bottom: 2px #ccc solid;    
+}
+
+/* Specific Divs */
+#glm-directions {
+    padding: 1em;
 }
\ No newline at end of file
diff --git a/misc/notes.txt b/misc/notes.txt
new file mode 100644 (file)
index 0000000..c030fe8
--- /dev/null
@@ -0,0 +1,26 @@
+Development Notes
+-----------------
+
+ADMIN AREA
+
+* Consider paginating certain lists
+
+* On all admin lists - add sort order links to headers
+
+* Amenities setup
+    - On Add an Amenity pop-up, move type to top of form
+    - Add list filter for Facility Type
+    - Add text search filter
+    
+
+FRONT-END
+
+* Add amenities to member lists and maps, and member detail pages
+
+
+DATA ABSTRACT
+
+* Add option to build alpha lists
+
+* Add pagenation, option to return total number of entries and number returned for display for getList()
+
index 3ae629d..0d0027f 100644 (file)
@@ -99,15 +99,38 @@ class GlmMembersFront_members_list extends GlmDataMemberInfo
     public function modelAction ($actionData = false)
     {
 
-        $where = '';
+        $where = ' TRUE';
         $filterPending = false;
         $filterArchived = false;
         $filterName = false;
         $haveFilter = false;
+        $textSearch = '';
+
+        // Apply any provided text search to name, description, short description, and street address
+        if (isset($_REQUEST['textSearch']) && $_REQUEST['textSearch'] != '') {
+            $textSearch = filter_input(INPUT_POST, 'textSearch', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
+            $where .= " AND (
+                (
+                    SELECT true
+                      FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX."members
+                     WHERE id = T.member
+                       AND name LIKE '%$textSearch%'
+                ) OR
+                T.descr LIKE '%$textSearch%' OR
+                T.short_descr LIKE '%$textSearch%' OR
+                T.addr1 LIKE '%$textSearch%' OR
+                T.addr2 LIKE '%$textSearch%'
+            )";
+        }
 
         // Apply any specified category filter
+        require_once(GLM_MEMBERS_PLUGIN_CLASS_PATH.'/data/dataCategories.php');
+        $Categories = new GlmDataCategories($this->wpdb, $this->config);
+        $categoryData = $Categories->getListSortedParentChild();
+//*** HERE complete category filter ****
 
-        $where .= " T.status = ".$this->config['status_numb']['Active'];
+        // Only look at active member information
+        $where .= " AND T.status = ".$this->config['status_numb']['Active'];
 
         /*
          *  Get a current list of members
@@ -139,7 +162,9 @@ class GlmMembersFront_members_list extends GlmDataMemberInfo
             'haveFilter' => $haveFilter,
             'filterArchived' => $filterArchived,
             'filterPending' => $filterPending,
-            'filterName' => stripslashes($filterName)
+            'filterName' => stripslashes($filterName),
+            'textSearch' => $textSearch,
+            'categories' => $categoryData
 //            'canEdit' => $canEdit
         );
 
index 7d893b5..4e76561 100644 (file)
@@ -1,7 +1,7 @@
 {include file='admin/configure/header.html'}
 
     <!-- Add Amenities Button and Dialog Box -->
-    <div id="newAmenityButton" class="button-primary glm-right">Add a Amenity</div>
+    <div id="newAmenityButton" class="button-primary glm-right">Add an Amenity</div>
     <div id="newAmenityDialog" class="glm-dialog-box" title="Enter a New Amenity">
         <form action="{$thisURL}?page={$thisPage}" method="post" enctype="multipart/form-data">
             <input type="hidden" name="glm_action" value="amenities">
index ae63293..4e43aee 100644 (file)
@@ -4,34 +4,65 @@
 
         <script src="http://maps.googleapis.com/maps/api/js?sensor=true&key={$googleMapsBrowserApiKey}"></script>
 
-        <div id="locationMap" class="glm-map">(map loads here)</div>     
-                    
+    {if $detail_show_map}
+        <div id="glm-locationMap-container">
+            <div id="glm-locationMap" class="glm-map">(map loads here)</div>
+        </div>     
+    {/if}
+    {if $detail_show_directions}
+        <div id="glm-directionsMap-container" class="glm-hidden">
+            <div id="glm-directionsMap" class="glm-map">(directions load here)</div>
+            <div id="directions-panel"></div>
+            <input type="submit" id="glm-hideDirectionsButton" class="button button-secondary glm-button glm-right glm-hidden" value="Hide Directions">
+        </div>
+        <div id="glm-directions" class="glm-member-entry-container">
+            <div>
+                Enter address to show directions ...<br>
+                <input id="glm-startLocation" type="text" name="startLocation" class="glm-form-text-input" placeholder=""><br>
+            </div>     
+            <div>
+                <input type="submit" id="glm-showDirectionsButton" class="button button-secondary glm-button" value="Show Directions">
+                <input type="submit" id="glm-showLocationButton" class="button button-secondary glm-button glm-hidden" value="Show Member Location">
+            </div>
+        </div>
+    {/if}
     
     <h3>Member Detail</h3>
     
-        <div class="glm-member-list-container">
-            <div class="glm-member-list-image"><img src="{$glmPluginMediaURL}/images/small/{$member.logo}"></div>
-            <div class="glm-member-list-nameAddress">
-                <h2><a href="{$thisURL}?glm_action=detail&id={$member.id}">{$member.member}</a></h2>
+       <div class="glm-member-detail-container">
+            {if $detail_show_logo}<div class="glm-member-detail-image"><img src="{$glmPluginMediaURL}/images/{$detail_logo_size}/{$member.logo}"></div>{/if}
+            <div class="glm-member-detail-nameAddress">
+                <h2>
+                  {if $detail_show_detaillink}
+                    <a href="{$thisURL}?glm_action=detail&id={$member.member_pointer}">{$member.member}</a>
+                  {else}
+                    {$member.member}
+                  {/if}
+                </h2>
+              {if $detail_show_address}
                 <p>
+                  {if $detail_show_street}
                     {if $member.addr1}{$member.addr1}<br>{/if}
                     {if $member.addr2}{$member.addr2}<br>{/if}
-                    {if $member.city.name}{$member.city.name}{if $member.state.name}, {/if}{/if}{if $member.state.name}{$member.state.name}{/if}{if $member.zip} {$member.zip}{/if} 
-                    {if $member.country.name}<br>{$member.country.name}{/if}
-                    {if $member.region.value}<p><b>Region:</b> {$member.region.name}</p>{/if}
-                </p>                
+                  {/if}
+                  {if $detail_show_citystatezip}
+                    {if $member.city.name}{$member.city.name}{if $member.state.name}, {/if}{/if}{if $member.state.name}{$member.state.name}{/if}{if $member.zip} {$member.zip}{/if}
+                  {/if} 
+                    {if $member.country.name && $detail_show_country}<br>{$member.country.name}{/if}
+                </p>        
+              {/if} {*list_show_address*}        
             </div>
-            <div class="glm-member-list-info">
-        {if $member.descr}
-                <p>{$member.descr}</p>
-        {else if $member.short_descr}
-                <p>{$member.short_descr}</p>
-        {/if}
-                {if $member.phone}<b>Phone:</b> {$member.phone}<br>{/if}
-                {if $member.toll_free}<b>Toll Free:</b> {$member.toll_free}<br>{/if}
-                {if $member.url}<b>Web site:</b> <a href="{$member.url}">{$member.url}</a><br>{/if}
-        {if $member.categories}
-                <div class="glm-member-list-items">           
+            <div class="glm-member-detail-info">
+                <p>
+                    {if $member.phone && $detail_show_phone}<b>Phone:</b> {$member.phone}<br>{/if}
+                    {if $member.toll_free && $detail_show_tollfree}<b>Toll Free:</b> {$member.toll_free}<br>{/if}
+                    {if $member.url && $detail_show_url}<b>Web site:</b> <a href="{$member.url}">{$member.url}</a><br>{/if}
+                    {if $member.region.value && $detail_show_region}<p><b>Region:</b> {$member.region.name}</p>{/if}
+                </p>
+                {if $member.descr && $detail_show_description}<p>{$member.descr}</p>{/if}
+                {if $member.short_descr && $detail_show_short_descr}<p>{$member.short_descr}</p>{/if}
+        {if $member.categories && $detail_show_categories}
+                <div class="glm-member-detail-items">           
                     <b>Member Categories</b>
                     <ul>
             {foreach $member.categories as $c}
@@ -42,8 +73,8 @@
                     </ul>
                 </div>
         {/if}
-        {if $member.cc_type}
-                <div class="glm-member-list-items">           
+        {if $member.cc_type && $detail_show_creditcards}
+                <div class="glm-member-detail-items">           
                     <b>Credit Cards Accepted:</b>
                     <ul>
             {foreach $member.cc_type.names as $c}
             {/foreach}
                     </ul>        
                 </div>
+        {/if}
+        {if $detail_show_amenities}
+                <div>
+                    <p>Amenities go here</p>
+                </div>
         {/if}
             </div>
         </div>
     <script type="text/javascript">
         jQuery(document).ready(function($) {
 
+    {if $detail_show_map}
             /*
              * Google Maps
              *  API reference: https://developers.google.com/maps/documentation/javascript/reference
              */
              
+            var myLocation = false;
+            var memberlocation = new google.maps.LatLng({$member.lat}, {$member.lon});
+            
             function initMap() {
                 
                 // Set default - Need to make this configurable
-                var location = new google.maps.LatLng({$member.lat}, {$member.lon});
-                var map = new google.maps.Map(document.getElementById('locationMap'), {
+                var map = new google.maps.Map(document.getElementById('glm-locationMap'), {
                        zoom: 14,
-                       center: location,
+                       center: memberlocation,
                     disableDefaultUI: false,   
                     mapTypeId: google.maps.MapTypeId.MAP,  
                 });  
                     position: new google.maps.LatLng({$member.lat}, {$member.lon}),
                     draggable: false,
                     animation: google.maps.Animation.DROP,  
-                    title: '{$member.member}',
-                    descr: ' \
-                        <div class="glm-map-member-name">{$member.member}</div> \
-                        {if $member.short_descr}{$member.short_descr}<br>{/if} \
-                        <a href="{$member.url}" target="memberWebSite">{$member.url}</a><br> \
-                        </p>',
-                    memberID: {$member.id}
+                    title: '{$member.member}'
                 });
                 
+                // Try HTML5 to get user geolocation
+                if(navigator.geolocation) {
+                  navigator.geolocation.getCurrentPosition(function(position) {
+                    myLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
+                    var pinIcon = new google.maps.MarkerImage(
+                        'https://maps.google.com/mapfiles/kml/shapes/man.png',
+                        null, /* size is determined at runtime */
+                        null, /* origin is 0,0 */
+                        null, /* anchor is bottom center of the scaled image */
+                        new google.maps.Size(30, 30)
+                    );
+                    var myMarker = new google.maps.Marker({  
+                        map: map,  
+                        position: myLocation,
+                        draggable: false,
+                        animation: google.maps.Animation.DROP,  
+                        title: 'My Location',
+                        icon: pinIcon,
+                        zIndex: 100
+                    });
+                    $('#glm-startLocation').attr('placeholder', 'Leave blank for your current location or enter address here.');
+                  });
+                }
+                
             }
             
             // Load map
-            google.maps.event.addDomListener(window, 'load', initMap); 
+            google.maps.event.addDomListener(window, 'load', initMap);
+            
+            
+    {/if} {*detail_show_map*}
+    
+    {if $detail_show_directions}
+    
+            var directionsDisplay;
+            var directionsService = new google.maps.DirectionsService();
+
+            // Display map with route from specified location to member location
+            function calcRoute() {
+               
+               // If an address was input, use that, otherwise use detected location if available
+               var start = $('#glm-startLocation').val();
+                if (start == '' ) {
+                       if (myLocation != false) {
+                               start = myLocation;
+                       }
+                }
+                
+                // If no start location available, tell user
+                if (start == '') {
+                       alert('No starting location. Please enter address.');
+                       return;
+                }
+
+                // Switch to directions map being visible
+                $('#glm-directionsMap-container').removeClass('glm-hidden');
+                $('#glm-locationMap-container').addClass('glm-hidden');
+                $('#glm-showLocationButton').removeClass('glm-hidden');
+                
+                // Initialize the directions map with a default center location
+                directionsDisplay = new google.maps.DirectionsRenderer();
+                var mapOptions = {
+                    zoom:7,
+                    center: memberlocation
+                }
+                directionsMap = new google.maps.Map(document.getElementById("glm-directionsMap"), mapOptions);
+                directionsDisplay.setMap(directionsMap);
+
+                // Specify origin and destination then get route
+                var request = {
+                       origin: start,
+                    destination: memberlocation,
+                    travelMode: google.maps.TravelMode.DRIVING
+                };
+                directionsService.route(request, function(result, status) {
+                    if (status == google.maps.DirectionsStatus.OK) {
+                        directionsDisplay.setDirections(result);
+                        $('#directions-panel').html('');
+                        directionsDisplay.setPanel(document.getElementById('directions-panel'));
+                    }
+                });
+                
+                // Check for first map idle (completely loaded) - Check max initial zoom
+                var mapLoadedListener = google.maps.event.addListener(directionsMap, 'idle', function() {
+                    if (directionsMap.getZoom() > 16) {
+                        this.setZoom(16);
+                    }
+                    google.maps.event.removeListener(mapLoadedListener);
+                });
+
+            }
+       
+            // Trigger route map either by button or input of address
+            $('#glm-showDirectionsButton' ).click( function() {
+                calcRoute();
+            });
+            $('#glm-startLocation' ).change( function() {
+                calcRoute();
+            });
+                          
+            // Switch back to member location map
+               $('#glm-showLocationButton').click( function() {
+                $('#glm-directionsMap-container').addClass('glm-hidden');          
+                $('#glm-locationMap-container').removeClass('glm-hidden');
+                $('#glm-showLocationButton').addClass('glm-hidden');
+               });
+               
+    {/if} {*detail_show_directions*}   
            
         });
     </script>
index 420075c..03874af 100644 (file)
@@ -3,35 +3,83 @@
 
         <script src="http://maps.googleapis.com/maps/api/js?sensor=true&key={$googleMapsBrowserApiKey}"></script>
 
+{if $list_show_map}
         <div id="locationMap" class="glm-map">(map loads here)</div>     
-                    
-    
+{/if}
+
+{if $list_show_search}
+        <form action="{$thisURL}?glm_action=list" method="post" enctype="multipart/form-data">
+            <div class="glm-member-entry-container ">
+                <h3><br>Search for a Member</h3>
+        {if $list_search_text}
+                <div>
+                    Text Search: <input type="text" name="textSearch" value="{$textSearch}" class="glm-form-text-input">
+                </div>
+        {/if}
+        {if $list_search_category}
+                <div>
+                    Member Category: 
+                    <select name="categorySelect" id="categorySelect">
+                        <option id="categoryNone" value=""></option>
+            {foreach from=$categories item=v}
+                        <option value="{$v.id}" data-parent="{$v.parent.name}">
+                            {if $v.parent.value}&nbsp;&nbsp;&nbsp;&nbsp;{/if}{$v.name}
+                        </option>
+            {/foreach}
+                    </select>
+                </div>
+        {/if}
+        {if $list_search_amenities}
+                <div>Amenity search goes here</div>
+        {/if}    
+        {if $list_search_alpha}
+                <div>Alpha search goes here</div>
+        {/if}
+                <input type="submit" value="Search">        
+            </div>
+        </form>
+{/if} {*list_show_search*}
+
+{if $list_show_list}    
     <h3>List of Members</h3>
     
-{if $haveMembers}
+  {if $haveMembers}
+  
+    <!-- Member information displayed in list -->
     {foreach $members as $m}
         <div class="glm-member-list-container">
-            <div class="glm-member-list-image"><img src="{$glmPluginMediaURL}/images/small/{$m.logo}"></div>
+            {if $list_show_logo}<div class="glm-member-list-image"><img src="{$glmPluginMediaURL}/images/{$list_logo_size}/{$m.logo}"></div>{/if}
             <div class="glm-member-list-nameAddress">
-                <h2><a href="{$thisURL}?glm_action=detail&id={$m.member_pointer}">{$m.member}</a></h2>
+                <h2>
+                  {if $list_show_detaillink}
+                    <a href="{$thisURL}?glm_action=detail&id={$m.member_pointer}">{$m.member}</a>
+                  {else}
+                    {$m.member}
+                  {/if}
+                </h2>
+              {if $list_show_address}
                 <p>
+                  {if $list_show_street}
                     {if $m.addr1}{$m.addr1}<br>{/if}
                     {if $m.addr2}{$m.addr2}<br>{/if}
-                    {if $m.city.name}{$m.city.name}{if $m.state.name}, {/if}{/if}{if $m.state.name}{$m.state.name}{/if}{if $m.zip} {$m.zip}{/if} 
-                    {if $m.country.name}<br>{$m.country.name}{/if}
-                    {if $m.region.value}<p><b>Region:</b> {$m.region.name}</p>{/if}
-                </p>                
+                  {/if}
+                  {if $list_show_citystatezip}
+                    {if $m.city.name}{$m.city.name}{if $m.state.name}, {/if}{/if}{if $m.state.name}{$m.state.name}{/if}{if $m.zip} {$m.zip}{/if}
+                  {/if} 
+                    {if $m.country.name && $list_show_country}<br>{$m.country.name}{/if}
+                </p>        
+              {/if} {*list_show_address*}        
             </div>
             <div class="glm-member-list-info">
-        {if $m.descr}
-                <p>{$m.descr}</p>
-        {else if $m.short_descr}
-                <p>{$m.short_descr}</p>
-        {/if}
-                {if $m.phone}<b>Phone:</b> {$m.phone}<br>{/if}
-                {if $m.toll_free}<b>Toll Free:</b> {$m.toll_free}<br>{/if}
-                {if $m.url}<b>Web site:</b> <a href="{$m.url}">{$m.url}</a><br>{/if}
-        {if $m.categories}
+                <p>
+                    {if $m.phone && $list_show_phone}<b>Phone:</b> {$m.phone}<br>{/if}
+                    {if $m.toll_free && $list_show_tollfree}<b>Toll Free:</b> {$m.toll_free}<br>{/if}
+                    {if $m.url && $list_show_url}<b>Web site:</b> <a href="{$m.url}">{$m.url}</a><br>{/if}
+                    {if $m.region.value && $list_show_region}<p><b>Region:</b> {$m.region.name}</p>{/if}
+                </p>
+                {if $m.descr && $list_show_description}<p>{$m.descr}</p>{/if}
+                {if $m.short_descr && $list_show_short_descr}<p>{$m.short_descr}</p>{/if}
+        {if $m.categories && $list_show_categories}
                 <div class="glm-member-list-items">           
                     <b>Member Categories</b>
                     <ul>
@@ -43,7 +91,7 @@
                     </ul>
                 </div>
         {/if}
-        {if $m.cc_type}
+        {if $m.cc_type && $list_show_creditcards}
                 <div class="glm-member-list-items">           
                     <b>Credit Cards Accepted:</b>
                     <ul>
             {/foreach}
                     </ul>        
                 </div>
+        {/if}
+        {if $list_show_amenities}
+                <div>
+                    <p>Amenities go here</p>
+                </div>
         {/if}
             </div>
         </div>
             
-    {/foreach}
-{else}
+        <!-- Member information displayed in map bubbles -->
+        <div id="map_info_{$m.id}" class="glm-hidden">
+            {if $m.logo && $list_map_show_logo}<div class="glm-member-list-image"><img src="{$glmPluginMediaURL}/images/{$list_map_logo_size}/{$m.logo}"></div>{/if}
+            <div class="glm-map-member-name">
+              {if $list_map_show_detaillink}
+                <a href="{$thisURL}?glm_action=detail&id={$m.member_pointer}">{$m.member}</a>
+              {else}
+                {$m.member}
+              {/if}
+            </div>
+          {if $list_map_show_address}
+            <p>
+              {if $list_map_show_street}
+                {if $m.addr1}{$m.addr1}<br>{/if}
+                {if $m.addr2}{$m.addr2}<br>{/if}
+              {/if}
+              {if $list_map_show_citystatezip}
+                {if $m.city.name}{$m.city.name}{if $m.state.name}, {/if}{/if}{if $m.state.name}{$m.state.name}{/if}{if $m.zip} {$m.zip}{/if}
+              {/if} 
+                {if $m.country.name && $list_map_show_country}<br>{$m.country.name}{/if}
+            </p>        
+          {/if} {*list_map_show_address*}        
+            <div class="glm-member-list-info">
+                <p>
+                    {if $m.phone && $list_map_show_phone}<b>Phone:</b> {$m.phone}<br>{/if}
+                    {if $m.toll_free && $list_map_show_tollfree}<b>Toll Free:</b> {$m.toll_free}<br>{/if}
+                    {if $m.url && $list_map_show_url}<b>Web site:</b> <a href="{$m.url}">{$m.url}</a><br>{/if}
+                    {if $m.region.value && $list_map_show_region}<p><b>Region:</b> {$m.region.name}</p>{/if}
+                </p>
+                {if $m.descr && $list_map_show_description}{$m.descr}<br>{/if}
+                {if $m.short_descr && $list_map_show_short_descr}{$m.short_descr}<br>{/if}
+        {if $m.categories && $list_map_show_categories}
+                <div class="glm-member-list-items">           
+                    <b>Member Categories</b>
+                    <ul>
+            {foreach $m.categories as $c}
+                        <li>
+                            {if $c.parent_name}{$c.parent_name}: {/if}{$c.name}
+                        </li>
+            {/foreach}
+                    </ul>
+                </div>
+        {/if}1
+        {if $m.cc_type && $list_map_show_creditcards}
+                <div class="glm-member-list-items">           
+                    <b>Credit Cards Accepted:</b>
+                    <ul>
+            {foreach $m.cc_type.names as $c}
+                        <li>{$c}</li>
+            {/foreach}
+                    </ul>        
+                </div>
+        {/if}
+        {if $list_map_show_amenities}
+                <div>
+                    <p>Amenities go here</p>
+                </div>
+        {/if}
+            </div>
+        </div> <!-- End of information displayed in map bubbles -->
+        
+    {/foreach} {*$members*}
+  {else}
         <div>(no members listed)</div>
-{/if}
-
+  {/if}
+{/if} {*list_show_list*}
     <script type="text/javascript">
         jQuery(document).ready(function($) {
-
+            
+{if $list_show_map}                            
             /*
              * Google Maps
              *  API reference: https://developers.google.com/maps/documentation/javascript/reference
             // Set default - Need to make this configurable
             var startLat = 45;
             var startLon = -84;
-            var location = new google.maps.LatLng(startLat, startLon);
+            
+            // Create a Google Map object
             var map = new google.maps.Map(document.getElementById('locationMap'), {  
-//                maxZoom: 12,  
                 disableDefaultUI: false,   
                 mapTypeId: google.maps.MapTypeId.MAP,  
             });  
+
             var geocoder = new google.maps.Geocoder();
             var bounds = new google.maps.LatLngBounds();
             var infowindow = new google.maps.InfoWindow();            
 
+            // Try HTML5 to get user geolocation
+            if(navigator.geolocation) {
+                navigator.geolocation.getCurrentPosition(function(position) {
+                    var myLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
+                    var pinIcon = new google.maps.MarkerImage(
+                       'https://maps.google.com/mapfiles/kml/shapes/man.png',
+                        null, /* size is determined at runtime */
+                        null, /* origin is 0,0 */
+                        null, /* anchor is bottom center of the scaled image */
+                        new google.maps.Size(30, 30)
+                    );
+                    var myMarker = new google.maps.Marker({  
+                        map: map,  
+                        position: myLocation,
+                        draggable: false,
+                        animation: google.maps.Animation.DROP,  
+                        title: 'My Location',
+                        icon: pinIcon,
+                        zIndex: 100
+                    });
+                });
+            }
+            
     {if $haveMembers}
         {foreach $members as $m}
 
                 draggable: false,
                 animation: google.maps.Animation.DROP,  
                 title: '{$m.member}',
-                descr: ' \
-                    <div class="glm-map-member-name">{$m.member}</div> \
-                    {if $m.short_descr}{$m.short_descr}<br>{/if} \
-                    <a href="{$m.url}" target="memberWebSite">{$m.url}</a><br> \
-                    <a href="{$thisURL}?glm_action=detail&id={$m.member_pointer}"><br>More Info</a> \
-                    </p>',
+                descr: $('#map_info_' + {$m.id}).html(),
                 memberID: {$m.id}
             });
 
             // Fit map to bounds of all markers
             map.fitBounds(bounds);
             
+            // Check for first map idle (completely loaded) - Check max zoom
+            var mapLoadedListener = google.maps.event.addListener(map, 'idle', function() {
+                if (map.getZoom() > 14) {
+                    this.setZoom(14);
+                }
+                google.maps.event.removeListener(mapLoadedListener);
+            });
+            
+            
+{/if}            
         });
     </script>