# Trigger a jquery function on post load

**URL:** https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003
**Category:** Development
**Created:** [April 10, 2018, 6:23pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003 "2018-04-10T18:23:59Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Olivier\_Lambert](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivier_lambert/32/74807_2.png) [@Olivier\_Lambert](https://meta.discourse.org/u/Olivier_Lambert)
#### Post date: [April 10, 2018, 6:23pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/1 "2018-04-10T18:23:59Z")

</div>

Hi!

If you access [this instance of disocurse](https://forum.latranchee.com/t/comment-accelerer-son-site-web-probleme-de-lenteur-a-regler/210/106), you’ll notive I’ve added levels next to peoples pictures.

 ![image](https://global.discourse-cdn.com/meta/original/3X/b/d/bd11903b7075b7fcd6f0b5df85b410c76f0c7825.png)

Thing is, when we scroll or reload the page, users don’t have their levels displayed.

I would need to run a function on the call back when users posts are displayed.

I’ve looked at the client side api doc:

[https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/plugin-api.js.es6#L11](https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/plugin-api.js.es6#L11)

but I can’t seem to figure it out.

U guys got any clues as to how I could do this?

---

<div class="post-metadata">

### Author: ![Olivier\_Lambert](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivier_lambert/32/74807_2.png) [@Olivier\_Lambert](https://meta.discourse.org/u/Olivier_Lambert)
#### Post date: [April 11, 2018, 2:03pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/2 "2018-04-11T14:03:19Z")

</div>

Update: I’m pretty sure I could use the onAppEvent() function. I just have no idea which events gets triggered when. Is there a way I could “listen” to events and log them in the console to make this easier?

```plaintext
  onAppEvent(name, fn) {
    let appEvents = this.container.lookup('app-events:main');
    appEvents.on(name, fn);
  }

```

---

<div class="post-metadata">

### Author: ![fefrei](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fefrei/32/119538_2.png) [@fefrei](https://meta.discourse.org/u/fefrei)
#### Post date: [April 11, 2018, 3:43pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/3 "2018-04-11T15:43:46Z")

</div>

This should help you:

> [@How do you force a script to refire on every page load in Discourse?](https://meta.discourse.org/t/how-do-you-force-a-script-to-refire-on-every-page-load-in-discourse/74856/5):
>
> I think you can use the PluginAPI onPageChange function to do what you are looking for. See: [Using the JS API](https://meta.discourse.org/t/using-the-pluginapi-in-site-customizations/41281) Here’s an example function: \<script type="text/discourse-plugin" version="0.8"\> api.onPageChange(() =\>{ randBackground(); }); function randBackground() { $('body').css('background-color', '#'+(Math.random()\*0xFFFFFF\<\<0).toString(16)); } \</script\> Update: If you are looking to apply similar changes to post bodies, see [post #26 below](https://meta.discourse.org/t/how-do-you-force-a-script-to-refire-on-every-page-load-in-discourse/74856/26).

---

<div class="post-metadata">

### Author: ![Olivier\_Lambert](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivier_lambert/32/74807_2.png) [@Olivier\_Lambert](https://meta.discourse.org/u/Olivier_Lambert)
#### Post date: [April 11, 2018, 4:17pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/4 "2018-04-11T16:17:53Z")

</div>

The thing is, I can’t use onPageChange because the actual post gets loaded in the DOM AFTER the onPageChange takes places.

I can’t use on AjaxComplete because there are wayyyy too many ajax request being made unrelated to what I’m trying to do.

The closest thing to what I’m trying to do is

````plaintext
 /**
   * Used for decorating the `cooked` content of a post after it is rendered using
   * jQuery.
   *
   * `callback` will be called when it is time to decorate with a jQuery selector.
   *
   * Use `options.onlyStream` if you only want to decorate posts within a topic,
   * and not in other places like the user stream.
   *
   * For example, to add a yellow background to all posts you could do this:
   *
   * ```
   * api.decorateCooked($elem => $elem.css({ backgroundColor: 'yellow' }));
   * ```
   **/
  decorateCooked(callback, opts) {
    opts = opts || {};

    addDecorator(callback);

    if (!opts.onlyStream) {
      decorate(ComposerEditor, 'previewRefreshed', callback);
      decorate(this.container.factoryFor('component:user-stream').class, 'didInsertElement', callback);
    }
  }

````

But I can only affect what’s INSIDE the user’s post. His avatar is off limits.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [April 11, 2018, 4:27pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/5 "2018-04-11T16:27:54Z")

</div>

Did you check this theme code?

[https://github.com/tshenry/discourse-trust-level-avatar-flair/blob/master/common/head\_tag.html](https://github.com/tshenry/discourse-trust-level-avatar-flair/blob/master/common/head_tag.html)

---

<div class="post-metadata">

### Author: ![Olivier\_Lambert](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivier_lambert/32/74807_2.png) [@Olivier\_Lambert](https://meta.discourse.org/u/Olivier_Lambert)
#### Post date: [April 11, 2018, 5:10pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/6 "2018-04-11T17:10:52Z")

</div>

I don’t want to display the user’s trust level, I did a custom leveling system that’s partly based on action made on both wordpress AND discourse.

Here’s the best workaround I’ve found so far:

```plaintext
// I fetch my JS object containing all my members with user levels, calculated server side.
$.get('https://www.latranchee.com/php/users/gamification.php', function( data ) {
    users = JSON.parse(data);
});

// The function that will add users level next to their name
function add_levels(){
    $('.topic-avatar img.avatar:not(.lvl)').each(function(){
        var username = $(this).attr("title");
        if(window.users[username]){
            $(this).after("<span class='user_level_img'>"+window.users[username]+"</span>")
        }
        $(this).addClass("lvl");
    });
}

// A timer that triggers the check Avatar function
window.setInterval(function(){
  checkForAvatar();
}, 1000);

// A function that check if there's an image on the page without it's level being displayed.
function checkForAvatar(){
   if ( $('.topic-avatar img.avatar:not(.lvl)').length ){
       add_levels();
    }
}

```

Far from optimal, but I guess it will have to do.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [April 11, 2018, 5:12pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/7 "2018-04-11T17:12:43Z")

</div>

> [@Olivier\_Lambert](#):
>
> I don’t want to display the user’s trust level, I did a custom leveling system that’s partly based on action made on both wordpress AND discourse.

That was an example of the optimal way to append a DOM element to the user avatar. You can add anything there, just change it from trust level to whatever you want.

---

<div class="post-metadata">

### Author: ![Olivier\_Lambert](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivier_lambert/32/74807_2.png) [@Olivier\_Lambert](https://meta.discourse.org/u/Olivier_Lambert)
#### Post date: [April 11, 2018, 5:14pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/8 "2018-04-11T17:14:05Z")

</div>

Got it! Thanks I’ll fiddle with it!

---

<div class="post-metadata">

### Author: ![Olivier\_Lambert](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivier_lambert/32/74807_2.png) [@Olivier\_Lambert](https://meta.discourse.org/u/Olivier_Lambert)
#### Post date: [April 11, 2018, 5:28pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/9 "2018-04-11T17:28:13Z")

</div>

Hey @Falco, I’ve tried the code and it is indeed much more efficient. However, I need to run a GET request first.

Using your method, the script fire before the users variable get registered in the window variable.

Unless you know of a quick workaround, I guess I’ll just let it be added after page load. The setInterval function is annoying but I guess it’ll have to do.

I still think the onAppEvent() would be best though!

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [April 11, 2018, 5:37pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/10 "2018-04-11T17:37:37Z")

</div>

> [@Olivier\_Lambert](#):
>
> the script fire before the users variable get registered in the window variable.

This line should give you all the info you need about the user.

[https://github.com/tshenry/discourse-trust-level-avatar-flair/blob/master/common/head\_tag.html#L7](https://github.com/tshenry/discourse-trust-level-avatar-flair/blob/master/common/head_tag.html#L7)

> [@Olivier\_Lambert](#):
>
> However, I need to run a GET request first.

Are you running this extra request for every poster in a topic?

If you store this info in a custom\_user\_field, and make put it in the `public_user_custom_fields` site setting they should be available there. (not sure about this, you will need to test. If they aren’t you can add those to the topic/post serializer in a plugin)

---

<div class="post-metadata">

### Author: ![Olivier\_Lambert](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivier_lambert/32/74807_2.png) [@Olivier\_Lambert](https://meta.discourse.org/u/Olivier_Lambert)
#### Post date: [April 11, 2018, 5:44pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/11 "2018-04-11T17:44:22Z")

</div>

> [@Falco](#):
>
> Are you running this extra request for every poster in a topic?

Just once when the app loads. But yeah, custom fields sounds much better.

I guess I’ll need to set this variable server side right? I add it once in the admin pannel, then store the data on user login through php or something?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [April 11, 2018, 5:49pm UTC](https://meta.discourse.org/t/trigger-a-jquery-function-on-post-load/85003/12 "2018-04-11T17:49:10Z")

</div>

> [@Olivier\_Lambert](#):
>
> I add it once in the admin pannel, then store the data on user login through php or something?

You can pass it in the SSO payload, via the API, set it using a plugin, etc.
