Last active
November 12, 2017 13:42
-
-
Save gsvster/333140f70b63e462a4ce43bdf0c785c3 to your computer and use it in GitHub Desktop.
react.js polls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style type="text/css"> | |
.dps_poll_content{{ poll.pk }} {/*background-color: #0B9D0B; padding: 3px;*/} | |
.dps_poll_content_header {font-variant: small-caps;} | |
.dps_poll_userspace {float: left; width: 100%; text-align: right;} | |
.dps_poll_title {color: #b10000; font-variant: small-caps; text-decoration: underline;} | |
.dps_poll_warning_message {color: #f88885;} | |
.dps_poll_body { | |
/* | |
background-color: #c1e0f1; | |
border-bottom: 1px solid #ccc; | |
border-left: 1px solid #ddd; | |
*/ | |
padding: 0px 0% 0px 0px; | |
clear: both; | |
} | |
.dps_poll_max_bar {display: block; padding: 5px; border-bottom: 1px solid #444; border-left: 1px solid #ccc; background-color: #cc0000;} | |
.dps_poll_normal_bar {display: block; padding: 5px; border-bottom: 1px solid #999; border-left: 1px solid #ddd; background-color: #339933;} | |
.dps_poll_item_dl {clear: both; width: 100%;} | |
.dps_poll_voters_count {text-align: right; border-top: 2px solid #333; margin-top: 20px; padding-top: 4px;} | |
.dps_poll_total {font-size: 1.5em;} | |
</style> | |
<div class="widget dps_poll_content_6" style="background-color: #c1e0f1; | |
border-bottom: 1px solid #ccc; | |
border-left: 1px solid #ddd; padding: 20px 50px 3px 20px;"> | |
<div id="polls"></div> | |
<script src="https://fb.me/react-15.0.0.js"></script> | |
<script src="https://fb.me/react-dom-15.0.0.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script> | |
<script type="text/babel"> | |
var PollsResult = React.createClass({ | |
getInitialState: function(){ | |
var result_total = 0; | |
var result_body = Array(); | |
return { | |
result_total: result_total, | |
result_body: result_body, | |
}; | |
}, | |
componentDidMount: function() { | |
}, | |
render: function() { | |
var divStyle = { | |
'display': 'block' | |
}; | |
var show_points = false; | |
var all_points = 0, total = 0, biggest = 0, points_txt = ""; | |
var rows = []; | |
$.each(this.props.result, function(index, value) { | |
if(index != 'total') { | |
if(this.props.result[index]['count'] > biggest) { | |
biggest = this.props.result[index]['count']; | |
} | |
all_points += this.props.result[index]['count']; | |
} | |
}.bind(this)); | |
$.each(this.props.result, function(index, value) { | |
if(index == 'total') { | |
total = value; | |
} else { | |
var percentage = (this.props.result[index]['count'] * 100) / all_points; | |
var display_percentage = (this.props.result[index]['count'] * 100) / biggest; | |
var bar_class = 'dps_poll_normal_bar'; | |
if(this.props.result[index]['count'] == biggest) { | |
bar_class = 'dps_poll_max_bar'; | |
} | |
if(show_points) { | |
points_txt = '<sup>(' + this.props.result[index]['count'] + ')</sup>'; | |
} | |
var divStyle = { | |
'width': display_percentage + "%", | |
}; | |
console.log("perc" + display_percentage); | |
rows.push( | |
<dl classname="dps_poll_item_dl"> | |
<dt>{this.props.result[index]["title"]}<strong> {(Math.round(percentage*100)/100)}%</strong> {points_txt}</dt> | |
<dd><div className={bar_class} style={divStyle} /></dd> | |
</dl> | |
); | |
} | |
}.bind(this)); | |
return ( | |
<div id="polls_component"> | |
<h4>Опитування: <strong>{this.props.poll_title}</strong></h4> | |
<p className="dps_poll_warning_message"> | |
<noscript> | |
WARNING: JavaScript is disabled in your browser. Please, turn it on to vote. | |
</noscript> | |
{this.props.message} | |
</p> | |
<form method="post"> | |
<div classname="dps_poll_body" style={divStyle}> | |
{rows} | |
<div classname="dps_poll_voters_count">Всього голосів: <span classname="dps_poll_total">{all_points}</span> </div> | |
</div> | |
</form> | |
</div> | |
) | |
} | |
}); | |
var Polls = React.createClass({ | |
getInitialState: function(){ | |
var poll_id = ""; | |
var poll_title = ""; | |
var items = []; | |
var selectedOption = {}; | |
return { | |
poll_id: poll_id, | |
poll_title: poll_title, | |
items: items, | |
selectedOption: selectedOption | |
}; | |
}, | |
componentDidMount: function() { | |
// отримання інформації про поточне опитування | |
$.getJSON('poll/default.json', function (data) { | |
this.setState({poll_id: data['poll_id'], poll_title: data['poll_title'], items: data['items']}); | |
// перевірка чи голосували раніше | |
if ($.cookie("poll_" + this.state.poll_id)){ | |
// якщо голосували, завантажуємо компонент результатів голосування з повідомленням що користувач вже голосував | |
$.post('poll/result/' + this.state.poll_id, {'csrfmiddlewaretoken': '{{ csrf_token }}'}, function(data) { | |
ReactDOM.render( | |
<PollsResult result={$.parseJSON(data)} poll_title={this.state.poll_title} poll_id={this.state.poll_id} message="Ви вже голосували!"/>, | |
document.getElementById('polls') | |
); | |
}.bind(this)); } | |
}.bind(this)); | |
//$.cookie("poll_6"); | |
}, | |
handleSubmit: function(e) { | |
// обробник кнопки "Голосувати" | |
e.preventDefault(); | |
// якщо не вибрали жодного варіанту відповіді | |
if (this.state.selectedOption == null) { | |
alert("Ви не обрали варіанту відповіді у голосуванні. Зробіть це"); | |
} | |
else { | |
// відправка даних голосування на сервер | |
$.post('poll/vote/' + this.state.poll_id, {'chosen_items': JSON.stringify(this.state.selectedOption[0]), 'csrfmiddlewaretoken': '{{ csrf_token }}'}, function(data) { | |
console.log("Vote" + $.parseJSON(data)); | |
}); | |
// встановлення кукі як індикатор, що користувач вже проголосував | |
$.cookie("poll_" + this.state.poll_id, this.state.poll_id); | |
// отримання результатів та передача їх у компонент результатів та його завантаження | |
$.post('poll/result/' + this.state.poll_id, {'csrfmiddlewaretoken': '{{ csrf_token }}'}, function(data) { | |
ReactDOM.render( | |
<PollsResult result={$.parseJSON(data)} poll_title={this.state.poll_title} poll_id={this.state.poll_id} message=""/>, | |
document.getElementById('polls') | |
); | |
}.bind(this)); | |
} | |
}, | |
handleOptionChange: function (changeEvent) { | |
// обробник кліків по варіантах опитування | |
var sOption = Array(); | |
sOption.push({[changeEvent.target.value] : "radio"},); | |
this.setState({ | |
selectedOption: sOption | |
}); | |
}, | |
render: function() { | |
var divStyle = { | |
'margin-top': '18px' | |
}; | |
var listItems = this.state.items.map((item, index) => | |
<div id="poll_item"> | |
<input name={"poll_" + this.state.poll_id} | |
key={'items-input' + index} | |
id={item['pk'].toString()} | |
type="radio" | |
value={item['pk'].toString()} | |
onChange={this.handleOptionChange} /> {item['fields']['value'].toString()} | |
</div> | |
); | |
return ( | |
<div id="polls_component"> | |
<h4>Опитування: <strong>{this.state.poll_title}</strong></h4> | |
<p className="dps_poll_warning_message"> | |
<noscript>WARNING: JavaScript is disabled in your browser. Please, turn it on to vote.</noscript> | |
</p> | |
<form method="post" onSubmit={this.handleSubmit}> | |
<div className="dps_poll_body"> | |
{listItems} | |
<p style={divStyle} > | |
<input className="dps_sendvote_6" value="Голосувати" type="submit" /> | |
</p> | |
</div> | |
</form> | |
</div> | |
) | |
} | |
}); | |
ReactDOM.render( | |
<Polls/>, | |
document.getElementById('polls') | |
); | |
</script> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment