Ansichten 3 entfernen den freigelegten Filter programmgesteuert


9

Ich habe mehrere Knotentypen, von denen jeder auf unterschiedliche Taxonomie-Vokabeln verweist. Für die Kategorieanzeige verwende ich das Modul taxonomy_display.

Zum Beispiel haben wir zwei Kategorien: Queues und Billardkugeln.

Cues hat Preis von, Preis bis und Holzfilter. Aber Bälle haben keinen Holzfilter.

Also muss ich den Holzfilter entfernen, wenn taxonomy_term auf das Vokabular der Billardkugeln verweist.

Daher muss ich einen von vielen exponierten Filtern programmgesteuert entfernen.

function modulename_views_pre_view(&$view, &$display_id, &$args) {
  // Some custom logic wich field_info_instances checking ...
  $filter_field = 'filter_id';
  // Removes from everywhere where i can find filter or filters properties
  unset($view->display[$view->current_display]->display_options['filters'][$filter_field]);
  unset($view->display[$view->current_display]->handler->options['filters'][$filter_field]);
  unset($view->display_handler->display->display_options['filters'][$filter_field]);
  unset($view->display_handler->options['filters'][$filter_field]);
}

Filterfeld erfolgreich entfernt, aber ich habe PHP-Hinweis:

  Notice: Undefined index: field_wood_reference_tid in function views_handler_filter_term_node_tid->exposed_validate()

Ich versuche auch, das Feld in hook_pre_execute () zu entfernen, aber mit dem gleichen Ergebnis:

function modulename_views_pre_execute(&$view) {
  $filter_field = 'filter_id';
  unset($view->display_handler->handlers['filter'][$filter_field]);
  unset($view->filter[$filter_field]);
}

Versuchen Sie es auch mit der Methode override_option () wie hier - http://groups.drupal.org/node/82219 , aber ohne Ergebnis.

Irgendwelche Vorschläge? Bitte helfen Sie =)


