Answers.Body: <p>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:</p>
  
  <pre><code>function mymodule_menu() {
    $items['civicrm-videos/%user/json'] = array(
      'access callback' =&gt; true,
      'page callback' =&gt; 'mymodule_output_my_view_json',
      'delivery callback' =&gt; 'drupal_json_output',
      'page arguments' =&gt; array(1)
    );
    return $items;
  }
  
  function mymodule_output_my_view_json($user) {
    civicrm_initialize();
    $content = views_embed_view('my_view', 'page', $user-&gt;uid);
    CRM_Core_Page_AJAX::returnJsonResponse($content);
  }
  
  function mymodule_civicrm_tabs(&amp;$tabs, $contactID) {
  
      $url = '/civicrm-videos/'. $contactID . '/json';
      $tabs[] = array( 'id'    =&gt; 'projectTab',
                       'url'   =&gt; $url,
                       'title' =&gt; 'Projects',
                       'weight' =&gt; 300,
                       'count' =&gt; 2 );
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-06-25T01:52:06.580Z
Answers.LastActivityDate: 2015-06-25T01:52:06.580Z
Answers.UserDisplayName: knsheely
Answers.Body: <p>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:</p>
  
  <pre><code>function mymodule_output_view($cid) {
    civicrm_initialize();
    $content = views_embed_view('my_view', 'default', $cid);
    CRM_Core_Page_AJAX::returnJsonResponse($content);
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-21T18:55:27.710Z
Answers.Text: 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
Answers.UserDisplayName: Amit
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-22T12:32:33.903Z
Answers.Text: Take a look at the crm.livepage.js code for how that's done.
Answers.UserDisplayName: Coleman
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-15T02:13:09.767Z
Answers.LastActivityDate: 2015-05-15T02:13:09.767Z
Answers.UserDisplayName: Coleman
Answers.Body: <p>For those looking for a no-coding solution to this question, see the Drupal module <a href="https://www.drupal.org/project/civicrm_views_contact_page" rel="nofollow noreferrer">Views in CiviCRM Contact Page</a>.  This module can add Views to a contact's tab.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-10-10T09:02:27.837Z
Answers.Text: any knowledge about this being viable? no release. code is at http://cgit.drupalcode.org/civicrm_views_contact_page/
Answers.UserDisplayName: petednz - fuzion
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-10-30T16:15:56.570Z
Answers.Text: Also curious if this is considered usable.
Answers.UserDisplayName: Laryn
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-10-30T19:04:39.620Z
Answers.Text: 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.
Answers.UserDisplayName: Jon G - Megaphone Tech
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-01-30T17:50:09.080Z
Answers.LastActivityDate: 2017-01-30T17:50:09.080Z
Answers.UserDisplayName: Jon G - Megaphone Tech
Answers.Body: <p>If you're receiving that error, that probably means an AJAX call is failing.  Check out <a href="http://forum.civicrm.org/index.php?topic=35850.0" rel="nofollow">these troubleshooting tips</a> - 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.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-14T23:01:55.670Z
Answers.LastActivityDate: 2015-05-14T23:01:55.670Z
Answers.UserDisplayName: Jon G - Megaphone Tech
Answers.Body: <p>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.</p>
  
  <pre><code>function MYMODULE_menu() {
    // Add a Downloads tab
    $items['admin/%/civitab/downloads/json'] = array(
      'access callback' =&gt; true,
      'page callback' =&gt; 'MYMODULE_downloads_json',
      'delivery callback' =&gt; 'drupal_json_output',
      'page arguments' =&gt; 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( &amp;$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' =&gt; 'downloads',
      'url' =&gt; $url,
      'title' =&gt; ts('Downloads'),
      'weight' =&gt; 300,
      'count' =&gt; $count,
    );
  };
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-02-01T22:55:52.570Z
Answers.Text: 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.
Answers.UserDisplayName: Coleman
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-01-30T11:57:10.823Z
Answers.LastActivityDate: 2016-01-30T11:57:10.823Z
Answers.UserDisplayName: Hans Rossel
Body: <p>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."</p>
  
  <p>Here is my code</p>
  
  <pre><code>function mymodule_civicrm_tabs(&amp;$tabs, $contactID) {
  
  $url = '/civicrm-videos/'. $contactID;
  $tabs[] = array( 'id'    =&gt; 'projectTab',
                   'url'   =&gt; $url,
                   'title' =&gt; 'Projects',
                   'weight' =&gt; 300,
                   'count' =&gt; '2' );
  }
  </code></pre>
  
  <p>What am I doing wrong? </p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-02-14T22:46:16.833Z
Comments.Text: Emily - did the answers below help. If so can you tick one to let others (like me) know which route to follow
Comments.UserDisplayName: petednz - fuzion
Tags: <drupal><drupal-views><hooks>
Title: How to display a Drupal view in a CiviCRM tab
ThreadText: # How to display a Drupal view in a CiviCRM tab
  
  (Asked by: username_0 on 2015-05-14)
  
  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?
  
  **Tags:** drupal, drupal-views, hooks
  
  > **Comments:**
  > **username_1**: Emily - did the answers below help. If so can you tick one to let others (like me) know which route to follow  
  
  ---
  
  ## 5 answers
  
  ### Answer by username_2 on 2015-06-25. Score: 4
  
  Extrapolating on username_3'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 );
  }
  
  
  ---
  
  ### Answer by username_3 on 2015-05-15. Score: 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);
  }
  
  > **Comments:**
  > **username_4**: 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  
  > **username_3**: Take a look at the crm.livepage.js code for how that's done.  
  
  ---
  
  ### Answer by username_5 on 2017-01-30. Score: 3
  
  For those looking for a no-coding solution to this question, see the Drupal module [Views in CiviCRM Contact Page](https://www.drupal.org/project/civicrm_views_contact_page). This module can add Views to a contact's tab.
  
  > **Comments:**
  > **username_1**: any knowledge about this being viable? no release. code is at http://cgit.drupalcode.org/civicrm_views_contact_page/  
  > **username_6**: Also curious if this is considered usable.  
  > **username_5**: 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.  
  
  ---
  
  ### Answer by username_5 on 2015-05-14. Score: 3
  
  If you're receiving that error, that probably means an AJAX call is failing. Check out [these troubleshooting tips](http://forum.civicrm.org/index.php?topic=35850.0) - 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.
  
  
  ---
  
  ### Answer by username_7 on 2016-01-30. Score: 1
  
  Here is my slightly different code based on username_2'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,
    );
  };
  
  > **Comments:**
  > **username_3**: 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.  
  
  ---
  
  