Thanks for the great module. I have a client who would like to implement node_compare with a views page of a search_api index. Possible? The client would likely be willing to pay for this feature. Anyone want to take this on?

Comments

robit8deb’s picture

I second this. My view returns indexed nodes and the add to compare is not available as field on the view. Comparing search results side by side would be great.

robit8deb’s picture

If anyone is trying to integrate with a search result view the quick way is to add a custom text field and add this:
<a id="compare-toggle-[nid]" class="compare-toggle use-ajax add" href="compare/toggle/[nid]/nojs?destination=<view page url>" rel="nofollow">Add to compare</a>

Make sure you have the nid field added and hidden before the custom text field so you can use the [nid] token.

deardagny’s picture

I did what robit8deb did, and while it works to an extent, the link doesn't behave correctly when navigating back and forth from a Search API results page. If you add a node to compare, navigate to the actual comparison page, then come back to the results page, the "Remove from compare" button doesn't appear on that node (because the view is just printing a static field).

I would think just adding the dynamic "add to" link to a views field tpl would work. The field itself shouldn't be indexed anyway.

michel.g’s picture

I made it work locally defining a new handler in which I overwrite the add_additional_fields function and retrieve my field info differently:

class MODULE_NAME_handler_field_compare_node extends entity_views_handler_field_uri {
  function query() {
    $this->add_additional_fields();
  }

  function element_type($none_supported = FALSE, $default_empty = FALSE, $inline = FALSE) {
    if (isset($this->definition['element type'])) {
      return $this->definition['element type'];
    }
    return 'div';
  }

  function render($values) {
    $type = $values->entity->{$this->aliases['type']};
    if (variable_get('node_compare_type_' . $type, array())) {
      return theme('node_compare_toggle_link', array('nid' => $values->entity->{$this->aliases['nid']}));
    }
  }

  /**
   * Add 'additional' fields to the query.
   *
   * Overwrites the parent function in such way
   * that the SearchApiViewsQuery API can be
   * used to add fields.
   *
   * @param array $fields
   *   An array of fields.
   */
  function add_additional_fields($fields = NULL) {
    if (!isset($fields)) {
      // Notice check.
      if (empty($this->additional_fields)) {
        return;
      }
      $fields = $this->additional_fields;
    }

    if (!empty($fields) && is_array($fields)) {
      foreach ($fields as $identifier => $info) {
        if (is_array($info)) {
          $table_alias = $base_table = $this->view->base_table;

          if (empty($table_alias)) {
            debug(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', array(
              '@handler' => $this->definition['handler'],
              '@identifier' => $identifier,
              '@table' => $info['table'],
            )));
            $this->aliases[$identifier] = 'broken';
            continue;
          }

          if (method_exists($this->query, 'add_field')) {
            $this->aliases[$identifier] = $this->query->add_field($table_alias, $info['field']);
          }
          else {
            $this->aliases[$identifier] = $this->query->addField($info['field']);
          }
        }
      }
    }
  }

}

Then you create a MODULE_NAME.views.inc file in which you set your data similar to node_compare_views_data_alter, just instead of $data['node], you will change your search_api_index table value. (In my case 'search_api_index_default_node_index')

I didn't want to create a patch because then you need a dependency on the entity module...

michel.g’s picture

Status: Active » Needs work