Javascript onload ne se déclenche pas

Salut les gars,

C’est peut-être une question un peu basique, je suis plutôt orienté back-end. Actuellement, j’essaie de connecter du code JavaScript à un élément du front-end. Le problème est que mon window.onload (et document.onload, j’ai essayé les deux) ne se déclenche jamais. Mon JavaScript se trouve dans le dossier d’initialisation du plugin ([plugin]/assets/javascripts/initializers/[plugin].js.es6).

export default {
  name: "meritmoot",
  initialize() {

    //ma fonction d'initialisation
    function initializeMeritmoot(api) {
      console.log("dans initializeMeritmoot")

      //fonction sur la montée de touche
      function repInputKeyUp() {
        inputBox = document.getElementById("rep-input")
        console.log("dans rep input key up")
        ajax("/reps/search/" + inputBox.value +".json", {type: 'GET'}).then((result) => {
          console.log(result)
          result = JSON.parse(result)
          repList = document.getElementById("rep-list")
          repList.innerHTML = ""
          result.forEach(op => {
            var x = document.createElement("INPUT");
            x.setAttribute("info-tag-id", op.id)
            x.setAttribute("value", op.mm_reference_str)
            repList.appendChild(x)
          });
          console.log(repList)
        });
      };
      console.log("Après la définition de la fonction");
      
      //chargement de la fenêtre (ne se produit pas)
      window.onload = () => {
        console.log("PageLoaded") <-----------------------------------cela ne s'affiche jamais
        document.getElementById('rep-input').onkeyup = repInputKeyUp;
      };
      console.log('sortie de initializeMeritmoot');
    }
    console.log("JavaScript MeritMoot dans Default")
    withPluginApi("0.8.37", api => initializeMeritmoot(api));
  }
};

Avez-vous des idées sur la raison possible ? Ce JavaScript est-il correctement configuré par rapport à Discourse ? Ou est-ce plutôt un problème général de JavaScript ?

Édition : tentative d’ajouter addEventListener…

Édition : remplacement de onload par :

  window.addEventListener('onload', function() {
    console.log("PageLoaded")
    document.getElementById('rep-input').onkeyup = repInputKeyUp;
  }, false);

n’a pas fonctionné non plus

Vous travaillez avec EmberJS ici, pas avec du JavaScript vanilla. Cela ne se comportera pas de la même manière.

Il est préférable de suivre les meilleures pratiques d’EmberJS.

Je vous conseillerais de greffer votre logique sur un composant existant ou d’en ajouter un à un point d’extension (plugin outlet) et d’utiliser le hook didInsertElement.

Consultez les Guides EmberJS.

Merci ! J’ai vu qu’Ember était une partie importante de Discourse, mais je ne réalisais pas qu’il remplacait la version de base. Je prendrai le temps de l’apprendre.

edit : J’utilise l’élément de plugin discovery-list-container-top et je me connecte à une architecture de plugin backend en Ruby.

edit : Quelle est la relation entre ember-rails et Discourse ? Ember en lui-même semble être un environnement full-stack. En regardant GitHub - emberjs/ember-rails: Ember for Rails 3.1+ · GitHub

ember-rails est un gem Ruby qui est effectivement utilisé dans Discourse.

Les membres de l’équipe de Discourse sont mieux placés pour commenter, mais de manière générale, EmberJS gère le front-end et Ruby on Rails le back-end. Bien sûr, Discourse comporte des éléments d’une architecture sur mesure et la configuration exacte est, comme pour toute grande application, au moins en partie unique.

Une belle description du fonctionnement des choses se trouve ici : Creating Routes in Discourse and Showing Data

La documentation de l’API est disponible ici : https://docs.discourse.org

J’ai beaucoup appris sur Ember.js récemment, mais il semble que ce soit sur la mauvaise version. D’après ce que j’ai pu constater, Discourse utilise Ember.js 1.9 (en consultant la documentation d’ember-rails et la syntaxe du code source). La version actuelle d’Ember.js est la 3.17. Le guide à suivre est donc celui-ci. La syntaxe est assez différente, mais j’ai compris les bases. Je publierai le code ci-dessus converti en Ember.js une fois terminé.

L’exécution d’une instance de développement dans un navigateur affiche ceci dans la console JavaScript :

DEBUG: -------------------------------
DEBUG: Ember  : 3.12.2 
DEBUG: jQuery : 3.4.1 
DEBUG: ------------------------------- 

