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