Skip to content

Instantly share code, notes, and snippets.

@gsvster
Last active November 12, 2017 13:42
Show Gist options
  • Save gsvster/333140f70b63e462a4ce43bdf0c785c3 to your computer and use it in GitHub Desktop.
Save gsvster/333140f70b63e462a4ce43bdf0c785c3 to your computer and use it in GitHub Desktop.
react.js polls
<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