design for poll participation implemented, saving works as well
This commit is contained in:
parent
04199837b3
commit
d0a77ce6b3
18 changed files with 197 additions and 13 deletions
5
app/assets/javascripts/app/models/poll_participation.js
Normal file
5
app/assets/javascripts/app/models/poll_participation.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
app.models.PollParticipation = Backbone.Model.extend({
|
||||
url : function(){
|
||||
"/poll_participations"
|
||||
}
|
||||
});
|
||||
|
|
@ -13,7 +13,8 @@ app.models.StatusMessage = app.models.Post.extend({
|
|||
status_message : _.clone(this.attributes),
|
||||
aspect_ids : this.get("aspect_ids"),
|
||||
photos : this.photos && this.photos.pluck("id"),
|
||||
services : this.get("services")
|
||||
services : this.get("services"),
|
||||
poll : this.get("poll")
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
50
app/assets/javascripts/app/views/poll.js
Normal file
50
app/assets/javascripts/app/views/poll.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
app.views.Poll = app.views.Base.extend({
|
||||
templateName : "poll",
|
||||
|
||||
events : {
|
||||
"click .submit" : "vote"
|
||||
},
|
||||
|
||||
initialize : function(options) {
|
||||
this.poll = this.model.attributes.poll;
|
||||
this.progressBarFactor = 3;
|
||||
//this.model.bind('remove', this.remove, this);
|
||||
},
|
||||
|
||||
postRenderTemplate : function() {
|
||||
if(this.poll) {
|
||||
this.setProgressBar();
|
||||
}
|
||||
},
|
||||
|
||||
setProgressBar : function() {
|
||||
var answers = this.poll.poll_answers;
|
||||
for(index = 0; index < answers.length; ++index) {
|
||||
var percentage = 0;
|
||||
if(this.poll.participation_count != 0) {
|
||||
percentage = answers[index].vote_count / this.poll.participation_count * 100;
|
||||
}
|
||||
var input = this.$("input[value="+answers[index].id+"]");
|
||||
var progressBar = $(input).parent().find(".poll_progress_bar");
|
||||
var width = percentage * this.progressBarFactor;
|
||||
progressBar.css("width", width + "px");
|
||||
}
|
||||
//
|
||||
},
|
||||
|
||||
vote : function(evt){
|
||||
var result = parseInt($(evt.target).parent().find("input[name=vote]:checked").val());
|
||||
var pollParticipation = new app.models.PollParticipation();
|
||||
pollParticipation.save({
|
||||
"poll_answer_id" : result,
|
||||
"poll_id" : this.poll.poll_id,
|
||||
},{
|
||||
url : "/posts/"+this.poll.post_id+"/poll_participations",
|
||||
success : function() {
|
||||
console.log(success);
|
||||
//todo remove radios+input
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -192,7 +192,7 @@ app.views.Publisher = Backbone.View.extend({
|
|||
var clone = this.el_poll_answer.clone();
|
||||
|
||||
var answer = clone.find('.poll_answer_input');
|
||||
//answer.attr("name", "poll_answer_" + this.option_counter);
|
||||
answer.val("");
|
||||
|
||||
var placeholder = answer.attr("placeholder");
|
||||
var expression = /[^0-9]+/;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ app.views.StreamPost = app.views.Post.extend({
|
|||
".post-content" : "postContentView",
|
||||
".oembed" : "oEmbedView",
|
||||
".opengraph" : "openGraphView",
|
||||
".poll" : "pollView",
|
||||
".status-message-location" : "postLocationStreamView"
|
||||
},
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ app.views.StreamPost = app.views.Post.extend({
|
|||
this.commentStreamView = new app.views.CommentStream({model : this.model});
|
||||
this.oEmbedView = new app.views.OEmbed({model : this.model});
|
||||
this.openGraphView = new app.views.OpenGraph({model : this.model});
|
||||
this.pollView = new app.views.Poll({model : this.model});
|
||||
},
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
@import 'header'
|
||||
@import 'footer'
|
||||
@import 'opengraph'
|
||||
@import 'poll'
|
||||
@import 'help'
|
||||
@import 'profile'
|
||||
@import 'publisher_blueprint'
|
||||
|
|
|
|||
43
app/assets/stylesheets/poll.css.scss
Normal file
43
app/assets/stylesheets/poll.css.scss
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
.poll_form {
|
||||
display: block;
|
||||
margin: 10px 0px 10px 0px;
|
||||
border-top: solid 1px $border-grey;
|
||||
border-bottom: solid 1px $border-grey;
|
||||
padding: 10px 0px 5px 0px;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.poll_form input[type="radio"] {
|
||||
display:inline !important;
|
||||
}
|
||||
|
||||
.poll_result {
|
||||
width:100%px;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.poll_progress_bar {
|
||||
position:absolute;
|
||||
width:100px;
|
||||
height:15px;
|
||||
top:-10px;
|
||||
z-index:-1;
|
||||
background-color:#3f8fba;
|
||||
}
|
||||
|
||||
.poll_statistic{
|
||||
float:right;
|
||||
}
|
||||
|
||||
.poll_progress_bar_wrapper {
|
||||
position: relative;
|
||||
width: 0;
|
||||
height: 0;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.poll_answer_entry{
|
||||
display:inline;
|
||||
width:100%;
|
||||
}
|
||||
19
app/assets/templates/poll_tpl.jst.hbs
Normal file
19
app/assets/templates/poll_tpl.jst.hbs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{{#if poll}}
|
||||
<div class="poll_form">
|
||||
<p class="poll_statistic">{{t "poll.result" votes=poll.participation_count}}</p>
|
||||
<strong>{{poll.question}}</strong><br/>
|
||||
{{#poll.poll_answers}}
|
||||
<div class="poll_answer_entry">
|
||||
<input type="radio" name="vote" value="{{id}}"/>
|
||||
<div class="poll_result">
|
||||
<div class="poll_progress_bar_wrapper">
|
||||
<div class="poll_progress_bar"> </div>
|
||||
</div>
|
||||
{{answer}}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{{/poll.poll_answers}}
|
||||
<input type="submit" class="button submit" style="float:right;" value="{{t "poll.vote"}}"/>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -18,4 +18,5 @@
|
|||
{{{text}}}
|
||||
<div class="oembed"></div>
|
||||
<div class="opengraph"></div>
|
||||
<div class="poll"></div>
|
||||
</div>
|
||||
|
|
|
|||
30
app/controllers/poll_participations_controller.rb
Normal file
30
app/controllers/poll_participations_controller.rb
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
class PollParticipationsController < ApplicationController
|
||||
include ApplicationHelper
|
||||
before_filter :authenticate_user!
|
||||
|
||||
def create
|
||||
answer = PollAnswer.find(params[:poll_answer_id])
|
||||
poll_participation = current_user.participate_in_poll!(target, answer) if target rescue ActiveRecord::RecordInvalid
|
||||
if poll_participation
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render :nothing => true, :status => 201 }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render :nothing => true, :status => 403 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= if params[:post_id]
|
||||
current_user.find_visible_shareable_by_id(Post, params[:post_id]) || raise(ActiveRecord::RecordNotFound.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -49,16 +49,18 @@ class StatusMessagesController < ApplicationController
|
|||
|
||||
@status_message = current_user.build_post(:status_message, params[:status_message])
|
||||
@status_message.build_location(:address => params[:location_address], :coordinates => params[:location_coords]) if params[:location_address].present?
|
||||
@status_message.build_poll(:question => params[:poll_question]) if params[:poll_question].present?
|
||||
poll_answers = params[:poll_answers]
|
||||
if params[:poll_answers].instance_of? String
|
||||
poll_answers = [params[:poll_answers]]
|
||||
end
|
||||
|
||||
poll_answers.each do |poll_answer|
|
||||
@status_message.poll.poll_answers.build(:answer => poll_answer)
|
||||
if params[:poll_question].present?
|
||||
@status_message.build_poll(:question => params[:poll_question])
|
||||
poll_answers = params[:poll_answers]
|
||||
if params[:poll_answers].instance_of? String
|
||||
poll_answers = [params[:poll_answers]]
|
||||
end
|
||||
poll_answers.each do |poll_answer|
|
||||
@status_message.poll.poll_answers.build(:answer => poll_answer)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@status_message.attach_photos_by_ids(params[:photos])
|
||||
|
||||
if @status_message.save
|
||||
|
|
@ -88,7 +90,7 @@ class StatusMessagesController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render {:nothing => true} , :status => 403 }
|
||||
format.json { render :nothing => true, :status => 403 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,8 +14,26 @@ class Poll < ActiveRecord::Base
|
|||
|
||||
validate :enough_poll_answers
|
||||
|
||||
#TODO check if user has the right to vote
|
||||
|
||||
self.include_root_in_json = false
|
||||
|
||||
def enough_poll_answers
|
||||
errors.add(:poll_answers, I18n.t("activerecord.errors.models.poll.attributes.poll_answers.not_enough_poll_answers")) if poll_answers.size < 2
|
||||
end
|
||||
|
||||
def as_json(options={})
|
||||
{
|
||||
:poll_id => self.id,
|
||||
:post_id => self.status_message.id,
|
||||
:question => self.question,
|
||||
:poll_answers => self.poll_answers,
|
||||
:participation_count => self.participation_count
|
||||
#TODO already participated?
|
||||
}
|
||||
end
|
||||
|
||||
def participation_count
|
||||
poll_answers.sum("vote_count")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ class PollAnswer < ActiveRecord::Base
|
|||
|
||||
xml_attr :answer
|
||||
|
||||
self.include_root_in_json = false
|
||||
|
||||
def update_vote_counter
|
||||
self.vote_count = self.vote_count + 1
|
||||
self.save!
|
||||
|
|
|
|||
|
|
@ -72,6 +72,9 @@ class Post < ActiveRecord::Base
|
|||
def address
|
||||
end
|
||||
|
||||
def poll
|
||||
end
|
||||
|
||||
def self.excluding_blocks(user)
|
||||
people = user.blocks.map{|b| b.person_id}
|
||||
scope = scoped
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class PostPresenter
|
|||
:root => root,
|
||||
:title => title,
|
||||
:address => @post.address,
|
||||
:poll => @post.poll,
|
||||
|
||||
:interactions => {
|
||||
:likes => [user_like].compact,
|
||||
|
|
|
|||
|
|
@ -172,3 +172,7 @@ en:
|
|||
reshared: "Reshared"
|
||||
comment: "Comment"
|
||||
home: "HOME"
|
||||
|
||||
poll:
|
||||
vote: "Vote"
|
||||
result: "<%=votes%> votes so far"
|
||||
|
|
|
|||
|
|
@ -31,11 +31,15 @@ Diaspora::Application.routes.draw do
|
|||
get :interactions
|
||||
end
|
||||
|
||||
resources :poll_participations, :only => [:create]
|
||||
|
||||
resources :likes, :only => [:create, :destroy, :index ]
|
||||
resources :participations, :only => [:create, :destroy, :index]
|
||||
resources :comments, :only => [:new, :create, :destroy, :index]
|
||||
end
|
||||
|
||||
|
||||
|
||||
get 'p/:id' => 'posts#show', :as => 'short_post'
|
||||
get 'posts/:id/iframe' => 'posts#iframe', :as => 'iframe'
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ module Federated
|
|||
FEDERATION_LOGGER.info("user:#{@user.id} dispatching #{relayable.class}:#{relayable.guid}")
|
||||
Postzord::Dispatcher.defer_build_and_post(@user, relayable)
|
||||
relayable
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue