Vues 3 supprimer le filtre exposé par programme

9

J'ai plusieurs types de nœuds, chacun référencé dans un vocabulaire de termes de taxonomie différent. Pour la catégorie montrant j'utilise le module taxonomy_display.

Par exemple, nous avons deux catégories: les queues de billard et les boules de billard.

Cues a des prix de, des prix et des filtres de type bois. Mais les boules n'ont pas de filtre à bois.

Je dois donc supprimer le filtre de type de bois si taxonomy_term tid fait référence au vocabulaire des boules de billard.

Par conséquent, je dois supprimer l'un des nombreux filtres exposés par programme.

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

Le champ de filtre se retire avec succès, mais j'ai un avis php:

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

J'essaie également de supprimer le champ dans hook_pre_execute (), mais avec le même résultat:

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

Essayez également avec la méthode override_option () comme ici - http://groups.drupal.org/node/82219 , mais aucun résultat du tout.

Aucune suggestion? Aide Pls =)


Merci à tous pour la réponse mais je n'ai toujours pas de réponse. Peut-être que quelque chose n'est pas clair? = (

Oleg Sherbakov
la source
Avez-vous essayé hook_views_pre_render () ? Vous pouvez également afficher / masquer les filtres pertinents en fonction de la sélection avec jQuery.
enzipher
Salut, je comprends que votre solution fonctionne bien, mais il n'y a pas de bonne façon . Je peux donc le cacher en utilisant même des conditions CSS ... Essayer d'expliquer. Chaque type de code doit être placé là où il devrait être. Pour ce problème, si je masque le filtre exposé avant ou après le rendu, les vues le traitent toujours. Et si j'essaie d'ajouter une chaîne de requête, smt like ?filter_id=val, vues renvoie un affichage vide ou une erreur de choix illégal ...
Oleg Sherbakov
Avez-vous essayé ma réponse?
Mathankumar
Je n'ai pas besoin de modifier la forme (je sais que votre variante fonctionne), je veux modifier l'objet de vues pour qu'il ressemble au vôtre, mais plus tôt que les versions de formulaire.
Oleg Sherbakov

Réponses:

5

J'utiliserais hook_form_alter en utilisant unset sur l'objet formulaire comme vous l'êtes dans votre exemple pour l'élément que vous souhaitez supprimer.

Scott Thomas
la source
1

Voici l'extrait testé qui vous permettra de supprimer les filtres des vues exposées du formulaire à l'aide de la modification de formulaire mentionnée par 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]);
  }     
}

En plus de supprimer le champ du formulaire, vous devez également supprimer les informations pour un filtre particulier qui est disponible dans $ form ['# info'], afin qu'il supprime également l'étiquette. Si vous supprimez l'élément de formulaire seul, le libellé du filtre s'affichera même si le champ est supprimé. Veillez donc toujours à supprimer également ces informations.

Modifiez cela selon vos besoins. Si vous souhaitez effectuer celui-ci pour une vue particulière, ajoutez une condition pour cela aussi,

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

Ici $ form_state ['view'] vous donnera l'objet de vue actuel qui est en cours de traitement.

J'espère que cela t'aides.

Mathankumar
la source
C'était la seule solution qui masquait les étiquettes ainsi que les widgets de champ pour moi, et cela fonctionnait sous forme de filtre exposé dans un bloc.
xénophyle
1

Suivez les étapes ci-dessous

  1. Écrivez d'abord un hook_form_alter dans un module personnalisé
  2. Ensuite, essayez le morceau de code suivant

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

J'espère que cela pourra aider.

Rons
la source
1

Vous pouvez également supprimer le filtre exposé à l'aide du fichier modèle.

Utilisez cette commande:

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

Dans le fichier modèle, trouvez ce code:

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

Et retirez-le. Votre filtre exposé sera supprimé de l'affichage, mais continuera de fonctionner si vous passez les arguments appropriés dans l'URL.

subhojit777
la source
Merci pour la réponse, mais j'attends D8 qui utilise l'API de base pour créer des filtres exposés :)
Oleg Sherbakov
0

Corrigez-moi si je me trompe car je ne suis pas sûr de bien comprendre votre problème. Vous souhaitez donc masquer un filtre exposé dans une vue en fonction de la valeur d'un autre filtre exposé? Si c'est le cas, vous pouvez essayer le module Filtres dépendants des vues . Je l'ai utilisé plusieurs fois et ça fait l'affaire.

Vous pouvez consulter notre fiend Lullabot examen sur ce module.

Si vous avez vraiment besoin de le faire dans le code, l'option exposée devrait fonctionner: filter [$ filter_id] -> options ['expose'] = FALSE;

Hervé Donner
la source
Je voudrais masquer le filtre exposé si le type de contenu actuel n'a pas ce champ (filtré). En essayant votre extrait, $view->display_handler->handlers['filter'][$filter_field]->options['exposed'] = FALSE;j'ai une erreur fatale - PHP Fatal error: Call to undefined method stdClass::access() in .../view.inc on line 766. Je pense que son comportement correct parce que si le filtre n'est pas exposé, il a également besoin d'une valeur par défaut. Des idées?
Oleg Sherbakov
pastebin.com/f1FKgUde voici mon code, peut-être qu'il sera plus clair que mon anglais
Oleg Sherbakov
0

Ce qui suit l'a fait pour moi dans 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
la source
0

Méthode 1

En utilisant hook_views_query_alter (). Voir l'exemple suivant:

<?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éthode 2

Voir l'exemple en utilisant hook_views_pre_execute et une fonction personnalisée qui essaie de trouver la bonne condition de champ et de lui renvoyer la référence:

/**
 * 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
la source
0

Je le supprime des fichiers de modèle. Substituez le views-view.tpl.php et supprimez-en le code suivant:

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

Je pense que l'op était sur la bonne voie. J'ai eu une situation similaire sans filtres exposés, donc je ne pouvais pas utiliser la méthode hook_form_alter. Voici un exemple de code pour toute autre personne rencontrant ceci:

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

L'objet de vue n'a pas de remove_itemfonction mais indique simplement dans le code que vous pouvez le définir sur null afin de supprimer un élément incluant les filtres: views/includes/view.incen ligne 2526.

Voici un exemple complet pour quiconque cible une vue et un affichage spécifiques:

/**
 * 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;
    }
  }
}
Développeur Web JNP
la source