Answers.Body: <p>Even i wanted an easy way of doing this as well but the current architecture of CiviCRM doesn't allow it automatically. I could achieve this by copying few functions(see below) from CRM_Core_Form_Search into my custom search file </p>
  
  <pre><code>  /**
     * @return array
     */
    public function getSearchFieldMetadata() {
      $searchFieldMetadata['contact'] = [
        'sort_name' =&gt; [
          'title' =&gt; ts('Sort Name'),
          'type' =&gt; CRM_Utils_Type::T_STRING,
        ]
      ];
      return $searchFieldMetadata;
    }
  
    /**
     * Get the validation rule to apply to a function.
     *
     * Alphanumeric is designed to always be safe &amp; for now we just return
     * that but in future we can use tighter rules for types like int, bool etc.
     *
     * @param string $entity
     * @param string $fieldName
     *
     * @return string
     */
    protected function getValidationTypeForField($entity, $fieldName) {
      switch ($this-&gt;getSearchFieldMetadata()[$entity][$fieldName]['type']) {
        case CRM_Utils_Type::T_BOOLEAN:
          return 'Boolean';
  
        case CRM_Utils_Type::T_INT:
          return 'CommaSeparatedIntegers';
  
        case CRM_Utils_Type::T_DATE:
        case CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME:
          return 'Timestamp';
  
        default:
          return 'Alphanumeric';
      }
    }
  
    /**
     * Get the defaults for the entity for any fields described in metadata.
     *
     * @param string $entity
     *
     * @return array
     *
     * @throws \CRM_Core_Exception
     */
    protected function getEntityDefaults($entity) {
      $defaults = [];
      foreach (CRM_Utils_Array::value($entity, $this-&gt;getSearchFieldMetadata(), []) as $fieldName =&gt; $fieldSpec) {
        if (empty($_POST[$fieldName])) {
          $value = CRM_Utils_Request::retrieveValue($fieldName, $this-&gt;getValidationTypeForField($entity, $fieldName), NULL, NULL, 'GET');
          if ($value !== NULL) {
            $defaults[$fieldName] = $value;
          }
          if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE || ($fieldSpec['type'] === CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME)) {
            $low = CRM_Utils_Request::retrieveValue($fieldName . '_low', 'Timestamp', NULL, NULL, 'GET');
            $high = CRM_Utils_Request::retrieveValue($fieldName . '_high', 'Timestamp', NULL, NULL, 'GET');
            if ($low !== NULL || $high !== NULL) {
              $defaults[$fieldName . '_relative'] = 0;
              $defaults[$fieldName . '_low'] = $low ? date('Y-m-d H:i:s', strtotime($low)) : NULL;
              $defaults[$fieldName . '_high'] = $high ? date('Y-m-d H:i:s', strtotime($high)) : NULL;
            }
            else {
              $relative = CRM_Utils_Request::retrieveValue($fieldName . '_relative', 'String', NULL, NULL, 'GET');
              if (!empty($relative) &amp;&amp; isset(CRM_Core_OptionGroup::values('relative_date_filters')[$relative])) {
                $defaults[$fieldName . '_relative'] = $relative;
              }
            }
          }
        }
      }
      return $defaults;
    }
  </code></pre>
  
  <p>and added below snippet in my custom search file __construct() function(at the beginning)</p>
  
  <pre><code>    $this-&gt;_force = CRM_Utils_Request::retrieve('force', 'Boolean');
      if ($this-&gt;_force) {
        foreach (array_keys($this-&gt;getSearchFieldMetadata()) as $entity) {
          $formValues = array_merge($this-&gt;getEntityDefaults($entity), $formValues);
        }
      }
  </code></pre>
  
  <p>HTH</p>
  
  <p>Pradeep</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-30T09:19:19.927Z
Answers.Text: Thanks Pradeep!
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-29T18:46:03.587Z
Answers.LastActivityDate: 2020-01-29T18:46:03.587Z
Answers.UserDisplayName: Pradeep Nayak
Body: <p>I have created a custom search, and it works nicely. What I would really like though is to pass default values to the custom search and it doing the initial search with those values.</p>
  
  <p>The user can then change the search criteria if he/she wants another filter.</p>
  
  <p>Is that possible and how can I do that?</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-01-29T20:01:26.867Z
