PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/app/javascript/shared-package/goal-new.js

https://gitlab.com/gregtyka/server
JavaScript | 390 lines | 321 code | 59 blank | 10 comment | 64 complexity | bf00322a50758b1ef1bfe67c217f275f MD5 | raw file
  1. var GoalCreator = {
  2. objectives: [],
  3. videosAreInit: false,
  4. init: function() {
  5. $(window).resize($.proxy(this.resize, this));
  6. $("#create-goal .goal-title")
  7. .focus(function() { $(this).animate({width: "600px"});})
  8. .blur(function() { $(this).animate({width: "250px"});})
  9. .placeholder();
  10. var form = $("#create-goal");
  11. form.find("input").mouseup(function() { $(this).removeClass("fieldError"); });
  12. form.find('input[name="title"]')
  13. .change(function() { GoalCreator.updateViewAndDescription(); })
  14. .keypress(function(e) {
  15. if (e.which == "13") { // enter
  16. e.preventDefault();
  17. $(e.target).blur();
  18. }
  19. });
  20. GoalCreator.updateViewAndDescription();
  21. },
  22. getCurrentObjectives: function() {
  23. if ($(".create-goal-page").parent().data("target")) {
  24. // this goal is targeted at some other user,
  25. // so the current-objectives are of no use to us
  26. return {};
  27. }
  28. var list = {};
  29. $.each(GoalBook.models, function(idx, model) {
  30. $.each(model.get("objectives"), function(idx2, objective) {
  31. list[objective.internal_id] = true;
  32. });
  33. });
  34. return list;
  35. },
  36. initCatalog: function() {
  37. $("#goal-choose-videos")
  38. .on("click", ".vl", function(e) {
  39. // prevent the href navigation from occuring
  40. e.preventDefault();
  41. var jel = $(e.currentTarget);
  42. var href = jel.attr("href");
  43. if (typeof href === "undefined") {
  44. return;
  45. }
  46. var type = href.indexOf("/video")==0 ? "video" : href.indexOf("/exercise")==0 ? "exercise" : "url";
  47. var span = jel.children("span");
  48. var name = jel.attr("data-id");
  49. var title = span.text();
  50. GoalCreator.onClicked(name, title, type);
  51. });
  52. if ($(".create-goal-page").parent().data("target")) {
  53. // this goal is targeted at some other user,
  54. // so the completed objectives are of no use to us
  55. return;
  56. }
  57. $("#goal-choose-videos .vl").each(function(i, element) {
  58. var jel = $(element);
  59. var span = jel.children("span");
  60. var image = $(span).css("background-image");
  61. if (image.indexOf("indicator-complete") >= 0) {
  62. jel.addClass("goalVideoInvalid");
  63. jel.removeAttr("href");
  64. }
  65. });
  66. },
  67. // reset window state
  68. reset: function() {
  69. GoalCreator.objectives = [];
  70. $('#create-goal input[name="title"]').val("");
  71. GoalCreator.updateCount();
  72. GoalCreator.updateViewAndDescription();
  73. GoalCreator.showCatalog();
  74. },
  75. toggleObjectiveInternal: function(type, css, id, name) {
  76. var idx = 1;
  77. var found_index = -1;
  78. $("#goal-commit-response").hide();
  79. $.each(GoalCreator.objectives, function(index, objective) {
  80. if (objective.type == type && objective.id == id) {
  81. found_index = index;
  82. }
  83. if (objective.idx >= idx)
  84. idx = objective.idx + 1;
  85. });
  86. if (found_index >= 0) {
  87. // Remove objective
  88. var objective = GoalCreator.objectives[found_index];
  89. GoalCreator.objectives.splice(found_index, 1);
  90. return null;
  91. } else if (GoalCreator.objectives.length < 10) {
  92. var newObjective = {
  93. type: type,
  94. css: css,
  95. description: name,
  96. progress: 0,
  97. url: "javascript:GoalCreator.onSelectedObjectiveClicked('" +
  98. type + "', '" + css + "', '" + id + "', '" + name + "');",
  99. idx: idx,
  100. id: id
  101. };
  102. GoalCreator.objectives.push(newObjective);
  103. return newObjective;
  104. }
  105. },
  106. updateViewAndDescription: function() {
  107. var goalObject = {
  108. title: $("#create-goal").find('input[name="title"]').val(),
  109. objectives: GoalCreator.objectives
  110. };
  111. var view = Templates.get("shared.goal-create")(goalObject);
  112. $("#create-goal-view").html(view);
  113. if (GoalCreator.objectives.length < 2) {
  114. $("#create-goal-view .goal").addClass("with-border");
  115. } else {
  116. $("#create-goal-view .goal").removeClass("with-border");
  117. }
  118. if (GoalCreator.objectives.length === 0) {
  119. $("#goal-info-section > .goal-description").remove();
  120. }
  121. if (GoalCreator.objectives.length > 0 && $("#goal-info-section").children(".goal-description").length === 0) {
  122. $("#create-goal-view .goal .goal-description").remove().insertAfter("#create-goal-view");
  123. }
  124. if (GoalCreator.objectives.length >= 1) {
  125. $("#create-goal-view .goal .goal-description").remove();
  126. }
  127. if (GoalCreator.objectives.length > 1) {
  128. $("#create-goal-view .goal li.objective").css("width", 100 / GoalCreator.objectives.length + "%");
  129. $("#create-goal-view .goal li.objective").last().children("a").css("border-right", "none");
  130. }
  131. var message = "";
  132. if (GoalCreator.objectives.length === 0) {
  133. message = "טרם בחרתם מטרות ליעד זה. בחרו <b>עד 10</b> תרגילים או סרטונים למטה.";
  134. } else {
  135. var matchingObjectives;
  136. message = "בכדי להשלים יעד זה, עליכם <ul>";
  137. // Exercises
  138. matchingObjectives = [];
  139. var hadExercises = false;
  140. $.each(GoalCreator.objectives, function(idx, objective) {
  141. if (objective.type == "GoalObjectiveExerciseProficiency")
  142. matchingObjectives.push(objective);
  143. });
  144. if (matchingObjectives.length > 0) {
  145. hadExercises = true;
  146. message += "<li class='exercise-objectives'>להשיג מיומנות בתרגיל";
  147. if (matchingObjectives.length == 1) {
  148. message += " <em>" + matchingObjectives[0].description + "</em>";
  149. } else {
  150. message += "ים ";
  151. $.each(matchingObjectives, function(idx, objective) {
  152. if (idx === 0)
  153. message += "<em>" + objective.description + "</em>";
  154. else if (idx < matchingObjectives.length - 1)
  155. message += ", <em>" + objective.description + "</em>";
  156. else
  157. message += " ו<em>" + objective.description + "</em>";
  158. });
  159. }
  160. message += "</li>";
  161. }
  162. // Videos
  163. matchingObjectives = [];
  164. $.each(GoalCreator.objectives, function(idx, objective) {
  165. if (objective.type == "GoalObjectiveWatchVideo")
  166. matchingObjectives.push(objective);
  167. });
  168. if (matchingObjectives.length > 0) {
  169. if (hadExercises) {
  170. message += ", ו"
  171. }
  172. message += "<li class='video-ojectives'>לצפות בסרט";
  173. if (matchingObjectives.length == 1) {
  174. message += " <em>" + matchingObjectives[0].description + "</em>";
  175. } else {
  176. message += "ים ";
  177. $.each(matchingObjectives, function(idx, objective) {
  178. if (idx === 0)
  179. message += "<em>" + objective.description + "</em>";
  180. else if (idx < matchingObjectives.length - 1)
  181. message += ", <em>" + objective.description + "</em>";
  182. else
  183. message += " ו<em>" + objective.description + "</em>";
  184. });
  185. }
  186. message += ".</li>";
  187. }
  188. message += "</ul>";
  189. }
  190. $(".create-goal-page .goal-description").html(message);
  191. this.resize();
  192. },
  193. resize: function() {
  194. var content = $("#goal-choose-videos .dashboard-content-stretch");
  195. var container = $(".goal-new-custom.modal");
  196. var containerHeight = container.outerHeight(true);
  197. var yTopPadding = content.offset().top - container.offset().top;
  198. var yBottomPadding = 30; // magic numbers ahoy
  199. var newHeight = containerHeight - (yTopPadding + yBottomPadding);
  200. content.height(newHeight);
  201. },
  202. onClicked: function(id, title, type) {
  203. if (id in GoalCreator.getCurrentObjectives())
  204. return; // Cannot select videos that are objectives in current goals
  205. if (type === "exercise") {
  206. GoalCreator.toggleObjectiveInternal("GoalObjectiveExerciseProficiency", "exercise", id, title);
  207. } else if (type === "video") {
  208. GoalCreator.toggleObjectiveInternal("GoalObjectiveWatchVideo", "video", id, title);
  209. } else {
  210. GoalCreator.toggleObjectiveInternal("GoalObjectiveVisitURL", "url", id, title);
  211. }
  212. GoalCreator.updateCount();
  213. GoalCreator.updateViewAndDescription();
  214. },
  215. showCatalog: function() {
  216. if (!GoalCreator.videosAreInit) {
  217. GoalCreator.videosAreInit = true;
  218. GoalCreator.initCatalog();
  219. }
  220. $("#goal-choose-videos").show();
  221. this.resize();
  222. for (var readableId in GoalCreator.getCurrentObjectives()) {
  223. $('.vl[data-id="' + readableId + '"]')
  224. .addClass("goalVideoInvalid")
  225. .removeAttr("href");
  226. }
  227. },
  228. updateCount: function() {
  229. var count = 0;
  230. $.each(GoalCreator.objectives, function(index, objective) {
  231. if (objective.type == "GoalObjectiveWatchVideo")
  232. count++;
  233. });
  234. $("#goal-video-count").html(count);
  235. $.each(GoalCreator.objectives, function(index, objective) {
  236. if (objective.type == "GoalObjectiveExerciseProficiency")
  237. count++;
  238. });
  239. $("#goal-exercise-count").html(count);
  240. $("#library-content-main").find(".vl").each(function(index, element) {
  241. var obj_id = $(element).attr("data-id");
  242. var found = false;
  243. $.each(GoalCreator.objectives, function(index2, objective) {
  244. if (objective.id == obj_id)
  245. {
  246. found = true;
  247. }
  248. });
  249. var goalIcon = $(element).children(".video-goal-icon");
  250. if (found)
  251. {
  252. if (goalIcon.length === 0)
  253. $('<span class="video-goal-icon"><img src="/images/flag.png"></span>')
  254. .insertBefore($(element).children("span")[0]);
  255. }
  256. else
  257. {
  258. goalIcon.detach();
  259. }
  260. });
  261. },
  262. onSelectedObjectiveClicked: function(type, css, name, id) {
  263. GoalCreator.toggleObjectiveInternal(type, css, name, id);
  264. GoalCreator.updateCount();
  265. GoalCreator.updateViewAndDescription();
  266. },
  267. validate: function(form) {
  268. var error = "";
  269. if (GoalCreator.objectives.length < 2)
  270. {
  271. error = "יש לבחור לפחות שתי משימות.";
  272. }
  273. if (error !== "") {
  274. $("#goal-commit-response").html(error).show();
  275. return false;
  276. }
  277. return true;
  278. },
  279. submit: function() {
  280. var form = $("#create-goal");
  281. var html = "";
  282. if (!GoalCreator.validate(form))
  283. return;
  284. var titleField = form.find('input[name="title"]');
  285. if (titleField.val() === "" || titleField.val() === titleField.attr("placeholder"))
  286. {
  287. var d = new Date();
  288. titleField.val("יעד מותאם אישית: " + d.getDate() + "/" + (d.getMonth()+1) + "/" + d.getFullYear());
  289. }
  290. var target = $(".create-goal-page").parent().data("target");
  291. var goal = new Goal({
  292. target: target,
  293. title: titleField.val(),
  294. objectives: _.map(GoalCreator.objectives, function(o) {
  295. var newObj = {
  296. type: o.type,
  297. internal_id: o.id,
  298. description: o.description
  299. };
  300. newObj.url = Goal.objectiveUrl(newObj);
  301. return newObj;
  302. })
  303. });
  304. // if this goal is not targeted to another user/student-list
  305. if (!target) {
  306. GoalBook.add(goal);
  307. }
  308. goal.save()
  309. .success(function(jqXHR) {
  310. KAConsole.log("Goal creation succeeded");
  311. GoalCreator.trigger("created", jqXHR)
  312. })
  313. .fail(function(jqXHR) {
  314. KAConsole.log("Goal creation failed: " + jqXHR.responseText, goal);
  315. if (!target) {
  316. GoalBook.remove(goal);
  317. }
  318. hideGenericMessageBox();
  319. popupGenericMessageBox({
  320. title: "אופס...",
  321. message: "חלה שגיאה כשניסינו ליצור את היעדים החדשים.</br>אנא נסו שנית, ואם השגיאה חוזרת דווחו לנו!" +
  322. "<div style='direction: ltr'>\"" + jqXHR.responseText + "\"</div>",
  323. popup_class: "rtl"
  324. });
  325. });
  326. newCustomGoalDialog.hide();
  327. GoalCreator.reset();
  328. return false;
  329. }
  330. };
  331. _.extend(GoalCreator, Backbone.Events);