Mais vous avez raison, certaines conventions de Discourse ne reflètent pas la toute dernière syntaxe des guides :slight_smile:

Merci pour ton aide, Robert. J’étais un peu dépassé par les événements pendant un moment ! Quoi qu’il en soit, voici ce que j’ai obtenu à la fin, comme promis. J’ai fini par utiliser la fonction onload, qui se déclenche après le chargement du DOM. J’ai essayé d’utiliser jQuery pendant un moment, jusqu’à ce que j’apprenne qu’Ember.js le dépréciait.

import { ajax } from 'discourse/lib/ajax';
// On pourrait aussi mettre à jour le highlight pour qu'il réagisse sur le split(" "). Si, tu vois, j'en ai envie.

export default Ember.Component.extend({
  runOnceRan: false,
  myAws: "",
  subbedReps: [],
  // Mettre à jour les options suggérées à suivre pour les représentants dans la boîte de saisie
  updatePossibles: function (substr) {
    var compContext = this; // contexte du composant
    if (substr == "") {
      return;
    }
    // Récupérer les suggestions
    substr = encodeURIComponent(substr);
    ajax(`meritmoot/reps/search/${substr}.json`, { type: "GET" }).then( result => {
      result = result.api;
      let pv = []; // valeurs possibles
      for(let i = 0; i < result.length; i++) {
        let newItem = {
          label: result[i].mm_reference_str,
          value: result[i].id,
          id: result[i].id,
        }
        pv.push(newItem);
      }
      console.log(pv)
      compContext.myAws.list = pv;
      // Mettre à jour la logique interne d'Awesomplete
      compContext.myAws.evaluate();
      // Afficher les suggestions d'Awesomplete
      compContext.myAws.open();
    });
  },
  runOnce: function () {
    // Nous informer que cela a été exécuté...
    console.log("dans runOnce")
    const substrInput = document.getElementById("rep-input");
    const compContext = this;
    
    // Créer un Awesomplete personnalisé (liste d'options) pour substrInput (rep-input).
    this.myAws = new Awesomplete(substrInput);
    console.log(substrInput)

    // Tous les éléments de la liste doivent être affichés, car ils sont sélectionnés avec préjugé sur le changement de valeur de substr
    this.myAws.filter = function (text, input) {
      return true
    }

    // Afficher à tout moment, activer la saisie automatique.
    this.myAws.minChars = 0;
    this.myAws.autocomplete = "on";

    // Lors de la sélection d'une option, la traiter.
    document.addEventListener('awesomplete-selectcomplete', function(e) {
        if(e.srcElement == substrInput) {
          let id = e.text.value;
          substrInput.value = "";
          
          // Envoyer la sélection au backend
          let uriid = encodeURIComponent(id)
          ajax(`meritmoot/reps/${uriid}`, {type: "PUT" }).then( result => {
            console.log("PUT renvoyé :");
            console.log(result);
          });

          // Mettre à jour la sélection côté frontend
          let l = compContext.get("subbedReps");
          l.pushObject(id) // pushObject est nécessaire au lieu de push (https://github.com/emberjs/ember.js/issues/10405)
          compContext.set("subbedReps", l);

          // 1. FAIT : Créer une table qui associe l'ID utilisateur aux représentants abonnés.
          // 2. FAIT : Créer un moyen d'ajouter des représentants abonnés à cette table. En cours (besoin de GET, PUT, DELETE)
          // 3. Afficher les représentants à côté de substrInput
          // 3. Créer un moyen d'afficher les votes à côté des sujets.
          // 4. Après tout cela, rafraîchir ce mécanisme d'affichage des votes ici.
        }
      }, false);
    
    // Récupérer les représentants sauvegardés par l'utilisateur et les afficher.
    ajax(`meritmoot/reps`, {type: "GET"}).then( result => {
      console.log("GET renvoyé :");
      console.log(result);
      compContext.set("subbedReps", result.mmfollows);
      console.log("subbedReps")
      console.log(compContext.get("subbedReps"));
    });

    // À chaque saisie, mettre à jour les suggestions
    document.addEventListener('input', function(e) {
        if(e.explicitOriginalTarget == substrInput) {
          compContext.updatePossibles(substrInput.value);
        }
      }, false)
    console.log(this.myAws);
  },
  didRender() {
    this._super(...arguments);
    if( ! this.runOnceRan ) {
      this.runOnce();
      this.set("runOnceRan", true);
    }
  }
});