# How to actually define the action inside a widget

**URL:** https://meta.discourse.org/t/how-to-actually-define-the-action-inside-a-widget/42081
**Category:** Development
**Created:** [April 5, 2016, 5:44pm UTC](https://meta.discourse.org/t/how-to-actually-define-the-action-inside-a-widget/42081 "2016-04-05T17:44:37Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 5, 2016, 5:44pm UTC](https://meta.discourse.org/t/how-to-actually-define-the-action-inside-a-widget/42081/1 "2016-04-05T17:44:38Z")

</div>

Continuing the discussion from [A tour of how the Widget (Virtual DOM) code in Discourse works](https://meta.discourse.org/t/a-tour-of-how-the-widget-virtual-dom-code-in-discourse-works/40347):

In the `topic-map` widget I have the below code adding an action and class name to some text in the `topic-map`:

```
contents.push(h('li.secondary', [
      h('a', { className: 'top-answer-link',
              action: 'scrollTopAnswer'}, 'Jump to Top Answer')
    ]));

```

The class gets added fine and I see now errors. My issue however, is that I do not know where to define the action. Usually, I would define such an action in a component. As this is a widget, where should I place this code:

```
actions: {
    scrollTopAnswer: function() {
      alert('scrollTopAnswer');
      $('html,body').animate({scrollTop: ($('.most_liked_post').offset().top-140)}, 'slow');
    }
  }

```

---

<div class="post-metadata">

### Author: ![joebuhlig](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joebuhlig/32/193054_2.png) [@joebuhlig](https://meta.discourse.org/u/joebuhlig)
#### Post date: [April 5, 2016, 6:46pm UTC](https://meta.discourse.org/t/how-to-actually-define-the-action-inside-a-widget/42081/2 "2016-04-05T18:46:51Z")

</div>

I use a few actions in the voting plugin. You might find a good reference here:

[https://github.com/joebuhlig/discourse-feature-voting/blob/master/assets/javascripts/initializers/feature-voting.js.es6#L7](https://github.com/joebuhlig/discourse-feature-voting/blob/master/assets/javascripts/initializers/feature-voting.js.es6#L7)

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [April 5, 2016, 7:20pm UTC](https://meta.discourse.org/t/how-to-actually-define-the-action-inside-a-widget/42081/3 "2016-04-05T19:20:46Z")

</div>

You can’t just add an action to an `<a>` element like that. You should create a new discourse widget for that:

```javascript
createWidget('jump-answer', {
  tagName: 'a.top-answer-link',
  click() {
    $('html,body').animate({scrollTop: ($('.most_liked_post').offset().top-140)}, 'slow');
  }
});

```

Then your contents would look like this instead:

```javascript
contents.push(h('li.secondary', this.attach('jump-answer')));

```

I should also mention that generally I prefer actions to be handled in controllers, but this is a bit of a weird case since you’re scrolling the page with jQuery. Normally you’d have the `click()` function call `sendWidgetAction` and have a method in the Controller or Route as @joebuhlig suggested.
