Las vistas 3 eliminan el filtro expuesto mediante programación

9

Tengo varios tipos de nodos, cada uno de ellos referenciado a vocabulario de términos de taxonomía diferente. Para la categoría que muestra, uso el módulo taxonomy_display.

Por ejemplo, tenemos dos categorías: tacos y bolas de billar.

Cues tiene precio desde, precio hasta y filtros de tipo madera. Pero las bolas no tienen filtro de madera.

Por lo tanto, necesito eliminar el filtro de tipo de madera si taxonomy_term tid hace referencia al vocabulario de bolas de billar.

Por lo tanto, necesito eliminar uno de los muchos filtros expuestos mediante programación.

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

El campo de filtro se elimina con éxito, pero recibí un aviso de php:

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

También trato de eliminar el campo en hook_pre_execute (), pero con el mismo resultado:

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

Pruebe también con el método override_option () como aquí: http://groups.drupal.org/node/82219 , pero no hay ningún resultado.

¿Alguna sugerencia? Por favor ayuda =)


Gracias a todos por la respuesta, pero todavía no tengo respuesta. Tal vez algo no está claro? = (

Oleg Sherbakov
fuente
¿Has probado hook_views_pre_render () ? También puede mostrar / ocultar filtros relevantes según la selección con jQuery.
enzipher
Hola, entiendo que su solución funciona bien, pero no hay una manera correcta . Entonces puedo ocultarlo usando incluso condiciones CSS ... Intentando explicarlo. Cada tipo de código debe ubicarse donde debería estar. Para este problema, si oculto el filtro expuesto antes o después del renderizado, las vistas aún lo procesan. Y si intento agregar una cadena de consulta, como smt ?filter_id=val, las vistas devuelven una pantalla vacía o un error de elección ilegal ...
Oleg Sherbakov
¿Has probado mi respuesta?
Mathankumar
No necesito alterar el formulario (sé que su variante funciona), quiero modificar el objeto de vistas para que tenga un resultado similar al suyo, pero antes que las compilaciones de formularios.
Oleg Sherbakov

Respuestas:

5

Me gustaría utilizar hook_form_alter utilizando no definido en el objeto de formulario que se encuentra en su ejemplo para el elemento que desea eliminar.

Scott Thomas
fuente
1

Aquí está el fragmento probado que le permitirá eliminar los filtros de las vistas expuestas usando el formulario alter como lo menciona 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]);
  }     
}

Además de eliminar el campo del formulario, también debe eliminar la información de un filtro particular que está disponible en $ form ['# info'], para que también elimine la etiqueta. Si elimina solo el elemento de formulario, la etiqueta del filtro se mostrará a pesar de que se elimine el campo, así que asegúrese siempre de eliminar también esta información.

Modifique esto de acuerdo a su necesidad. Si desea realizar este para una vista particular, agregue una condición para eso también,

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

Aquí $ form_state ['view'] le dará el objeto de vista actual que se está procesando.

Espero que esto ayude.

Mathankumar
fuente
Esta fue la única solución que ocultó las etiquetas y los widgets de campo para mí, y funcionó en forma de filtro expuesto en un bloque.
xenophyle
1

Sigue los pasos a continuación

  1. Primero escriba un hook_form_alter en un módulo personalizado
  2. A continuación, intente con el siguiente código

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

Espero que ayude.

Rons
fuente
1

Puede eliminar el filtro expuesto utilizando el archivo de plantilla también.

Usa 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

En el archivo de plantilla encuentre este código:

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

Y quítalo. Su filtro expuesto se eliminará de la pantalla, pero seguirá funcionando si pasa los argumentos adecuados en la URL.

subhojit777
fuente
Gracias por la respuesta, pero estoy esperando D8 que usa la API de forma central para construir filtros expuestos :)
Oleg Sherbakov
0

Corrígeme si me equivoco porque no estoy seguro de entender completamente tu problema. ¿Entonces le gustaría ocultar un filtro expuesto en una vista dependiendo del valor de otro filtro expuesto? Si es así, puede probar el módulo de Filtros dependientes de vistas . Lo usé varias veces y hace el trabajo.

Puede consultar la reseña de nuestro amigo Lullabot sobre este módulo.

Si realmente necesita hacerlo en código, la opción expuesta debería funcionar: filtro [$ filter_id] -> opciones ['expuesta'] = FALSO;

Hervé Donner
fuente
Me gustaría ocultar el filtro expuesto si el tipo de contenido actual no tiene este campo (filtrado). Al probar su fragmento, $view->display_handler->handlers['filter'][$filter_field]->options['exposed'] = FALSE;tengo un error fatal PHP Fatal error: Call to undefined method stdClass::access() in .../view.inc on line 766. Creo que es el comportamiento correcto porque si el filtro no está expuesto, también requiere un valor predeterminado. ¿Algunas ideas?
Oleg Sherbakov
pastebin.com/f1FKgUde aquí está mi código, tal vez sea más claro que mi inglés
Oleg Sherbakov
0

Lo siguiente lo hizo por mí dentro de 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
fuente
0

Método 1

Mediante el uso de hook_views_query_alter (). Vea el siguiente ejemplo:

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

Vea el ejemplo utilizando hook_views_pre_execute y una función personalizada que intenta encontrar la condición de campo correcta y devolverle la referencia:

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

Lo estoy eliminando de los archivos de plantilla. Anule el archivo views-view.tpl.php y elimine el siguiente código:

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

Creo que la operación estaba en el camino correcto. Tuve una situación similar sin filtros expuestos, por lo que no pude usar el método hook_form_alter. Aquí hay un código de ejemplo para cualquier persona que se encuentre con esto:

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

El objeto de vista no tiene una remove_itemfunción, sino que simplemente establece en el código que puede establecerlo como nulo para eliminar un elemento que incluye filtros: views/includes/view.incen línea 2526.

Aquí hay un ejemplo completo para cualquier persona que se dirija a una vista y pantalla específicas:

/**
 * 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;
    }
  }
}
Desarrollador web JNP
fuente