diff --git a/app/resources/locales/en_US/field.po b/app/resources/locales/en_US/field.po
index 53a4f4a8d..d0a500df0 100644
--- a/app/resources/locales/en_US/field.po
+++ b/app/resources/locales/en_US/field.po
@@ -107,6 +107,9 @@ msgstr "Email"
 msgid "ends_at"
 msgstr "Ends at:"
 
+msgid "ends_at.tz"
+msgstr "Ends at ({0})"
+
 msgid "extension"
 msgstr "Extension"
 
@@ -243,6 +246,9 @@ msgstr "Sponsor"
 msgid "starts_at"
 msgstr "Starts at:"
 
+msgid "starts_at.tz"
+msgstr "Starts at ({0})"
+
 msgid "state"
 msgstr "State"
 
diff --git a/app/resources/locales/en_US/information.po b/app/resources/locales/en_US/information.po
index 6a05a1458..933cd91f0 100644
--- a/app/resources/locales/en_US/information.po
+++ b/app/resources/locales/en_US/information.po
@@ -106,4 +106,7 @@ msgid "plugin.active.only"
 msgstr "Active, Cannot Be Disabled"
 
 msgid "plugin.inactive"
-msgstr "Inactive"
\ No newline at end of file
+msgstr "Inactive"
+
+msgid "table.list"
+msgstr "{0} List"
\ No newline at end of file
diff --git a/app/resources/locales/en_US/operation.po b/app/resources/locales/en_US/operation.po
index 4d3f3bfb1..9127afaee 100644
--- a/app/resources/locales/en_US/operation.po
+++ b/app/resources/locales/en_US/operation.po
@@ -63,6 +63,9 @@ msgstr "Apply Database Schema"
 msgid "assign"
 msgstr "Assign"
 
+msgid "any"
+msgstr "Any"
+
 msgid "cancel"
 msgstr "Cancel"
 
@@ -144,6 +147,9 @@ msgstr "Logout"
 msgid "next"
 msgstr "Next"
 
+msgid "none"
+msgstr "None"
+
 msgid "page.display"
 msgstr "Display records"
 
