Guest User

Untitled

a guest
Jan 16th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.88 KB | None | 0 0
  1. <!DOCTYPE html>
  2.  
  3. <!-- ************************************************************* -->
  4.  
  5. <!--!
  6.  
  7. Filename: gist.3a = quizBank.html
  8. _ _
  9. | | | |
  10. ___ | |_ | | __
  11. / __| | __| | |/ /
  12. | (__ | |_ | <
  13. \___| \__| |_|\_\
  14.  
  15. CTK = Contacts Toolkit
  16.  
  17. Built for performance; is responsive & small in file size.
  18. Above means: all comments+whitespace removed. CS/JS minified.
  19. Toolbox = Gulp, Plain JavaScript & more. Hosted on Google Cloud.
  20.  
  21. Unless otherwise noted, copyright 2018-2019 CTK, LLC. All rights reserved.
  22. If questions, feedback or you would like to hire us: email info@contactstoolkit.com
  23.  
  24. -->
  25.  
  26. <html>
  27. <head>
  28. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  29. <link href="/css/pure.min.css" rel="stylesheet" media="screen" type="text/css">
  30. <title></title>
  31. </head>
  32.  
  33. <body>
  34.  
  35. <div class="container-fluid">
  36. <div id="quiz"></div>
  37. </div>
  38.  
  39. <script src="/js/zepto.min.js"></script>
  40. <script src="/js/tabletop.min.js"></script>
  41.  
  42. <script>
  43. (function($) {
  44. function score (nCorrect, nQuestions) {
  45. var answersWord = nCorrect === 1 ? 'answer' : 'answers';
  46. var html = '<div id=\'summaryBox\'>' +
  47. '<div id=\'summaryTop\'>Select answer</div>' +
  48. '<div id=\'summaryScore\'><p>Current score: <span class="correct-answers">' + nCorrect + '</span> of ' + nQuestions + ' correct</div></div>' +
  49. '<div id=\'buttonNext\'><p><button style="">Next</button></div>' +
  50. '</div>';
  51. return html;
  52. }
  53. function scores(nQuestions) {
  54. var ret = [];
  55. for (var i = 0; i <= nQuestions; i++) {
  56. ret.push(score(i, nQuestions));
  57. }
  58. return ret;
  59. }
  60. $.quiz = function(quiz_data, results_data, options) {
  61. var container_elem;
  62. var self;
  63. var cover;
  64. var cheater_answer_tracking = [];
  65. var answer_tracking = [];
  66. var how_you_did_element;
  67. var right_answers = 0;
  68. var oneByOne = false;
  69. var onFinish;
  70.  
  71. var quiz = {
  72. defaulting_behavior_on : true,
  73. defaulting_flag : '!default',
  74. container : 'quiz',
  75. not_finished_html : undefined,
  76. cheating : false,
  77. possible_display_elements : [
  78. {
  79. name : 'backgroundimage',
  80. finder: function(container) {
  81. return container.find('.' + this.name);
  82. },
  83. create_element : function(slide) {
  84. if (!slide[this.name]) {return '';}
  85. return $('<div class="' + this.name + '" style="background-image: url(\'' +
  86. slide[this.name] + '\'); height: 100%; width: 100%;position:absolute;z-index: -1"></div>');
  87. }
  88. },
  89. {
  90. name : 'topimage',
  91. finder: function(container) {
  92. return container.find('.' + this.name);
  93. },
  94. create_element : function(slide) {
  95. if (!slide[this.name]) {return '';}
  96. return $('<img src="' + slide[this.name] + '" class="img-responsive' + this.name + '"></img>');
  97. }
  98. },
  99. {
  100. name : 'title',
  101. finder: function(container) {
  102. return container.find('.' + this.name);
  103. },
  104. create_element : function(slide) {
  105. if (!slide[this.name]) {return '';}
  106. return $('<h3 class="' + this.name + '">' + slide[this.name] + '</h3>' );
  107. }
  108. },
  109. {
  110. name : 'middleimage',
  111. finder: function(container) {
  112. return container.find('.' + this.name);
  113. },
  114. create_element : function(slide) {
  115. if (!slide[this.name]) {return '';}
  116. return $('<img src="' + slide[this.name] + '" class="img-responsive ' + this.name + '"></img>');
  117. }
  118. },
  119. {
  120. name : 'subhed',
  121. finder: function(container) {
  122. return container.find('.' + this.name);
  123. },
  124. create_element : function(slide) {
  125. if (!slide[this.name]) {return '';}
  126. return $('<h2 class="' + this.name + '">' + slide[this.name] + '</h2>');
  127. }
  128. },
  129. {
  130. name : 'text',
  131. finder: function(container) {
  132. return container.find('.' + this.name);
  133. },
  134. create_element : function(slide) {
  135. if (!slide[this.name]) {return '';}
  136. return $('<p class="' + this.name + '">' + slide[this.name] + '</p>');
  137. }
  138. },
  139. {
  140. name : 'bottomimage',
  141. finder: function(container) {
  142. return container.find('.' + this.name);
  143. },
  144. create_element : function(slide) {
  145. if (!slide[this.name]) {return '';}
  146. return $('<img src="' + slide[this.name] + '" class="img-responsive ' + this.name + '"></img>');
  147. }
  148. }
  149. ],
  150. init : function(quiz_data, results_data, options) {
  151. self = this;
  152. if (options) {
  153. for ( var option in options ) {
  154. self[option] = options[option];
  155. }
  156. }
  157. if (typeof(quiz_data) === 'string') {
  158. self.load_from_google_spreadsheet(quiz_data);
  159. } else {
  160. if (!results_data) {
  161. results_data = scores(quiz_data.length);
  162. }
  163. self.init_data(quiz_data, results_data);
  164. }
  165. return self;
  166. },
  167. init_data: function(quiz_data, results_data) {
  168. self.quiz_data = quiz_data;
  169. self.results_data = results_data;
  170. self.calculate_aspectratios(quiz_data);
  171. self.create_cover();
  172. for ( var i = 0; i < self.quiz_data.length; i++ ) {
  173. self.append_question(i);
  174. }
  175. self.append_how_you_did_section();
  176. self.update_how_you_did_element();
  177. },
  178. append_how_you_did_section: function() {
  179. how_you_did_element = $('<p class="how_you_did"></p>');
  180. cover.append(how_you_did_element);
  181. },
  182. setHowYouDidTriggers : function () {
  183. $('.how_you_did button').on('click', function () {
  184. $('.question_container:not(.hidden)').addClass('hidden').next().removeClass('hidden');
  185. if ($('.question_container:not(.hidden)').length == 0) {
  186.  
  187. var elem1 = document.getElementById("summaryTop");
  188. elem1.remove();
  189.  
  190. var elem2 = document.getElementById("summaryScore");
  191. elem2.remove();
  192.  
  193. var elem3 = document.getElementById("buttonNext");
  194. elem3.remove();
  195. var target = document.querySelector('#summaryBox');
  196. var div = document.createElement('div');
  197. div.innerHTML = '<div id=\'finalScore\' style="color:white;><p>FINAL score: <span class="correct-answers">' + self.right_answers + '</span> of ' + self.quiz_data.length + ' correct</div></div>';
  198. target.parentNode.insertBefore( div, target.nextSibling );
  199. }
  200. });
  201. },
  202. cleanCells : function (cells) {
  203. for (k in cells) {
  204. if (cells[k] == " ") {
  205. cells[k] = "";
  206. }
  207. }
  208. return cells;
  209. },
  210. load_from_google_spreadsheet: function(spreadsheet_id) {
  211. Tabletop.init({
  212. proxy: this.proxy ? this.proxy : undefined,
  213. key: spreadsheet_id,
  214. prettyColumnNames: false,
  215. callback: function(data) {
  216. var quiz_data = self.make_quiz_data_from_spreadsheet_data(data);
  217. var results_data = self.make_results_data_from_spreadsheet_data(data, quiz_data);
  218. self.init_data(quiz_data, results_data);
  219. }
  220. });
  221. },
  222. calculate_aspectratios: function(data) {
  223. for (var i = 0; i < data.length; i++) {
  224. var row = data[i];
  225. for (var k = 0; k < row.possible_answers.length; k++) {
  226. var answer = row.possible_answers[k];
  227. self.find_aspectratio_for_each_type_of_video_embed(answer);
  228. }
  229. self.find_aspectratio_for_each_type_of_video_embed(row.question);
  230. }
  231. },
  232. find_aspectratio_for_each_type_of_video_embed : function(slide) {
  233. for (var i = 0; i < self.possible_display_elements.length; i++ ) {
  234. var display = self.possible_display_elements[i];
  235. if ( display.needs_aspect_ratio && slide[display.name] ) {
  236. slide[display.name + 'aspectratio'] =
  237. self.find_aspectratio(slide[display.name]);
  238. }
  239. }
  240. },
  241. find_aspectratio: function(videoembed) {
  242. var height = videoembed.match(/height="\d+"/);
  243. if (!height || !height[0]) {
  244. return '';
  245. }
  246. height = parseInt(height[0].replace(/height="/, '').replace(/"/, ''), 10);
  247.  
  248. var width = videoembed.match(/width="\d+"/);
  249. if (!width || !width[0]) {
  250. return '';
  251. }
  252. width = parseInt(width[0].replace(/width="/, '').replace(/"/, ''), 10);
  253. return (height / width)*100;
  254. },
  255. pull_answer_value_from_spreadsheet : function(row, value, wrong_number, correct) {
  256. correct = correct ? 'right' : 'wrong';
  257. if (row[correct + wrong_number + value] && row[correct + wrong_number + value] !== self.defaulting_flag) {
  258. return (row[correct + wrong_number + value]);
  259. }
  260.  
  261. if ((self.defaulting_behavior_on && row[correct + wrong_number + value] !== self.defaulting_flag) ||
  262. (!self.defaulting_behavior_on && row[correct + wrong_number + value] === self.defaulting_flag)
  263. ) {
  264. return (row[correct + value] && row[correct + value] !== self.defaulting_flag ? row[correct + value] :
  265. (row['answer' + value] && row['answer' + value] !== self.defaulting_flag ?
  266. row['answer' + value] : row['question' + value] )
  267. );
  268. } else {
  269. return '';
  270. }
  271. },
  272. get_possible_answers : function(row, is_correct) {
  273. var possible_answers = [];
  274. var right_or_wrong = (is_correct ? 'right' : 'wrong');
  275. if (row[right_or_wrong]) {
  276. possible_answers.push(self.make_possible_answer(row, '', is_correct));
  277. }
  278. for (var i = 0; i < 10; i++ ) {
  279. if (row[right_or_wrong + i]) {
  280. possible_answers.push(self.make_possible_answer(row, i, is_correct));
  281. }
  282. }
  283. return possible_answers;
  284. },
  285. make_possible_answer: function(row, row_number, is_correct) {
  286. var right_or_wrong = (is_correct ? 'right' : 'wrong');
  287. var answer = {
  288. answer: row[right_or_wrong + row_number],
  289. correct: is_correct
  290. };
  291. for (var i = 0; i < self.possible_display_elements.length; i++ ) {
  292. var display_element = self.possible_display_elements[i].name;
  293. answer[display_element] = self.pull_answer_value_from_spreadsheet(
  294. row, display_element, row_number, is_correct
  295. );
  296. }
  297. return answer;
  298. },
  299. make_quiz_data_from_spreadsheet_data: function(tabletop) {
  300. var i, j, sheetName, data;
  301. var quiz = [];
  302. for (sheetName in tabletop) {
  303. if (tabletop.hasOwnProperty(sheetName) && sheetName !== 'Results') {
  304. break;
  305. }
  306. }
  307. data = tabletop['<a_test_file>'].elements;
  308. for (i = 0; i < data.length; i++) {
  309. var row = row = self.cleanCells(data[i]);
  310. var possible_wrong_answers = self.get_possible_answers(row, false);
  311. var possible_right_answers = self.get_possible_answers(row, true);
  312. var right_answer_placement = [];
  313. for (j = 0; j < possible_right_answers.length; j++) {
  314. right_answer_placement.push(
  315. Math.round(Math.random() * possible_wrong_answers.length)
  316. );
  317. }
  318. right_answer_placement.sort();
  319. var possible_answers= [];
  320. var right_answers_placed = 0;
  321. for (j = 0; j <= possible_wrong_answers.length; j++) {
  322. while (j === right_answer_placement[right_answers_placed]) {
  323. possible_answers.push(possible_right_answers[right_answers_placed]);
  324. right_answers_placed++;
  325. }
  326. if (j === possible_wrong_answers.length) {
  327. continue;
  328. }
  329. possible_answers.push(possible_wrong_answers[j]);
  330. }
  331. var question = {
  332. question : {
  333. },
  334. possible_answers : possible_answers,
  335. rowNumber : row.rowNumber - 1
  336. };
  337. for (j = 0; j < self.possible_display_elements.length; j++) {
  338. var display_value = self.possible_display_elements[j].name;
  339. question.question[display_value] = row['question' + display_value];
  340. }
  341. quiz.push(question);
  342. }
  343. return quiz;
  344. },
  345. make_results_data_from_spreadsheet_data: function(tabletop, quiz_data) {
  346. var ret = scores(quiz_data.length);
  347. var data = tabletop['Results'] ? tabletop['Results'].elements : [];
  348. for (var i = 0; i < data.length; i++) {
  349. var index = data[i].numberofrightanswers;
  350. if (index) { index = parseInt(index, 10); }
  351. if (!isNaN(index)) {
  352. if (!ret[index]) {
  353. console.log("invalid" + index);
  354. } else {
  355. ret[index] = data[i].html;
  356. }
  357. }
  358. }
  359. return ret;
  360. },
  361. append_question : function(question_index) {
  362. var question_data = self.quiz_data[question_index],
  363. hidden = "";
  364.  
  365. if (question_index != 0 && self.oneByOne) {
  366. hidden = 'hidden';
  367. }
  368. var question_container = $('<div class="question_container '+ hidden +' row-fluid question_' + question_index + '"></div>');
  369. var qNumber = question_index+1;
  370. question_container.append('<h3 class=\'title\' style="padding:10px"> Question ' +qNumber+ '</h3><hr>');
  371. question_container.append( self.build_question_element_from_row(question_data) );
  372. question_container.append( self.build_possible_answer_elements_from_row(question_data, question_index) );
  373. container_elem.append(question_container);
  374. },
  375. build_question_element_from_row: function(row) {
  376. var question_container = $('<div class="question show" style="overflow: hidden; position: relative; padding: 10px; width:95%;"></div>');
  377. for (var i = 0; i < self.possible_display_elements.length; i++) {
  378. question_container.append(self.possible_display_elements[i].create_element(row.question)
  379. );
  380. }
  381. return question_container;
  382. },
  383. build_possible_answer_elements_from_row : function(question, question_index) {
  384. var answers_container = $('<ul id=possibleAnswers class="list-unstyled possible_answers possible_answers_' + question_index + '"></ul>');
  385. function bindClick(question_index, answer_index, possible_answer) {
  386. possible_answer.bind('click', function() {
  387. var was_correct = self.quiz_data[question_index].possible_answers[answer_index].correct;
  388. var qNumber = question_index+1;
  389. var qStatus = was_correct;
  390. var qTitle = JSON.stringify(self.quiz_data[question_index].question.title);
  391. google.script.run.qDetails(qNumber, qTitle, qStatus);
  392. answers_container.find('.selected').removeClass('selected');
  393. $(this).addClass('selected');
  394. $(this).removeClass('possible_answer');
  395. answers_container
  396. .find('.answer_' + answer_index)
  397. .addClass(
  398. was_correct ? 'correct-answer' : 'wrong-answer'
  399. );
  400. var elemAnswers = document.getElementById("possibleAnswers");
  401. elemAnswers.remove();
  402. cheater_answer_tracking[question_index] = was_correct;
  403. if ( typeof(answer_tracking[question_index]) === 'undefined' ) {
  404. answer_tracking[question_index] = was_correct;
  405. cover.find('.question_' + question_index).addClass(
  406. 'first_guess_' +
  407. (was_correct ? 'right' : 'wrong')
  408. );
  409. }
  410. self.update_how_you_did_element();
  411. self.display_answer(self.quiz_data[question_index], question_index, self.quiz_data[question_index].possible_answers[answer_index]);
  412. self.quiz_data[question_index].previously_selected = self.quiz_data[question_index].possible_answers[answer_index];
  413. });
  414. }
  415. for (var i = 0; i < question.possible_answers.length; i++) {
  416. var answer_data = question.possible_answers[i];
  417. var possible_answer = $('<li><p class="bg-warning possible_answer answer_' + i + '">' + answer_data.answer + '</p></li>');
  418. bindClick(question_index, i, possible_answer);
  419. answers_container.append(possible_answer);
  420. }
  421. return answers_container;
  422. },
  423. add_display_in_correct_place: function(container, place_in_display_elements, slide) {
  424. for ( var i = place_in_display_elements; i > 0; i-- ) {
  425. if (self.possible_display_elements[i - 1].finder(container).length ) {
  426. self.possible_display_elements[i - 1].finder(container)
  427. .after( self.possible_display_elements[place_in_display_elements].create_element(slide) );
  428. return;
  429. }
  430. }
  431. container.prepend(
  432. self.possible_display_elements[place_in_display_elements].create_element(slide)
  433. );
  434. },
  435. display_answer : function(question, question_index, answer) {
  436. var displayed_slide = question.previously_selected ?
  437. question.previously_selected :
  438. question.question;
  439. var slide = container_elem.find('.question_' + question_index + ' .question');
  440. slide.addClass('revealed_answer');
  441. for (var i = 0; i < self.possible_display_elements.length; i++) {
  442. var display_value = self.possible_display_elements[i].name;
  443. if ( answer[display_value] !== displayed_slide[display_value] ) {
  444. if ( !answer[display_value] ) {
  445. self.possible_display_elements[i].finder(slide).remove();
  446. } else if ( !displayed_slide[display_value] ) {
  447. self.add_display_in_correct_place(slide, i, answer);
  448. } else {
  449. self.possible_display_elements[i].finder(slide).before(
  450. self.possible_display_elements[i].create_element( answer )
  451. ).remove();
  452. }
  453. }
  454. }
  455. },
  456. create_cover : function() {
  457. cover = $('#' + self.container);
  458. container_elem = $('<ul></ul>');
  459. cover.append(container_elem);
  460. container_elem.addClass('quiz');
  461. container_elem.css('padding', '0px');
  462. },
  463. update_how_you_did_element: function() {
  464. self.right_answers = 0;
  465. var user_answers = self.cheating ? cheater_answer_tracking : answer_tracking;
  466. var unfinished = false;
  467. for (var i = 0; i < self.quiz_data.length; i++) {
  468. if (typeof(answer_tracking[i]) === 'undefined') {
  469. unfinished = true;
  470. }
  471. if (user_answers[i]) {
  472. self.right_answers++;
  473. }
  474. }
  475. var html;
  476. if (unfinished && typeof(this.not_finished_html) !== 'undefined') {
  477. html = this.not_finished_html;
  478. } else {
  479. html = this.results_data[self.right_answers];
  480. }
  481. how_you_did_element.html(html);
  482.  
  483. if (self.oneByOne) {
  484. self.setHowYouDidTriggers();
  485. }
  486. }
  487. };
  488. return quiz.init(quiz_data, results_data, options);
  489. };
  490. $.fn.quiz = function(quiz_data, results_data, options) {
  491. if (!options) { options = results_data; results_data = null; }
  492. if (!options) { options = {}; }
  493. options.container = this.attr('id');
  494. this.quiz = $.quiz(quiz_data, results_data, options);
  495. return this;
  496. };
  497. })(Zepto);
  498. </script>
  499.  
  500. <script type="text/javascript">
  501. var quiz = $('#quiz').quiz('<a_google_spreadsheeet>', { oneByOne: "aName" });
  502. $(document).mouseleave(function () {
  503. google.script.run.mouseOffPage();
  504. });
  505. </script>
  506.  
  507. </body>
  508. </html>
Add Comment
Please, Sign In to add comment