8

I'm trying to display a drupal view in a CiviCRM contact tab. I've tested out my tab function with the code snippet on hook_civicrm_tabs and it will show the contribution tab correctly, and I've tested out my drupal view url on its own with a contact id appended and that displays correctly, but when I try to use my code to display the view in the tab, after I click the tab I get a civicrm error pop up message that says "Network Error Unable to reach the server. Please refresh this page in your browser and try again."

Here is my code

function mymodule_civicrm_tabs(&$tabs, $contactID) {

$url = '/civicrm-videos/'. $contactID;
$tabs[] = array( 'id'    => 'projectTab',
                 'url'   => $url,
                 'title' => 'Projects',
                 'weight' => 300,
                 'count' => '2' );
}

What am I doing wrong?

1
  • 1
    Emily - did the answers below help. If so can you tick one to let others (like me) know which route to follow
    – petednz - fuzion
    Feb 14, 2016 at 22:46

5 Answers 5

4

Extrapolating on Coleman's answer, you can get the json output required by creating a new Drupal page with hook_menu. Here is the full code:

function mymodule_menu() {
  $items['civicrm-videos/%user/json'] = array(
    'access callback' => true,
    'page callback' => 'mymodule_output_my_view_json',
    'delivery callback' => 'drupal_json_output',
    'page arguments' => array(1)
  );
  return $items;
}

function mymodule_output_my_view_json($user) {
  civicrm_initialize();
  $content = views_embed_view('my_view', 'page', $user->uid);
  CRM_Core_Page_AJAX::returnJsonResponse($content);
}

function mymodule_civicrm_tabs(&$tabs, $contactID) {

    $url = '/civicrm-videos/'. $contactID . '/json';
    $tabs[] = array( 'id'    => 'projectTab',
                     'url'   => $url,
                     'title' => 'Projects',
                     'weight' => 300,
                     'count' => 2 );
}
3

If you're receiving that error, that probably means an AJAX call is failing. Check out these troubleshooting tips - but more importantly, in your Developer Tools tab (F12 in Firefox/Chrome), check the Net tab and see what comes back when you click your custom tab. My guess is you'll see an HTTP error (a 404, 500, or similar) which will yield helpful troubleshooting info.

3

Generally when CiviCRM uses ajax to fetch content it is not expecting to get raw html back from the server. What it expects is a structured json array. I don't know of a way to easily get Views to return output in this way without writing your own drupal page callback that does something like:

function mymodule_output_view($cid) {
  civicrm_initialize();
  $content = views_embed_view('my_view', 'default', $cid);
  CRM_Core_Page_AJAX::returnJsonResponse($content);
}
2
  • my view has sortable result and a pager. Clicking sortable column refreshes the page and takes me to original view page. I want to sort the result the same way as it occurs on Activity tab of contact view page. Thanks in advance
    – Amit
    Apr 21, 2016 at 18:55
  • Take a look at the crm.livepage.js code for how that's done.
    – Coleman
    Apr 22, 2016 at 12:32
3

For those looking for a no-coding solution to this question, see the Drupal module Views in CiviCRM Contact Page. This module can add Views to a contact's tab.

3
  • 1
    any knowledge about this being viable? no release. code is at cgit.drupalcode.org/civicrm_views_contact_page
    – petednz - fuzion
    Oct 10, 2017 at 9:02
  • Also curious if this is considered usable.
    – Laryn
    Oct 30, 2017 at 16:15
  • 1
    I've used it a couple of times! I recall some trickiness due to lack of docs; I documented the trick but then didn't publish before I left my old employer. IIRC it's something to do with the Views path. However, once you've used it once successfully it's very straightforward. Oct 30, 2017 at 19:04
1

Here is my slightly different code based on knsheely's answer. My view has an url admin/%/civitab/downloads, this view has an contextual filter "CiviCRM Contacts: Contact ID". There is also a count of the number of results so the tab shows the correct amount. I did not have to initialise civicrm with civicrm_initialize(); so I left this out but if needed you can add it again.

function MYMODULE_menu() {
  // Add a Downloads tab
  $items['admin/%/civitab/downloads/json'] = array(
    'access callback' => true,
    'page callback' => 'MYMODULE_downloads_json',
    'delivery callback' => 'drupal_json_output',
    'page arguments' => array(1),
  );
  return $items;
}

function MYMODULE_downloads_json($contactID) {
  $content = views_embed_view('civicrm_downloads_tab', 'page_2', $contactID);
  CRM_Core_Page_AJAX::returnJsonResponse($content);
}

/**
 * Add an extra tab to civicrm contact
 * @todo: implement hook_civicrm_tabset because tabs is deprecated
 */
function MYMODULE_civicrm_tabs( &$tabs, $contactID ) {
  $url = CRM_Utils_System::url('admin/'. $contactID . '/civitab/downloads/json');
  $result = views_get_view_result('civicrm_downloads_tab', 'page_2', $contactID);
  $count = count($result);
  $tabs[] = array(
    'id' => 'downloads',
    'url' => $url,
    'title' => ts('Downloads'),
    'weight' => 300,
    'count' => $count,
  );
};
1
  • note that civicrm_initialize() will return early if civi is already bootstrapped, so it doesn't hurt anything and can save your code from hard-crashing in situations where it's not.
    – Coleman
    Feb 1, 2016 at 22:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.