WritingBoard.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. MWF.xDesktop.requireApp("process.Xform", "$Module", null, false);
  2. /** @class WritingBoard 手写板组件。
  3. * @o2cn 手写板
  4. * @example
  5. * //可以在脚本中获取该组件
  6. * //方法1:
  7. * var writingBoard = this.form.get("name"); //获取组件
  8. * //方法2
  9. * var writingBoard = this.target; //在组件事件脚本中获取
  10. * @extends MWF.xApplication.process.Xform.$Module
  11. * @o2category FormComponents
  12. * @o2range {Process|CMS}
  13. * @hideconstructor
  14. */
  15. MWF.xApplication.process.Xform.WritingBoard = MWF.APPWritingBoard = new Class(
  16. /** @lends MWF.xApplication.process.Xform.WritingBoard# */
  17. {
  18. Implements: [Events],
  19. Extends: MWF.APP$Module,
  20. options: {
  21. "moduleEvents": ["load", "queryLoad", "postLoad","change"]
  22. },
  23. initialize: function (node, json, form, options) {
  24. this.node = $(node);
  25. this.node.store("module", this);
  26. this.json = json;
  27. this.form = form;
  28. this.field = true;
  29. this.fieldModuleLoaded = false;
  30. },
  31. _loadUserInterface: function () {
  32. this.field = true;
  33. this.node.empty();
  34. if (!this.isReadonly()) {
  35. var actionNode = new Element("div").inject(this.node);
  36. actionNode.set({
  37. //"id": this.json.id,
  38. "text": this.json.name || this.json.id,
  39. "styles": this._parseStyles(this.json.actionStyles || {})
  40. });
  41. actionNode.addEvent("click", function () {
  42. this.validationMode();
  43. var d = this._getBusinessData();
  44. if (layout.mobile) {
  45. window.setTimeout(function () {
  46. this.handwriting(d);
  47. }.bind(this), 100)
  48. } else {
  49. this.handwriting(d);
  50. }
  51. }.bind(this));
  52. }
  53. var data = this._getBusinessData();
  54. if (data) {
  55. var img = new Element("img", {
  56. src: MWF.xDesktop.getImageSrc(data)
  57. });
  58. if (this.json.imageStyles) {
  59. img.setStyles(this._parseStyles(this.json.imageStyles));
  60. }
  61. if( !this.json.imageStyles || !this.json.imageStyles["max-width"] ){
  62. img.setStyles({
  63. "max-width": "90%"
  64. })
  65. }
  66. img.inject(this.node);
  67. }
  68. this.fieldModuleLoaded = true;
  69. },
  70. getTextData: function () {
  71. var value = this._getBusinessData() || "";
  72. return {"value": [value], "text": [value]};
  73. },
  74. /**
  75. * @summary 判断组件值是否为空.
  76. * @example
  77. * if( this.form.get('fieldId').isEmpty() ){
  78. * this.form.notice('请进行手写', 'warn');
  79. * }
  80. * @return {Boolean} 值是否为空.
  81. */
  82. isEmpty: function () {
  83. return !this.getData();
  84. },
  85. /**
  86. * 获取手写图片的ID。
  87. * @summary 获取手写图片的ID。
  88. * @example
  89. * var id = this.form.get('fieldId').getData(); //获取手写图片的ID
  90. * var url = MWF.xDesktop.getImageSrc( id ); //获取图片的url
  91. */
  92. getData: function (data) {
  93. return this._getBusinessData() || "";
  94. },
  95. setData: function (data) {
  96. this._setBusinessData(data);
  97. var img = this.node.getElement("img");
  98. if( !data ){
  99. if(img)img.destroy();
  100. return;
  101. }
  102. if (img){
  103. img.set("src", MWF.xDesktop.getImageSrc(data))
  104. }else{
  105. img = new Element("img", {
  106. src: MWF.xDesktop.getImageSrc(data)
  107. }).inject(this.node);
  108. }
  109. if (this.json.imageStyles) {
  110. img.setStyles(this._parseStyles(this.json.imageStyles));
  111. }
  112. if( !this.json.imageStyles || !this.json.imageStyles["max-width"] ){
  113. img.setStyles({
  114. "max-width": "90%"
  115. })
  116. }
  117. },
  118. /**
  119. * @summary 弹出手写板.
  120. * @example
  121. * this.form.get("fieldId").handwriting();
  122. */
  123. handwriting: function () {
  124. if (!this.handwritingNode) this.createHandwriting();
  125. this.handwritingNode.show();
  126. if (layout.mobile) {
  127. this.handwritingNode.setStyles({
  128. "top": "0px",
  129. "left": "0px"
  130. });
  131. } else {
  132. this.handwritingNode.position({
  133. "relativeTo": this.form.app.content || this.form.container,
  134. "position": "center",
  135. "edge": "center"
  136. });
  137. //var p = this.handwritingNode.getPosition(this.form.app.content);
  138. var p = this.handwritingNode.getPosition(this.handwritingNode.getOffsetParent());
  139. var top = p.y;
  140. var left = p.x;
  141. if (p.y < 0) top = 10;
  142. if (p.x < 0) left = 10;
  143. this.handwritingNode.setStyles({
  144. "top": "" + top + "px",
  145. "left": "" + left + "px"
  146. });
  147. }
  148. },
  149. createHandwriting: function () {
  150. /**
  151. * @summary 手写板容器.
  152. * @member {Element}
  153. */
  154. this.handwritingNode = new Element("div", {"styles": this.form.css.handwritingNode}).inject(this.node, "after");
  155. var x, y;
  156. if(layout.mobile){
  157. var bodySize = $(document.body).getSize();
  158. x = bodySize.x;
  159. y = bodySize.y;
  160. this.json.tabletWidth = 0;
  161. this.json.tabletHeight = 0;
  162. }else{
  163. var size = this.node.getSize();
  164. x = Math.max(this.json.tabletWidth || size.x, 600);
  165. this.json.tabletWidth = x;
  166. y = Math.max(this.json.tabletHeight ? (parseInt(this.json.tabletHeight) + 110) : size.y, 320);
  167. }
  168. var zidx = this.node.getStyle("z-index").toInt() || 0;
  169. zidx = (zidx < 1000) ? 1000 : zidx;
  170. this.handwritingNode.setStyles({
  171. "height": "" + y + "px",
  172. "width": "" + x + "px",
  173. "z-index": zidx + 1
  174. });
  175. if (layout.mobile) {
  176. this.handwritingNode.addEvent('touchmove', function (e) {
  177. e.preventDefault();
  178. });
  179. this.handwritingNode.setStyles({
  180. "top": "0px",
  181. "left": "0px"
  182. }).inject($(document.body));
  183. } else {
  184. this.handwritingNode.position({
  185. "relativeTo": this.node,
  186. "position": "center",
  187. "edge": "center"
  188. });
  189. }
  190. this.handwritingAreaNode = new Element("div", {"styles": this.form.css.handwritingAreaNode}).inject(this.handwritingNode);
  191. if( !layout.mobile ){
  192. this.handwritingActionNode = new Element("div", {
  193. "styles": this.form.css.handwritingActionNode,
  194. "text": MWF.xApplication.process.Work.LP.saveWrite
  195. }).inject(this.handwritingNode);
  196. var h = this.handwritingActionNode.getSize().y + this.handwritingActionNode.getStyle("margin-top").toInt() + this.handwritingActionNode.getStyle("margin-bottom").toInt();
  197. h = y - h;
  198. this.handwritingAreaNode.setStyle("height", "" + h + "px");
  199. }else{
  200. this.handwritingAreaNode.setStyle("height", "" + y + "px");
  201. }
  202. this.handwritingFile = {};
  203. MWF.require("MWF.widget.Tablet", function () {
  204. var id = this.getData();
  205. var opt = {
  206. "style": "default",
  207. "imageSrc": id ? MWF.xDesktop.getImageSrc( id ) : "",
  208. "toolHidden": this.json.toolHidden || [],
  209. "contentWidth": this.json.tabletWidth || 0,
  210. "contentHeight": this.json.tabletHeight || 0,
  211. "onSave": function (base64code, base64Image, imageFile) {
  212. this.handwritingNode.hide();
  213. if( this.tablet.isBlank() ){
  214. this.setData("");
  215. this.validation();
  216. this.fireEvent("change");
  217. }else{
  218. this.upload(function (json) {
  219. var data = json.data;
  220. this.setData(data ? data.id : "");
  221. this.validation();
  222. this.fireEvent("change");
  223. }.bind(this));
  224. }
  225. }.bind(this),
  226. "onCancel": function () {
  227. this.handwritingNode.hide();
  228. }.bind(this)
  229. };
  230. if (layout.mobile) {
  231. opt.tools = [
  232. "save", "|",
  233. "undo",
  234. "redo", "|",
  235. "reset", "|",
  236. "cancel"
  237. ]
  238. }
  239. /**
  240. * @summary 手写板组件.
  241. * @member {o2.widget.Tablet}
  242. * @example
  243. * var tablet = this.form.get("fieldId").tablet; //获取手写板
  244. * tablet.cancel(); //关闭手写板
  245. */
  246. this.tablet = new MWF.widget.Tablet(this.handwritingAreaNode, opt, null);
  247. this.tablet.load();
  248. }.bind(this));
  249. if(this.handwritingActionNode){
  250. this.handwritingActionNode.addEvent("click", function () {
  251. //this.handwritingNode.hide();
  252. if (this.tablet) this.tablet.save();
  253. }.bind(this));
  254. }
  255. },
  256. upload: function( callback ){
  257. var img = this.tablet.getImage( null, true );
  258. if(img)Promise.resolve( img ).then(function( image ){
  259. Promise.resolve( this.tablet.getFormData(image) ).then(function (formData) {
  260. var fileName = "handwriting"+"_"+new Date().getTime();
  261. if( image.type && image.type.contains("/") ) {
  262. image.name = fileName + "." + image.type.split("/")[1];
  263. }
  264. o2.xDesktop.uploadImageByScale(
  265. this.form.businessData.work.job,
  266. "processPlatformJob",
  267. 0, //maxSize
  268. formData,
  269. image,
  270. function (json) {
  271. if (callback) callback(json);
  272. }.bind(this),
  273. function () {
  274. }.bind(this)
  275. );
  276. }.bind(this))
  277. }.bind(this))
  278. },
  279. createErrorNode: function (text) {
  280. var node = new Element("div");
  281. var iconNode = new Element("div", {
  282. "styles": {
  283. "width": "20px",
  284. "height": "20px",
  285. "float": "left",
  286. "background": "url(" + "../x_component_process_Xform/$Form/default/icon/error.png) center center no-repeat"
  287. }
  288. }).inject(node);
  289. var textNode = new Element("div", {
  290. "styles": {
  291. "line-height": "20px",
  292. "margin-left": "20px",
  293. "color": "red",
  294. "word-break": "keep-all"
  295. },
  296. "text": text
  297. }).inject(node);
  298. return node;
  299. },
  300. notValidationMode: function (text) {
  301. if (!this.isNotValidationMode) {
  302. this.isNotValidationMode = true;
  303. this.node.store("borderStyle", this.node.getStyles("border-left", "border-right", "border-top", "border-bottom"));
  304. this.node.setStyle("border", "1px solid red");
  305. this.errNode = this.createErrorNode(text).inject(this.node, "after");
  306. this.showNotValidationMode(this.node);
  307. if (!this.errNode.isIntoView()) this.errNode.scrollIntoView(false);
  308. }
  309. },
  310. showNotValidationMode: function (node) {
  311. var p = node.getParent("div");
  312. if (p) {
  313. if (p.get("MWFtype") == "tab$Content") {
  314. if (p.getParent("div").getStyle("display") == "none") {
  315. var contentAreaNode = p.getParent("div").getParent("div");
  316. var tabAreaNode = contentAreaNode.getPrevious("div");
  317. var idx = contentAreaNode.getChildren().indexOf(p.getParent("div"));
  318. var tabNode = tabAreaNode.getLast().getFirst().getChildren()[idx];
  319. tabNode.click();
  320. p = tabAreaNode.getParent("div");
  321. }
  322. }
  323. this.showNotValidationMode(p);
  324. }
  325. },
  326. validationMode: function () {
  327. if (this.isNotValidationMode) {
  328. this.isNotValidationMode = false;
  329. this.node.setStyles(this.node.retrieve("borderStyle"));
  330. if (this.errNode) {
  331. this.errNode.destroy();
  332. this.errNode = null;
  333. }
  334. }
  335. },
  336. validationConfigItem: function (routeName, data) {
  337. var flag = (data.status == "all") ? true : (routeName == data.decision);
  338. if (flag) {
  339. var n = this.getData();
  340. var v = (data.valueType == "value") ? n : n.length;
  341. switch (data.operateor) {
  342. case "isnull":
  343. if (!v) {
  344. this.notValidationMode(data.prompt);
  345. return false;
  346. }
  347. break;
  348. case "notnull":
  349. if (v) {
  350. this.notValidationMode(data.prompt);
  351. return false;
  352. }
  353. break;
  354. case "gt":
  355. if (v > data.value) {
  356. this.notValidationMode(data.prompt);
  357. return false;
  358. }
  359. break;
  360. case "lt":
  361. if (v < data.value) {
  362. this.notValidationMode(data.prompt);
  363. return false;
  364. }
  365. break;
  366. case "equal":
  367. if (v == data.value) {
  368. this.notValidationMode(data.prompt);
  369. return false;
  370. }
  371. break;
  372. case "neq":
  373. if (v != data.value) {
  374. this.notValidationMode(data.prompt);
  375. return false;
  376. }
  377. break;
  378. case "contain":
  379. if (v.indexOf(data.value) != -1) {
  380. this.notValidationMode(data.prompt);
  381. return false;
  382. }
  383. break;
  384. case "notcontain":
  385. if (v.indexOf(data.value) == -1) {
  386. this.notValidationMode(data.prompt);
  387. return false;
  388. }
  389. break;
  390. }
  391. }
  392. return true;
  393. },
  394. validationConfig: function (routeName, opinion) {
  395. if (this.json.validationConfig) {
  396. if (this.json.validationConfig.length) {
  397. for (var i = 0; i < this.json.validationConfig.length; i++) {
  398. var data = this.json.validationConfig[i];
  399. if (!this.validationConfigItem(routeName, data)) return false;
  400. }
  401. }
  402. return true;
  403. }
  404. return true;
  405. },
  406. validation: function (routeName, opinion) {
  407. if( !this.isReadonly() ){
  408. if (!this.validationConfig(routeName, opinion)) return false;
  409. if (!this.json.validation) return true;
  410. if (!this.json.validation.code) return true;
  411. this.currentRouteName = routeName;
  412. var flag = this.form.Macro.exec(this.json.validation.code, this);
  413. this.currentRouteName = "";
  414. if (!flag) flag = MWF.xApplication.process.Xform.LP.notValidation;
  415. if (flag.toString() != "true") {
  416. this.notValidationMode(flag);
  417. return false;
  418. }
  419. }
  420. return true;
  421. },
  422. _parseStyles: function (styles) {
  423. Object.each(styles, function (value, key) {
  424. if ((value.indexOf("x_processplatform_assemble_surface") != -1 || value.indexOf("x_portal_assemble_surface") != -1 || value.indexOf("x_cms_assemble_control") != -1)) {
  425. var host1 = MWF.Actions.getHost("x_processplatform_assemble_surface");
  426. var host2 = MWF.Actions.getHost("x_portal_assemble_surface");
  427. var host3 = MWF.Actions.getHost("x_cms_assemble_control");
  428. if (value.indexOf("/x_processplatform_assemble_surface") !== -1) {
  429. value = value.replace("/x_processplatform_assemble_surface", host1 + "/x_processplatform_assemble_surface");
  430. } else if (value.indexOf("x_processplatform_assemble_surface") !== -1) {
  431. value = value.replace("x_processplatform_assemble_surface", host1 + "/x_processplatform_assemble_surface");
  432. }
  433. if (value.indexOf("/x_portal_assemble_surface") !== -1) {
  434. value = value.replace("/x_portal_assemble_surface", host2 + "/x_portal_assemble_surface");
  435. } else if (value.indexOf("x_portal_assemble_surface") !== -1) {
  436. value = value.replace("x_portal_assemble_surface", host2 + "/x_portal_assemble_surface");
  437. }
  438. if (value.indexOf("/x_cms_assemble_control") !== -1) {
  439. value = value.replace("/x_cms_assemble_control", host3 + "/x_cms_assemble_control");
  440. } else if (value.indexOf("x_cms_assemble_control") !== -1) {
  441. value = value.replace("x_cms_assemble_control", host3 + "/x_cms_assemble_control");
  442. }
  443. value = o2.filterUrl(value);
  444. }
  445. }.bind(this));
  446. return styles;
  447. }
  448. });