Advertisement
Guest User

Untitled

a guest
Nov 13th, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.15 KB | None | 0 0
  1. (function(jQuery) {
  2. "use strict";
  3.  
  4. function AdvanceFillBlanksGame(instance, options) {
  5. var defaultOptions = {
  6. practiceMode: true,
  7. submitBtn: null,
  8. solutionBtn: null,
  9. retryBtn: null,
  10. sentenceHolder: null,
  11. blank: "###",
  12. template: null,
  13. sentences: [],
  14. showResult: false,
  15. allRequired: false,
  16. highlightEmptyText: false,
  17. showSolutionButton: false,
  18. isBack: false,
  19. response: []
  20. };
  21. this.instance = instance;
  22. this.options = jQuery.extend(true, {}, defaultOptions, options);
  23. this.options.solutionBtn.hide();
  24. this.options.retryBtn.hide();
  25. if (this.options.practiceMode) {
  26. this.options.submitBtn.hide();
  27. }
  28. this.$el = jQuery(this.instance);
  29. this.data = [];
  30. this.currentData = {};
  31. this.response = [];
  32. this.index = 0;
  33. this.wordIndex = 0;
  34. this.totalBlanks = 0;
  35. this.init();
  36. }
  37. AdvanceFillBlanksGame.prototype = {
  38. init: function() {
  39. var self = this;
  40. self.setupData();
  41. self.display();
  42. self.setupEventListeners();
  43. if (self.options.isBack) {
  44. self.showResponse();
  45. }
  46. },
  47. showResponse: function() {
  48. let self = this;
  49. for (let i = 0, j = self.options.response.length; i < j; i++) {
  50. let q = self.options.response[i];
  51. let $question = jQuery(
  52. ".advance-fill-question[data-id='" + q.id + "']"
  53. );
  54. let keys = Object.keys(q.answer);
  55. for (const key of keys) {
  56. let $input = jQuery($question).find(
  57. '.answer-input[data-c="' + key + '"]'
  58. );
  59. $input.val(q.answer[key].value);
  60. if (self.options.practiceMode) {
  61. if (q.answer[key].correct) {
  62. $input.closest(".input-holder").addClass("correct");
  63. } else {
  64. $input.closest(".input-holder").addClass("incorrect");
  65. }
  66. }
  67. }
  68. }
  69. },
  70. setupEventListeners: function() {
  71. var self = this;
  72. var element = $("#gameBody");
  73.  
  74. element
  75. .attr("unselectable", "on")
  76. .css("user-select", "none")
  77. .on("selectstart dragstart", false);
  78. jQuery(document).on("blur keydown", ".answer-input", function(e) {
  79. var keyCode = 0;
  80. if (e.type == "keydown") {
  81. jQuery(this)
  82. .removeClass("empty")
  83. .closest(".input-holder")
  84. .removeClass("incorrect correct");
  85. keyCode = e.keyCode ? e.keyCode : e.which;
  86. self.options.solutionBtn.hide();
  87. }
  88. if (keyCode == 13 || e.type == "focusout") {
  89. e.stopPropagation();
  90. if (self.options.practiceMode) {
  91. self.checkAnswer(this);
  92. }
  93. }
  94. });
  95. self.options.solutionBtn.on("click", function() {
  96. self.showSolution();
  97. self.options.solutionBtn.hide();
  98. self.options.retryBtn.show();
  99. });
  100. self.options.retryBtn.on("click", function() {
  101. self.resetInputs();
  102. self.options.solutionBtn.hide();
  103. self.options.retryBtn.hide();
  104. });
  105. self.options.submitBtn.on("click", function() {
  106. var $inputs = jQuery(".answer-input");
  107. if (self.options.highlightEmptyText) {
  108. var $empties = $inputs
  109. .filter(function() {
  110. return this.value.trim().length == 0;
  111. })
  112. .addClass("empty");
  113. }
  114.  
  115. if (self.options.allRequired && $empties.length > 0) {
  116. return;
  117. }
  118. self.response = [];
  119. var $questions = jQuery(".advance-fill-question");
  120. var $question, $input;
  121. for (var i = 0, j = $questions.length; i < j; i++) {
  122. $question = jQuery($questions[i]);
  123. $input = $question.find(".answer-input");
  124.  
  125. var q_i = $question.attr("data-i");
  126. var question = self.data[q_i].data;
  127.  
  128. var ans = {};
  129. for (var x = 0, y = $input.length; x < y; x++) {
  130. var $a = jQuery($input[x]);
  131.  
  132. if (self.options.showResult) {
  133. self.checkAnswer($a);
  134. }
  135.  
  136. var val = $a.val();
  137. var a_i = $a.attr("data-i");
  138. var correct_answers = question[a_i].word;
  139. var correct = false;
  140. jQuery.each(correct_answers, function(i, word) {
  141. if (val === word) {
  142. correct = true;
  143. }
  144. });
  145.  
  146. ans[$a.attr("data-c")] = { value: val, correct: correct };
  147. }
  148. self.response.push({
  149. id: $question.attr("data-id"),
  150. answer: ans
  151. });
  152. }
  153. if (self.showResult) $inputs.attr("disabled", true);
  154. // jQuery(this)
  155. // .off()
  156. // .attr("disabled", true);
  157. self.gameComplete();
  158. });
  159. },
  160. gameComplete: function() {
  161. let self = this;
  162. let r = { skipped: false, correct: true };
  163. for (let i = 0, j = self.response.length; i < j; i++) {
  164. let a = self.response[i].answer;
  165. let ak = Object.keys(a);
  166. for (let x = 0, y = ak.length; x < y; x++) {
  167. if (a[x].value.length == 0) {
  168. r.skipped = true;
  169. r.correct = false;
  170. break;
  171. }
  172. if (a[x].correct == false) {
  173. r.correct = false;
  174. }
  175. }
  176. }
  177.  
  178. self.$el.trigger("gameComplete", [self.response, self.data, r]);
  179. },
  180. resetInputs: function() {
  181. var self = this;
  182. jQuery(".feedback").remove();
  183. self.$el
  184. .find(".answer-input")
  185. .removeClass("attempted solution")
  186. .attr("disabled", false)
  187. .val("");
  188. self.$el.find(".input-holder").removeClass("correct incorrect");
  189. },
  190. showSolution: function() {
  191. var self = this;
  192. var $inputs = self.$el.find(".answer-input");
  193. self.resetInputs();
  194. for (var i = 0, j = $inputs.length; i < j; i++) {
  195. var $input = jQuery($inputs[i]);
  196. var $question = $input.closest(".advance-fill-question");
  197. var q_i = $question.attr("data-i");
  198. var a_i = $input.attr("data-i");
  199. var question = self.data[q_i].data;
  200. var answers = question[a_i].word;
  201. $input.val(answers[0]).attr("disabled", true);
  202. $input.addClass("solution");
  203. }
  204. },
  205. checkAnswer: function(ref) {
  206. var self = this;
  207. var $input = jQuery(ref);
  208. var $inputHolder = $input.closest(".input-holder");
  209. var val = $input.val();
  210. val = val.replace(/\s\s+/g, " ").toLowerCase();
  211. if (val.length > 0 || self.options.showResult) {
  212. jQuery(".feedback").remove();
  213. var $question = $input.closest(".advance-fill-question");
  214. var q_i = $question.attr("data-i");
  215. var a_i = $input.attr("data-i");
  216. var question = self.data[q_i].data;
  217. var answers = question[a_i].word;
  218. var correct = false;
  219. jQuery.each(answers, function(i, word) {
  220. word = word.toLowerCase();
  221. if (val === word) {
  222. correct = true;
  223. }
  224. });
  225. if (correct) {
  226. $inputHolder.removeClass("incorrect").addClass("correct");
  227. $input.off().attr("disabled", true);
  228. } else {
  229. $inputHolder.removeClass("correct").addClass("incorrect");
  230. var feedbacks = question[a_i].feedback;
  231. self.showFeedback($input, val, feedbacks);
  232. }
  233. $input.addClass("attempted");
  234. } else {
  235. $input.removeClass("attempted");
  236. $inputHolder.removeClass("incorrect");
  237. }
  238.  
  239. self.checkCompletion();
  240. },
  241. showFeedback: function($input, val, feedbacks) {
  242. var feedback, regex;
  243. for (var i = 0, j = feedbacks.length; i < j; i++) {
  244. feedback = feedbacks[i];
  245. regex = RegExp(feedback.test);
  246. if (regex.test(val)) {
  247. $input
  248. .closest(".advance-fill-question")
  249. .prepend("<p class='feedback'>" + feedback.msg + "</p>");
  250. }
  251. }
  252. },
  253. display: function() {
  254. var self = this;
  255. var t = self.options.template({
  256. questions: self.data
  257. });
  258. self.$el.html(t);
  259. },
  260. checkCompletion: function() {
  261. var self = this;
  262. if (!self.options.showSolutionButton) return;
  263. var attempted = self.$el.find(".attempted");
  264. if (attempted.length == self.totalBlanks) {
  265. var incorrects = self.$el.find(".incorrect");
  266. if (incorrects.length > 0) {
  267. self.options.solutionBtn.show();
  268. }
  269. }
  270. },
  271. setupData: function() {
  272. var self = this;
  273. var i, j, k, l, tmp, sentence, blank_i;
  274. for (i = 0, j = self.options.sentences.length; i < j; i++) {
  275. sentence = [];
  276. tmp = self.options.sentences[i].sentence.split(self.options.blank);
  277. blank_i = 0;
  278. for (k = 0, l = tmp.length; k < l; k++) {
  279. sentence.push({
  280. word: tmp[k],
  281. blank: false
  282. });
  283. if (k + 1 < l) {
  284. sentence.push({
  285. index: blank_i,
  286. word: self.options.sentences[i].answer[k],
  287. feedback:
  288. jQuery.isArray(self.options.sentences[i].feedback) &&
  289. typeof self.options.sentences[i].feedback[k] !== "undefined"
  290. ? self.options.sentences[i].feedback[k]
  291. : [],
  292. blank: true
  293. });
  294. blank_i++;
  295. self.totalBlanks++;
  296. }
  297. }
  298. self.data.push({ id: self.options.sentences[i].id, data: sentence });
  299. }
  300. self.shuffle(self.data);
  301. },
  302. shuffle: function(array) {
  303. var currentIndex = array.length;
  304. var temporaryValue, randomIndex;
  305. while (0 !== currentIndex) {
  306. randomIndex = Math.floor(Math.random() * currentIndex);
  307. currentIndex -= 1;
  308. temporaryValue = array[currentIndex];
  309. array[currentIndex] = array[randomIndex];
  310. array[randomIndex] = temporaryValue;
  311. }
  312. return array;
  313. }
  314. };
  315.  
  316. jQuery.fn.AdvanceFillBlanksGame = function(options) {
  317. var args = Array.prototype.slice.call(arguments, 1);
  318. var plgName = "AdvanceFillBlanksGame";
  319. return this.each(function() {
  320. var inst = jQuery.data(this, plgName);
  321. if (typeof inst === "undefined") {
  322. if (
  323. typeof options === "undefined" ||
  324. typeof options == "string" ||
  325. options instanceof String
  326. ) {
  327. throw "invalid options passed while creating new instance.";
  328. }
  329. if (
  330. typeof options.sentences === "undefined" ||
  331. !jQuery.isArray(options.sentences)
  332. ) {
  333. throw "invalid options";
  334. }
  335. if (typeof options.template !== "function") {
  336. throw "template should be compiled handlebars template";
  337. }
  338. var p = new AdvanceFillBlanksGame(this, options);
  339. jQuery.data(this, plgName, p);
  340. } else if (typeof options !== "undefined") {
  341. if (typeof inst[options] === "function") {
  342. inst[options].apply(inst, args);
  343. }
  344. }
  345. });
  346. };
  347. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement