mark-board.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. //给分板模块
  2. var mark_board = function(option, success) {
  3. var object = new MarkBoard(option);
  4. success();
  5. return object;
  6. }
  7. function MarkBoard(option) {
  8. this.markControl = option.markControl;
  9. this.timeoutSecond = 0.4;
  10. this.needConfirm = option.needConfirm === true ? true : false;
  11. this.autoSubmit = option.autoSubmit === false ? false : true;
  12. this.enableSkip = option.enableSkip === true ? true : false;
  13. this.init(this.markControl.option.forceSpecialTag);
  14. this.markControl.on('task.get.before', this, function(event, context, eventObject) {
  15. this.task = undefined;
  16. this.stepList = undefined;
  17. this.currentStep = undefined;
  18. this.stepCount = undefined;
  19. this.render();
  20. });
  21. this.markControl.on('task.load.finish', this, function(event, context, eventObject) {
  22. this.initByTask(context.task);
  23. });
  24. this.markControl.on('mark.focus.change', this, function(event, context, eventObject) {
  25. this.onFocusChange();
  26. });
  27. this.markControl.on('special.tag.enable', this, function(event, context, eventObject) {
  28. this.specialTag=true;
  29. });
  30. this.markControl.on('special.tag.disable', this, function(event, context, eventObject) {
  31. this.specialTag=false;
  32. });
  33. this.markControl.on('image.click.event', this, function(event, context, track) {
  34. if(track != undefined && this.currentStep != undefined
  35. && this.currentStep.currentScore != undefined
  36. && this.specialTag!=true) {
  37. track.score = this.currentStep.currentScore;
  38. track.questionNumber = this.currentStep.questionNumber;
  39. track.number = this.currentStep.trackList.length + 1;
  40. this.currentStep.trackList.push(track);
  41. this.resetScore();
  42. this.updateStepScore();
  43. this.trySetScore(track.score);
  44. this.markControl.trigger('mark.tag.show', {
  45. content: track.score,
  46. positionX: track.positionX,
  47. positionY: track.positionY
  48. });
  49. }
  50. });
  51. //图片重新加载后,恢复显示所有标记
  52. this.markControl.on('image.reload.event', this, function(event, context, eventObject) {
  53. for(var i = 0; i < this.stepList.length; i++) {
  54. var step = this.stepList[i];
  55. for(var j = 0; j < step.trackList.length; j++) {
  56. this.markControl.trigger('mark.tag.show', {
  57. content: step.trackList[j].score,
  58. positionX: step.trackList[j].positionX,
  59. positionY: step.trackList[j].positionY
  60. });
  61. }
  62. }
  63. });
  64. this.markControl.on('key.press', this, function(e, context, event) {
  65. var code = event.keyCode;
  66. // console.log('key press:' + code);
  67. var self = this;
  68. if (this.currentStep != undefined && this.task != undefined) {
  69. if (code >= 48 && code <= 57) {
  70. this.onNumberInput(code - 48);
  71. event.preventDefault();
  72. return false;
  73. } else if (code >= 96 && code <= 105 && event.numLock) {
  74. this.onNumberInput(code - 96);
  75. event.preventDefault();
  76. return false;
  77. } else if (code == 46 || code == 110 || code == 190) {
  78. //小数点
  79. this.onNumberInput('.');
  80. event.preventDefault();
  81. return false;
  82. }
  83. }
  84. });
  85. this.markControl.on('key.up', this, function(e, context, event) {
  86. var code = event.keyCode;
  87. //console.log('key up:' + code);
  88. var self = this;
  89. if (this.currentStep != undefined && this.task != undefined) {
  90. if (code == 37) {
  91. //← 按键,切换到上一个步骤
  92. if (this.currentStep.number > 1) {
  93. self.onStepSelect(this.currentStep.number - 1);
  94. event.preventDefault();
  95. return false;
  96. }
  97. } else if (code == 39) {
  98. // →按键,切换到下一个步骤
  99. if (this.currentStep.number < this.stepCount ) {
  100. self.onStepSelect(this.currentStep.number + 1);
  101. event.preventDefault();
  102. return false;
  103. }
  104. }
  105. }
  106. });
  107. }
  108. MarkBoard.prototype.init = function(forceSpecialTag) {
  109. var self = this;
  110. this.stepBoard = getDom(this.step_board_dom, this.markControl).appendTo(this.markControl.container.centerContainer);
  111. this.stepBoard.height(this.markControl.container.centerContent.height());
  112. var stepDom = this.stepBoard.find('.step-list');
  113. stepDom.height((this.stepBoard.height() - 153) * 0.5);
  114. this.stepBoard.stepContainer = stepDom.find('ul');
  115. var scoreDom = this.stepBoard.find('.score_board');
  116. scoreDom.height((this.stepBoard.height() - 153) * 0.5);
  117. this.stepBoard.scoreContainer = scoreDom.find('ul');
  118. this.stepBoard.find('.task-submit-button').click(this, function(event) {
  119. self.onTaskSubmit();
  120. });
  121. //给分板上是否显示全零分
  122. if(forceSpecialTag===true){
  123. this.stepBoard.find('.all-zero-button').attr("type","hidden");
  124. }
  125. this.stepBoard.find('.all-zero-button').click(this, function(event) {
  126. self.allZeroSubmit();
  127. });
  128. this.stepBoard.find('.undo-last-track-button').click(this, function() {
  129. if(self.currentStep != undefined && self.currentStep.trackList.length>0) {
  130. self.currentStep.trackList.pop();
  131. self.updateStepScore();
  132. self.refreshTrack();
  133. }
  134. });
  135. this.stepBoard.find('.clear-current-track-button').click(this, function() {
  136. if(self.currentStep != undefined) {
  137. self.currentStep.currentScore = undefined;
  138. self.currentStep.trackList = [];
  139. self.updateStepScore();
  140. self.refreshTrack();
  141. }
  142. });
  143. this.stepBoard.find('.clear-all-track-button').click(this, function() {
  144. if(self.stepList != undefined) {
  145. for(var i = 0; i < self.stepList.length; i++) {
  146. self.stepList[i].currentScore = undefined;
  147. self.stepList[i].trackList = [];
  148. self.updateStepScore(self.stepList[i]);
  149. }
  150. self.refreshTrack();
  151. }
  152. });
  153. }
  154. MarkBoard.prototype.initByTask = function(task) {
  155. this.task = task;
  156. this.stepList = task.markStepList;
  157. this.currentStep = undefined;
  158. this.stepCount = this.stepList != undefined ? this.stepList.length : 0;
  159. task.totalScore = parseFloat(task.totalScore);
  160. var markFinish = true;
  161. var scoreList = task.scoreList != undefined && task.scoreList != '' ? task.scoreList.split(',') : [];
  162. for(var j = 0; j < task.markStepList.length; j++) {
  163. var step = task.markStepList[j];
  164. step.scoreArray = [];
  165. if(step.trackList == undefined) {
  166. step.trackList = [];
  167. }
  168. if(scoreList != undefined && scoreList.length > j) {
  169. step.markScore = parseFloat(scoreList[j]);
  170. step.markFinish = true;
  171. } else {
  172. step.markFinish = false;
  173. markFinish = false;
  174. }
  175. }
  176. task.markFinish = task.totalScore != undefined && markFinish == true;
  177. this.render(task);
  178. this.refreshTrack();
  179. if(this.stepCount > 0) {
  180. this.onStepSelect(1);
  181. }
  182. }
  183. MarkBoard.prototype.render = function(task) {
  184. if(task != undefined) {
  185. var self = this;
  186. this.stepBoard.stepContainer.empty();
  187. this.stepBoard.scoreContainer.empty();
  188. this.stepArray = [];
  189. if(task.markFinish === true) {
  190. this.stepBoard.find('#total-score').html(task.totalScore + '');
  191. } else {
  192. this.stepBoard.find('#total-score').html('');
  193. }
  194. for( var i in task.markStepList) {
  195. var step = task.markStepList[i];
  196. // 初始化步骤列表
  197. var dom = getDom(this.step_dom, this.markControl).appendTo(this.stepBoard.stepContainer);
  198. dom.attr('data-number', step.number);
  199. dom.find('p').html(step.title);
  200. dom.find('h2').html(step.markScore != undefined ? step.markScore : '');
  201. dom.click(function() {
  202. self.onStepSelect($(this).attr('data-number'));
  203. });
  204. this.stepArray.push(dom);
  205. step.dom = dom;
  206. }
  207. } else {
  208. this.stepBoard.stepContainer.empty();
  209. this.stepBoard.scoreContainer.empty();
  210. this.stepArray = [];
  211. this.stepBoard.find('#total-score').html('');
  212. this.stepBoard.find('#subject-score').html('');
  213. this.stepBoard.find('#ObjectiveAndSubjectScore').html('');
  214. }
  215. }
  216. //切换步骤时,重置当前步骤的状态
  217. //若当前分数未提交,则还原之前已给的分数;若之前还未给分,则清空分数显示
  218. MarkBoard.prototype.resetCurrentStep = function() {
  219. var step = this.currentStep;
  220. if (step != undefined) {
  221. if (step.markScore != undefined) {
  222. step.markFinish = true;
  223. step.score = new String(step.markScore);
  224. } else {
  225. step.markFinish = false;
  226. step.score = '';
  227. }
  228. this.markControl.trigger('mark.score.change');
  229. }
  230. }
  231. MarkBoard.prototype.onStepSelect = function(stepNumber) {
  232. if(stepNumber <= this.stepCount && stepNumber > 0) {
  233. var self = this;
  234. // 还是点击当前步骤,不触发任何动作
  235. if(this.currentStep != undefined && this.currentStep.number == stepNumber) {
  236. return;
  237. }
  238. // 修改原step状态
  239. if(this.currentStep != undefined) {
  240. this.currentStep.dom.removeClass('selected');
  241. this.currentStep.currentScore = undefined;
  242. this.currentStep.scoreArray = [];
  243. }
  244. this.currentStep = this.stepList[stepNumber - 1];
  245. this.currentStep.currentScore = undefined;
  246. this.currentStep.scoreArray = [];
  247. this.currentStep.dom.addClass('selected');
  248. this.stepBoard.scoreContainer.empty();
  249. for(var i = 0; i < this.currentStep.scoreList.length; i++) {
  250. var score = this.currentStep.scoreList[i];
  251. var dom2 = getDom(this.score_dom, this.markControl).appendTo(self.stepBoard.scoreContainer);
  252. dom2.find('p').html(score);
  253. dom2.attr('data-score', score);
  254. dom2.attr('data-number', (i + 1));
  255. this.currentStep.scoreArray.push(dom2);
  256. if(this.currentStep.markScore != undefined && score > (this.currentStep.max - this.currentStep.markScore)) {
  257. dom2.hide();
  258. }
  259. dom2.click(function() {
  260. self.onScoreClick($(this).attr('data-number'));
  261. });
  262. }
  263. }
  264. }
  265. MarkBoard.prototype.onNumberInput = function(number) {
  266. var self = this;
  267. if(this.currentStep == undefined){
  268. return;
  269. }
  270. if(this.numberInput == undefined){
  271. this.numberInput = '0';
  272. }
  273. this.numberInput = this.numberInput + number;
  274. if(this.timeoutId != undefined){
  275. clearTimeout(this.timeoutId);
  276. }
  277. this.timeoutId = setTimeout(function(){
  278. self.inputTimeout();
  279. }, this.timeoutSecond * 1000);
  280. }
  281. MarkBoard.prototype.inputTimeout = function() {
  282. if(this.currentStep!=undefined && this.numberInput!=undefined && this.numberInput.length>0){
  283. if(this.numberInput.endWith('.')){
  284. this.numberInput = this.numberInput + '5';
  285. }
  286. this.trySetScore(parseFloat(this.numberInput));
  287. }
  288. this.numberInput=undefined;
  289. this.timeoutId=undefined;
  290. }
  291. MarkBoard.prototype.onScoreClick = function(scoreNumber) {
  292. if(this.task == undefined || this.currentStep == undefined) {
  293. return;
  294. }
  295. for(var i = 0; i < this.currentStep.scoreArray.length; i++) {
  296. var dom = this.currentStep.scoreArray[i];
  297. if(scoreNumber == dom.attr('data-number')) {
  298. if(dom.hasClass('selected')) {
  299. dom.removeClass('selected');
  300. this.currentStep.currentScore = undefined;
  301. } else {
  302. dom.addClass('selected');
  303. this.currentStep.currentScore = parseFloat(dom.attr('data-score'));
  304. }
  305. } else {
  306. dom.removeClass('selected');
  307. }
  308. }
  309. }
  310. MarkBoard.prototype.trySetScore = function(score) {
  311. var scoreNumber = undefined;
  312. if(this.currentStep != undefined && score != undefined) {
  313. for(var i = 0; i < this.currentStep.scoreArray.length; i++) {
  314. var dom = this.currentStep.scoreArray[i];
  315. if(!dom.is(':hidden') && parseFloat(dom.attr('data-score'))==score){
  316. scoreNumber = dom.attr('data-number');
  317. dom.removeClass('selected');
  318. }
  319. }
  320. }
  321. if(scoreNumber!=undefined){
  322. this.onScoreClick(scoreNumber);
  323. }
  324. }
  325. MarkBoard.prototype.resetScore = function() {
  326. if(this.currentStep != undefined) {
  327. for(var i = 0; i < this.currentStep.scoreArray.length; i++) {
  328. this.currentStep.scoreArray[i].removeClass('selected');
  329. }
  330. this.currentStep.currentScore = undefined;
  331. }
  332. }
  333. MarkBoard.prototype.refreshTrack = function() {
  334. if(this.stepList == undefined) {
  335. return;
  336. }
  337. this.markControl.trigger('mark.tag.clear');
  338. }
  339. MarkBoard.prototype.updateStepScore = function(step) {
  340. if(step == undefined) {
  341. step = this.currentStep;
  342. }
  343. if(step == undefined) {
  344. return;
  345. }
  346. var totalScore = undefined;
  347. for(var i = 0; i < step.trackList.length; i++) {
  348. if(totalScore == undefined) {
  349. totalScore = 0;
  350. }
  351. totalScore += parseFloat(step.trackList[i].score);
  352. }
  353. var leftScore = totalScore != undefined ? (step.max - totalScore) : step.max;
  354. for(var i = 0; i < step.scoreArray.length; i++) {
  355. var dom = step.scoreArray[i];
  356. dom.removeClass('selected');
  357. if(parseFloat(dom.attr('data-score')) > leftScore) {
  358. dom.hide();
  359. } else {
  360. dom.show();
  361. if(step.currentScore!=undefined && step.currentScore==parseFloat(dom.attr('data-score'))){
  362. dom.addClass('selected');
  363. }
  364. }
  365. }
  366. if(totalScore != undefined) {
  367. step.markFinish = true;
  368. step.markScore = totalScore;
  369. step.dom.find('h2').html(this.currentStep.markScore);
  370. } else {
  371. step.markFinish = false;
  372. step.markScore = undefined;
  373. step.dom.find('h2').html('');
  374. }
  375. this.updateTotalScore();
  376. }
  377. MarkBoard.prototype.updateTotalScore = function() {
  378. if(this.task != undefined) {
  379. var totalScore = '';
  380. var finish = true;
  381. for(var i = 0; i < this.stepList.length; i++) {
  382. if(this.stepList[i].markScore != undefined) {
  383. if(totalScore == '') {
  384. totalScore = 0;
  385. }
  386. totalScore += this.stepList[i].markScore;
  387. } else {
  388. finish = false;
  389. }
  390. }
  391. this.task.totalScore = totalScore;
  392. this.task.markFinish = finish;
  393. this.stepBoard.find('#total-score').html(totalScore);
  394. }
  395. }
  396. MarkBoard.prototype.allZeroSubmit = function() {
  397. if(this.task != undefined && this.stepList != undefined && this.stepList.length > 0 && confirm('确认要提交全零分吗?')) {
  398. for(var i = 0; i < this.stepList.length; i++) {
  399. this.stepList[i].markFinish = true;
  400. this.stepList[i].markScore = 0;
  401. this.stepList[i].trackList = [];
  402. this.stepList[i].trackList.push({
  403. questionNumber: this.stepList[i].questionNumber,
  404. number: 1,
  405. score: 0,
  406. positionX: 0,
  407. positionY: 0
  408. });
  409. }
  410. this.onTaskSubmit();
  411. }
  412. }
  413. MarkBoard.prototype.onTaskSubmit = function() {
  414. if(this.task == undefined) {
  415. return;
  416. }
  417. var totalScore = 0;
  418. var scoreList = [];
  419. var trackList = [];
  420. var finish = true;
  421. for( var i in this.stepList) {
  422. var score = this.stepList[i].markScore;
  423. var tracks = this.stepList[i].trackList;
  424. if(score != undefined) {
  425. totalScore = totalScore + score;
  426. scoreList.push(score);
  427. } else {
  428. finish = false;
  429. }
  430. if(tracks != undefined) {
  431. trackList = trackList.concat(tracks);
  432. }
  433. }
  434. if(!finish) {
  435. alert('当前任务还有未给分的题,请继续给分');
  436. } else if(!this.needConfirm || confirm('总分为' + totalScore + ', 确认要提交吗?')) {
  437. this.task.totalScore = totalScore;
  438. this.task.scoreList = scoreList.join(',');
  439. this.task.trackList = trackList;
  440. this.markControl.submitTask();
  441. }
  442. }
  443. MarkBoard.prototype.onFocusChange = function() {
  444. this.currentStep = null;
  445. }
  446. MarkBoard.prototype.step_board_dom = '<div class="span3 mark-steps"><div class="step-board">\
  447. <div class="sublist"><p class="fraction">总分 <i id="total-score">5</i></p></div>\
  448. <div class="button">\
  449. <input type="submit" value="全零分" class="btn1 all-zero-button"/>\
  450. <input type="submit" value="提&nbsp;交" class="btn2 task-submit-button"/></div>\
  451. <div class="step-list"><div class="number"><ul></ul></div></div>\
  452. <div class="score_board"><div class="score"><ul></ul></div></div>\
  453. <div class="clear_button">\
  454. <input type="submit" value="回退" class="btn1 undo-last-track-button" />\
  455. <input type="submit" value="清除本题" class="btn1 clear-current-track-button" />\
  456. <!--<input type="submit" value="清除全卷" class="btn1 clear-all-track-button"/></div>-->\
  457. </div></div>';
  458. MarkBoard.prototype.step_dom = '<li><a href="#"><p></p><h2></h2></a></li>';
  459. MarkBoard.prototype.score_dom = '<li><a href="#"><p></p></a></li>';