Change the state of another widget


(Steven Slade) #1

Continuing the discussion from A tour of how the Widget (Virtual DOM) code in Discourse works:

When creating a widget using Virtual DOM you can create a defaultState method that returns an object that will represent its default state (for example: if a post is collapsed or expanded). You can than implement a click() function to change the state of the widget.

I am wondering if it is possible to change the state of another widget, apart from the one you are clicking. So for example, you would click a button and the state of another widget would become expanded.

#EDIT: What I ended up doing…

I just wanted to update this post and let everyone in on what I ended up doing.

So to break what I wanted to do down into parts it was as following:

  1. Give a plugin’s created post-menu button an action
  2. This action would trigger toggle a created widget to show/hide

First I gave the post and attribute:
api.includePostAttributes('show_more_menu');

Then I gave the action of the created post-menu button to toggle the new attribute:

api.attachWidgetAction('post-menu', 'showMoreMenu', function(attrs) {
  const post = this.findAncestorModel();
  post.toggleProperty('show_more_menu');
});

Finally, in my post decorator ( api.decorateWidget('post:after', dec => { ) I simple added an if statement that would attach the new widget if show_more_menu was true:

const result = [];
if (attrs.show_more_menu) {
  result.push([dec.attach('show-more-menu', attrs)]);
}

The result of all this was that on click of the new post-menu button, it toggled my newly created widget in and out of view :smile: