/learn-portlet/src/main/webapp/js2.0/content-manager/entities.js

https://github.com/ViLPy/JSCORM · JavaScript · 488 lines · 442 code · 35 blank · 11 comment · 17 complexity · 3bae56d8596a2d6221ea6eec345a841a MD5 · raw file

  1. /**
  2. * Created by igorborisov on 21.04.15.
  3. */
  4. contentManager.module("Entities", function (Entities, contentManager, Backbone, Marionette, $, _) {
  5. var CategoryService = new Backbone.Service({
  6. url: path.root,
  7. targets: {
  8. 'move': {
  9. 'path': path.api.category,
  10. 'data': function (model, options) {
  11. return {
  12. action: 'move',
  13. id: model.get('id'),
  14. parentId: options.parentId,
  15. index: options.index,
  16. courseId: model.get('courseId')
  17. };
  18. },
  19. 'method': 'post'
  20. },
  21. 'getChildren': {
  22. 'path': path.api.category,
  23. 'data': function (model) {
  24. return {
  25. parentId: model.get('id'),
  26. courseId: model.get('courseId')
  27. };
  28. },
  29. 'method': 'get'
  30. },
  31. 'getContentAmount': {
  32. 'path': path.api.category,
  33. 'method': 'get',
  34. 'data': function (model, options) {
  35. return {
  36. 'action': 'CONTENTAMOUNT',
  37. 'parentId': model.get('id'),
  38. 'courseId': model.get('courseId')
  39. };
  40. }
  41. }
  42. },
  43. sync: {
  44. 'read': {
  45. 'path': path.api.category,
  46. 'data': function (model) {
  47. var params = {
  48. parentId: model.get('id'),
  49. courseId: model.get('courseId')
  50. };
  51. return params;
  52. },
  53. 'method': 'get'
  54. },
  55. 'create': {
  56. 'path': path.api.category,
  57. 'data': function (model) {
  58. var params = {
  59. action: 'add'
  60. };
  61. _.extend(params, model.toJSON());
  62. return params;
  63. },
  64. 'method': 'post'
  65. },
  66. 'update': {
  67. 'path': path.api.category,
  68. 'data': function (model) {
  69. var params = {
  70. action: 'update'
  71. };
  72. _.extend(params, model.toJSON());
  73. return params;
  74. },
  75. 'method': 'post'
  76. },
  77. 'delete': {
  78. 'path': path.api.category,
  79. 'data': function (model) {
  80. var params = {
  81. action: 'delete',
  82. id: model.get('id'),
  83. courseId: model.get('courseId')
  84. };
  85. return params;
  86. },
  87. 'method': 'post'
  88. }
  89. }
  90. });
  91. var ContentItemsService = new Backbone.Service({
  92. url: path.root,
  93. sync: {
  94. 'read': {
  95. 'path': path.api.category,
  96. 'data': function (collection, options) {
  97. var params = {
  98. action: 'ALLCHILDREN',
  99. parentId: options.parentId,
  100. courseId: options.courseId || Utils.getCourseId()
  101. };
  102. return params;
  103. },
  104. 'method': 'get'
  105. }
  106. }
  107. });
  108. var QuestionType = {
  109. "ChoiceQuestion": 0,
  110. "ShortAnswerQuestion": 1,
  111. "NumericQuestion": 2,
  112. "PositioningQuestion": 3,
  113. "MatchingQuestion": 4,
  114. "EssayQuestion": 5,
  115. "EmbeddedAnswerQuestion": 6,
  116. "CategorizationQuestion": 7,
  117. "PlainText": 8,
  118. "PurePlainText": 9
  119. };
  120. var QuestionAnswerType = {
  121. "ChoiceQuestion": Entities.ChoiceAnswer,
  122. "ShortAnswerQuestion": Entities.ShortAnswer,
  123. "NumericQuestion": Entities.NumericAnswer,
  124. "PositioningQuestion": Entities.PositioningAnswer,
  125. "MatchingQuestion": Entities.MatchingAnswer,
  126. "CategorizationQuestion": Entities.CategorizationAnswer
  127. };
  128. var QuestionService = new Backbone.Service({
  129. url: path.root,
  130. targets: {
  131. 'move': {
  132. 'path': path.api.questions,
  133. 'method': 'post',
  134. 'data': function (model, options) {
  135. return {
  136. 'action': 'move',
  137. 'id': model.get('id'),
  138. 'parentID': options.parentId,
  139. 'index': options.index,
  140. 'courseId': model.get('courseId')
  141. };
  142. }
  143. }
  144. },
  145. sync: {
  146. 'read': {
  147. 'path': function (model) {
  148. return path.api.questions + model.id;
  149. },
  150. 'data': function (model) {
  151. var params = {
  152. 'action': 'getById',
  153. 'courseId': model.get('courseId')
  154. };
  155. return params;
  156. },
  157. 'method': 'get'
  158. },
  159. 'create': {
  160. 'path': path.api.questions,
  161. 'data': function (model) {
  162. var params = {
  163. 'action': 'add'
  164. };
  165. _.extend(params, model.toJSON());
  166. return params;
  167. },
  168. 'method': 'post'
  169. },
  170. 'update': {
  171. 'path': function (model) {
  172. return path.api.questions + model.get('id');
  173. },
  174. 'data': function (model) {
  175. var params = {
  176. 'action': 'update'
  177. };
  178. _.extend(params, model.toJSON());
  179. return params;
  180. },
  181. 'method': 'post'
  182. },
  183. 'delete': {
  184. 'path': function (model) {
  185. return path.api.questions + model.get('id');
  186. },
  187. 'data': function (model) {
  188. var params = {
  189. 'action': 'delete',
  190. 'courseId': model.get('courseId')
  191. };
  192. return params;
  193. },
  194. 'method': 'post'
  195. }
  196. }
  197. });
  198. //Answers
  199. Entities.AnswerModel = Backbone.Model.extend({});
  200. Entities.AnswerModelCollection = Backbone.Collection.extend({
  201. model: Entities.AnswerModel
  202. });
  203. Entities.ChoiceAnswer = Entities.AnswerModel.extend({
  204. defaults: {
  205. answerText: '',
  206. isCorrect: false,
  207. score: null
  208. }
  209. });
  210. Entities.ShortAnswer = Entities.AnswerModel.extend({
  211. defaults: {
  212. answerText: '',
  213. score: null
  214. }
  215. });
  216. Entities.NumericAnswer = Entities.AnswerModel.extend({
  217. defaults: {
  218. rangeFrom: 0,
  219. rangeTo: 0,
  220. score: null
  221. }
  222. });
  223. Entities.PositioningAnswer = Entities.AnswerModel.extend({
  224. defaults: {
  225. answerText: '',
  226. isCorrect: false,
  227. score: null
  228. }
  229. });
  230. Entities.MatchingAnswer = Entities.AnswerModel.extend({
  231. defaults: {
  232. answerText: '',
  233. matchingText: '',
  234. score: null
  235. }
  236. });
  237. Entities.CategorizationAnswer = Entities.AnswerModel.extend({
  238. defaults: {
  239. answerText: '',
  240. matchingText: '',
  241. score: null
  242. }
  243. });
  244. Entities.Category = Backbone.Model.extend({
  245. defaults: {
  246. title: '',
  247. description: '',
  248. parentId: null,
  249. arrangementIndex: 0,
  250. contentType: 'category',
  251. selected: false,
  252. courseId: ''
  253. }
  254. }).extend(CategoryService);
  255. Entities.Question = Backbone.Model.extend({
  256. defaults: {
  257. title: '',
  258. text: '',
  259. explanationText: '',
  260. wrongAnswerText: '',
  261. rightAnswerText: '',
  262. questionType: QuestionType.ChoiceQuestion,
  263. categoryID: null,
  264. forceCorrectCount: false,
  265. isCaseSensitive: false,
  266. answers: '[]',
  267. type: '',
  268. contentType: 'question',
  269. selected: false,
  270. courseId: ''
  271. },
  272. initialize: function () {
  273. this.updateAnswerModel();
  274. this.on('change', this.updateAnswerModel, this);
  275. this.on('sync', this.updateAnswerModel, this);
  276. this.set('type', this.getStringType());
  277. this.on('change:questionType', function () {
  278. this.set('type', this.getStringType());
  279. }, this);
  280. },
  281. getStringType: function () {
  282. switch (parseInt(this.get('questionType'))) {
  283. case QuestionType.ChoiceQuestion:
  284. return 'Choice question';
  285. break;
  286. case QuestionType.ShortAnswerQuestion:
  287. return 'Short answer question';
  288. break;
  289. case QuestionType.NumericQuestion:
  290. return 'Numeric question';
  291. break;
  292. case QuestionType.PositioningQuestion:
  293. return 'Positioning question';
  294. break;
  295. case QuestionType.MatchingQuestion:
  296. return 'Matching question';
  297. break;
  298. case QuestionType.EssayQuestion:
  299. return 'Essay question';
  300. break;
  301. case QuestionType.EmbeddedAnswerQuestion:
  302. return 'Embedded question';
  303. break;
  304. case QuestionType.CategorizationQuestion:
  305. return 'Categorization question';
  306. break;
  307. case QuestionType.PlainText:
  308. return 'Plain text';
  309. break;
  310. case QuestionType.PurePlainText:
  311. return 'Plain text';
  312. break;
  313. default:
  314. return '';
  315. }
  316. },
  317. updateAnswerModel: function () {
  318. switch (this.get('questionType')) {
  319. case QuestionType.ChoiceQuestion:
  320. this.answerModel = QuestionAnswerType.ChoiceQuestion;
  321. break;
  322. case QuestionType.ShortAnswerQuestion:
  323. this.answerModel = QuestionAnswerType.ShortAnswerQuestion;
  324. break;
  325. case QuestionType.NumericQuestion:
  326. this.answerModel = QuestionAnswerType.NumericQuestion;
  327. break;
  328. case QuestionType.PositioningQuestion:
  329. this.answerModel = QuestionAnswerType.PositioningQuestion;
  330. break;
  331. case QuestionType.MatchingQuestion:
  332. this.answerModel = QuestionAnswerType.MatchingQuestion;
  333. break;
  334. case QuestionType.CategorizationQuestion:
  335. this.answerModel = QuestionAnswerType.CategorizationQuestion;
  336. break;
  337. default:
  338. this.answerModel = null;
  339. }
  340. },
  341. getParentId: function () {
  342. return this.get('categoryID');
  343. }//,
  344. //idAttribute: 'uniqueId'
  345. }).extend(QuestionService);
  346. Entities.TreeNode = {
  347. //defaults: {
  348. // title: '',
  349. // arrangementIndex: 0,
  350. // nodes: [],
  351. // parentId: ''
  352. //},
  353. idAttribute: 'uniqueId',
  354. getParentId: function () {
  355. },
  356. isNode: function () {
  357. return true;
  358. },
  359. isLeaf: function () {
  360. return true;
  361. },
  362. getDescendants: function () {
  363. var models = [];
  364. var children = this.nodes.models;
  365. models = models.concat(children);
  366. _(children).each(function (child) {
  367. if (child.isNode()) {
  368. var descendants = child.getDescendants();
  369. if (descendants.length) {
  370. models = models.concat(descendants);
  371. }
  372. }
  373. });
  374. return models;
  375. },
  376. getChild: function (filter) {
  377. return _.filter(this.getDescendants(), filter)[0] || {}
  378. },
  379. getChildNode: function (id) {
  380. return _.filter(this.getDescendants(), function (item) {
  381. return item.get('id') == id && item.isNode();
  382. })[0] || {};
  383. },
  384. fetchChildren: function () {
  385. }
  386. };
  387. Entities.TreeNodes = Backbone.Collection.extend({
  388. model: Entities.TreeNode,
  389. comparator: function (a, b) {
  390. if (a.isNode() && b.isLeaf()) {
  391. return -1;
  392. } else if (a.isLeaf() && b.isNode()) {
  393. return 1;
  394. }
  395. var arrangementIndexA = a.get('arrangementIndex');
  396. var arrangementIndexB = b.get('arrangementIndex');
  397. return arrangementIndexA - arrangementIndexB;
  398. },
  399. idAttribute: 'uniqueId'
  400. });
  401. Entities.TreeContentItems = Entities.TreeNodes.extend({
  402. model: function (attrs, options) {
  403. switch (attrs.contentType) {
  404. case 'category' :
  405. return new Entities.TreeCategory(attrs, options);
  406. case 'question' :
  407. return new Entities.TreeQuestion(attrs, options);
  408. }
  409. },
  410. idAttribute: "uniqueId",
  411. hasChildNodes: function () {
  412. return this.some(function (item) {
  413. return item.isNode();
  414. });
  415. }
  416. }).extend(ContentItemsService);
  417. Entities.TreeQuestion = Entities.Question.extend(Entities.TreeNode).extend({
  418. isNode: function () {
  419. return false;
  420. },
  421. getParentId: function () {
  422. return this.get('categoryID');
  423. }
  424. });
  425. Entities.TreeCategory = Entities.Category.extend(Entities.TreeNode).extend({
  426. getParentId: function () {
  427. return this.get('parentId');
  428. },
  429. initialize: function (args) {
  430. var that = this;
  431. this.nodes = new Entities.TreeContentItems(args.children);
  432. this.nodes.on('add', function () {
  433. that.updateContentAmount();
  434. });
  435. this.nodes.on('remove', function () {
  436. that.updateContentAmount();
  437. });
  438. this.nodes.on('change:childrenAmount', function () {
  439. that.updateContentAmount();
  440. });
  441. },
  442. updateContentAmount: function () {
  443. var that = this;
  444. this.getContentAmount().then(function (data) {
  445. that.set('childrenAmount', data || 0);
  446. });
  447. },
  448. fetchChildren: function () {
  449. this.updateContentAmount();
  450. return this.nodes.fetch({parentId: this.get('id') || '', courseId: this.get('courseId'), reset: true});
  451. }
  452. });
  453. });