Visualizações 3 remover o filtro exposto programaticamente

9

Eu tenho vários tipos de nós, cada um deles relacionado a diferentes vocabulários de termos taxonômicos. Para exibição de categoria, eu uso o módulo taxonomy_display.

Por exemplo, temos duas categorias: tacos e bolas de bilhar.

Cues tem preço de, preço e filtros do tipo madeira. Mas as bolas não têm filtro de madeira.

Então, eu preciso remover o filtro de tipo de madeira se taxonomy_term tid referenciado ao vocabulário de bolas de bilhar.

Portanto, preciso remover um dos muitos filtros expostos programaticamente.

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

O campo de filtro é removido com êxito, mas tenho o aviso php:

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

Também tento remover o campo em hook_pre_execute (), mas com o mesmo resultado:

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

Tente também com o método override_option () como aqui - http://groups.drupal.org/node/82219 , mas sem resultado.

Alguma sugestão? Pls help =)


Obrigado a todos pela resposta, mas ainda não tenho resposta. Talvez algo não esteja claro? = (

Oleg Sherbakov
fonte
Você já tentou hook_views_pre_render () ? Você também pode mostrar / ocultar filtros relevantes, dependendo da seleção com o jQuery.
enzipher 27/03
Olá, entendo que sua solução funciona bem, mas não existe o caminho certo . Para que eu possa escondê-lo usando até mesmo condições CSS ... Tentando explicar. Cada tipo de código deve colocar onde deveria estar. Para esse problema, se eu ocultar o filtro exposto antes ou depois da renderização, as exibições ainda o processam. E se eu tentar adicionando string de consulta, smt como ?filter_id=val, vistas retornos de exibição vazio ou erro escolha ilegal ...
Oleg Sherbakov
Você já tentou minha resposta?
Mathankumar
Não preciso alterar o formulário (sei que sua variante funciona), quero modificar o objeto de visualizações para ter um resultado semelhante ao seu, mas antes das compilações do formulário.
Oleg Sherbakov

Respostas:

5

Eu usaria hook_form_alter usando unset no objeto de formulário, como no exemplo para o elemento que você deseja remover.

Scott Thomas
fonte
1

Aqui está o snippet testado que permitirá remover os filtros das exibições expostas do formulário usando alterar o formulário, conforme mencionado por 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]);
  }     
}

Além de remover o campo do formulário, você também precisa remover as informações de um filtro específico, disponíveis em $ form ['# info'], para que também remova o rótulo. Se você remover o elemento do formulário sozinho, o rótulo do filtro será exibido mesmo que o campo tenha sido removido. Portanto, sempre verifique se você está removendo essas informações também.

Modifique isso de acordo com sua necessidade. Se você deseja executar este para uma exibição específica, adicione uma condição para isso também,

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

Aqui $ form_state ['view'] fornecerá o objeto de visualização atual que está sendo processado.

Espero que isto ajude.

Mathankumar
fonte
Essa foi a única solução que ocultou os rótulos e os widgets de campo para mim e funcionou em um filtro exposto em um bloco.
Xenophyle #
1

Siga os passos abaixo

  1. Primeiro, escreva um hook_form_alter em um módulo personalizado
  2. Em seguida, tente o seguinte trecho de código

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

Espero que ajude.

Rons
fonte
1

Você pode remover o filtro exposto usando o arquivo de modelo também.

Use este comando:

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

No arquivo de modelo, encontre este código:

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

E remova-o. Seu filtro exposto será removido da exibição, mas continuará funcionando com você passando argumentos adequados no URL.

subhojit777
fonte
Thx pela resposta, mas eu estou esperando D8 que usa núcleo forma api para a construção de filtros expostos :)
Oleg Sherbakov
0

Corrija-me se estiver errado, porque não tenho certeza de entender completamente o seu problema. Então, você gostaria de ocultar um filtro exposto em uma exibição, dependendo do valor de outro filtro exposto? Nesse caso, você pode tentar o módulo Views Dependent Filters . Eu usei várias vezes e faz o trabalho.

Você pode verificar o nosso Lullabot demônio revisão sobre este módulo.

Se você realmente precisar fazer isso no código, a opção exposta deve funcionar: filter [$ filter_id] -> options ['posed '] = FALSE;

Hervé Donner
fonte
Gostaria de ocultar o filtro exposto se o tipo de conteúdo atual não tiver esse campo (filtrado). Tentando seu snippet, $view->display_handler->handlers['filter'][$filter_field]->options['exposed'] = FALSE;eu tenho um erro fatal - PHP Fatal error: Call to undefined method stdClass::access() in .../view.inc on line 766. Eu acho que seu comportamento correto, porque se o filtro não for exposto, ele também precisará de valor padrão. Alguma ideia?
amigos estão dizendo sobre oleg sherbakov
pastebin.com/f1FKgUde aqui é o meu código, talvez ele vai ser mais claro do que o meu Inglês
Oleg Sherbakov
0

O seguinte foi feito por mim dentro do 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
fonte
0

Método 1

Usando hook_views_query_alter (). Veja o seguinte exemplo:

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

Método 2

Veja o exemplo usando hook_views_pre_execute e a função customizada que tenta encontrar a condição de campo correta e retornar a referência a ela:

/**
 * 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
fonte
0

Estou removendo-o dos arquivos de modelo. Substitua o views-view.tpl.php e remova o seguinte código:

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

Eu acho que a operação estava no caminho certo. Eu tive uma situação semelhante sem filtros expostos, então não pude usar o método hook_form_alter. Aqui está um exemplo de código para qualquer pessoa que se depare com isso:

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

O objeto de exibição não tem uma remove_itemfunção, mas simplesmente declara no código que você pode configurá-lo como nulo para remover um item incluindo filtros: views/includes/view.incon-line 2526.

Aqui está um exemplo completo para qualquer pessoa que segmentar uma exibição e exibição específica:

/**
 * 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
fonte