On a CiviCRM 4 site I help run, there is a profile search form exposed to authorised public users of the Drupal site. This form provides many search options including the selection of a region of the UK.
My task is to provide a Drupal block on the site home page that shows a map of the UK with each region clickable - when you click, a map of the results is shown, not a text listing of results.
My solution was to build on the existing profile, as it's display templates have been customised in various ways. To work out what to do, you will have to analyse what is generated by CiviCRM for the actual search form, in particular the (custom) fields that are used.
Basic block structure
My block creates an HTML form that is posts to CiviCRM. Civi uses session keys to differentiate between each user's search. A crucial task is therefore to set a valid "qfKey" hidden form parameter. To get a suitable key, the PHP code creates a suitable form controller and retrieves the key. The code below shows the PHP and a skeleton of the form itself.
<?php civicrm_initialize(TRUE); require_once 'CRM/Core/Controller/Simple.php'; $formController = new CRM_Core_Controller_Simple( 'CRM_Profile_Form_Search', ts('Search Profile'), CRM_Core_Action::ADD ); $formController->setEmbedded( true ); $formController->set( 'gid', 123 ); $ky = $formController->_key; ?> <form action="/civicrm/profile?gid=123" method="post" name="RegionMap" id="RegionMap"> <input name="qfKey" type="hidden" value="<?php echo $ky ?>" /> <input name="_qf_default" type="hidden" value="Search:refresh" /> ... <input name="_qf_Search_refresh" value="Search" type="submit"/> </form>
To work out what needs to go in the form, you will have to copy what's in the standard search form generated by CiviCRM. It seems like you only need to include the chunks for the sub-search you wish to do, ie you do not need to have dummy/hidden entries for all fields.
For my region search, the standard form output consists of a hidden INPUT, a checkbox INPUT and an associated LABEL. You can slim it right down to one hidden INPUT like this:
<input type="hidden" id="northeast" name="custom_21[1.00]" value="" />
"custom_21" is the Civi custom data field internal name. The string in square brackets is the field value - in my case, one of the mulitple choice option values. I have added the "northeast" id to this INPUT.
If you set the value for the above hidden field to "1" and submit the form, you should see the standard text listing of results that match that search. On that page, there should be a "Map these contacts" link.
Showing the result map straight away
To show a map of results straight away, you'd think you'd simply copy the URL of the map page, and it would work:
<form action="/civicrm/profile/map?map=1&gid=123&reset=1" method="post" name="RegionMap" id="RegionMap" >
You do need to do that change, but by itself it doesn't work. If you try it, you will find that it always uses the last proper search terms that you used. Civi is storing the last search parameters in the "profileParams" session variable. So, our first task is to clear this session variable when our block is initialised, ie in the above code:
$session = CRM_Core_Session::singleton();
Here's how I set the profileParams session value. First, I created another hidden field which will be set by JavsScript to contain the value chosen on my block:
<input name="regionCode" type="hidden" value="" />
In the custom CiviCRM code for my site, I amended CRM/Profile/Page/Listings.php in getProfileContact() to rebuild the profileParams session value if my new hidden variable is set:
$regionCode = CRM_Utils_Array::value( 'regionCode', $_REQUEST );
if ( isset($regionCode))
$params = array();
$custom_21 = array();
$custom_21[$regionCode] = 1;
$params["custom_21"] = $custom_21;
For this to work, the regionCode hidden field needs to be set to a suitable value, such as "1.00" in my case.
And the block image map...
<area shape="poly" coords="149,123,158,101,205,169,187,166,181,190" href="/" alt="North East" title="North East England" onclick="return ShowRegion('northeast');" />