diff --git a/js/src/admin/components/PermissionDropdown.js b/js/src/admin/components/PermissionDropdown.js index aa635d9250..597e37b156 100644 --- a/js/src/admin/components/PermissionDropdown.js +++ b/js/src/admin/components/PermissionDropdown.js @@ -38,6 +38,7 @@ export default class PermissionDropdown extends Dropdown { attrs.className = 'PermissionDropdown'; attrs.buttonClassName = 'Button Button--text'; + attrs.lazyDraw = true; } view(vnode) { diff --git a/js/src/admin/components/PermissionGrid.js b/js/src/admin/components/PermissionGrid.js index 384b1f594a..a0c10da4b8 100644 --- a/js/src/admin/components/PermissionGrid.js +++ b/js/src/admin/components/PermissionGrid.js @@ -144,6 +144,7 @@ export default class PermissionGrid extends Component { { value: '1', label: app.translator.trans('core.admin.permissions_controls.signup_open_button') }, { value: '0', label: app.translator.trans('core.admin.permissions_controls.signup_closed_button') }, ], + lazyDraw: true, }), }, 90 @@ -191,6 +192,7 @@ export default class PermissionGrid extends Component { { value: '10', label: app.translator.trans('core.admin.permissions_controls.allow_ten_minutes_button') }, { value: 'reply', label: app.translator.trans('core.admin.permissions_controls.allow_until_reply_button') }, ], + lazyDraw: true, }); }, }, diff --git a/js/src/common/components/Dropdown.js b/js/src/common/components/Dropdown.js index 3a38cfcf05..6ed232c94f 100644 --- a/js/src/common/components/Dropdown.js +++ b/js/src/common/components/Dropdown.js @@ -38,11 +38,12 @@ export default class Dropdown extends Component { view(vnode) { const items = vnode.children ? listItems(vnode.children) : []; + const renderItems = this.attrs.lazyDraw ? this.showing : true; return (
{this.getButton(vnode.children)} - {this.getMenu(items)} + {renderItems && this.getMenu(items)}
); } @@ -54,13 +55,25 @@ export default class Dropdown extends Component { // bottom of the viewport. If it does, we will apply class to make it show // above the toggle button instead of below it. this.$().on('shown.bs.dropdown', () => { + const { lazyDraw, onshow } = this.attrs; + this.showing = true; - if (this.attrs.onshow) { - this.attrs.onshow(); + // If using lazy drawing, redraw before calling `onshow` function + // to make sure the menu DOM exists in case the callback tries to use it. + if (lazyDraw) { + m.redraw.sync(); } - m.redraw(); + if (typeof onshow === 'function') { + onshow(); + } + + // If not using lazy drawing, keep previous functionality + // of redrawing after calling onshow() + if (!lazyDraw) { + m.redraw(); + } const $menu = this.$('.Dropdown-menu'); const isRight = $menu.hasClass('Dropdown-menu--right');