Skip to content
VoteFirst Docs
Dashboard

Embed

Widgets

Nine things you can put in a page, each one call. Every example below assumes VoteFirst.init has already run, as it does at the end of the quickstart.

Widgets that render into your page take a target first, either a CSS selector or the element itself, and an options object second. The two popups take options only, because they have nothing to render into until they open. Every call returns a handle you can listen on and destroy.

Roadmap board

Your columns and your cards, with a vote control on the cards in the columns that accept votes. Where a column takes no votes the card shows its count as text instead. A column longer than one page carries a Show more of its own, which asks the server with your filters still applied. This is the one most pages start with.

<div id="roadmap"></div>

<script>
  VoteFirst.roadmap('#roadmap');
</script>

A custom board

The same rendering, for one of your named boards rather than the roadmap. The board slug is the one in its address in the dashboard.

VoteFirst.board('#ideas', { board: 'ideas' });

Most Wanted list

What people are asking for, ranked, with a bar for the share of your voters behind each one. A project with no voters yet shows the vote count instead, because a share of nobody is a made up number. Good on a marketing page, where a board would be too much.

VoteFirst.topFeatures('#most-wanted', { limit: 5 });

Flat feature list

One list, no columns, with a button to load more. For a page that wants the content of a board without its shape.

VoteFirst.features('#ideas', { sort: 'trending', limit: 10 });

Changelog

Your published releases and the features in each one, newest first.

VoteFirst.changelog('#changelog');

Vote button

One feature's vote control on its own, to sit next to that feature wherever it already appears in your product. Without a feature id, or with feature: 'first', it draws whichever feature has the most votes at the moment the page loads.

VoteFirst.voteButton('#vote', { feature: 1234 });

Feature badge

One feature on a single line: its vote control and its name. The same idea as the vote button, with the heading attached.

VoteFirst.badge('#badge', { feature: 1234 });

Suggestion popup

The add a feature form, opened from any element on your page. Nothing renders until somebody presses the trigger.

<button id="suggest-btn">Suggest a feature</button>

<script>
  VoteFirst.suggest({ trigger: '#suggest-btn' });
</script>

Problem report popup

The same form for problems rather than ideas. It also sends the address of the page it was opened from and the visitor's browser, which is most of what you would otherwise have to ask for.

VoteFirst.report({ trigger: '#report-btn' });

Pass context: false to leave the page address and the browser out of it.

What a card opens

On the widgets that draw cards, which are the roadmap, a custom board and the flat feature list, clicking one opens that request in place of the list, in the same element and with a Back control above it. Nothing is laid over your page and nothing about its scroll position changes, so a board in a narrow panel stays in its panel.

The request shows what was asked, the owner's answer or the reason it was declined, its tags, its counts, its progress, and the comment thread underneath. A visitor can sort the thread, like a comment, reply to one, and delete their own. Voting works there exactly as it does on the card.

A board whose cards do not open
VoteFirst.roadmap('#roadmap', { detail: false });

Handles

Every call returns a handle. Keep it if the widget has to change or go away later, which it does in a single page application where the element it drew into is about to be removed.

const board = VoteFirst.roadmap('#roadmap');

board.on('vote', function (event) { /* ... */ });
board.refresh();
board.destroy();
MemberWhat it is
elementThe element the widget drew into, which is the one carrying the vf- classes your CSS writes rules against. On a popup it is null until the popup opens.
optionsThe options this widget was created with. Changing a value here and calling refresh() is how a widget changes what it draws without being rebuilt.
on(name, fn), off(name, fn)This widget's events. off with no function drops every listener for that name.
refresh()Loads and draws again. Returns a promise.
destroy()Takes the widget out of the page and stops it being refreshed when a visitor signs in or out. On a popup it also unbinds the trigger, so calling suggest() again after a route change does not leave two dialogs on one button.
open(), close()Popups only. Opening one from your own code instead of from a trigger element.

What lands in your page

A widget draws real elements into your own document, not an iframe, so your stylesheet and your developer tools reach all of it. The root of each one says what it is and how it is doing.

<div class="vf vf-roadmap" data-vf-widget="roadmap" data-vf-state="ready" data-vf-theme="dark">
  ...
</div>
AttributeWhat it carries
data-vf-widgetWhich call drew it: roadmap, board, changelog, top-features, features, vote-button, badge, suggest or report.
data-vf-stateloading, ready or error, on the seven widgets that draw into your page. A rule on [data-vf-state="loading"] is how you put your own skeleton over the wait. A popup has no state to report and carries none.
data-vf-themelight or dark, resolved. With theme: 'auto' this is what your page's own color-scheme came out as.