Javascript onload not firing

Hey guys,

This may be a bit of a basic question, I am more of a back-end guy. Currently I am trying to connect some java-script code to a front end element. The issue is that my window.onload (and document.onload, I tried them both) never fires. my javascript is in the plugin init folder ( [plugin]/assets/javascripts/initializers/[plugin].js.es6 )

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

    //my initialization function
    function initializeMeritmoot(api) {
      console.log("inside initializeMeritmoot")

      //function on key up
      function repInputKeyUp() {
        inputBox = document.getElementById("rep-input")
        console.log("in 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("Past Function Def");
      
      //window load (doesnt happen)
      window.onload = () => {
        console.log("PageLoaded") <-----------------------------------this never prints
        document.getElementById('rep-input').onkeyup = repInputKeyUp;
      };
      console.log('leaving initializeMeritmoot');
    }
    console.log("MeritMoot Javascript In Default")
    withPluginApi("0.8.37", api => initializeMeritmoot(api));
  }
};

Any thoughts on why this may be? Is this javascript setup correctly in relation to discourse? Or is this more of a general javascript thing?

Edit: trying addEventListener…

Edit: substituting onload for:

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

did not work either

You are working with EmberJS here, not vanilla JavaScript. It will not behave the same.

Best to follow EmberJS best practice.

I would consider piggybacking your logic onto an existing component or adding one to a plugin outlet and using the didInsertElement hook.

Read the EmberJS Guides

3 Likes

Thanks! I saw ember was a big part of discourse, but didn’t realize it overrode vanilla. Ill take a time and learn it.

edit: I am using the plugin element discovery-list-container-top and connecting to a ruby backend plugin archetecture

edit: Whats the relation between ember-rails and discourse? Ember by itself seems to be a full stack enviroment. Looking at https://github.com/emberjs/ember-rails

ember-rails is a Ruby gem that is actually used in Discourse.

Discourse staffers are far better to comment, but broadly, EmberJS deals with the front-end, and Ruby-on-Rails, the back end. Of course, Discourse has elements of a bespoke architecture and the exact configuration is, like any big application, at least somewhat unique.

A nice description of the way things work is here Creating Routes in Discourse and Showing Data

The API docs are here https://docs.discourse.org

2 Likes

Learned a lot of emberjs over the last bit - but it looks like on the wrong version. As far as I can tell Emberjs 1.9 is used by discourse (by looking at the ember-rails docs and source code syntax). Current version of Emberjs is 3.17 So the guide that should be followed is this one. The syntax is quite diffrent, but I got the basics down. I will post the above code converted to emberjs when finished

2 Likes

Running a dev instance in a browser reveals this in the javascript console:

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

But you are right, some of the Discourse conventions don’t reflect the very latest syntax on the guides :slight_smile:

2 Likes

Thanks for the help Robert, I was kind of out of my depth on this for a bit! Anyway, here is what I got in the end as promised. I ended up using the onload function, which triggers after the DOM is loaded. I tried to use jquery for a bit until I heard that emberjs was depreciating it.

import { ajax } from 'discourse/lib/ajax';
//could update the highlight to hit on the split(" ") aswell. If, you know, i feel like it.

export default Ember.Component.extend({
  runOnceRan: false,
  myAws: "",
  subbedReps: [],
  //update the suggested options to follow for representatives in the input box
  updatePossibles: function (substr) {
    var compContext = this; //component context
    if (substr == "") {
      return;
    }
    //get suggestions
    substr = encodeURIComponent(substr);
    ajax(`meritmoot/reps/search/${substr}.json`, { type: "GET" }).then( result => {
      result = result.api;
      let pv = []; //possible values
      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;
      //update Awesomplete internal logic
      compContext.myAws.evaluate();
      //show Awesomplete suggestions
      compContext.myAws.open();
    });
  },
  runOnce: function () {
    //let us know it ran...
    console.log("in runOnce")
    const substrInput = document.getElementById("rep-input");
    const compContext = this;
    
    //create custom Awesomplete (options list) for substrInput (rep-input).
    this.myAws = new Awesomplete(substrInput);
    console.log(substrInput)

    //all list items should be shown, as they are selected with predjudice on substr value change
    this.myAws.filter = function (text, input) {
      return true
    }

    //show whenever, turn autocomplete on.
    this.myAws.minChars = 0;
    this.myAws.autocomplete = "on";

    //on selection of option, handle it.
    document.addEventListener('awesomplete-selectcomplete', function(e) {
        if(e.srcElement == substrInput) {
          let id = e.text.value;
          substrInput.value = "";
          
          //send selection backend
          let uriid = encodeURIComponent(id)
          ajax(`meritmoot/reps/${uriid}`, {type: "PUT" }).then( result => {
            console.log("put passed back:");
            console.log(result);
          });

          //update selection frontend
          let l = compContext.get("subbedReps");
          l.pushObject(id) //pushObject is needed instead of push (https://github.com/emberjs/ember.js/issues/10405)
          compContext.set("subbedReps", l);

          //1. DONE create a table that matches user id to subscribed reps.
          //2. DONE create a way to add subscribed reps to that table. in progress (need GET PUT DELETE)
          //3. view reps next to substrInput
          //3. create a way to view votes next to topics.
          //4. after all that, refresh that mechanism of viewing votes here.
        }
      }, false);
    
    //get users saved representatives, show them.
    ajax(`meritmoot/reps`, {type: "GET"}).then( result => {
      console.log("get passed back:");
      console.log(result);
      compContext.set("subbedReps", result.mmfollows);
      console.log("subbedReps")
      console.log(compContext.get("subbedReps"));
    });

    //on input, update 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);
    }
  }
});

2 Likes