diff --git a/app/src/Lib/Traits/IndexQueryTrait.php b/app/src/Lib/Traits/IndexQueryTrait.php
index e94394dd2..b62d65c11 100644
--- a/app/src/Lib/Traits/IndexQueryTrait.php
+++ b/app/src/Lib/Traits/IndexQueryTrait.php
@@ -136,7 +136,7 @@ public function getIndexQuery(bool $pickerMode = false, array $requestParams = [
     $link = $this->getPrimaryLink(true);
     // Initialize the Query Object
     $query = $table->find();
-    // Get a pointer to my expressions list
+    // Get a pointer to my expression list
     $newexp = $query->newExpr();
     // The searchable attributes can have an AND or an OR conjunction. The first one is used from the filtering block
     // while the second one from the picker vue module.
@@ -159,6 +159,8 @@ public function getIndexQuery(bool $pickerMode = false, array $requestParams = [
                                                               $this->viewBuilder()
                                                                    ->getVar('vv_tz'));
 
+      // Pass any additional field filter confiration in the view
+      $this->set('vv_searchable_attributes_extras', $table->getSearchFiltersExtras());
       if(!empty($searchableAttributes)) {
         $this->set('vv_searchable_attributes', $searchableAttributes);
 
@@ -195,7 +197,7 @@ public function getIndexQuery(bool $pickerMode = false, array $requestParams = [
       // Specific expressions per view
       $query = match($requestParams['for'] ?? '') {
         // GroupMembers Add view: We need to filter the active members
-        'GroupMembers' => $query->leftJoinWith('GroupMembers', fn($q) => $q->where(['GroupMembers.group_id' => (int)$requestParams['groupid'] ?? -1]))
+        'GroupMembers' => $query->leftJoinWith('GroupMembers', fn($q) => $q->where(['GroupMembers.group_id' => (int)($requestParams['groupid'] ?? -1)]))
                                 ->where($this->getTableLocator()->get('GroupMembers')->checkValidity($query))
                                 ->where(fn(QueryExpression $exp, Query $query) => $exp->isNull('GroupMembers.' . StringUtilities::classNameToForeignKey($table->getAlias()))),
         // Just return the query
diff --git a/app/src/Lib/Traits/SearchFilterTrait.php b/app/src/Lib/Traits/SearchFilterTrait.php
index e8d449e66..7827e6593 100644
--- a/app/src/Lib/Traits/SearchFilterTrait.php
+++ b/app/src/Lib/Traits/SearchFilterTrait.php
@@ -29,6 +29,7 @@
 
 namespace App\Lib\Traits;
 
+use App\Lib\Util\StringUtilities;
 use Bake\Utility\Model\AssociationFilter;
 use Cake\Database\Expression\QueryExpression;
 use Cake\Http\ServerRequest;
@@ -37,9 +38,25 @@
 use Cake\I18n\FrozenTime;
 
 trait SearchFilterTrait {
-  // Array (and configuration) of permitted search filters
+  /**
+   * Array (and configuration) of permitted search filters
+   *
+   * @var array
+   */
   private array $searchFilters = [];
-  // Optional filter configuration that dictates display state and allows for related models
+
+  /**
+   * Extra Configurations for each filter
+   *
+   * @var array
+   */
+  private array $searchFiltersExtras = [];
+
+  /**
+   * Optional filter configuration that dictates display state and allows for related models
+   *
+   * @var array
+   */
   private array $filterConfig = [];
 
   /**
@@ -167,21 +184,30 @@ public function expressionsConstructor(Query $query, QueryExpression $exp, strin
 
     $attributeWithModelPrefix = $modelPrefix . '.' . $attribute;
 
-
     $search = $q;
-    // Use the `lower` function to apply uniformity for the search
-    $lower = $query->func()->lower([$attributeWithModelPrefix => 'identifier']);
+
+    // Handle special expression functions here
+    if(\in_array($search, ['isnull', 'isnotnull'])) {
+      return match($search) {
+        'isnull'    => $exp->isNull($attributeWithModelPrefix),
+        'isnotnull' => $exp->isNotNull($attributeWithModelPrefix)
+      };
+    }
+
 
     // XXX Strings and Enums are not treated the same. Enums require an exact match but strings
-    //     are partially/non-case sensitive  matched
+    //     are partially/non-case sensitive matched
     return match ($this->searchFilters[$attribute]['type']) {
-      'string'             => $exp->like($lower, strtolower('%' . $search . '%')),
+      // Use the `lower` function to apply uniformity for the search
+      'string'             => $exp->like($query->func()->lower([$attributeWithModelPrefix => 'identifier']),
+                                         strtolower('%' . $search . '%')),
       'integer',
       'boolean',
       'parent'             => $exp->add([$attributeWithModelPrefix => $search]),
       'date'               => $exp->add([$attributeWithModelPrefix => FrozenTime::parseDate($search, 'y-M-d')]),
       'timestamp'          => $this->constructDateComparisonClause($exp, $attributeWithModelPrefix, $search),
-      default              => $exp->eq($lower, strtolower($search))
+      default              => $exp->eq($query->func()->lower([$attributeWithModelPrefix => 'identifier']),
+                                       strtolower($search))
     };
   }
 
@@ -209,16 +235,24 @@ public function getSearchableAttributes(string $controller, string $vv_tz=null):
     // Gather up related models defined in the $filterConfig
     // XXX For now, we'll list these first - but we should probably provide a better way to order these.
     foreach ($filterConfig as $field => $f) {
-      if($f['type'] == 'relatedModel') {
-        $fieldName = Inflector::classify(Inflector::underscore($field));
-        $this->searchFilters[$field] = [
-          'type' => 'string', // XXX for now - this needs to be looked up.
-          'label' => \App\Lib\Util\StringUtilities::columnKey($fieldName, $field, $vv_tz, true),
-          'active' => $f['active'] ?? true,
-          'model' => $f['model'],
-          'order' => $f['order']
-        ];
+      $fieldName = Inflector::classify(Inflector::underscore($field));
+
+      if(isset($f['extras'])) {
+        $this->searchFiltersExtras[$field] = $f['extras'];
+        continue;
       }
+
+      $filterType = $f['type'] ?? 'string';
+      if(\in_array($f['type'], ['isNull', 'isNotNull'])) {
+        $filterType = 'boolean';
+      }
+      $this->searchFilters[$field] = [
+        'type' => $filterType,
+        'label' => $f['label'] ?? StringUtilities::columnKey($fieldName, $field, $vv_tz, true),
+        'active' => $f['active'] ?? true,
+        'model' => $f['model'],
+        'order' => $f['order']
+      ];
     }
 
     foreach ($this->filterMetadataFields() as $column => $type) {
@@ -239,7 +273,7 @@ public function getSearchableAttributes(string $controller, string $vv_tz=null):
 
       $attribute = [
         'type' => $type,
-        'label' => \App\Lib\Util\StringUtilities::columnKey($modelname, $column, $vv_tz, true),
+        'label' => StringUtilities::columnKey($modelname, $column, $vv_tz, true),
         'active' => $fieldIsActive,
         'order' => 99 // this is the default
       ];
@@ -270,7 +304,7 @@ public function getSearchableAttributes(string $controller, string $vv_tz=null):
   }
 
   /**
-   * Set explicilty defined filter configuration defined in the table class.
+   * Set explicit defined filter configuration defined in the table class.
    *
    * @since  COmanage Registry v5.0.0
    */
@@ -279,4 +313,14 @@ public function setFilterConfig(array $filterConfig): void {
     $this->filterConfig = $filterConfig;
   }
 
+  /**
+   * Get field extra configurations calculated in getSearchableAttributes
+   *
+   * @since  COmanage Registry v5.0.0
+   */
+  public function getSearchFiltersExtras(): array
+  {
+    return $this->searchFiltersExtras;
+  }
+
 }
diff --git a/app/src/Lib/Util/FunctionUtilities.php b/app/src/Lib/Util/FunctionUtilities.php
index cb7728d8b..8ed32710d 100644
--- a/app/src/Lib/Util/FunctionUtilities.php
+++ b/app/src/Lib/Util/FunctionUtilities.php
@@ -43,7 +43,7 @@ class FunctionUtilities {
    *      // Chain of methods
    *      'getRequest',
    *      'getQuery' => [
-   *        // parameter name => parameter value, We are taking advantage the named parameters feature
+   *        // parameter name => parameter value, We are taking advantage of the named parameters feature
    *        'name' =>'group_id'
    *      ],
    *    ]
diff --git a/app/src/Model/Table/CousTable.php b/app/src/Model/Table/CousTable.php
index 78dada52d..ee4d59b21 100644
--- a/app/src/Model/Table/CousTable.php
+++ b/app/src/Model/Table/CousTable.php
@@ -113,6 +113,29 @@ public function initialize(array $config): void {
         'index' =>    ['platformAdmin', 'coAdmin']
       ]
     ]);
+
+    $this->setFilterConfig([
+     'identifier' => [
+       'type' => 'string',
+       'model' => 'Identifiers',
+       'active' => true,
+       'order' => 4
+     ],
+     'parent_id' => [
+       // We want to keep the default column configuration and add extra functionality.
+       // Here the extra functionality is additional to select options since the parent_id
+       // is of type select
+       // XXX If the extras key is present, no other provided key will be evaluated. The rest
+       //     of the configuration will be expected from the TableMetaTrait::filterMetadataFields()
+       'extras' => [
+         'options' => [
+           'isnotnull' => __d('operation','any'),
+           'isnull' => __d('operation','none'),
+           __d('information','table.list', 'COUs') => '@DATA@',
+         ]
+       ]
+     ]
+   ]);
   }
   
   /**
diff --git a/app/src/Model/Table/GroupMembersTable.php b/app/src/Model/Table/GroupMembersTable.php
index a35fdd5ef..3aaca7a71 100644
--- a/app/src/Model/Table/GroupMembersTable.php
+++ b/app/src/Model/Table/GroupMembersTable.php
@@ -131,13 +131,13 @@ public function initialize(array $config): void {
 
       $this->setFilterConfig([
          'family' => [
-             'type' => 'relatedModel',
+             'type' => 'string',
              'model' => 'People.Names',
              'active' => true,
              'order' => 2
          ],
          'given' => [
-             'type' => 'relatedModel',
+             'type' => 'string',
              'model' => 'People.Names',
              'active' => true,
              'order' => 1
diff --git a/app/src/Model/Table/GroupNestingsTable.php b/app/src/Model/Table/GroupNestingsTable.php
index 26e76f323..0fdda7cb2 100644
--- a/app/src/Model/Table/GroupNestingsTable.php
+++ b/app/src/Model/Table/GroupNestingsTable.php
@@ -96,24 +96,26 @@ public function initialize(array $config): void {
       ]
     ]);
 
-    $this->setAutoViewVars([
-     'groupMembers' => [
-       'type' => 'auxiliary',
-       'model' => 'GroupMembers',
-       'whereEval' => [
-         // Where Clause column name
-         'GroupMembers.group_id' => [
-           // Chain of methods that will construct the whereClause condition value
-           // Method that accepts no parameters
-           'getRequest',
-           // Method that accepts only one parameter
-           // getQuery(name: 'group_id')
-           'getQuery' => [
-             'name' =>'group_id'
-           ]
-         ]
-       ]
-     ]]);
+    // XXX Keeping for functionality reference
+//    $this->setAutoViewVars([
+//     'groupMembers' => [
+//       'type' => 'auxiliary',
+//       'model' => 'GroupMembers',
+//       'whereEval' => [
+//         // Where Clause column name
+//         'GroupMembers.group_id' => [
+//           // Chain of methods that will construct the whereClause condition value
+//           // Method that accepts no parameters
+//           'getRequest',
+//           // Method that accepts only one parameter
+//           // getQuery(name: 'group_id')
+//           'getQuery' => [
+//             'name' =>'group_id'
+//           ]
+//         ]
+//       ]
+//     ]]);
+
   }
   
   /**
diff --git a/app/src/Model/Table/GroupsTable.php b/app/src/Model/Table/GroupsTable.php
index 339693d10..a91ea9e38 100644
--- a/app/src/Model/Table/GroupsTable.php
+++ b/app/src/Model/Table/GroupsTable.php
@@ -150,7 +150,7 @@ public function initialize(array $config): void {
 
     $this->setFilterConfig([
       'identifier' => [
-        'type' => 'relatedModel',
+        'type' => 'string',
         'model' => 'Identifiers',
         'active' => true,
         'order' => 4
diff --git a/app/src/Model/Table/IdentifiersTable.php b/app/src/Model/Table/IdentifiersTable.php
index 881bd1587..ecaa2f28d 100644
--- a/app/src/Model/Table/IdentifiersTable.php
+++ b/app/src/Model/Table/IdentifiersTable.php
@@ -30,6 +30,7 @@
 namespace App\Model\Table;
 
 use Cake\Event\EventInterface;
+use Cake\ORM\Query;
 use Cake\ORM\Table;
 use Cake\Validation\Validator;
 use \App\Lib\Enum\SuspendableStatusEnum;
@@ -191,24 +192,43 @@ public function localAfterSave(\Cake\Event\EventInterface $event, \Cake\Datasour
   /**
    * Look up a Person ID from an identifier and identifier type ID.
    * Only active Identifiers can be used for lookups.
-   * 
-   * @since  COmanage Registry v5.0.0
-   * @param  int    $typeId     Identifier Type ID
-   * @param  string $identifier Identifier
+   *
+   * @param   int       $typeId      Identifier Type ID
+   * @param   string    $identifier  Identifier
+   * @param   int|null  $coId        CO Id
+   * @param   bool      $login       The identifier is login enabled
+   *
    * @return int                Person ID
-   * @throws Cake\Datasource\Exception\RecordNotFoundException
+   * @since  COmanage Registry v5.0.0
    */
 
-  public function lookupPerson(int $typeId, string $identifier): int {
-    $id = $this->find()
-               ->where([
-                'identifier'  => $identifier,
-                'type_id'     => $typeId,
-                'status'      => SuspendableStatusEnum::Active,
-                'person_id IS NOT NULL'
-               ])
-               ->firstOrFail();
-    
+  public function lookupPerson(int $typeId, string $identifier, ?int $coId, bool $login=false): int {
+    $whereClause = [
+      'identifier'  => $identifier,
+      'status'      => SuspendableStatusEnum::Active,
+      'person_id IS NOT NULL'
+    ];
+
+    if($typeId) {
+      $whereClause['type_id'] = $typeId;
+    }
+
+    if($login) {
+      $whereClause['login'] = true;
+    }
+
+    $query = $this->find()
+                  ->where($whereClause);
+
+    if($coId) {
+      $query->matching(
+        'People',
+        fn(QueryExpression $exp, Query $query) => $query->where(['People.co_id' => $coId])
+      );
+    }
+
+    $id = $query->firstOrFail();
+
     return $id->person_id;
   }
 
diff --git a/app/src/Model/Table/PeopleTable.php b/app/src/Model/Table/PeopleTable.php
index e39220db6..39de20376 100644
--- a/app/src/Model/Table/PeopleTable.php
+++ b/app/src/Model/Table/PeopleTable.php
@@ -164,31 +164,32 @@ public function initialize(array $config): void {
     // XXX expand/revise this as needed to work best with looking up the related models
     $this->setFilterConfig([
       'family' => [
-        'type' => 'relatedModel',
+        'type' => 'string',
         'model' => 'Names',
         'active' => true,
         'order' => 2
       ],
       'given' => [
-        'type' => 'relatedModel',
+        'type' => 'string',
         'model' => 'Names',
         'active' => true,
         'order' => 1
       ],
       'mail' => [
-        'type' => 'relatedModel',
+        'type' => 'string',
         'model' => 'EmailAddresses',
         'active' => true,
         'order' => 3
       ],
       'identifier' => [
-        'type' => 'relatedModel',
+        'type' => 'string',
         'model' => 'Identifiers',
         'active' => true,
         'order' => 4
       ],
       'timezone' => [
         'type' => 'field',
+        'model' => 'People',
         'active' => false,
         'order' => 99
       ]      
diff --git a/app/src/View/Helper/CommonHelper.php b/app/src/View/Helper/CommonHelper.php
new file mode 100644
index 000000000..e7660bf88
--- /dev/null
+++ b/app/src/View/Helper/CommonHelper.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * COmanage Registry Common Helper
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @link          https://www.internet2.edu/comanage COmanage Project
+ * @package       registry
+ * @since         COmanage Registry v5.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+
+declare(strict_types = 1);
+
+namespace App\View\Helper;
+
+use Cake\ORM\TableRegistry;
+use Cake\Utility\Inflector;
+use Cake\View\Helper;
+
+class CommonHelper extends Helper
+{
+  /**
+   * Select count(*)
+   *
+   * @param   string  $modelName       Model name in `group_members` format
+   * @param   array   $whereClause     where clause array
+   *
+   * @return int
+   */
+  public function getModelTotalCount(string $modelName, array $whereClause): int
+  {
+    $modelsName = Inflector::camelize($modelName);
+    $ModelTable = TableRegistry::getTableLocator()->get($modelsName);
+    $count = $ModelTable->find()
+                        ->where($whereClause)
+                        ->count();
+
+    return $count;
+  }
+}
\ No newline at end of file
diff --git a/app/src/View/Helper/FieldHelper.php b/app/src/View/Helper/FieldHelper.php
index 87bec56ae..1b26ac583 100644
--- a/app/src/View/Helper/FieldHelper.php
+++ b/app/src/View/Helper/FieldHelper.php
@@ -167,108 +167,137 @@ public function control(string $fieldName,
                  $this->formInfoDiv($controlCode, $beforeField, $afterField) )
            . $this->endLine();
   }
-  
+
   /**
    * Emit a date/time form control.
    * This is a wrapper function for $this->control()
    *
-   * @since  COmanage Registry v5.0.0
-   * @param  string $fieldName Form field
-   * @param  string $dateType Standard, DateOnly, FromTime, ThroughTime
-   * 
+   * @param   string      $fieldName    Form field
+   * @param   string      $dateType     Standard, DateOnly, FromTime, ThroughTime
+   * @param   array|null  $queryParams  Request Query parameters used by the filtering Blocks to get the date values
+   *
    * @return string  HTML for control
+   * @since  COmanage Registry v5.0.0
    */
   
-  public function dateControl(string $fieldName, string $dateType=DateTypeEnum::Standard): string {
+  public function dateControl(string $fieldName, string $dateType=DateTypeEnum::Standard, array $queryParams = null): string
+  {
+    $dateFieldConfig = $this->dateField($fieldName, $dateType, $queryParams);
+    return $this->control(fieldName:       $fieldName,
+                          options:         $dateFieldConfig['coptions'],
+                          ctrlCode:        $dateFieldConfig['controlCode'],
+                          cssClass:        $dateFieldConfig['cssClass'],
+                          labelIsTextOnly: $dateFieldConfig['labelIsTextOnly']);
+
+  }
+
+  /**
+   * Emit a date/time form control.
+   * This is a wrapper function for $this->control()
+   *
+   * @param   string      $fieldName    Form field
+   * @param   string      $dateType     Standard, DateOnly, FromTime, ThroughTime
+   * @param   array|null  $queryParams  Request Query parameters used by the filtering Blocks to get the date values
+   *
+   * @return array HTML for control
+   * @since  COmanage Registry v5.0.0
+   */
+
+  public function dateField(string $fieldName, string $dateType=DateTypeEnum::Standard, array $queryParams = null): array
+  {
+    // Initialize
+    $dateFormat = $dateType === DateTypeEnum::DateOnly ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss';
+    $dateTitle = $dateType === DateTypeEnum::DateOnly ? 'datepicker.enterDate' : 'datepicker.enterDateTime';
+    $datePattern = $dateType === DateTypeEnum::DateOnly ? '\d{4}-\d{2}-\d{2}' : '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}';
+    $date_object = null;
+
+    if(isset($queryParams)) {
+      if(!empty($queryParams[$fieldName])) {
+        $date_object = FrozenTime::parse($queryParams[$fieldName]);
+      }
+    } else {
+      // This is an entity view. We are getting the data from the object
+      $entity = $this->getView()->get('vv_obj');
+      $date_object = $entity->$fieldName;
+    }
+
+    // Create the options array for the (text input) form control
+    $coptions = [];
+
+    // A datetime field will be rendered as a plain text input with adjacent date and time pickers
+    // that will interact with the field value. Allowing direct access to the input field is for
+    // accessibility purposes.
+
+    // ACTION VIEW
     if($this->action == 'view') {
       // return the date as plaintext
-      $coptions = [];
-      $entity = $this->getView()->get('vv_obj');
-      if (!empty($entity->$fieldName)) {
+      $controlCode = $this->notSetElement();
+      if ($date_object !== null) {
         // Adjust the time back to the user's timezone
-        if ($dateType == DateTypeEnum::DateOnly) {
-          $controlCode = '<time>' . $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz')) . '</time>';
-        } else {
-          $controlCode = '<time>' . $entity->$fieldName->i18nFormat("yyyy-MM-dd HH:mm:ss", $this->getView()->get('vv_tz')) . '</time>';
-        }
-      } else {
-        $controlCode = '<div class="not-set">' . __d('information', 'notset') . '</div>';
+        $controlCode = '<time>' . $date_object->i18nFormat($dateFormat) . '</time>';
       }
+
       // Return this to the generic control() function
+      return ['controlCode' => $controlCode,
+              'coptions' => [],
+              'cssClass' => '',
+              'labelIsTextOnly' => true];
       return $this->control($fieldName, $coptions, ctrlCode: $controlCode, labelIsTextOnly: true);
-      
-    } else {
-      // A datetime field will be rendered as a plain text input with adjacent date and time pickers
-      // that will interact with the field value. Allowing direct access to the input field is for
-      // accessibility purposes.
-  
-      $pickerType = $dateType;
-      // Special-case the very common "valid_from" and "valid_through" fields so we won't need
-      // to specify their types in fields.inc.
-      if ($fieldName == 'valid_from') {
-        $pickerType = DateTypeEnum::FromTime;
-      }
-      if ($fieldName == 'valid_through') {
-        $pickerType = DateTypeEnum::ThroughTime;
-      }
-  
-      // Append the timezone to the label -- TODO: see that the timezone gets output to the display
-      $label = __d('field', $fieldName . ".tz", [$this->_View->get('vv_tz')]);
-  
-      // Create the options array for the (text input) form control
-      $coptions = [];
-      $coptions['class'] = 'form-control datepicker';
-  
-      if ($pickerType == DateTypeEnum::DateOnly) {
-        $coptions['placeholder'] = 'YYYY-MM-DD';
-        $coptions['pattern'] = '\d{4}-\d{2}-\d{2}';
-        $coptions['title'] = __d('field', 'datepicker.enterDate');
-      } else {
-        $coptions['placeholder'] = 'YYYY-MM-DD HH:MM:SS';
-        $coptions['pattern'] = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}';
-        $coptions['title'] = __d('field', 'datepicker.enterDateTime');
-      }
-      $coptions['id'] = str_replace("_", "-", $fieldName);
-  
-      $entity = $this->getView()->get('vv_obj');
-  
-      // Default the picker date to today
-      $now = FrozenTime::now();
-      $pickerDate = $now->i18nFormat('yyyy-MM-dd');
-  
-      // Get the existing values, if present
-      if(!empty($entity->$fieldName)) {
-        // Adjust the time back to the user's timezone
-        if($pickerType == DateTypeEnum::DateOnly) {
-          $coptions['value'] = $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz'));
-        } else {
-          $coptions['value'] = $entity->$fieldName->i18nFormat("yyyy-MM-dd HH:mm:ss", $this->getView()->get('vv_tz'));
-        }
-        $pickerDate = $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz'));
-      }
-  
-      // Set the date picker floor year value (-100 years)
-      $pickerDateFT = new FrozenTime($pickerDate);
-      $pickerDateFT = $pickerDateFT->subYears(100);
-      $pickerFloor = $pickerDateFT->i18nFormat("yyyy-MM-dd");
-  
-      $date_picker_args = [
-        'fieldName' => $fieldName,
-        'pickerDate' => $pickerDate,
-        'pickerType' => $pickerType,
-        'pickerFloor' => $pickerFloor
-      ];
-  
-      // Create a text field to hold our value and call the datePicker
-      $controlCode = $this->Form->text($fieldName, $coptions)
-        . $this->getView()->element('datePicker', $date_picker_args);
-  
-      // Specify a class on the <li> form control wrapper
-      $liClass = "fields-datepicker";
-      
-      // Pass everything to the generic control() function
-      return $this->control($fieldName, $coptions, ctrlCode: $controlCode, cssClass: $liClass);
     }
+
+    // Special-case the very common "valid_from" and "valid_through" fields, so we won't need
+    // to specify their types in fields.inc.
+    $pickerType = match ($fieldName) {
+      'valid_from' => DateTypeEnum::FromTime,
+      'valid_through' => DateTypeEnum::ThroughTime,
+      default => $dateType
+    };
+
+    // Append the timezone to the label
+    $coptions['class'] = 'form-control datepicker';
+    $coptions['placeholder'] = $dateFormat;
+    if(!empty($label)) {
+      $coptions['label'] = $label;
+    }
+    $coptions['pattern'] = $datePattern;
+    $coptions['title'] = __d('field', $dateTitle);
+
+    $coptions['id'] = str_replace('_', '-', $fieldName);
+
+
+    // Default the picker date to today
+    $now = FrozenTime::now();
+    $pickerDate = $now->i18nFormat($dateFormat);
+
+    // Get the existing values, if present
+    if($date_object !== null) {
+      // Adjust the time back to the user's timezone
+      $coptions['value'] = $date_object->i18nFormat($dateFormat);
+      $pickerDate = $date_object->i18nFormat($dateFormat);
+    }
+
+    // Set the date picker floor year value (-100 years)()
+    $pickerDateFT = new FrozenTime($pickerDate);
+    $pickerDateFT = $pickerDateFT->subYears(100);
+    $pickerFloor = $pickerDateFT->i18nFormat($dateFormat);
+
+    $date_picker_args = [
+      'fieldName' => $fieldName,
+      'pickerDate' => $pickerDate,
+      'pickerType' => $pickerType,
+      'pickerFloor' => $pickerFloor,
+    ];
+
+    // Create a text field to hold our value and call the datePicker
+    $controlCode = $this->Form->text($fieldName, $coptions) . $this->getView()->element('datePicker', $date_picker_args);
+
+    // Specify a class on the <li> form control wrapper
+    $liClass = 'fields-datepicker';
+    // Pass everything to the generic control() function
+    return ['controlCode' => $controlCode,
+            'coptions' => $coptions,
+            'labelIsTextOnly' => false,
+            'cssClass' => $liClass];
   }
   
   /**
@@ -667,11 +696,24 @@ public function peopleAutocompleteControl(string $fieldName, array $viewConfigPa
    * @return string
    * @since  COmanage Registry v5.0.0
    */
-  protected function requiredSpanElement() {
+  protected function requiredSpanElement(): string
+  {
     return "<span class='required' aria-hidden='true'>*</span>"
            . "<span class='visually-hidden'>{__d('field', 'required')}</span>";
   }
 
+  /**
+   * Static Not Set Div Element
+   *
+   * @return string
+   * @since  COmanage Registry v5.0.0
+   */
+
+  protected function notSetElement(): string
+  {
+    return '<div class="not-set">' . __d('information', 'notset') . '</div>';
+  }
+
   /**
    * Emit a source control for an MVEA that has a source_foo_id field pointing
    * to an External Identity attribute.
diff --git a/app/templates/Standard/index.php b/app/templates/Standard/index.php
index 783ffa70e..a262d8d08 100644
--- a/app/templates/Standard/index.php
+++ b/app/templates/Standard/index.php
@@ -180,7 +180,7 @@
       $filterArgs['indexColumns'] = $indexColumns;
     }
   ?>
-  <?= $this->element('filter', $filterArgs); ?>
+  <?= $this->element('filter/filter', $filterArgs); ?>
 <?php endif; ?>
 
 <!-- Index table -->
diff --git a/app/templates/element/datePicker.php b/app/templates/element/datePicker.php
index 7d25f5d20..6eda46363 100644
--- a/app/templates/element/datePicker.php
+++ b/app/templates/element/datePicker.php
@@ -70,7 +70,19 @@
     },
     components: {
       CmDateTimePicker
-    }
+    },
+    template: `
+      <cm-date-time-picker
+        :id="id"
+        :target="target"
+        :date="date"
+        :datemin="datemin"
+        :datemax="datemax"
+        :type="type"
+        :ampm="ampm"
+        :txt="txt">
+      </cm-date-time-picker>
+    `
   });
 
   // Add custom global directives available to all child components.
@@ -92,15 +104,4 @@
 
   app.mount("#<?= $pickerId ?>-container");
 </script>
-<div id="<?= $pickerId ?>-container">
-  <cm-date-time-picker
-    :id="id"
-    :target="target"
-    :date="date"
-    :datemin="datemin"
-    :datemax="datemax"
-    :type="type"
-    :ampm="ampm"
-    :txt="txt">
-  </cm-date-time-picker>
-</div>
+<div id="<?= $pickerId ?>-container" class="datepicker-container"></div>
diff --git a/app/templates/element/filter.php b/app/templates/element/filter.php
deleted file mode 100644
index d7a6226d9..000000000
--- a/app/templates/element/filter.php
+++ /dev/null
@@ -1,417 +0,0 @@
-<?php
-/**
- * COmanage Registry Filter Element - for index view filtering
- *
- * Portions licensed to the University Corporation for Advanced Internet
- * Development, Inc. ("UCAID") under one or more contributor license agreements.
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership.
- *
- * UCAID licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @link          https://www.internet2.edu/comanage COmanage Project
- * @package       registry
- * @since         COmanage Registry v5.0.0
- * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
- */
-use Cake\Collection\Collection;
-use Cake\Utility\Inflector;
-
-
-// $this->name = Models
-$modelsName = $this->name;
-// $modelName = Model
-$modelName = Inflector::singularize($modelsName);
-// $columns = the passed parameter $indexColumns as found in columns.inc; provides overrides for labels and sorting. 
-$columns = $indexColumns;
-
-// Get the query string and separate the search params from the non-search params
-$query = $this->request->getQueryParams();
-// Search attributes collection
-$search_attributes_collection = new Collection($vv_searchable_attributes);
-$alias_params = $search_attributes_collection->filter(fn ($val, $attr) => (is_array($val) && array_key_exists('alias', $val)) )
-                                             ->extract('alias')
-                                             ->unfold()
-                                             ->toArray();
-// For the non search params we need to search the alias params as well
-$searchable_parameters = [
-  ...array_keys($vv_searchable_attributes),
-  ...$alias_params
-  ];
-$non_search_params = (new Collection($query))->filter( fn($value, $key) => !in_array($key, $searchable_parameters) )
-                                             ->toArray();
-
-// Filter the search params and take params with aliases into consideration
-$search_params = [];
-foreach ($vv_searchable_attributes as $attr => $value) {
-  if(isset($query[$attr])) {
-    $search_params[$attr] = $query[$attr];
-    continue;
-  }
-
-  if(isset($value['alias'])
-     && is_array($value['alias'])) {
-    foreach ($value['alias'] as $alias_key) {
-      if(isset($query[$alias_key])) {
-        $search_params[$attr][$alias_key] = $query[$alias_key];
-      }
-    }
-  }
-}
-
-// Begin the form
-print $this->Form->create(null, [
-  'id'   => 'top-filters-form',
-  'type' => 'get'
-]);
-
-// Pass back the non-search params as hidden fields, but always exclude the page parameter
-// because we need to start new searches on page one (or we're likely to end up with a 404).
-if(!empty($non_search_params)) {
-  foreach($non_search_params as $param => $value) {
-    if($param != 'page') {
-      print $this->Form->hidden(filter_var($param, FILTER_SANITIZE_SPECIAL_CHARS), array('default' => filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS))) . "\n";
-    }
-  }
-}
-
-// Boolean to distinguish between search filters and sort parameters
-$hasActiveFilters = false;
-?>
-
-<div id="<?= $modelName . ucfirst($this->request->getParam('action')) ?>Search" class="top-filters">
-  <fieldset>
-    <legend id="top-filters-toggle">
-      <em class="material-icons top-filters-search-icon" aria-hidden="true">search</em>
-      <span class="top-filters-title">
-        <?= __d('operation', 'filter'); ?>
-      </span>
-
-      <?php if(!empty($search_params)):?>
-        <span id="top-filters-active-filters">
-        <?php foreach($search_params as $key => $params): ?>
-          <?php
-            // Construct aria-controls string
-            $aria_controls = $key;
-            // We save the name of the id into a dataset variable, data-identifier. This is an easy way
-            // to store the correct identifier in the case of dates. Dates have two search fields for each column
-            // which makes it more complicated to keep track of the id.
-            $data_identifier = is_array($params) ? implode(':', array_keys($params)) : $key;
-
-            // We have active filters - not just a sort.
-            $hasActiveFilters = true;
-
-            // The populated variables are in plural while the column names are singular
-            // Convention: It is a prerequisite that the vvar should be the plural of the column name
-            $populated_vvar = lcfirst(Inflector::pluralize(Inflector::camelize($key)));
-            $button_label = isset($$populated_vvar) ?
-              $$populated_vvar[ $search_params[$key] ] :
-              (is_array($search_params[$key]) ? 'Range' : $search_params[$key]);
-          ?>
-          <button class="top-filters-active-filter deletebutton spin btn btn-default btn-sm" data-identifier="<?= $data_identifier ?>" type="button" aria-controls="<?php print $aria_controls; ?>" title="<?= __d('operation', 'clear.filters',[2]); ?>">
-            <em class="material-icons" aria-hidden="true">cancel</em>
-            <span class="top-filters-active-filter-title">
-              <?= Inflector::humanize(Inflector::underscore($vv_searchable_attributes[$key]['label'] ?? $columns[$key]['label'])) ?>
-            </span>
-            <?php if($vv_searchable_attributes[$key]['type'] != 'boolean'): ?>
-              <span class="top-filters-active-filter-value">
-                <?= filter_var($button_label, FILTER_SANITIZE_SPECIAL_CHARS); ?>
-              </span>
-            <?php endif; ?>
-          </button>
-        <?php endforeach; ?>
-          <?php if($hasActiveFilters): ?>
-            <button id="top-filters-clear-all-button" class="filter-clear-all-button spin btn" type="button" aria-controls="top-filters-clear" onclick="event.stopPropagation()">
-              <?= __d('operation', 'clear.filters',[2]); ?>
-           </button>
-          <?php endif; ?>
-      </span>
-      <?php endif; ?>
-      <button class="cm-toggle nospin" aria-expanded="false" aria-controls="top-filters-fields" type="button"><em class="material-icons drop-arrow">arrow_drop_down</em></button>
-    </legend>
-    <div id="top-filters-fields">
-      <div class="top-filters-fields-subgroups">
-      <?php
-        $field_booleans_columns = [];
-        $field_datetime_columns = [];
-        
-        $inactiveFiltersCount = 0; // for re-balancing the columns and submit buttons
-
-        foreach($vv_searchable_attributes as $key => $options) {
-          if($options['type'] == 'boolean') {
-            $field_booleans_columns[$key] = $options;
-            continue;
-          } elseif ($options['type'] == 'timestamp') {
-            $field_datetime_columns[$key] = $options;
-            continue;
-          }
-
-          $label = Inflector::humanize(
-            Inflector::underscore(
-              $options['label'] ?? $columns[$key]['label']
-            )
-          );
-
-          if($options['type'] == 'date') {
-            // Date fields use a date picker (e.g. DOB)
-            // (Note that timestamps are handled specially. See below.)
-            $opts = [];
-            $opts['type'] = 'text'; // date inputs must be text for accessibility reasons for now.
-            $opts['required'] = false;
-            $opts['pattern'] = '\d{4}-\d{2}-\d{2}';
-            $opts['placeholder'] = 'YYYY-MM-DD';
-            $opts['title'] = __d('field','datepicker.enterDate');
-            $opts['class'] = 'form-control datepicker';
-            $opts['id'] = str_replace("_", "-", $key);
-
-            $date = \Cake\I18n\FrozenTime::parseDate(date("Y-m-d"),'yyyy-MM-dd');
-            if(!empty($query[$key])) {
-              $date = \Cake\I18n\FrozenTime::parseDate($query[$key],'yyyy-MM-dd');
-              $opts['value'] = $date->i18nFormat("yyyy-MM-dd");
-            }
-            $pickerDate = $date->i18nFormat("yyyy-MM-dd");
-            $pickerFloor = $date->subYears(100)->i18nFormat("yyyy-MM-dd");
-            
-            $date_args = [
-              'fieldName' => $key,
-              'pickerDate' => $pickerDate,
-              'pickerType' => \App\Lib\Enum\DateTypeEnum::DateOnly,
-              'pickerFloor' => $pickerFloor
-            ];
-
-            $wrapperCssClass = 'filter-active';
-            if(empty($options['active'])) {
-              $wrapperCssClass = 'filter-inactive';
-              $inactiveFiltersCount++;
-            }
-            
-            // Create a text field to hold our date value.
-            print '<div class="top-filters-fields-date filter-standard ' . $wrapperCssClass . '">';
-            print $this->Form->label($key, $label);
-            print '<div class="d-flex">';
-            print $this->Form->text($key, $opts) . $this->element('datePicker', $date_args);
-            print '</div>';
-            print '</div>';
-          } else {
-            // text input
-            $formParams = [
-              'label' => $label,
-              // The default type is text, but we might convert to select below
-              'type' => 'text',
-              'value' => (!empty($query[$key]) ? $query[$key] : ''),
-              'required' => false,
-              'class' => 'form-control'
-            ];
-          }
-          
-          // The populated variables are in plural while the column names are singular
-          // Convention: It is a prerequisite that the vvar should be the plural of the column name
-          $populated_vvar = lcfirst(Inflector::pluralize(Inflector::camelize($key)));
-          if(isset($$populated_vvar)) {
-            // If we have an AutoViewVar matching the name of this key,
-            // convert to a select
-            $formParams['type'] = 'select';
-            $formParams['options'] = $$populated_vvar;
-            // Allow empty so a filter doesn't require (eg) SOR
-            $formParams['empty'] = true;
-          }
-
-          $wrapperCssClass = 'filter-active';
-          if(empty($options['active'])) {
-            $wrapperCssClass = 'filter-inactive';
-            $inactiveFiltersCount++;
-          }
-          
-          if($options['type'] != 'date') {
-            print '<div class="filter-standard ' . $wrapperCssClass . '">';
-            print $this->Form->control($key, $formParams);
-            print '</div>';
-          }
-        }
-      ?>
-      <?php if(!empty($field_booleans_columns)): ?>
-        <div class="top-filters-checkboxes input">
-          <div class="top-filters-checkbox-fields">
-            <?php foreach($field_booleans_columns as $key => $options): ?>
-              <div class="filter-boolean <?= empty($options['active']) ? 'filter-inactive' : 'filter-active' ?>">
-                <div class="form-check form-check-inline">
-                  <?php
-                    print $this->Form->label($options['label'] ?? $key);
-                    print $this->Form->checkbox($key, [
-                      'id' => str_replace("_", "-", $key),
-                      'class' => 'form-check-input',
-                      'checked' => $query[$key] ?? 0,
-                      'hiddenField' => false,
-                      'required' => false
-                    ]);
-                  ?>
-                </div>
-              </div>
-            <?php endforeach; ?>
-          </div>
-        </div>
-      <?php endif; ?>
-      </div>
-      
-      <?php if(!empty($field_datetime_columns)): ?>
-        <div class="top-filters-fields-subgroups">
-        <?php foreach($field_datetime_columns as $key => $options): ?>
-          <div class="input">
-            <div class="top-search-date-label">
-              <?= !empty($columns[$key]['label']) ? $columns[$key]['label'] : Inflector::humanize($key) ?>
-            </div>
-            <div class="top-filters-fields-dates">
-              <!--     Start at       -->
-              <div class="top-search-start-date">
-                <div class="d-flex">
-                  <?php
-                  // A datetime field will be rendered as plain text input with adjacent date and time pickers
-                  // that will interact with the field value. Allowing direct access to the input field is for
-                  // accessibility purposes.
-                  $starts_field = $key . "_starts_at";
-                  $coptions = [];
-                  $coptions['class'] = 'form-control datepicker';
-                  $coptions['label'] = __d('field','starts_at');
-                  $coptions['required'] = false;
-                  $coptions['placeholder'] = '';
-//                  $coptions['placeholder'] = 'YYYY-MM-DD HH:MM:SS';
-                  $coptions['pattern'] = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}';
-                  $coptions['title'] = __d('field','datepicker.enterDateTime');
-                  $coptions['id'] = str_replace("_", "-", $starts_field);
-
-                  $pickerDate = '';
-                  if(!empty($query[$starts_field])) {
-                    $starts_date = \Cake\I18n\FrozenTime::parse($query[$starts_field]);
-                    // Adjust the time back to the user's timezone
-                    $coptions['value'] = $starts_date->i18nFormat("yyyy-MM-dd HH:mm:ss", $this->get('vv_tz'));
-                    $pickerDate = $starts_date->i18nFormat("yyyy-MM-dd", $this->get('vv_tz'));
-                  }
-
-                  $date_args = [
-                    'fieldName' => $starts_field,
-                    'pickerDate' => $pickerDate
-                  ];
-                  // Create a text field to hold our value.
-                  print $this->Form->label($starts_field, __d('field','starts_at'), ['class' => 'filter-datepicker-lbl']);
-                  print $this->Form->text($starts_field, $coptions) . $this->element('datePicker', $date_args);
-                  ?>
-                </div>
-              </div>
-              <!--     Ends at       -->
-              <div class="top-search-end-date">
-                <div class="d-flex">
-                  <?php
-                  // A datetime field will be rendered as plain text input with adjacent date and time pickers
-                  // that will interact with the field value. Allowing direct access to the input field is for
-                  // accessibility purposes.
-                  $ends_field = $key . "_ends_at";
-                  $coptions = [];
-                  $coptions['class'] = 'form-control datepicker';
-                  $coptions['required'] = false;
-                  $coptions['placeholder'] = ''; // todo: Make this configurable
-//                  $coptions['placeholder'] = 'YYYY-MM-DD HH:MM:SS';
-                  $coptions['pattern'] = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}';
-                  $coptions['title'] = __d('field','datepicker.enterDateTime');
-                  $coptions['label'] = __d('field','ends_at');
-                  $coptions['id'] = str_replace("_", "-", $ends_field);
-
-                  $pickerDate = '';
-                  if(!empty($query[$ends_field])) {
-                    // Adjust the time back to the user's timezone
-                    $ends_date = \Cake\I18n\FrozenTime::parse($query[$ends_field]);
-                    $coptions['value'] = $ends_date->i18nFormat("yyyy-MM-dd HH:mm:ss", $this->get('vv_tz'));
-                    $pickerDate = $ends_date->i18nFormat("yyyy-MM-dd", $this->get('vv_tz'));
-                  }
-
-                  $date_args = [
-                    'fieldName' => $ends_field,
-                    'pickerDate' => $pickerDate
-                  ];
-                  // Create a text field to hold our value.
-                  print $this->Form->label($ends_field, __d('field','ends_at'), ['class' => 'filter-datepicker-lbl']);
-                  print $this->Form->text($ends_field, $coptions) . $this->element('datePicker', $date_args);
-                  ?>
-                </div>
-              </div>
-            </div>
-          </div>
-        <?php endforeach; ?>
-        </div>
-      <?php endif; ?>
-
-      <?php $rebalanceColumns = (((count($vv_searchable_attributes) - $inactiveFiltersCount) % 2 == 1) && empty($field_booleans_columns)) ? ' class="tss-rebalance"' : ''; ?>
-      <div id="top-filters-submit"<?php print $rebalanceColumns ?>>
-        
-        <?php
-          // Order of the submit buttons is important here: the Enter key will submit the first (and we want the tab order to follow suit).  
-          // We reverse the visual order of all these buttons with CSS (flex-direction: row-reverse;).
-          
-          // search button (submit)
-          $args = array();
-          $args['id'] = 'top-filters-filter-button';
-          $args['aria-label'] = __d('operation', 'filter');
-          $args['class'] = 'submit-button spin btn btn-primary';
-          print $this->Form->submit(__d('operation', 'filter'),$args);
-
-          // clear button
-          $args = array();
-          $args['id'] = 'top-filters-clear';
-          $args['class'] = 'clear-button spin btn btn-default';
-          $args['aria-label'] = __d('operation', 'clear');
-          $args['onclick'] = 'clearTopSearch(this.form)';
-          print $this->Form->button(__d('operation', 'clear'),$args);
-        ?>
-        
-        <?php if(!empty($vv_searchable_attributes)): ?>
-          <div id="top-filters-options-container">
-            <button id="top-filters-options-button" class="btn btn-default options-button dropdown-toggle" 
-                    type="button" data-bs-toggle="dropdown" aria-expanded="false">
-              <?= __d('menu', 'options') ?>
-            </button>
-            <div class="dropdown-menu dropdown-menu-lg-end" aria-labelledby="top-filters-options-button">
-              <h4><?= __d('menu','available.filters') ?></h4>
-              <div id="top-filters-options">
-                <?php foreach($vv_searchable_attributes as $key => $options): ?>
-                  <?php if($options['type'] == 'timestamp' || $options['type'] == 'boolean') continue; // skip timestamp types and put booleans at the bottom of the list ?>
-                  <div class="form-check filter-selector filter-selector-text">
-                    <input class="form-check-input" 
-                           type="checkbox" 
-                           value="<?= Cake\Utility\Inflector::dasherize($key) ?>" 
-                           id="filter-selector-<?= $key ?>"<?= !empty($options['active']) ? ' checked' : '' ?>>
-                    <label class="form-check-label" for="filter-selector-<?= $key ?>">
-                      <?= $options['label'] ?>
-                    </label>
-                  </div>
-                <?php endforeach; ?>
-                <?php foreach($field_booleans_columns as $key => $options): ?>
-                  <div class="form-check filter-selector filter-selector-boolean">
-                    <input class="form-check-input" 
-                           type="checkbox" 
-                           value="<?= Cake\Utility\Inflector::dasherize($key) ?>" 
-                           id="filter-selector-<?= $key ?>"<?= !empty($options['active']) ? ' checked' : '' ?>>
-                    <label class="form-check-label" for="filter-selector-<?= $key ?>">
-                      <?= $options['label'] ?>
-                    </label>
-                  </div>
-                <?php endforeach; ?>
-              </div>
-            </div>
-          </div>
-        <?php endif; ?>
-      </div>
-    </div>
-  </fieldset>
-</div>
-
-<?= $this->Form->end(); ?>
-
diff --git a/app/templates/element/filter/activeTopButton.php b/app/templates/element/filter/activeTopButton.php
new file mode 100644
index 000000000..2c3895d95
--- /dev/null
+++ b/app/templates/element/filter/activeTopButton.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * COmanage Registry Active Top Button Element
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @link          https://www.internet2.edu/comanage COmanage Project
+ * @package       registry
+ * @since         COmanage Registry v5.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+
+use Cake\Utility\{Inflector, Hash};
+
+// Construct aria-controls string
+$aria_controls = $key;
+// We save the name of the id into a dataset variable, data-identifier. This is an easy way
+// to store the correct identifier in the case of dates. Dates have two search fields for each column
+// which makes it more complicated to keep track of the id.
+$data_identifier = is_array($params) ? implode(':', array_keys($params)) : $key;
+
+// The populated variables are in plural while the column names are singular
+// Convention: It is a prerequisite that the vvar should be the plural of the column name
+$populated_vvar = lcfirst(Inflector::pluralize(Inflector::camelize($key)));
+$button_label = 'Range';
+if(isset($$populated_vvar) && isset($$populated_vvar[$params])) {
+  $button_label = $$populated_vvar[$params];
+} elseif(!is_array($params)) {
+  $button_label = $params;
+  if(isset($vv_searchable_attributes_extras)) {
+    $flattenedSearchableAttributesExtras = Hash::flatten($vv_searchable_attributes_extras);
+    $filteredFlattenedSearchableAttributesExtras = array_filter(
+      $flattenedSearchableAttributesExtras,
+      static fn($flKey) => str_contains($flKey, $params),
+      ARRAY_FILTER_USE_KEY
+    );
+    if(!empty($filteredFlattenedSearchableAttributesExtras)) {
+      $button_label = array_pop($filteredFlattenedSearchableAttributesExtras);
+    }
+  }
+}
+
+$filter_title =
+  Inflector::humanize(
+    Inflector::underscore(
+      $vv_searchable_attributes[$key]['label'] ?? $columns[$key]['label']
+    )
+  );
+
+?>
+
+<button class="top-filters-active-filter deletebutton spin btn btn-default btn-sm"
+        data-identifier="<?= $data_identifier ?>"
+        type="button" aria-controls="<?= $aria_controls ?>"
+        title="<?= __d('operation', 'clear.filters',[2]) ?>">
+  <em class="material-icons" aria-hidden="true">cancel</em>
+  <span class="top-filters-active-filter-title"><?= $filter_title ?></span>
+  <?php if($vv_searchable_attributes[$key]['type'] != 'boolean'): ?>
+  <span class="top-filters-active-filter-value">
+    <?= filter_var($button_label, FILTER_SANITIZE_SPECIAL_CHARS) ?>
+  </span>
+  <?php endif; ?>
+</button>
\ No newline at end of file
diff --git a/app/templates/element/filter/dateTimeFilters.php b/app/templates/element/filter/dateTimeFilters.php
new file mode 100644
index 000000000..4c7440dba
--- /dev/null
+++ b/app/templates/element/filter/dateTimeFilters.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * COmanage Registry Filter Element - for index view filtering
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @link          https://www.internet2.edu/comanage COmanage Project
+ * @package       registry
+ * @since         COmanage Registry v5.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+
+use App\Lib\Enum\DateTypeEnum;
+use Cake\Utility\Inflector;
+
+?>
+
+<div class="top-filters-fields-subgroups">
+  <?php foreach($field_datetime_columns as $key => $options): ?>
+    <div class="input">
+      <div class="top-search-date-label">
+        <?= !empty($columns[$key]['label']) ? $columns[$key]['label'] : Inflector::humanize($key) ?>
+      </div>
+      <div class="top-filters-fields-dates">
+        <!--     Start at       -->
+        <div class="top-search-start-date">
+          <?php
+          // Create a text field to hold our value.
+          print $this->Form->label("{$key}_starts_at", __d('field', 'starts_at'), ['class' => 'filter-datepicker-lbl']);
+          print $this->Field->dateField("{$key}_starts_at", DateTypeEnum::DateOnly, $query)['controlCode'];
+          ?>
+        </div>
+        <!--     Ends at       -->
+        <div class="top-search-end-date">
+          <?php
+          // Create a text field to hold our value.
+          print $this->Form->label("{$key}_ends_at", __d('field','ends_at'), ['class' => 'filter-datepicker-lbl']);
+          print $this->Field->dateField("{$key}_ends_at", DateTypeEnum::DateOnly, $query)['controlCode'];
+          ?>
+        </div>
+      </div>
+    </div>
+  <?php endforeach; ?>
+</div>
diff --git a/app/templates/element/filter/filter.php b/app/templates/element/filter/filter.php
new file mode 100644
index 000000000..ca534135b
--- /dev/null
+++ b/app/templates/element/filter/filter.php
@@ -0,0 +1,246 @@
+<?php
+/**
+ * COmanage Registry Filter Element - for index view filtering
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @link          https://www.internet2.edu/comanage COmanage Project
+ * @package       registry
+ * @since         COmanage Registry v5.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+use Cake\Collection\Collection;
+use Cake\Utility\{Inflector, Hash};
+use App\Lib\Enum\DateTypeEnum;
+
+
+// $this->name = Models
+$modelsName = $this->name;
+// $modelName = Model
+$modelName = Inflector::singularize($modelsName);
+// $columns = the passed parameter $indexColumns as found in columns.inc; provides overrides for labels and sorting. 
+$columns = $indexColumns;
+
+// Get the query string and separate the search params from the non-search params
+$query = $this->request->getQueryParams();
+// Search attributes collection
+$search_attributes_collection = new Collection($vv_searchable_attributes);
+$alias_params = $search_attributes_collection->filter(fn ($val, $attr) => (is_array($val) && array_key_exists('alias', $val)) )
+                                             ->extract('alias')
+                                             ->unfold()
+                                             ->toArray();
+// For the non search params we need to search the alias params as well
+$searchable_parameters = [
+  ...array_keys($vv_searchable_attributes),
+  ...$alias_params
+  ];
+$non_search_params = (new Collection($query))->filter( fn($value, $key) => !in_array($key, $searchable_parameters) )
+                                             ->toArray();
+
+// Filter the search params and take params with aliases into consideration
+$search_params = [];
+foreach ($vv_searchable_attributes as $attr => $value) {
+  if(isset($query[$attr])) {
+    $search_params[$attr] = $query[$attr];
+    continue;
+  }
+
+  if(isset($value['alias'])
+     && is_array($value['alias'])) {
+    foreach ($value['alias'] as $alias_key) {
+      if(isset($query[$alias_key])) {
+        $search_params[$attr][$alias_key] = $query[$alias_key];
+      }
+    }
+  }
+}
+
+// Begin the form
+print $this->Form->create(null, [
+  'id'   => 'top-filters-form',
+  'type' => 'get'
+]);
+
+// Pass back the non-search params as hidden fields, but always exclude the page parameter
+// because we need to start new searches on page one (or we're likely to end up with a 404).
+if(!empty($non_search_params)) {
+  foreach($non_search_params as $param => $value) {
+    if($param != 'page') {
+      print $this->Form->hidden(filter_var($param, FILTER_SANITIZE_SPECIAL_CHARS), array('default' => filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS))) . "\n";
+    }
+  }
+}
+
+// Boolean to distinguish between search filters and sort parameters
+$hasActiveFilters = false;
+?>
+
+<div id="<?= $modelName . ucfirst($this->request->getParam('action')) ?>Search" class="top-filters">
+  <fieldset>
+    <!--  Top Filters toggle legend  -->
+    <?= $this->element('filter/topFiltersToggle', compact('search_params')) ?>
+    <div id="top-filters-fields">
+      <div class="top-filters-fields-subgroups">
+      <?php
+        $field_booleans_columns = [];
+        $field_datetime_columns = [];
+        
+        $inactiveFiltersCount = 0; // for re-balancing the columns and submit buttons
+
+        foreach($vv_searchable_attributes as $key => $options) {
+          if($options['type'] == 'boolean') {
+            $field_booleans_columns[$key] = $options;
+            continue;
+          } elseif ($options['type'] == 'timestamp') {
+            $field_datetime_columns[$key] = $options;
+            continue;
+          }
+
+          $wrapperCssClass = 'filter-active';
+          if(empty($options['active'])) {
+            $wrapperCssClass = 'filter-inactive';
+            $inactiveFiltersCount++;
+          }
+
+
+          $label = Inflector::humanize(
+            Inflector::underscore(
+              $options['label'] ?? $columns[$key]['label']
+            )
+          );
+
+          if($options['type'] == 'date') {
+            // Create a text field to hold our date value.
+            print '<div class="top-filters-fields-date filter-standard ' . $wrapperCssClass . '">';
+            print $this->Form->label($key, $label);
+            print '<div class="d-flex">';
+            print $this->Field->dateField($key, DateTypeEnum::DateOnly, $query)['controlCode'];
+            print '</div>';
+            print '</div>';
+          } else {
+            // text input
+            $formParams = [
+              'label' => $label,
+              // The default type is text, but we might convert to select below
+              'type' => 'text',
+              'value' => (!empty($query[$key]) ? $query[$key] : ''),
+              'required' => false,
+              'class' => 'form-control'
+            ];
+          }
+          
+          // The populated variables are in plural while the column names are singular
+          // Convention: It is a prerequisite that the vvar should be the plural of the column name
+          $populated_vvar = lcfirst(Inflector::pluralize(Inflector::camelize($key)));
+          if(isset($$populated_vvar)) {
+            // If we have an AutoViewVar matching the name of this key,
+            // convert to a select
+            $formParams['type'] = 'select';
+            $formParams['options'] = $$populated_vvar;
+            if(isset($vv_searchable_attributes_extras[$key]['options'])) {
+              // Flatten the custom options
+              $customOptionsFlattened = Hash::flatten($vv_searchable_attributes_extras[$key]['options']);
+              // Get the key of the place holder string
+              $dataKey = array_search('@DATA@', $customOptionsFlattened, true);
+              if($dataKey !== false) {
+                $customOptionsFlattened[$dataKey] = $formParams['options'];
+                $formParams['options'] = Hash::expand($customOptionsFlattened);
+              }
+            }
+            // Allow empty so a filter doesn't require (eg) SOR
+            $formParams['empty'] = true;
+          }
+          
+          if($options['type'] != 'date') {
+            print '<div class="filter-standard ' . $wrapperCssClass . '">';
+            print $this->Form->control($key, $formParams);
+            print '</div>';
+          }
+        }
+      ?>
+      <?php if(!empty($field_booleans_columns)): ?>
+        <div class="top-filters-checkboxes input">
+          <div class="top-filters-checkbox-fields">
+            <?php foreach($field_booleans_columns as $key => $options): ?>
+              <div class="filter-boolean <?= empty($options['active']) ? 'filter-inactive' : 'filter-active' ?>">
+                <div class="form-check form-check-inline">
+                  <?php
+                    print $this->Form->label($options['label'] ?? $key);
+                    print $this->Form->checkbox($key, [
+                      'id' => str_replace("_", "-", $key),
+                      'class' => 'form-check-input',
+                      'checked' => $query[$key] ?? 0,
+                      'hiddenField' => false,
+                      'required' => false
+                    ]);
+                  ?>
+                </div>
+              </div>
+            <?php endforeach; ?>
+          </div>
+        </div>
+      <?php endif; ?>
+      </div>
+
+      <?php
+      // Date Time filtering block
+      if (!empty($field_datetime_columns)) {
+        print $this->element(
+          'filter/dateTimeFilters',
+          compact('field_datetime_columns', 'query')
+        );
+      }
+      ?>
+
+      <?php $rebalanceColumns = (((count($vv_searchable_attributes) - $inactiveFiltersCount) % 2 == 1) && empty($field_booleans_columns)) ? ' class="tss-rebalance"' : ''; ?>
+      <div id="top-filters-submit"<?= $rebalanceColumns ?>>
+        
+      <?php
+        // Order of the submitted buttons is important here: the Enter key will submit the first (and we want the tab order to follow suit).
+        // We reverse the visual order of all these buttons with CSS (flex-direction: row-reverse;).
+
+        // search button (submit)
+        $args = array();
+        $args['id'] = 'top-filters-filter-button';
+        $args['aria-label'] = __d('operation', 'filter');
+        $args['class'] = 'submit-button spin btn btn-primary';
+        print $this->Form->submit(__d('operation', 'filter'),$args);
+
+        // clear button
+        $args = array();
+        $args['id'] = 'top-filters-clear';
+        $args['class'] = 'clear-button spin btn btn-default';
+        $args['aria-label'] = __d('operation', 'clear');
+        $args['onclick'] = 'clearTopSearch(this.form)';
+        print $this->Form->button(__d('operation', 'clear'),$args);
+
+        // Options dropdown list
+        if(!empty($vv_searchable_attributes)) {
+          print $this->element(
+            'filter/filterOptions',
+            compact('vv_searchable_attributes', 'field_booleans_columns')
+          );
+        }
+      ?>
+      </div>
+    </div>
+  </fieldset>
+</div>
+
+<?= $this->Form->end(); ?>
+
diff --git a/app/templates/element/filter/filterOptions.php b/app/templates/element/filter/filterOptions.php
new file mode 100644
index 000000000..327f456db
--- /dev/null
+++ b/app/templates/element/filter/filterOptions.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * COmanage Registry Filter Options
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @link          https://www.internet2.edu/comanage COmanage Project
+ * @package       registry
+ * @since         COmanage Registry v5.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+
+?>
+
+<div id="top-filters-options-container">
+  <button id="top-filters-options-button" class="btn btn-default options-button dropdown-toggle"
+          type="button" data-bs-toggle="dropdown" aria-expanded="false">
+    <?= __d('menu', 'options') ?>
+  </button>
+  <div class="dropdown-menu dropdown-menu-lg-end" aria-labelledby="top-filters-options-button">
+    <h4><?= __d('menu','available.filters') ?></h4>
+    <div id="top-filters-options">
+      <?php foreach($vv_searchable_attributes as $key => $options): ?>
+        <?php if($options['type'] == 'timestamp' || $options['type'] == 'boolean') continue; // skip timestamp types and put booleans at the bottom of the list ?>
+        <div class="form-check filter-selector filter-selector-text">
+          <input class="form-check-input"
+                 type="checkbox"
+                 value="<?= Cake\Utility\Inflector::dasherize($key) ?>"
+                 id="filter-selector-<?= $key ?>"<?= !empty($options['active']) ? ' checked' : '' ?>>
+          <label class="form-check-label" for="filter-selector-<?= $key ?>">
+            <?= $options['label'] ?>
+          </label>
+        </div>
+      <?php endforeach; ?>
+      <?php foreach($field_booleans_columns as $key => $options): ?>
+        <div class="form-check filter-selector filter-selector-boolean">
+          <input class="form-check-input"
+                 type="checkbox"
+                 value="<?= Cake\Utility\Inflector::dasherize($key) ?>"
+                 id="filter-selector-<?= $key ?>"<?= !empty($options['active']) ? ' checked' : '' ?>>
+          <label class="form-check-label" for="filter-selector-<?= $key ?>">
+            <?= $options['label'] ?>
+          </label>
+        </div>
+      <?php endforeach; ?>
+    </div>
+  </div>
+</div>
diff --git a/app/templates/element/filter/topFiltersToggle.php b/app/templates/element/filter/topFiltersToggle.php
new file mode 100644
index 000000000..442b474e4
--- /dev/null
+++ b/app/templates/element/filter/topFiltersToggle.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * COmanage Registry Top Filters Toggle Element
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @link          https://www.internet2.edu/comanage COmanage Project
+ * @package       registry
+ * @since         COmanage Registry v5.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+
+// $search_params passed as a parameter
+
+$hasActiveFilters = false;
+
+?>
+
+
+<legend id="top-filters-toggle">
+  <em class="material-icons top-filters-search-icon" aria-hidden="true">search</em>
+  <span class="top-filters-title">
+        <?= __d('operation', 'filter'); ?>
+      </span>
+
+  <?php if(!empty($search_params)):?>
+    <span id="top-filters-active-filters">
+        <?php
+        foreach($search_params as $key => $params) {
+          // We have active filters - not just a sort.
+          $hasActiveFilters = true;
+          print $this->element('filter/activeTopButton', compact('key', 'params'));
+        }
+        ?>
+      <?php if($hasActiveFilters): ?>
+        <button id="top-filters-clear-all-button" class="filter-clear-all-button spin btn" type="button" aria-controls="top-filters-clear" onclick="event.stopPropagation()">
+            <?= __d('operation', 'clear.filters',[2]); ?>
+          </button>
+      <?php endif; ?>
+      </span>
+  <?php endif; ?>
+  <button class="cm-toggle nospin" aria-expanded="false" aria-controls="top-filters-fields" type="button"><em class="material-icons drop-arrow">arrow_drop_down</em></button>
+</legend>
diff --git a/app/templates/element/subnavigation.php b/app/templates/element/subnavigation.php
index 0455fb437..22f3461c2 100644
--- a/app/templates/element/subnavigation.php
+++ b/app/templates/element/subnavigation.php
@@ -302,25 +302,16 @@
           <?php
             $linkClass = ($active == 'members') ? 'nav-link active' : 'nav-link';
             $title = __d('controller', 'Members', [99]);
-            $num_group_members = 0;
-            // Group Members tab
-            if(isset($group_members)) {
-              $num_group_members = $this->Paginator->counter('{{count}}');
-            } elseif(isset($groupMembers)) {
-              // Group Nesting
-              $num_group_members = count($groupMembers);
-            } elseif($vv_obj?->group_members) {
-              // Group Properties Tab
-              $num_group_members = count($vv_obj->group_members);
-            }
 
-            $tab_title = "<span class='tab-count'>"
-                         . "<span class='tab-count-item'>{$num_group_members}</span>"
-                       . '</span>'
-                       . "<span class='tab-title'>{$title}</span>";
+            // Create the title with the count badge
+            $title = $this->element('tabs/tabTitleWithCount', [
+              'title' => $title,
+              'model' => 'group_members',
+              'where' => $linkFilter
+            ]);
 
             print $this->Html->link(
-              $tab_title,
+              $title,
               [ 'controller' => 'group_members',
                 'action' => 'index',
                 '?' => $linkFilter
diff --git a/app/templates/element/tabs/tabTitleWithCount.php b/app/templates/element/tabs/tabTitleWithCount.php
new file mode 100644
index 000000000..07845fa6c
--- /dev/null
+++ b/app/templates/element/tabs/tabTitleWithCount.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * COmanage Registry Tab Title With count Element
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @link          https://www.internet2.edu/comanage COmanage Project
+ * @package       registry
+ * @since         COmanage Registry v5.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ *
+ *
+ */
+
+if(empty($num)) {
+  $num = $this->Common->getModelTotalCount($model, $where);
+}
+
+?>
+
+<span class='tab-count'>
+  <span class='tab-count-item'><?= $num ?></span>
+</span>
+<span class='tab-title'><?= $title ?></span>
\ No newline at end of file
diff --git a/app/webroot/css/co-base.css b/app/webroot/css/co-base.css
index 0165ae67a..cb07ae8fa 100644
--- a/app/webroot/css/co-base.css
+++ b/app/webroot/css/co-base.css
@@ -716,6 +716,8 @@ ul.form-list li.alert-banner .co-alert {
   font-size: 0.9em;
   border: 1px solid var(--cmg-color-link);
   border-radius: 16px;
+  min-width: 24px;
+  text-align: center;
 }
 .tab-count-item {
   display: inline-block;
@@ -855,7 +857,6 @@ ul.form-list li.alert-banner .co-alert {
 .side-search select {
   width: 100%;
   box-sizing: border-box;
-  margin: 0 0 0.5em 0;
   height: 28px;
   padding: 2px 4px;
   border: 1px solid var(--cmg-color-bg-006);
@@ -865,6 +866,12 @@ ul.form-list li.alert-banner .co-alert {
 .top-filters label {
   margin-bottom: 0;
 }
+.top-search-end-date,
+.top-search-start-date {
+  display: flex;
+  margin-bottom: 0.5em;
+  align-items: center;
+}
 ::-webkit-input-placeholder,
 ::-moz-placeholder,
 :-ms-input-placeholder,
@@ -964,9 +971,6 @@ ul.form-list li.alert-banner .co-alert {
   white-space: nowrap;
   margin-right: 0.5em;
 }
-.top-filters-fields-date .duet-date__toggle {
-  margin-top: -3px;
-}
 /* PLATFORM NOTICE (for COmanage CO) */
 #platform-notice {
   padding: 0.5em;
@@ -1448,6 +1452,9 @@ ul.form-list li.info-title {
   align-items: center;
   margin-left: 2.8em;
 }
+.datepicker-container {
+  display: flex;
+}
 .duet-date__toggle {
   width: 30px;
   height: 30px;