Comments.Text: i suspect this isn't helpful but we did a PR to get more parameters accepted by Adv Search - https://github.com/civicrm/civicrm-core/pull/12455
Comments.UserDisplayName: petednz - fuzion
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-01-30T09:19:48.870Z
Comments.Text: Thanks for the comment, but I really need something like a Custom Search :-)
Comments.UserDisplayName: ErikH - CiviCooP
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-02-04T23:13:18.060Z
Comments.Text: What about creating a smart group from your custom search ? ... and then modifying your smart group criteria ?
Comments.UserDisplayName: Jacques-Marie Moranne
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-02-05T07:20:07.743Z
Comments.Text: Hmmm might give that a try...thanks for the suggestion!
Comments.UserDisplayName: ErikH - CiviCooP
Tags: <custom-search>
Title: How can I make a Custom Search do an initial search?
ThreadText: # How can I make a Custom Search do an initial search?
  
  (Asked by: username_0 on 2020-01-29)
  
  I have created a custom search, and it works nicely. What I would really like though is to pass default values to the custom search and it doing the initial search with those values.
  
  The user can then change the search criteria if he/she wants another filter.
  
  Is that possible and how can I do that?
  
  **Tags:** custom-search
  
  > **Comments:**
  > **username_1**: i suspect this isn't helpful but we did a PR to get more parameters accepted by Adv Search - https://github.com/civicrm/civicrm-core/pull/12455  
  > **username_0**: Thanks for the comment, but I really need something like a Custom Search :-)  
  > **username_2**: What about creating a smart group from your custom search ? ... and then modifying your smart group criteria ?  
  > **username_0**: Hmmm might give that a try...thanks for the suggestion!  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_3 on 2020-01-29. Score: 3
  
  Even i wanted an easy way of doing this as well but the current architecture of CiviCRM doesn't allow it automatically. I could achieve this by copying few functions(see below) from CRM\_Core\_Form\_Search into my custom search file
  
  ```
    /**
     * @return array
     */
    public function getSearchFieldMetadata() {
      $searchFieldMetadata['contact'] = [
        'sort_name' => [
          'title' => ts('Sort Name'),
          'type' => CRM_Utils_Type::T_STRING,
        ]
      ];
      return $searchFieldMetadata;
    }
  
    /**
     * Get the validation rule to apply to a function.
     *
     * Alphanumeric is designed to always be safe & for now we just return
     * that but in future we can use tighter rules for types like int, bool etc.
     *
     * @param string $entity
     * @param string $fieldName
     *
     * @return string
     */
    protected function getValidationTypeForField($entity, $fieldName) {
      switch ($this->getSearchFieldMetadata()[$entity][$fieldName]['type']) {
        case CRM_Utils_Type::T_BOOLEAN:
          return 'Boolean';
  
        case CRM_Utils_Type::T_INT:
          return 'CommaSeparatedIntegers';
  
        case CRM_Utils_Type::T_DATE:
        case CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME:
          return 'Timestamp';
  
        default:
          return 'Alphanumeric';
      }
    }
  
    /**
     * Get the defaults for the entity for any fields described in metadata.
     *
     * @param string $entity
     *
     * @return array
     *
     * @throws \CRM_Core_Exception
     */
    protected function getEntityDefaults($entity) {
      $defaults = [];
      foreach (CRM_Utils_Array::value($entity, $this->getSearchFieldMetadata(), []) as $fieldName => $fieldSpec) {
        if (empty($_POST[$fieldName])) {
          $value = CRM_Utils_Request::retrieveValue($fieldName, $this->getValidationTypeForField($entity, $fieldName), NULL, NULL, 'GET');
          if ($value !== NULL) {
            $defaults[$fieldName] = $value;
          }
          if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE || ($fieldSpec['type'] === CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME)) {
            $low = CRM_Utils_Request::retrieveValue($fieldName . '_low', 'Timestamp', NULL, NULL, 'GET');
            $high = CRM_Utils_Request::retrieveValue($fieldName . '_high', 'Timestamp', NULL, NULL, 'GET');
            if ($low !== NULL || $high !== NULL) {
              $defaults[$fieldName . '_relative'] = 0;
              $defaults[$fieldName . '_low'] = $low ? date('Y-m-d H:i:s', strtotime($low)) : NULL;
              $defaults[$fieldName . '_high'] = $high ? date('Y-m-d H:i:s', strtotime($high)) : NULL;
            }
            else {
              $relative = CRM_Utils_Request::retrieveValue($fieldName . '_relative', 'String', NULL, NULL, 'GET');
              if (!empty($relative) && isset(CRM_Core_OptionGroup::values('relative_date_filters')[$relative])) {
                $defaults[$fieldName . '_relative'] = $relative;
              }
            }
          }
        }
      }
      return $defaults;
    }
  
  ```
  
  and added below snippet in my custom search file \_\_construct() function(at the beginning)
  
  ```
      $this->_force = CRM_Utils_Request::retrieve('force', 'Boolean');
      if ($this->_force) {
        foreach (array_keys($this->getSearchFieldMetadata()) as $entity) {
          $formValues = array_merge($this->getEntityDefaults($entity), $formValues);
        }
      }
  
  ```
  
  HTH
  
  username_3
  
  > **Comments:**
  > **username_0**: Thanks username_3!  
  
  ---
  
  