Vielen Dank an alle für die Antwort, aber ich habe noch keine Antwort. Vielleicht ist etwas nicht klar? = ((


Haben Sie hook_views_pre_render () ausprobiert ? Sie können relevante Filter auch abhängig von der Auswahl mit jQuery ein- / ausblenden.
Enzipher

Hallo, ich verstehe, dass Ihre Lösung in Ordnung funktioniert, aber es gibt keinen richtigen Weg . Also kann ich es sogar unter CSS-Bedingungen verstecken ... Ich versuche es zu erklären. Jede Art von Code sollte dort platziert werden, wo er sein sollte. Wenn ich bei diesem Problem den exponierten Filter vor oder nach dem Rendern ausblende, wird er von den Ansichten weiterhin verarbeitet. Und wenn ich versuche, eine Abfragezeichenfolge hinzuzufügen, smt wie ?filter_id=val, gibt Ansichten eine leere Anzeige oder einen Fehler bei der illegalen Auswahl zurück ...
Oleg Sherbakov

Hast du meine Antwort ausprobiert?
Mathankumar

Ich muss das Formular nicht ändern (ich weiß, dass Ihre Variante funktioniert). Ich möchte das Ansichtsobjekt so ändern, dass es Ihrem Ergebnis ähnelt, jedoch früher als das Erstellen von Formularen.
Oleg Sherbakov

Antworten:



1

Hier ist das getestete Snippet, mit dem Sie die Filter aus den Ansichten entfernen können, die in Formblättern angezeigt werden, indem Sie form alter verwenden, wie von Scott Thomas erwähnt.

/**
 *Implements hook_form_FORM_ID_alter().
 */
function hook_form_views_exposed_form_alter(&$form, &$form_state) {
  $filter_field = 'filter_id';
  // Get the filters list for the current view. Here page_1 is the display ID.
  $filters = $form_state['view']->get_items('filter', 'page_1');
  if (isset($filters[$filter_field])) {
    $info_key = 'filter-' . $filter_field;
    unset($form[$filter_field], $form['#info'][$info_key]);
  }     
}

Neben dem Entfernen des Formularfelds müssen Sie auch die Informationen für einen bestimmten Filter entfernen, die in $ form ['# info'] verfügbar sind, damit auch die Beschriftung entfernt wird. Wenn Sie nur das Formularelement entfernen, wird die Filterbezeichnung angezeigt, obwohl das Feld entfernt wurde. Stellen Sie daher immer sicher, dass Sie auch diese Informationen entfernen.

Ändern Sie dies entsprechend Ihren Anforderungen. Wenn Sie diese für eine bestimmte Ansicht ausführen möchten, fügen Sie auch dafür eine Bedingung hinzu:

if ($form_state['view']->name == 'view_name') {
  // DO your operation.
}

Hier gibt $ form_state ['view'] das aktuelle Ansichtsobjekt an, das gerade verarbeitet wird.

Hoffe das hilft.


Dies war die einzige Lösung, die sowohl die Beschriftungen als auch die Feld-Widgets für mich versteckte, und sie funktionierte in einer exponierten Filterform in einem Block.
Xenophyle

1

Folgen Sie den unteren Schritten

  1. Schreiben Sie zunächst einen hook_form_alter in ein benutzerdefiniertes Modul
  2. Versuchen Sie als nächstes den folgenden Code

    nicht gesetzt ($ form ['# info'] ['your_field_name']); $ form ['your_field_name'] ['# access'] = 'FALSE';

Ich hoffe, das hilft.


1

Sie können exponierte Filter auch mithilfe der Vorlagendatei entfernen.

Verwenden Sie diesen Befehl:

cp sites/all/modules/contrib/views/theme/views-view.tpl.php sites/all/themes/costa/templates/views/views-view--<machine_name>.tpl.php

Suchen Sie in der Vorlagendatei diesen Code:

  <?php if ($exposed): ?>
    <div class="view-filters">
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>

Und entferne es. Ihr exponierter Filter wird aus der Anzeige entfernt, funktioniert aber weiterhin, wenn Sie die richtigen Argumente in der URL übergeben.


Danke für die Antwort, aber ich warte auf D8, der die Kernform-API zum Erstellen exponierter Filter verwendet :)
Oleg Sherbakov

0

Korrigieren Sie mich, wenn ich falsch liege, weil ich nicht sicher bin, ob ich Ihr Problem vollständig verstehe. Sie möchten also einen belichteten Filter in Abhängigkeit vom Wert eines anderen belichteten Filters in einer Ansicht ausblenden? In diesem Fall können Sie das Modul Ansichtenabhängige Filter ausprobieren . Ich habe es mehrmals benutzt und es macht den Job.

Sie können die Bewertung unseres Freundes Lullabot zu diesem Modul überprüfen .

Wenn Sie dies wirklich im Code tun müssen, sollte die exponierte Option funktionieren: filter [$ filter_id] -> options ['exponiert'] = FALSE;


Ich möchte exponierte Filter ausblenden, wenn der aktuelle Inhaltstyp dieses (gefilterte) Feld nicht enthält. Beim Versuch Ihres Snippets habe $view->display_handler->handlers['filter'][$filter_field]->options['exposed'] = FALSE;ich einen schwerwiegenden Fehler - PHP Fatal error: Call to undefined method stdClass::access() in .../view.inc on line 766. Ich denke, es ist korrekt, denn wenn der Filter nicht verfügbar ist, ist auch ein Standardwert erforderlich. Irgendwelche Ideen?
Oleg

pastebin.com/f1FKgUde hier ist mein Code, vielleicht wird es klarer als mein Englisch
Oleg Sherbakov

0

Folgendes hat es für mich in hook_form_alter getan:

$info_key = 'filter-' . $fieldName;
unset($form[$fieldName], $form['#info'][$info_key], $form_state['view']->display_handler->options['filters'][$fieldName], $form_state['view']->display_handler->handlers['filter'][$fieldName], $form_state['view']->filter[$fieldName]);

0

Methode 1

Mit hook_views_query_alter (). Siehe folgendes Beispiel:

<?php
/**
 * Implements hook_views_query_alter().
 */
function foo_views_query_alter(&$view, &$query) {

  if ($view->name == 'foo_view') {

    // Allow any distance when the postcode it is not specified.
    if (empty($_GET['postcode']['postal_code']) || $_GET['postcode']['postal_code'] === 'All') { 
      // Scan through the query.
      foreach ($query->where as $condition_group_key => &$condition_group) {
        foreach ($condition_group['conditions'] as $condition_key => &$condition) {
          $search_name = '(COALESCE(ACOS(';
          if (is_string($condition['field']) && strstr($condition['field'], $search_name) !== FALSE) {
            // Remove filter from the query.
            unset($query->where[$condition_group_key]['conditions'][$condition_key]);
          }
        } // end: foreach
      } // end: foreach
    } // end: if


    /*
     * Change the field conditions.
     * Possible field values: 1, 2, 3
     * Logic: When 3 is selected, then display 1, 2 and 3.
     */
    switch (@$view->display_handler->handlers['filter']['field_123_value']->value[0]) {

      case 3:
        foreach ($query->where as $condition_group_key => &$condition_group) {
          foreach ($condition_group['conditions'] as $condition_key => &$condition) {
            if($condition['field'] == 'field_data_field_123.field_123_value') {
              unset($query->where[$condition_group_key]['conditions'][$condition_key]);
              $query->where[] = array(
                  'conditions' => array(
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 1,
                          'operator' => "=",
                      ),
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 2,
                          'operator' => "=",
                      ),
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 3,
                          'operator' => "=",
                      ),
                  ),
                  'args' => array(),
                  'type' => 'OR',
              );
            }
          }
        } // end: foreach
        break;

    } // end: switch

  } // end: if
}

