1$(function () { 2 var $root = $('.js-sidebar-poll'); 3 if (!$root.length) { 4 return; 5 } 6 7 $root.each(function () { 8 var $poll = $(this); 9 var pollId = $poll.data('poll-id'); 10 var ajaxUrl = $poll.data('ajax-url'); 11 var maxChoices = parseInt($poll.data('max-choices'), 10) || 3; 12 var $form = $poll.find('.js-sidebar-poll-form'); 13 var $message = $poll.find('.js-sidebar-poll-message'); 14 var $resultsPanel = $poll.find('.js-sidebar-poll-results-panel'); 15 16 function showMessage(text, isError) { 17 if (!text) { 18 $message.attr('hidden', true).text(''); 19 return; 20 } 21 $message 22 .attr('hidden', false) 23 .toggleClass('c-left-poll__message--error', !!isError) 24 .text(text); 25 } 26 27 function getSelectedChoices() { 28 var values = []; 29 $form.find('.js-sidebar-poll-choice:checked').each(function () { 30 values.push($(this).val()); 31 }); 32 return values; 33 } 34 35 function enforceMaxChoices($changed) { 36 var $checked = $form.find('.js-sidebar-poll-choice:checked'); 37 if ($checked.length <= maxChoices) { 38 showMessage(''); 39 return; 40 } 41 if ($changed && $changed.length) { 42 $changed.prop('checked', false); 43 } 44 showMessage('Ðожно вÑбÑаÑÑ Ð½Ðµ более ' + maxChoices + ' ваÑианÑов.', true); 45 } 46 47 $form.on('change', '.js-sidebar-poll-choice', function () { 48 enforceMaxChoices($(this)); 49 }); 50 51 function renderResultsHtml(results) { 52 if (!results || !results.rows) { 53 return; 54 } 55 var colors = ['#bd1f26', '#3d3d3d', '#9a9a9a', '#c47a4a', '#6b8e23', '#4a7fc4', '#7b5ea7', '#2f9e9e']; 56 var html = '<ul class="c-left-poll__results h-reset-list">'; 57 58 if (!results.rows.length) { 59 html += '<li class="c-left-poll__result c-left-poll__result--empty">Ðока Ð½ÐµÑ Ð³Ð¾Ð»Ð¾Ñов.</li>'; 60 } else { 61 results.rows.forEach(function (row, index) { 62 var percent = parseFloat(row.percent) || 0; 63 var percentText = percent.toFixed(2).replace(/\.?0+$/, ''); 64 var color = colors[index % colors.length]; 65 html += '<li class="c-left-poll__result">'; 66 html += '<div class="c-left-poll__result-head">'; 67 html += '<span class="c-left-poll__result-label">' + $('<div>').text(row.label).html() + '</span>'; 68 html += '<span class="c-left-poll__result-percent">(' + percentText + '%)</span>'; 69 html += '</div>'; 70 html += '<div class="c-left-poll__result-bar" style="--poll-bar-color:' + color + ';--poll-bar-width:' + Math.min(100, percent) + '%;"></div>'; 71 html += '</li>'; 72 }); 73 } 74 html += '</ul>'; 75 return html; 76 } 77 78 function updateVotersLabel(label) { 79 var $voters = $poll.find('.js-sidebar-poll-voters'); 80 if (!$voters.length || !label) { 81 return; 82 } 83 $voters.text(label); 84 } 85 86 function showResultsPanel(results, withThanks) { 87 var $thanks = $resultsPanel.find('.c-left-poll__thanks'); 88 if (withThanks && !$thanks.length) { 89 $resultsPanel.prepend('<p class="c-left-poll__thanks">СпаÑибо за ÑÑаÑÑие в опÑоÑе.</p>'); 90 } 91 var $list = $resultsPanel.find('.c-left-poll__results'); 92 if ($list.length) { 93 $list.replaceWith(renderResultsHtml(results)); 94 } else { 95 $resultsPanel.append(renderResultsHtml(results)); 96 } 97 updateVotersLabel(results && results.voters_label ? results.voters_label : ''); 98 $resultsPanel.removeAttr('hidden'); 99 } 100 101 function parsePollResponse(xhr) { 102 if (!xhr || !xhr.responseText) { 103 return null; 104 } 105 try { 106 return JSON.parse(xhr.responseText); 107 } catch (e) { 108 return null; 109 } 110 } 111 112 function getPollErrorMessage(xhr, fallback) { 113 var data = parsePollResponse(xhr); 114 if (data && data.message) { 115 return data.message; 116 } 117 return fallback; 118 } 119 120 function requestPoll(action, payload, onSuccess, onError) { 121 return $.ajax({ 122 url: ajaxUrl, 123 type: 'POST', 124 dataType: 'json', 125 data: $.extend({ 126 action: action, 127 poll_id: pollId 128 }, payload || {}) 129 }).done(function (data) { 130 if (data && data.success) { 131 onSuccess(data); 132 return; 133 } 134 onError((data && data.message) ? data.message : 'ÐÑибка запÑоÑа.'); 135 }).fail(function (xhr) { 136 onError(getPollErrorMessage(xhr, 'Ðе ÑдалоÑÑ ÑвÑзаÑÑÑÑ Ñ ÑеÑвеÑом.')); 137 }); 138 } 139 140 function loadResults(withThanks) { 141 requestPoll('results', {}, function (data) {
142 showResultsPanel(data.results, withThanks); 143 }, function (message) { 144 showMessage(message, true); 145 }); 146 } 147 148 $poll.on('click', '.js-sidebar-poll-vote', function () { 149 var choices = getSelectedChoices(); 150 if (!choices.length) { 151 showMessage('ÐÑбеÑиÑе Ñ Ð¾ÑÑ Ð±Ñ Ð¾Ð´Ð¸Ð½ ваÑианÑ.', true); 152 return; 153 } 154 if (choices.length > maxChoices) { 155 showMessage('Ðожно вÑбÑаÑÑ Ð½Ðµ более ' + maxChoices + ' ваÑианÑов.', true); 156 return; 157 } 158 159 var $btn = $(this).prop('disabled', true); 160 showMessage(''); 161 162 requestPoll('vote', {choices: choices}, function (data) { 163 $form.remove(); 164 showResultsPanel(data.results, true); 165 }, function (message) { 166 showMessage(message, true); 167 $btn.prop('disabled', false); 168 }); 169 }); 170 171 $poll.on('click', '.js-sidebar-poll-results', function () { 172 loadResults(false); 173 }); 174 }); 175});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.