# blockenberg/2.0.7/blocks/interactive-poll/frontend.js

Blockenberg — 600+ Advanced Gutenberg Blocks &amp; AI Agent for WordPress Block Editor, version 2.0.7. 143 lines.

- Page: https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/interactive-poll/frontend.js
- Raw: https://pluginprobe.com/plugins/blockenberg/2.0.7/raw/blocks/interactive-poll/frontend.js
- Modified: 2026-03-06T12:32:40+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/interactive-poll/frontend.js#L10-L20`.

```javascript
(function () {
    'use strict';

    var LS_PREFIX = 'bkip_vote_';

    function getStoredData(instanceId) {
        try {
            var raw = localStorage.getItem(LS_PREFIX + instanceId);
            return raw ? JSON.parse(raw) : null;
        } catch (e) {
            return null;
        }
    }

    function storeData(instanceId, data) {
        try {
            localStorage.setItem(LS_PREFIX + instanceId, JSON.stringify(data));
        } catch (e) {}
    }

    function calcTotals(votes) {
        return votes.reduce(function (a, b) { return a + b; }, 0);
    }

    function renderResults(wrap, votes, animate) {
        var total = calcTotals(votes);
        var fills = wrap.querySelectorAll('.bkip-bar-fill');
        var pcts  = wrap.querySelectorAll('.bkip-result-pct');
        var totalNum = wrap.querySelector('.bkip-total-num');

        fills.forEach(function (fill, i) {
            var pct = total > 0 ? Math.round((votes[i] / total) * 100) : 0;

            if (!animate) {
                fill.style.transition = 'none';
            }

            // Trigger transition by setting width after a tiny delay
            setTimeout(function () {
                fill.style.width = pct + '%';
            }, animate ? 50 : 0);

            if (pcts[i]) pcts[i].textContent = pct + '%';
        });

        if (totalNum) totalNum.textContent = total;
    }

    function showResults(wrap) {
        var votesEl  = wrap.querySelector('.bkip-votes');
        var resultsEl = wrap.querySelector('.bkip-results');
        if (votesEl)   votesEl.classList.add('bkip-hidden');
        if (resultsEl) resultsEl.classList.add('bkip-visible');
    }

    function showVotes(wrap) {
        var votesEl   = wrap.querySelector('.bkip-votes');
        var resultsEl = wrap.querySelector('.bkip-results');
        if (votesEl)   votesEl.classList.remove('bkip-hidden');
        if (resultsEl) resultsEl.classList.remove('bkip-visible');
    }

    function initPoll(wrap) {
        var instanceId   = wrap.dataset.instance;
        var allowRevote  = wrap.dataset.allowRevote  !== 'false';
        var showBefore   = wrap.dataset.showBefore   === 'true';
        var animate      = wrap.dataset.animate      !== 'false';

        if (!instanceId) return;

        // Load option data from embedded JSON
        var dataScript = wrap.querySelector('.bkip-data');
        var baseOptions;
        try {
            baseOptions = JSON.parse(dataScript ? dataScript.textContent : '[]');
        } catch (e) {
            baseOptions = [];
        }

        // Initialise votes array from localStorage or base
        var stored = getStoredData(instanceId);
        var votes   = stored ? stored.votes : baseOptions.map(function (o) { return o.votes || 0; });
        var voted   = stored ? stored.voted : false;

        // Initial render
        if (showBefore || voted) {
            renderResults(wrap, votes, false);
            if (voted) showResults(wrap);
        }

        // Vote buttons
        var btns = Array.prototype.slice.call(wrap.querySelectorAll('.bkip-option-btn'));
        btns.forEach(function (btn) {
            btn.addEventListener('click', function () {
                if (voted && !allowRevote) return;

                var idx = parseInt(btn.dataset.index, 10);
                if (isNaN(idx) || idx < 0 || idx >= votes.length) return;

                // If revote: subtract previous vote
                if (voted && stored && typeof stored.lastVote === 'number') {
                    votes[stored.lastVote] = Math.max(0, votes[stored.lastVote] - 1);
                }

                votes[idx] = (votes[idx] || 0) + 1;
                voted = true;

                var newStored = { votes: votes, voted: true, lastVote: idx };
                storeData(instanceId, newStored);
                stored = newStored;

                renderResults(wrap, votes, animate);
                showResults(wrap);
            });
        });

        // Revote button
        var revoteBtn = wrap.querySelector('.bkip-revote');
        if (revoteBtn) {
            if (!allowRevote) {
                revoteBtn.style.display = 'none';
            }
            revoteBtn.addEventListener('click', function () {
                if (!allowRevote) return;
                voted = false;
                showVotes(wrap);
            });
        }
    }

    function init() {
        var polls = document.querySelectorAll('.bkip-wrap[data-instance]');
        polls.forEach(initPoll);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

}());

```
