Widoki 3 programowo usuwają odsłonięty filtr

9

Mam kilka typów węzłów, z których każdy odnosi się do innego słownictwa terminów taksonomicznych. Do wyświetlania kategorii używam modułu taksonomii.

Na przykład mamy dwie kategorie: wskazówki i kule bilardowe.

Cue ma cenę od, cena do i filtry typu drewna. Ale kule nie mają filtra typu drewna.

Więc muszę usunąć filtr typu drewna, jeśli taksonomia_term tid odnosi się do słownictwa kule bilardowe.

Dlatego muszę programowo usunąć jeden z wielu odsłoniętych filtrów.

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]);
}

Pole filtru zostało pomyślnie usunięte, ale dostałem powiadomienie php:

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

Próbuję również usunąć pole w hook_pre_execute (), ale z tym samym rezultatem:

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

Spróbuj także za pomocą metody override_option (), jak tutaj - http://groups.drupal.org/node/82219 , ale nie ma żadnego wyniku.

Jakieś sugestie? Pls help =)


Dziękuję wszystkim za odpowiedź, ale wciąż nie mam odpowiedzi. Może coś nie jest jasne? = (

Oleg Sherbakov
źródło
Próbowałeś hook_views_pre_render () ? Możesz także pokazać / ukryć odpowiednie filtry w zależności od wyboru w jQuery.
enzipher
Cześć, rozumiem, że twoje rozwiązanie działa dobrze, ale nie ma właściwego sposobu . Więc mogę to ukryć, używając nawet warunków CSS ... Próbuję wyjaśnić. Każdy rodzaj kodu powinien znajdować się tam, gdzie powinien być. W przypadku tego problemu, jeśli ukrywam odsłonięty filtr przed lub po renderowaniu, widoki nadal go przetwarzają. A jeśli spróbuję dodać ciąg zapytania, np. Smt ?filter_id=val, widoki zwrócą pusty ekran lub błąd nielegalnego wyboru ...
Oleg Sherbakov
Próbowałeś już mojej odpowiedzi?
Mathankumar 16.04.13
Nie muszę zmieniać formy (wiem, że twój wariant działa), chcę zmodyfikować widok obiektu, aby miał podobny do twojego wyniku, ale wcześniej niż kompilacje formularza.
Oleg Sherbakov

Odpowiedzi:

5

Użyłbym hook_form_alter użyciu rozbrojony na obiekcie formularz jak jesteś w swoim przykład dla elementu, który chcesz usunąć.

Scott Thomas
źródło
1

Oto przetestowany fragment, który pozwoli Ci usunąć filtry z odsłoniętej formy przy użyciu formularza alter, jak wspomniał Scott Thomas,

/**
 *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]);
  }     
}

Oprócz usunięcia pola formularza musisz również usunąć informacje dla konkretnego filtra, który jest dostępny w $ form ['# info'], aby usunąć również etykietę. Jeśli usuniesz sam element formularza, etykieta filtra zostanie wyświetlona, ​​nawet jeśli pole zostanie usunięte, więc zawsze upewnij się, że usuwasz również te informacje.

Zmodyfikuj to zgodnie ze swoimi potrzebami. Jeśli chcesz wykonać to dla konkretnego widoku, dodaj też warunek, np.

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

Tutaj $ form_state ['view'] da ci bieżący obiekt widoku, który jest przetwarzany.

Mam nadzieję że to pomoże.

Mathankumar
źródło
To było jedyne rozwiązanie, które ukrywało dla mnie etykiety oraz widżety pola i działało w formie odsłoniętego filtra w bloku.
xenophyle
1

Wykonaj poniższe kroki

  1. Najpierw napisz hook_form_alter w niestandardowym module
  2. Następnie wypróbuj następujący fragment kodu

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

Mam nadzieję, że to pomaga.

Rons
źródło
1

Możesz usunąć odsłonięty filtr również przy użyciu pliku szablonu.

Użyj tego polecenia:

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

W pliku szablonu znajdź ten kod:

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

I usuń to. Twój odsłonięty filtr zostanie usunięty z ekranu, ale nadal będzie działał, przekazując odpowiednie argumenty w adresie URL.

subhojit777
źródło
Dziękuję za odpowiedź, ale czekam na D8, który wykorzystuje rdzeń interfejsu API do budowania odsłoniętych filtrów :)
Oleg Sherbakov
0

Popraw mnie, jeśli się mylę, ponieważ nie jestem w stanie w pełni zrozumieć Twojego problemu. Czy chcesz ukryć odsłonięty filtr w widoku w zależności od wartości innego odsłoniętego filtra? Jeśli tak, możesz wypróbować moduł Widoki zależne od filtrów . Użyłem go kilka razy i to działa.

Możesz sprawdzić nasze Fiend Lullabot za opinię na temat tego modułu.

Jeśli naprawdę musisz to zrobić w kodzie, opcja narażona powinna działać: filter [$ filter_id] -> options ['posed '] = FALSE;

Hervé Donner
źródło
Chciałbym ukryć odsłonięty filtr, jeśli bieżący typ zawartości nie ma tego (filtrowanego) pola. Próbuję swojego fragmentu, $view->display_handler->handlers['filter'][$filter_field]->options['exposed'] = FALSE;mam błąd krytyczny - PHP Fatal error: Call to undefined method stdClass::access() in .../view.inc on line 766. Myślę, że jego poprawne zachowanie, ponieważ jeśli filtr nie jest narażony, wymaga również wartości domyślnej. Jakieś pomysły?
Oleg Sherbakov
pastebin.com/f1FKgUde tutaj jest mój kod, może będzie bardziej przejrzysty niż mój angielski
Oleg Sherbakov
0

To zrobiłem dla mnie wewnątrz hook_form_alter:

$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]);
benezech jerome
źródło
0

Metoda 1

Za pomocą hook_views_query_alter (). Zobacz następujący przykład:

<?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
}

Metoda 2

Zobacz przykład, używając hook_views_pre_execute i funkcji niestandardowej, która próbuje znaleźć odpowiedni warunek pola i zwrócić do niego odwołanie:

/**
 * 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;
}
kenorb
źródło
0

Usuwam go z plików szablonów. Zastąp view-view.tpl.php i usuń z niego następujący kod:

  <?php if ($exposed): ?>
    <div class="view-filters">
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>
Henz
źródło
0

Myślę, że operacja była na dobrej drodze. Miałem podobną sytuację bez odsłoniętych filtrów, więc nie mogłem użyć metody hook_form_alter. Oto przykładowy kod dla każdego, kto natknie się na to:

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

Obiekt widoku nie ma remove_itemfunkcji, ale po prostu stwierdza w kodzie, że można ustawić go na zero, aby usunąć element zawierający filtry: views/includes/view.incon-line 2526.

Oto pełny przykład dla każdego, kto kieruje na określony widok i wyświetlanie:

/**
 * 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;
    }
  }
}
JNP Web Developer
źródło