Comment obtenir l'ID de nœud dans jQuery / JavaScript

8

Existe-t-il une manière définitive et universelle de procéder? Par exemple, en utilisant une variable d'environnement fournie avec Drupal.behaviours?

J'ai fait quelques recherches et il ne semble pas y avoir de réponse commune.

therobyouknow
la source
Non, il n'y a pas de variable d'environnement comme ça ... que voulez-vous dire exactement par «obtenir l'identifiant du nœud drupal»? Que classez-vous comme «l'ID de nœud drupal» dans ce contexte? L'ID d'un nœud dont vous êtes sur la page complète?
Clive
oui, l'ID d'un nœud dont je suis sur la page complète, par exemple comme dans mysite.com/node/6 je voudrais que le jquery que j'exécute à partir de cette page puisse obtenir l'ID du nœud et le mettre dans une variable, dans l'exemple, cela aurait la valeur 6.
therobyouknow
Si vous voulez une méthode robuste, vous devrez passer l'ID de nœud côté serveur manuellement en utilisant drupal_add_js(); le nid n'est jamais utilisé côté client par cœur, il n'est donc pas nécessaire de l'ajouter en tant que paramètre en général
Clive

Réponses:

13

Comme mentionné ci-dessus, le noyau Drupal n'a aucune utilité pour l'ID de nœud côté client, il ne le transmet donc pas. si vous voulez y accéder, vous devrez l'ajouter manuellement:

function MYMODULE_node_view($node, $view_mode, $langcode) {
  if ($view_mode == 'full') {
    $setting = array('MYMODULE' => array('currentNid' => $node->nid));
    $node->content['#attached']['js'][] = array(
      'data' => $setting,
      'type' => 'setting',
    );
  }
} 

Ensuite, côté client, vous y aurez accès via Drupal.settings:

var currentNid = Drupal.settings.MYMODULE.currentNid;
Clive
la source
Merci @Clive - très content de cette solution! Je vais l'essayer. Cela m'aidera à tenter de résoudre le problème du module pop_links : Version 7 Not Recording Links . Je vous créditerai de l'aide, n'hésitez pas à y participer également. Jusqu'à présent, mes conclusions avec ce module sont que le javascript qu'ils fournissent ne "tire" pas et un collègue a fourni un correctif provisoire basé sur un classattribut du thème de bootstrap. En fin de compte, nous visons une solution indépendante du thème.
therobyouknow
Puis-je mentionner une correction de travail à votre code: il faut lire: $setting = array('MYMODULE' => array('currentNid' => $node->nid));le =est étranger. Cela a fait le travail - a collé votre code sur cette fonction qui existait déjà pop_linkset a ajouté votre javascript dans pop_links.js.
therobyouknow
Oups, faute de frappe - désolé :)
Clive
1
+1 en passant pour votre réponse. Cela fonctionne et m'a permis de fournir un correctif provisoire pour le problème pop_links ici: drupal.org/node/1269290#comment-7625019
therobyouknow
1
PS vous a crédité de la solution.
therobyouknow
5

Comme mentionné par MPD dans sa réponse, travailler avec les classes css par défaut générées par Drupal pour l'élément est une solution simple qui fonctionne sans code PHP personnalisé.

Voici notre implémentation:

(function($) {

  /**
   * Find Drupal Node ID based on <body> element classes.
   *
   * @return Node ID or false
   **/
  function getCurrentNodeId() {
    var $body = $('body.page-node');
    if ( ! $body.length )
      return false;
    var bodyClasses = $body.attr('class').split(/\s+/);
    for ( i in bodyClasses ) {
      var c = bodyClasses[i];
      if ( c.length > 10 && c.substring(0, 10) === "page-node-" )
        return parseInt(c.substring(10), 10);
    }
    return false;
  }


  /**
   * Example usage...
   *
   **/
  Drupal.behaviors.yourModuleNameHere = {
    var nodeId = getCurrentNodeId();
    if ( nodeId ) {
      // Node ID found.
      // ...do something with it.
    } else {
      // Node ID not found. Guess we are not on a node page
      // ...handle this case with care too. 
    }
  }

}(jQuery);
gue
la source
cela fonctionne également sur Drupal 8 si vous changez une ligne en var $body = $('body.path-node');(testé avec zurb_foundation pour 8.x-6.x)
HongPong
3

La valeur par défaut template_preprocess_html()contient ce morceau de code dans

if ($suggestions = theme_get_suggestions(arg(), 'page', '-')) {
  foreach ($suggestions as $suggestion) {
    if ($suggestion != 'page-front') {
      // Add current suggestion to page classes to make it possible to theme
      // the page depending on the current page type (e.g. node, admin, user,
      // etc.) as well as more specific data like node-12 or node-edit.
      $variables['classes_array'][] = drupal_html_class($suggestion);
    }
  }
}

Cela collera les classes à la <body>ligne d'élément page-node-123. Si vous ne souhaitez pas utiliser votre propre code dans un module personnalisé, vous pouvez obtenir les classes via jQuery , trouver celle qui correspond page-node-, puis analyser le nid.

mpdonadio
la source
+1 Merci pour votre contribution @MPD à savoir. Dans mon cas, l'ajout de trucs à un module me convient car je corrige un bug dans le module pop_links - voir mon commentaire ci-dessous la réponse de Clive. Votre réponse sera sans aucun doute utile dans d'autres scénarios.
therobyouknow
1

Ce qui a fonctionné pour moi, c'est d'ajouter la ligne suivante à mon page.tpl.phpmodèle. Cela ajoute l'ID de nœud window.Drupal.settings.nidauquel vous pouvez utiliser à volonté en JavaScript.

drupal_add_js(array('nid' => $node->nid), 'setting');

Comme suggéré dans les commentaires, voici le code pour ajouter l'ID de nœud à partir de template.php:

function MYTHEME_preprocess_page(&$variables, $hook) {

  if ($node = menu_get_object()) {

    drupal_add_js(array('nid' => $node->nid),'setting'); 
  } 
}
Daniel Lefebvre
la source
Il vaut peut-être mieux ajouter cette ligne à la template_preprocess_pageplace (si vous en avez besoin au niveau de la page). Pour ne pas mélanger les choses et garder les modèles aussi propres et lisibles que possible. Les modèles doivent être utilisés pour le balisage.
leymannx
Je l'ai également fait sur d'autres versions. L'ajouter à page.tpl.php est un "hack" assez facile pour les gens qui sont intimidés par le thème. Bonne suggestion, merci :)
Daniel Lefebvre
Est-ce là une faute de frappe settingset setting?
leymannx
ce n'est pas ... ça m'a jeté plusieurs fois ... mais "setting" va dans drupal_add_js et ça crée window.Drupal.settings.wever
Daniel Lefebvre