Methode 2

Sehen Sie sich das Beispiel an, indem Sie hook_views_pre_execute und eine benutzerdefinierte Funktion verwenden, die versucht, die richtige Feldbedingung zu finden und den Verweis darauf zurückzugeben:

/**
 * Implements hook_views_pre_execute().
 */
function foo_views_pre_execute(&$view) {

  if ($view->name == 'foo_view') {


    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      'field_data_field_123.field_123_value',
      $filter
    );

    // We want our filter to work as a bit mask.
    $filter[0]['operator'] = '&';

    unset ($filter);

    // Example of finding Proximity filter condition
    $search_name = '(COALESCE(ACOS(';

    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      $search_name,
      $filter
    );

    if (empty($_GET['postcode']['postal_code']) || $_GET['postcode']['postal_code'] === 'All') {
      // Allowing any distance.
      $filter[0]['value'][':distance'] = 10000000;
    }
    else {
      $filter[0]['value'][':distance'] = 80000;
    }

    unset ($filter);


    // Fetching single record?

    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      'node.nid',
      $filter
    );

    if (!empty($_GET['nid'])) {
      $filter[0]['value'] = (int) $_GET['nid'];
    }
    else {
      $filter[0]['operator'] = '<>';
    }

    unset ($filter);                                                        

    // echo '<pre style="font-size:11px;font-family: Monaco">'; print_r($view->build_info['query']); exit;
  }
}

/**
 * Custom function to find the field condition within the view
 */
function foo_get_view_filter_recursively($view, &$conditions, $field_name, &$filter) {

  if (!empty($conditions)) {

    foreach ($conditions as &$condition) {
      if ($condition instanceof DatabaseCondition) {
        if (foo_get_view_filter_recursively($view, $condition->conditions(), $field_name, $filter)) {
          return TRUE;
        }
      } else if ($condition['field'] instanceof DatabaseCondition) {
        if (foo_get_view_filter_recursively($view, $condition['field']->conditions(), $field_name, $filter)) {
          return TRUE;
        }
      } elseif (is_string($condition['field']) && strstr($condition['field'], $field_name) !== FALSE) {
        @$filter = array(&$condition);
        return TRUE;
      }
    } // end: foreach

  } // end: if

  return FALSE;
}

0

Ich entferne es aus Vorlagendateien. Überschreiben Sie die Datei views-view.tpl.php und entfernen Sie den folgenden Code:

  <?php if ($exposed): ?>
    <div class="view-filters">
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>

0

Ich denke, die Operation war auf dem richtigen Weg. Ich hatte eine ähnliche Situation ohne exponierte Filter, sodass ich die Methode hook_form_alter nicht verwenden konnte. Hier ist ein Beispielcode für alle anderen, die darauf stoßen:

$view->set_item($view->current_display, 'filter', $filter_id, null);

Das Ansichtsobjekt hat keine remove_itemFunktion, sondern gibt im Code einfach an, dass Sie es auf null setzen können, um ein Element mit Filtern zu entfernen: views/includes/view.inconline 2526.

Hier ist ein vollständiges Beispiel für alle, die auf eine bestimmte Ansicht und Anzeige abzielen:

/**
 * Implements HOOK_views_pre_view().
 */
function HOOK_views_pre_view(&$view) {
  if($view->name == 'VIEW_MACHINE_NAME') {
    switch($view->current_display) {
      case 'VIEW_DISPLAY_MACHINE_NAME':
        $view_filters = $view->display_handler->get_option('filters');
        foreach ($view_filters as $filter_id => $filter) {
          if ($filter_id == 'my_filter') {
            $view->set_item($view->current_display, 'filter', $filter_id, null);
          }
        }
      break;
    }
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.