bcms_polling 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/COPYRIGHT.txt ADDED
@@ -0,0 +1,23 @@
1
+ All BrowserCMS code is Copyright (C) 1998-2010 by BrowserMedia, LLC.
2
+
3
+ This program is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU Lesser General Public License as published by
5
+ the Free Software Foundation, either version 3 of the License, or
6
+ (at your option) any later version.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ GNU Lesser General Public License for more details.
12
+
13
+ You should have received a copy of the GNU Lesser General Public License
14
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ BrowserCMS is a registered trademark of BrowserMedia, LLC.
17
+
18
+ BrowserCMS includes works under other copyright notices and distributed
19
+ according to the terms of the GNU Lesser Public License or a compatible
20
+ license, including:
21
+
22
+ - jQuery - Copyright (C) 2009 John Resig
23
+ - CKEditor - Copyright (C) 2003-2009 Frederico Caldeira Knabben
data/LICENSE.txt ADDED
@@ -0,0 +1,165 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+
9
+ This version of the GNU Lesser General Public License incorporates
10
+ the terms and conditions of version 3 of the GNU General Public
11
+ License, supplemented by the additional permissions listed below.
12
+
13
+ 0. Additional Definitions.
14
+
15
+ As used herein, "this License" refers to version 3 of the GNU Lesser
16
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
+ General Public License.
18
+
19
+ "The Library" refers to a covered work governed by this License,
20
+ other than an Application or a Combined Work as defined below.
21
+
22
+ An "Application" is any work that makes use of an interface provided
23
+ by the Library, but which is not otherwise based on the Library.
24
+ Defining a subclass of a class defined by the Library is deemed a mode
25
+ of using an interface provided by the Library.
26
+
27
+ A "Combined Work" is a work produced by combining or linking an
28
+ Application with the Library. The particular version of the Library
29
+ with which the Combined Work was made is also called the "Linked
30
+ Version".
31
+
32
+ The "Minimal Corresponding Source" for a Combined Work means the
33
+ Corresponding Source for the Combined Work, excluding any source code
34
+ for portions of the Combined Work that, considered in isolation, are
35
+ based on the Application, and not on the Linked Version.
36
+
37
+ The "Corresponding Application Code" for a Combined Work means the
38
+ object code and/or source code for the Application, including any data
39
+ and utility programs needed for reproducing the Combined Work from the
40
+ Application, but excluding the System Libraries of the Combined Work.
41
+
42
+ 1. Exception to Section 3 of the GNU GPL.
43
+
44
+ You may convey a covered work under sections 3 and 4 of this License
45
+ without being bound by section 3 of the GNU GPL.
46
+
47
+ 2. Conveying Modified Versions.
48
+
49
+ If you modify a copy of the Library, and, in your modifications, a
50
+ facility refers to a function or data to be supplied by an Application
51
+ that uses the facility (other than as an argument passed when the
52
+ facility is invoked), then you may convey a copy of the modified
53
+ version:
54
+
55
+ a) under this License, provided that you make a good faith effort to
56
+ ensure that, in the event an Application does not supply the
57
+ function or data, the facility still operates, and performs
58
+ whatever part of its purpose remains meaningful, or
59
+
60
+ b) under the GNU GPL, with none of the additional permissions of
61
+ this License applicable to that copy.
62
+
63
+ 3. Object Code Incorporating Material from Library Header Files.
64
+
65
+ The object code form of an Application may incorporate material from
66
+ a header file that is part of the Library. You may convey such object
67
+ code under terms of your choice, provided that, if the incorporated
68
+ material is not limited to numerical parameters, data structure
69
+ layouts and accessors, or small macros, inline functions and templates
70
+ (ten or fewer lines in length), you do both of the following:
71
+
72
+ a) Give prominent notice with each copy of the object code that the
73
+ Library is used in it and that the Library and its use are
74
+ covered by this License.
75
+
76
+ b) Accompany the object code with a copy of the GNU GPL and this license
77
+ document.
78
+
79
+ 4. Combined Works.
80
+
81
+ You may convey a Combined Work under terms of your choice that,
82
+ taken together, effectively do not restrict modification of the
83
+ portions of the Library contained in the Combined Work and reverse
84
+ engineering for debugging such modifications, if you also do each of
85
+ the following:
86
+
87
+ a) Give prominent notice with each copy of the Combined Work that
88
+ the Library is used in it and that the Library and its use are
89
+ covered by this License.
90
+
91
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
+ document.
93
+
94
+ c) For a Combined Work that displays copyright notices during
95
+ execution, include the copyright notice for the Library among
96
+ these notices, as well as a reference directing the user to the
97
+ copies of the GNU GPL and this license document.
98
+
99
+ d) Do one of the following:
100
+
101
+ 0) Convey the Minimal Corresponding Source under the terms of this
102
+ License, and the Corresponding Application Code in a form
103
+ suitable for, and under terms that permit, the user to
104
+ recombine or relink the Application with a modified version of
105
+ the Linked Version to produce a modified Combined Work, in the
106
+ manner specified by section 6 of the GNU GPL for conveying
107
+ Corresponding Source.
108
+
109
+ 1) Use a suitable shared library mechanism for linking with the
110
+ Library. A suitable mechanism is one that (a) uses at run time
111
+ a copy of the Library already present on the user's computer
112
+ system, and (b) will operate properly with a modified version
113
+ of the Library that is interface-compatible with the Linked
114
+ Version.
115
+
116
+ e) Provide Installation Information, but only if you would otherwise
117
+ be required to provide such information under section 6 of the
118
+ GNU GPL, and only to the extent that such information is
119
+ necessary to install and execute a modified version of the
120
+ Combined Work produced by recombining or relinking the
121
+ Application with a modified version of the Linked Version. (If
122
+ you use option 4d0, the Installation Information must accompany
123
+ the Minimal Corresponding Source and Corresponding Application
124
+ Code. If you use option 4d1, you must provide the Installation
125
+ Information in the manner specified by section 6 of the GNU GPL
126
+ for conveying Corresponding Source.)
127
+
128
+ 5. Combined Libraries.
129
+
130
+ You may place library facilities that are a work based on the
131
+ Library side by side in a single library together with other library
132
+ facilities that are not Applications and are not covered by this
133
+ License, and convey such a combined library under terms of your
134
+ choice, if you do both of the following:
135
+
136
+ a) Accompany the combined library with a copy of the same work based
137
+ on the Library, uncombined with any other library facilities,
138
+ conveyed under the terms of this License.
139
+
140
+ b) Give prominent notice with the combined library that part of it
141
+ is a work based on the Library, and explaining where to find the
142
+ accompanying uncombined form of the same work.
143
+
144
+ 6. Revised Versions of the GNU Lesser General Public License.
145
+
146
+ The Free Software Foundation may publish revised and/or new versions
147
+ of the GNU Lesser General Public License from time to time. Such new
148
+ versions will be similar in spirit to the present version, but may
149
+ differ in detail to address new problems or concerns.
150
+
151
+ Each version is given a distinguishing version number. If the
152
+ Library as you received it specifies that a certain numbered version
153
+ of the GNU Lesser General Public License "or any later version"
154
+ applies to it, you have the option of following the terms and
155
+ conditions either of that published version or of any later version
156
+ published by the Free Software Foundation. If the Library as you
157
+ received it does not specify a version number of the GNU Lesser
158
+ General Public License, you may choose any version of the GNU Lesser
159
+ General Public License ever published by the Free Software Foundation.
160
+
161
+ If the Library as you received it specifies that a proxy can decide
162
+ whether future versions of the GNU Lesser General Public License shall
163
+ apply, that proxy's public statement of acceptance of any version is
164
+ permanent authorization for you to choose that version for the
165
+ Library.
data/README.markdown ADDED
@@ -0,0 +1,48 @@
1
+ This is a polling module for BrowerCMS. It allows editors to create polls which have a single question, and an unlimited number of answers.
2
+ Users can participate in polls by voting (once), and can see the results ahead of time. This module is primarily designed to
3
+ provide a simple feedback option for sites to collect information from visitors.
4
+
5
+ * Editors should have the ability to easily create, edit and delete polls on any page of
6
+ the website
7
+ * Polls should consist of a question followed by a series of potential answers
8
+ * Users should be limited to selecting only one answer, and submitting that answer to any
9
+ given Poll only once
10
+ * Users should be able to view Poll results in a simple, graphical format, without requiring
11
+ users to leave or refresh the page
12
+ * Pages should be able to contain one or many Polls
13
+ * A single Poll should be able to reside on one or many pages simultaneously
14
+ * Content Editors have a convient link to 'reset' their voting privileges in order to support testing.
15
+
16
+ Security Caveat:
17
+ =====
18
+ Security to prevent multiple voting is extremely simple, storing a cookie when a user votes, so this solution is not appropriate for 'serious' voting. Users can
19
+ vote multiple times from multiple computers or just clear their cookies to revote.
20
+
21
+ Installation:
22
+ =============
23
+
24
+ gem install bcms_polling
25
+
26
+ Follow standard module installation after that.
27
+
28
+ Finally, edit your project's app/helpers/application_helper.rb so it looks like:
29
+
30
+ module ApplicationHelper
31
+ include Cms::PollsHelper
32
+ end
33
+
34
+ Finally, add the default stylesheet for polls to your template, tweaking as necessary or inlining into the site's main stylesheet.
35
+
36
+ <%= stylesheet_link_tag '/bcms/polling/bcms-polling' %>
37
+
38
+
39
+
40
+ Bugs:
41
+ ====
42
+ * Tab order for responses is wrong. [Minor Issue]
43
+
44
+ BrowserCMS Core Notes:
45
+ ================
46
+ * Using nested_attributes doesn't work without some monkeying around. Specifically, BrowserCMS doesn't consider nested attributes as 'changes', so
47
+ updates (and a new version) doesn't get saved. Can fix this by timestamping 'updated_at' but the core CMS should be aware of
48
+ nested_attributes and save correctly if they are present.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+ require 'rake/rdoctask'
9
+
10
+ require 'tasks/rails'
11
+
12
+ begin
13
+ require 'jeweler'
14
+ Jeweler::Tasks.new do |gemspec|
15
+ gemspec.name = "bcms_polling"
16
+ gemspec.rubyforge_project = "browsercms"
17
+ gemspec.summary = "A Polling Module for BrowserCMS"
18
+ gemspec.email = "github@browsermedia.com"
19
+ gemspec.homepage = "http://browsercms.org"
20
+ gemspec.description = "Allows for user feedback via short polling questions."
21
+ gemspec.authors = ["BrowserMedia"]
22
+ gemspec.files = []
23
+ gemspec.files += Dir["app/**/*"]
24
+ gemspec.files -= Dir["app/views/layouts/templates/*"]
25
+ gemspec.files -= Dir["app/controllers/application_controller.rb"]
26
+ gemspec.files -= Dir["app/helpers/application_helper.rb"]
27
+ gemspec.files += Dir["doc/**/*"]
28
+ gemspec.files += Dir["db/migrate/[0-9]*.rb"].reject {|f| f =~ /_browsercms|_load_seed/ }
29
+ gemspec.files += Dir["lib/**/*"]
30
+ gemspec.files += Dir["rails/init.rb"]
31
+ gemspec.files += Dir["public/bcms/polling/**/*"]
32
+ gemspec.files += Dir["README.markdown"]
33
+ gemspec.files += Dir["Rakefile"]
34
+ gemspec.files += Dir["LICENSE.txt"]
35
+ gemspec.files += Dir["COPYRIGHT.txt"]
36
+ gemspec.files += Dir["VERSION"]
37
+ end
38
+ rescue LoadError
39
+ puts "Jeweler not available. Install it with: gem install jeweler"
40
+ end
41
+
42
+ Jeweler::GemcutterTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,2 @@
1
+ class Cms::PollsController < Cms::ContentBlockController
2
+ end
@@ -0,0 +1,44 @@
1
+ # Handles the public submissions of answers to poll questions.
2
+ class PollingController < ApplicationController
3
+ include Cms::PollsHelper
4
+ include Cms::Authentication::Controller
5
+
6
+ def update
7
+ @response = PollResponse.find(params[:id])
8
+ unique_key = cookie_key(@response.poll)
9
+
10
+ if !cookies[unique_key]
11
+ @response.votes += 1
12
+ @response.save!
13
+
14
+ cookies[unique_key] = {
15
+ :value => true,
16
+ :expires => 1.year.from_now
17
+ }
18
+ logger.warn "Saving cookie called '#{unique_key}'"
19
+ else
20
+ logger.warn "User attempted to submit another answer to the same poll."
21
+ end
22
+
23
+ render :nothing => true, :status => :ok
24
+ end
25
+
26
+ def results
27
+ @poll = Poll.find(params[:id])
28
+ render :layout => false
29
+ end
30
+
31
+ def reset
32
+ @poll = Poll.find(params[:id])
33
+
34
+ cookie = cookie_key(@poll)
35
+ cookies.delete(cookie)
36
+
37
+ redirect_to "/"
38
+ end
39
+
40
+ private
41
+ def cookie_key(poll)
42
+ cookie_for(poll)
43
+ end
44
+ end
@@ -0,0 +1,10 @@
1
+ module Cms::PollsHelper
2
+ def response_results(response)
3
+ total = response.poll.total_votes == 0 ? 0 : (response.votes.to_f / response.poll.total_votes.to_f) * 100
4
+ "#{response.votes} votes (#{sprintf("%.2f", total)}%)"
5
+ end
6
+
7
+ def cookie_for(poll)
8
+ "cmspolls_#{poll.id}".to_sym
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ class Poll < ActiveRecord::Base
2
+ acts_as_content_block
3
+
4
+ has_many :responses, :class_name => "PollResponse"
5
+ accepts_nested_attributes_for :responses, :allow_destroy => true
6
+
7
+ validates_presence_of :question
8
+
9
+ def total_votes
10
+ self.responses.inject(0) { |sum, r| sum += r.votes }
11
+ end
12
+
13
+ def name
14
+ question
15
+ end
16
+
17
+
18
+ # Overridden to make sure nested attributes (i.e. poll responses) will correctly update.
19
+ def update_attributes(attributes)
20
+ unless attributes[:responses_attributes].blank?
21
+ logger.debug "Forcing update of poll so updated answers are saved."
22
+ self.updated_at = Time.now # Force this block to update, regardless of what was submitted.
23
+
24
+ else
25
+ logger.debug "No poll attributes were submitted."
26
+ end
27
+ super(attributes)
28
+ end
29
+
30
+ # Overridden for purely debugging purposes.
31
+ def different_from_last_draft?
32
+ result = super
33
+ logger.debug "Is this poll is different than the last draft? '#{result}'"
34
+ result
35
+ end
36
+
37
+ end
@@ -0,0 +1,4 @@
1
+ class PollResponse < ActiveRecord::Base
2
+ belongs_to :poll
3
+ validates_presence_of :answer
4
+ end
@@ -0,0 +1,68 @@
1
+ <script type="text/javascript">
2
+
3
+ var new_response = '<div class="fields text_fields">\n';
4
+ new_response += '<label for="poll_responses">Response #X</label>\n';
5
+ new_response += '<input type="text" value="" tabindex="5" size="30" name="" id="poll_responses">\n';
6
+ new_response += '</div>';
7
+
8
+ function addResponse() {
9
+ var responseCount = $('div#responses > div').length;
10
+ $('div#responses').append(new_response);
11
+ $('div.fields.text_fields > label[for="poll_responses"]:last').text('Response #' + (responseCount + 1));
12
+ $('div.fields.text_fields > input#poll_responses:last').attr('name', 'poll[responses_attributes][' + responseCount + '][answer]');
13
+ }
14
+
15
+ $(document).ready(function() {
16
+ var new_record = <%= @block.new_record? %>;
17
+ if (new_record) {
18
+ addResponse();
19
+ addResponse();
20
+ }
21
+ });
22
+
23
+ function removeResponse(element){
24
+ var delete_button = $(element);
25
+ delete_button.prev().hide();
26
+ delete_button.hide();
27
+ var delete_checkbox_class = '#poll_responses_attributes_'+ delete_button.attr('data-count-id') +'__destroy';
28
+ $(delete_checkbox_class).attr('checked', 'checked');
29
+ }
30
+ </script>
31
+
32
+ <style>
33
+ div.response {
34
+ position: relative;
35
+ }
36
+
37
+ div.response a {
38
+ position: absolute;
39
+ top: 15px;
40
+ right: 170px;
41
+ }
42
+
43
+ div.response > div.text_fields input {
44
+ width: 400px;
45
+ padding-bottom: 0px;
46
+ }
47
+ </style>
48
+
49
+ <%= f.cms_text_field :question %>
50
+
51
+
52
+ <div id="responses">
53
+ <% count = 0 -%>
54
+ <% available_responses = PollResponse.find(:all, :conditions => {:poll_id => f.object.id}) %>
55
+ <% f.fields_for(:responses, available_responses) do |response_fields| %>
56
+ <%= response_fields.cms_text_field :answer, :label => "Response ##{count = count + 1}" %>
57
+ <%= link_to_function('Delete', 'removeResponse(this)', 'data-count-id'=>count-1, :style=>'position: relative; left: 465px; top: -25px;') %>
58
+ <%= response_fields.check_box :_destroy, :style=>"display:none" %>
59
+
60
+ <% end %>
61
+
62
+ </div>
63
+
64
+ <div class="fields">
65
+ <label style="padding-left: 140px"></label>
66
+ <%= link_to_function('Add response', 'addResponse()') %>
67
+ </div>
68
+
@@ -0,0 +1,28 @@
1
+ <% unless self.controller.instance_variable_defined? :@include_js_http_methods -%>
2
+ <%= javascript_include_tag 'jquery', '/bcms/polling/bcms-polling' %>
3
+ <%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? -%>
4
+ <% self.controller.instance_variable_set(:@include_js_http_methods, true) -%>
5
+ <% end -%>
6
+
7
+
8
+ <div id='vote-<%= @content_block.id %>' class="bcms_poll">
9
+ <span class="question"><%= @content_block.question %></span>
10
+
11
+ <ul class="vote-choices">
12
+ <% for response in PollResponse.find(:all, :conditions => {:poll_id => @content_block.id}) %>
13
+ <li>
14
+ <span class="response"><%= response.answer %></span>
15
+ <%= link_to "Vote!", poll_response_url(response), :class => "vote-this", 'data-poll-id'=>@content_block.id %>
16
+ </li>
17
+ <% end %>
18
+ </ul>
19
+ <span class="show-results"><%= link_to "See the results", "#", 'data-poll-id'=>@content_block.id, :class => "show-results" %></span>
20
+ </div>
21
+
22
+ <% if cookies[cookie_for(@content_block)] -%>
23
+ <script type="text/javascript">
24
+ $(document).ready(function() {
25
+ showResults(<%= @content_block.id %>, false);
26
+ });
27
+ </script>
28
+ <% end -%>
@@ -0,0 +1,13 @@
1
+ <ul class="vote-results">
2
+ <% for response in @poll.responses %>
3
+ <li>
4
+ <strong><%= response.answer %></strong> &mdash; <%= response_results(response) %>
5
+ </li>
6
+ <% end %>
7
+ </ul>
8
+ <% if cookies[cookie_for(@poll)] && current_user.able_to?(:edit_content)-%>
9
+ <%= link_to "Vote Again (Reset Cookie)", poll_reset_path(@poll) %>
10
+ <% end %>
11
+ <% if params[:return] == 'true' %>
12
+ <%= link_to_function "Back to Poll", 'history.go(0);return false;' %>
13
+ <% end %>
@@ -0,0 +1,25 @@
1
+ class CreatePolls < ActiveRecord::Migration
2
+ def self.up
3
+ create_content_table :polls do |t|
4
+ t.string :name
5
+ t.text :question
6
+ end
7
+
8
+ create_table :poll_responses do |t|
9
+ t.text :answer
10
+ t.integer :votes, :default => 0
11
+ t.belongs_to :poll
12
+ end
13
+
14
+ ContentType.create!(:name => "Poll", :group_name => "Polling")
15
+ end
16
+
17
+ def self.down
18
+ ContentType.delete_all(['name = ?', 'Poll'])
19
+ CategoryType.all(:conditions => ['name = ?', 'Poll']).each(&:destroy)
20
+ #If you aren't creating a versioned table, be sure to comment this out.
21
+ drop_table :poll_responses
22
+ drop_table :poll_versions
23
+ drop_table :polls
24
+ end
25
+ end
@@ -0,0 +1,2 @@
1
+ Use this README file to introduce your application and point to useful places in the API for learning more.
2
+ Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
@@ -0,0 +1,12 @@
1
+ module Cms::Routes
2
+ def routes_for_bcms_polling
3
+
4
+ poll_results '/polls/:id/results', :controller=>"polling", :action=>'results'
5
+ poll_reset '/polls/:id/reset', :controller=>"polling", :action=>'reset'
6
+ poll_response '/poll_responses/:id', :controller=>"polling", :action=>'update'
7
+ namespace(:cms) do |cms|
8
+ cms.content_blocks :poll_responses
9
+ cms.content_blocks :polls
10
+ end
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ require 'bcms_polling/routes'
@@ -0,0 +1 @@
1
+ Use this directory to add public files that should copied from the gem into the project.
@@ -0,0 +1,35 @@
1
+ .bcms_poll .question {
2
+ font-weight: bold;
3
+ }
4
+
5
+ ul.vote-choices, ul.vote-results {
6
+ margin: 10px 0 !important;
7
+ padding: 0 !important;
8
+ }
9
+
10
+ ul.vote-choices li, ul.vote-results li {
11
+ background: none !important;
12
+ padding: 5px 0 !important;
13
+ }
14
+
15
+ a.vote-this, a.show-results {
16
+ display: inline;
17
+ text-align: center;
18
+ text-transform: uppercase;
19
+ background: #A2BC39;
20
+ color: #FFF;
21
+ font-size: 90%;
22
+ margin: 10px 0 !important;
23
+ padding: 2px 5px;
24
+ text-decoration: none;
25
+ }
26
+
27
+ a.vote-this {
28
+
29
+ }
30
+
31
+ a.show-results {
32
+ width: 60px;
33
+ right: 0;
34
+ font-weight: bold;
35
+ }
@@ -0,0 +1,44 @@
1
+ function _ajax_request(url, data, callback, type, method) {
2
+ if (jQuery.isFunction(data)) {
3
+ callback = data;
4
+ data = {};
5
+ }
6
+
7
+ data = (data ? data + "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
8
+
9
+ return jQuery.ajax({
10
+ type: method,
11
+ url: url,
12
+ data: data,
13
+ success: callback,
14
+ dataType: type
15
+ });
16
+ }
17
+
18
+ jQuery.extend({
19
+ put: function(url, data, callback, type) {
20
+ return _ajax_request(url, data, callback, type, 'PUT');
21
+ },
22
+ delete_: function(url, data, callback, type) {
23
+ return _ajax_request(url, data, callback, type, 'DELETE');
24
+ }
25
+ });
26
+
27
+ function showResults(id, add_return_link) {
28
+ var pollUrl = '/polls/' + id + '/results?return=' + add_return_link;
29
+ $('div#vote-' + id).load(pollUrl);
30
+ }
31
+
32
+ $(document).ready(function() {
33
+ $('a.vote-this').click(function(eventObject) {
34
+ $.put(eventObject.target);
35
+ showResults($(this).attr('data-poll-id'), false);
36
+ return false;
37
+ });
38
+
39
+ $('.show-results').click(function(eventObject) {
40
+ showResults($(this).attr('data-poll-id'), true);
41
+ return false;
42
+ });
43
+
44
+ });
data/rails/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ gem_root = File.expand_path(File.join(File.dirname(__FILE__), ".."))
2
+ Cms.add_to_rails_paths gem_root
3
+ Cms.add_generator_paths gem_root, "db/migrate/[0-9]*_*.rb"
4
+ Cms.add_generator_paths gem_root, "public/bcms/polling/**/*"
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), '/../../test_helper')
2
+
3
+ class Cms::PollResponsesControllerTest < ActionController::TestCase
4
+
5
+ test "Add_test_here" do
6
+
7
+ end
8
+
9
+
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), '/../../test_helper')
2
+
3
+ class Cms::PollsControllerTest < ActionController::TestCase
4
+
5
+ test "Add_test_here" do
6
+
7
+ end
8
+
9
+
10
+
11
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class PollResponsesControllerTest < ActionController::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class PollsControllerTest < ActionController::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'performance_test_help'
3
+
4
+ # Profiling results for each test method are written to tmp/performance.
5
+ class BrowsingTest < ActionController::PerformanceTest
6
+ def test_homepage
7
+ get '/'
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
3
+ require 'test_help'
4
+
5
+ class ActiveSupport::TestCase
6
+ # Transactional fixtures accelerate your tests by wrapping each test method
7
+ # in a transaction that's rolled back on completion. This ensures that the
8
+ # test database remains unchanged so your fixtures don't have to be reloaded
9
+ # between every test method. Fewer database queries means faster tests.
10
+ #
11
+ # Read Mike Clark's excellent walkthrough at
12
+ # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
13
+ #
14
+ # Every Active Record database supports transactions except MyISAM tables
15
+ # in MySQL. Turn off transactional fixtures in this case; however, if you
16
+ # don't care one way or the other, switching from MyISAM to InnoDB tables
17
+ # is recommended.
18
+ #
19
+ # The only drawback to using transactional fixtures is when you actually
20
+ # need to test transactions. Since your test is bracketed by a transaction,
21
+ # any transactions started in your code will be automatically rolled back.
22
+ self.use_transactional_fixtures = true
23
+
24
+ # Instantiated fixtures are slow, but give you @david where otherwise you
25
+ # would need people(:david). If you don't want to migrate your existing
26
+ # test cases which use the @david style and don't mind the speed hit (each
27
+ # instantiated fixtures translates to a database query per test method),
28
+ # then set this back to true.
29
+ self.use_instantiated_fixtures = false
30
+
31
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
32
+ #
33
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
34
+ # -- they do not yet inherit this setting
35
+ fixtures :all
36
+
37
+ # Add more helper methods to be used by all tests here...
38
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class PollResponsesHelperTest < ActionView::TestCase
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class PollsHelperTest < ActionView::TestCase
4
+ end
@@ -0,0 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), '/../../test_helper')
2
+
3
+ class PollResponseTest < ActiveSupport::TestCase
4
+
5
+ test "should be able to create new block" do
6
+ assert PollResponse.create!(:answer=>"Non-blank")
7
+ end
8
+
9
+ end
@@ -0,0 +1,41 @@
1
+ require File.join(File.dirname(__FILE__), '/../../test_helper')
2
+
3
+ class PollTest < ActiveSupport::TestCase
4
+
5
+ test "should be able to create new block" do
6
+ assert Poll.create!(:question=>"A?")
7
+ end
8
+
9
+
10
+ test "Should have responses" do
11
+ p = Poll.create!(:question=>"What color?")
12
+
13
+ p.responses << PollResponse.create!(:answer=>"Red")
14
+ p.responses << PollResponse.create!(:answer=>"Blue")
15
+
16
+ found = Poll.find(p.id)
17
+ assert_equal 2, p.responses.size
18
+
19
+ end
20
+
21
+ test "Should have responses unpublished" do
22
+ p = Poll.create!(:question=>"What color?")
23
+
24
+ p.responses << PollResponse.create!(:answer=>"Red")
25
+ p.responses << PollResponse.create!(:answer=>"Blue")
26
+
27
+ found = Poll.find(p.id)
28
+ found = found.as_of_draft_version
29
+ assert_equal 2, p.responses.size
30
+
31
+ end
32
+
33
+ test "Binding responses as nested attributes for new object" do
34
+ poll = Poll.create!(:question=>"Are you different?")
35
+ poll.update_attributes({ :responses_attributes=>{"0"=>{"answer"=>"Answer 1"}}})
36
+ assert_equal 1, poll.responses.size
37
+ assert_equal 1, PollResponse.count
38
+
39
+ end
40
+
41
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bcms_polling
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - BrowserMedia
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-17 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Allows for user feedback via short polling questions.
23
+ email: github@browsermedia.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - LICENSE.txt
30
+ - README.markdown
31
+ files:
32
+ - COPYRIGHT.txt
33
+ - LICENSE.txt
34
+ - README.markdown
35
+ - Rakefile
36
+ - VERSION
37
+ - app/controllers/cms/polls_controller.rb
38
+ - app/controllers/polling_controller.rb
39
+ - app/helpers/cms/polls_helper.rb
40
+ - app/models/poll.rb
41
+ - app/models/poll_response.rb
42
+ - app/views/cms/polls/_form.html.erb
43
+ - app/views/cms/polls/render.html.erb
44
+ - app/views/polling/results.html.erb
45
+ - db/migrate/20110216195733_create_polls.rb
46
+ - doc/README_FOR_APP
47
+ - lib/bcms_polling.rb
48
+ - lib/bcms_polling/routes.rb
49
+ - public/bcms/polling/README
50
+ - public/bcms/polling/bcms-polling.css
51
+ - public/bcms/polling/bcms-polling.js
52
+ - rails/init.rb
53
+ - test/functional/cms/poll_responses_controller_test.rb
54
+ - test/functional/cms/polls_controller_test.rb
55
+ - test/functional/poll_responses_controller_test.rb
56
+ - test/functional/polls_controller_test.rb
57
+ - test/performance/browsing_test.rb
58
+ - test/test_helper.rb
59
+ - test/unit/helpers/poll_responses_helper_test.rb
60
+ - test/unit/helpers/polls_helper_test.rb
61
+ - test/unit/models/poll_response_test.rb
62
+ - test/unit/models/poll_test.rb
63
+ has_rdoc: true
64
+ homepage: http://browsercms.org
65
+ licenses: []
66
+
67
+ post_install_message:
68
+ rdoc_options: []
69
+
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project: browsercms
93
+ rubygems_version: 1.3.7
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: A Polling Module for BrowserCMS
97
+ test_files:
98
+ - test/functional/cms/poll_responses_controller_test.rb
99
+ - test/functional/cms/polls_controller_test.rb
100
+ - test/functional/poll_responses_controller_test.rb
101
+ - test/functional/polls_controller_test.rb
102
+ - test/performance/browsing_test.rb
103
+ - test/test_helper.rb
104
+ - test/unit/helpers/poll_responses_helper_test.rb
105
+ - test/unit/helpers/polls_helper_test.rb
106
+ - test/unit/models/poll_response_test.rb
107
+ - test/unit/models/poll_test.rb