28 |
29 |
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Johannes Schildgen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/poll/script.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | get_poll();
3 | })
4 |
5 | COLORS = ["success", "danger", "warning", "primary"];
6 |
7 | current_qid = null;
8 |
9 | function get_poll() {
10 | $.get( "./api/?method=get_poll", function( data ) {
11 | if(!('question' in data)) { // no quiz active
12 | $('#question').html('- currently no poll running -');
13 | $('#answers').hide();
14 | } else if(current_qid == data.qid) { // current question
15 | return;
16 | } else { // new question
17 | current_qid = data.qid;
18 | $('#question').html(data.question);
19 | $('#answers').html('');
20 | for(i in data.answers) {
21 | $('#answers').append(
22 | ' ');
25 | }
26 | $('#answers').show();
27 | window.navigator.vibrate(200);
28 | }
29 | });
30 | }
31 |
32 | function respond(aid) {
33 | $('#answers > button').prop('disabled', true);
34 | $('#answers > button')[aid].innerHTML = '→ '+$('#answers > button')[aid].innerHTML+' ←';
35 | $.get( "./api/?method=respond&aid="+aid, function( data ) { });
36 | }
37 |
38 | window.setInterval(function(){
39 | get_poll();
40 | }, 3000);
41 |
--------------------------------------------------------------------------------
/poll/poll.css:
--------------------------------------------------------------------------------
1 | .poll {
2 | display: none;
3 | position: absolute;
4 | right:-160px;
5 | bottom:-151px;
6 | width: 10cm;
7 | background-clip: padding-box;
8 | border: 1px solid rgba(0,0,0,.2);
9 | border-radius: 6px;
10 | outline: 0;
11 | box-shadow: 0 3px 9px rgba(0,0,0,.5);
12 | background-color: #fff;
13 | }
14 |
15 | .poll > h1 {
16 | min-height: 16.43px;
17 | padding: 15px;
18 | border-bottom: 1px solid #e5e5e5;
19 | font-size: 24px;
20 | margin-top: 0px;
21 | margin-bottom: 0px;
22 | }
23 |
24 | .poll > ul {
25 | display: block;
26 | padding: 15px;
27 | margin: 0;
28 | }
29 |
30 | .poll > ul > li {
31 | display: inline-block;
32 | font-size: 18px;
33 | text-align: center;
34 | color:#fff !important;
35 | text-decoration: none !important;
36 | padding:14px 60px;
37 | line-height:1;
38 | overflow: hidden;
39 | position:relative;
40 | width: -webkit-fill-available;
41 | cursor: pointer;
42 |
43 | box-shadow:0 1px 1px #ccc;
44 | border-radius: 6px;
45 |
46 | background-color: #aaa;
47 | background-image:-webkit-linear-gradient(top, #aaa, #aaa);
48 | background-image:-moz-linear-gradient(top, #aaa, #aaa);
49 | background-image:linear-gradient(top, #aaa, #aaa);
50 | }
51 |
52 | .poll > ul > li > .poll-percentage {
53 | display: block;
54 | height: 100%;
55 | border-radius: 2px;
56 | bottom: 0;
57 | left: 0;
58 | position: absolute;
59 | z-index: 1;
60 | transition: width 0.5s, height 0.5s;
61 | width: 100%;
62 | }
63 |
64 | .poll > ul > li:nth-child(4n+1) > .poll-percentage {
65 | background-color: #5cb85c;
66 | }
67 | .poll > ul > li:nth-child(4n+2) > .poll-percentage {
68 | background-color: #d9534f;
69 | }
70 | .poll > ul > li:nth-child(4n+3) > .poll-percentage {
71 | background-color: #f0ad4e;
72 | }
73 | .poll > ul > li:nth-child(4n+4) > .poll-percentage {
74 | background-color: #428bca;
75 | }
76 |
77 | .poll > ul > li > .poll-answer-text {
78 | z-index: 2;
79 | position:relative;
80 | }
81 |
82 | .poll > h2 {
83 | padding: 6px;
84 | border-top: 1px solid #e5e5e5;
85 | font-size:18px;
86 | margin-bottom: 1px;
87 | }
88 |
89 | .poll > .poll-responses {
90 | position: absolute;
91 | top: 3px;
92 | right: 8px;
93 | font-size: 18px;
94 | }
95 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # reveal.js-poll-plugin
2 | Plugin for embedding polls / quizzes into reveal.js presentations
3 |
4 | ## General Information
5 |
6 | The poll plugin consists of three parts:
7 |
8 | 1. reveal.js plugin to show a poll and the result within the slides
9 | 1. mobile website for end users to participate in the poll
10 | 1. API server and SQLite database to manage the poll data
11 |
12 | When a slide is shown that has a poll, the audience can open the mobile website and vote. When the presenter clicks on one of the answers, the poll is finished and the result is shown on the slides as a bar chart. All the time, when there is at least one response, the number of participations is shown on the top right corner of the poll.
13 |
14 | 
15 |
16 | 
17 |
18 | ## Files
19 |
20 | - index.php Mobile web site for end users to participate in the poll
21 | - script.js Javascript logic for the mobile web site
22 | - poll.css Stylesheet for reveal.js
23 | - poll.js reveal.js Plugin
24 | - api/index.php PHP script that handles API requests (start/stop poll, respond, ...)
25 | - api/poll.db SQLite database that stores the questions, answers and responses
26 |
27 | ## Installation and Usage
28 |
29 | ### Server
30 |
31 | The web server that hosts the API and the database requires PHP and php-sqlite3. The same server can be used to host the mobile website.
32 |
33 | 1. Move the content of the `poll` folder to the root directory of the server, let's call it http://example.com for now
34 | 1. Make the folder `api` and the database file `api/poll.db` writable (777)
35 | 1. Test the API with http://example.com/api, it should show "No method"
36 | 1. Test the mobile website with http://example.com, it should show "currently no poll running"
37 | 1. Test the API again: http://example.com/api/?method=start_poll&data={"question":"Test","answers":["X","Y","Z"],"correct_answers":["B"]}, it should show `{"OK":true}`
38 | 1. Test the mobile website again: http://example.com, It should show the question "Test" and three answers.
39 |
40 | ### Presentation Client
41 |
42 | The presentation client needs a PHP-enabled web server to forward API requests to the server. It's also possible that the presentation client is the same machine as the web server.
43 |
44 | 1. Move the content of the `poll` folder to the reveal.js presentation directory
45 | 1. Write the URL to the server into poll.js
46 | 1. Include the CSS in your slides: ``
47 | 1. Add the jQuery library (download from https://jquery.com, unzip, load: ``)
48 | 1. Initialize reveal.js with the following dependency: `{ src: 'poll/poll.js', async: true }`
49 | 1. Add polls to your slides:
50 |
51 | ```
52 |