APIs

Show:
  1. /**
  2. * @namespace flexygo.ui.wc
  3. */
  4. var flexygo;
  5. (function (flexygo) {
  6. var ui;
  7. (function (ui) {
  8. var wc;
  9. (function (wc) {
  10. /**
  11. * Library for the FlxImageElement web component.
  12. *
  13. * @class FlxImageElement
  14. * @constructor
  15. * @return {FlxImageElement}
  16. */
  17. class FlxImageElement extends HTMLElement {
  18. constructor() {
  19. super();
  20. /**
  21. * Set when component is attached to DOM
  22. * @property connected {boolean}
  23. */
  24. this.connected = false;
  25. this.property = null;
  26. this.options = null;
  27. this.value = null;
  28. this.moduleName = null;
  29. this.TypeMode = null;
  30. this.fileName = null;
  31. this.name = null;
  32. /**
  33. * Control Mode
  34. * @property type {string}
  35. */
  36. this.mode = 'object';
  37. this.pageContainer = null;
  38. this.control = null;
  39. this.files = null; //TODO_TS
  40. }
  41. /**
  42. * Fires when element is attached to DOM
  43. * @method connectedCallback
  44. */
  45. connectedCallback() {
  46. let element = $(this);
  47. let typeMode = element.attr('type') || element.attr('typemode') || 'embeded';
  48. if (typeMode && typeMode !== '') {
  49. this.TypeMode = typeMode;
  50. }
  51. let propName = element.attr('property');
  52. if (propName && flexygo.utils.isBlank(this.options)) {
  53. let parentCtl = element.closest('flx-edit,flx-list,flx-propertymanager,flx-view,flx-filter');
  54. if (parentCtl && parentCtl.length > 0) {
  55. let wcParent = parentCtl[0];
  56. if (parentCtl.is('flx-filter')) {
  57. let objName = element.attr('object');
  58. this.options = jQuery.extend(true, {}, wcParent.properties[objName + '-' + propName]);
  59. }
  60. else {
  61. this.options = jQuery.extend(true, {}, wcParent.properties[propName]);
  62. }
  63. if (wcParent && wcParent.mode) {
  64. this.mode = wcParent.mode;
  65. }
  66. }
  67. this.property = propName;
  68. }
  69. if (typeof element.attr('Required') !== 'undefined') {
  70. if (!this.options) {
  71. this.options = new flexygo.api.ObjectProperty();
  72. }
  73. this.options.IsRequired = true;
  74. }
  75. let RequiredMessage = element.attr('RequiredMessage');
  76. if (RequiredMessage && RequiredMessage !== '') {
  77. if (!this.options) {
  78. this.options = new flexygo.api.ObjectProperty();
  79. }
  80. this.options.IsRequiredMessage = RequiredMessage;
  81. }
  82. if (typeof element.attr('Locked') !== 'undefined' || typeof element.attr('Disabled') !== 'undefined') {
  83. if (!this.options) {
  84. this.options = new flexygo.api.ObjectProperty();
  85. }
  86. this.options.Locked = true;
  87. }
  88. let Style = element.attr('Style');
  89. if (Style && Style !== '') {
  90. if (!this.options) {
  91. this.options = new flexygo.api.ObjectProperty();
  92. }
  93. this.options.Style = Style;
  94. element.attr('Control-Style', this.options.Style);
  95. element.attr('Style', '');
  96. }
  97. let Class = element.attr('Class');
  98. if (Class && Class !== '') {
  99. if (!this.options) {
  100. this.options = new flexygo.api.ObjectProperty();
  101. }
  102. this.options.CssClass = Class;
  103. element.attr('Control-Class', this.options.CssClass);
  104. element.attr('Class', '');
  105. }
  106. let ctlClass = element.attr('Control-Class');
  107. if (ctlClass && ctlClass !== '') {
  108. if (!this.options) {
  109. this.options = new flexygo.api.ObjectProperty();
  110. }
  111. this.options.CssClass = ctlClass;
  112. }
  113. let ctlStyle = element.attr('Control-Style');
  114. if (ctlStyle && ctlStyle !== '') {
  115. if (!this.options) {
  116. this.options = new flexygo.api.ObjectProperty();
  117. }
  118. this.options.Style = ctlStyle;
  119. }
  120. let Hide = element.attr('Hide');
  121. if (Hide && Hide !== '') {
  122. if (!this.options) {
  123. this.options = new flexygo.api.ObjectProperty();
  124. }
  125. this.options.Hide = Hide == 'true';
  126. }
  127. let defaultValue = element.attr('defaultvalue');
  128. if (defaultValue && defaultValue !== '') {
  129. if (!this.options) {
  130. this.options = new flexygo.api.ObjectProperty();
  131. }
  132. this.options.DefaultValue = defaultValue;
  133. }
  134. let rootPath = element.attr('rootpath');
  135. if (rootPath && rootPath !== '') {
  136. if (!this.options) {
  137. this.options = new flexygo.api.ObjectProperty();
  138. }
  139. this.options.RootPath = rootPath;
  140. }
  141. let Tag = element.attr('Tag');
  142. if (Tag && Tag !== '') {
  143. if (!this.options) {
  144. this.options = new flexygo.api.ObjectProperty();
  145. }
  146. this.options.Tag = Tag;
  147. }
  148. let ImageCompressionType = element.attr('ImageCompression');
  149. if (ImageCompressionType && ImageCompressionType !== '') {
  150. if (!this.options) {
  151. this.options = new flexygo.api.ObjectProperty();
  152. }
  153. this.options.ImageCompressionType = parseInt(ImageCompressionType);
  154. }
  155. this.init();
  156. this.connected = true;
  157. //let Value = element.attr('value');
  158. //if (Value && Value !== '') {
  159. // this.setValue(Value);
  160. //}
  161. }
  162. /**
  163. * Array of observed attributes.
  164. * @property observedAttributes {Array}
  165. */
  166. static get observedAttributes() {
  167. return ['type', 'typemode', 'modulename', 'property', 'required', 'locked', 'disabled', 'style', 'class', 'hide', 'tag'];
  168. }
  169. /**
  170. * Fires when the attribute value of the element is changed.
  171. * @method attributeChangedCallback
  172. */
  173. attributeChangedCallback(attrName, oldVal, newVal) {
  174. let element = $(this);
  175. if (!this.connected) {
  176. return;
  177. }
  178. if (attrName.toLowerCase() === 'type' || attrName.toLowerCase() === 'typemode' && newVal && newVal !== '') {
  179. this.TypeMode = newVal;
  180. this.refresh();
  181. }
  182. if (attrName.toLowerCase() === 'modulename' && newVal && newVal !== '') {
  183. this.moduleName = newVal;
  184. if (this.moduleName) {
  185. this.refresh();
  186. }
  187. this.init();
  188. }
  189. if (attrName.toLowerCase() === 'property' && newVal && newVal !== '') {
  190. let propName = newVal;
  191. let parentCtl = element.closest('flx-edit, flx-list,flx-propertymanager');
  192. if (parentCtl && parentCtl.length > 0) {
  193. let wcParent = parentCtl[0];
  194. this.options = jQuery.extend(true, {}, wcParent.properties[propName]);
  195. }
  196. this.property = newVal;
  197. this.init();
  198. }
  199. if (attrName.toLowerCase() === 'required') {
  200. if (typeof element.attr('required') !== 'undefined') {
  201. if (!this.options) {
  202. this.options = new flexygo.api.ObjectProperty();
  203. }
  204. this.options.IsRequired = true;
  205. }
  206. this.refresh();
  207. }
  208. if (attrName.toLowerCase() === 'locked' || attrName.toLowerCase() === 'disabled') {
  209. if (typeof element.attr('locked') !== 'undefined' || typeof element.attr('disabled') !== 'undefined') {
  210. if (!this.options) {
  211. this.options = new flexygo.api.ObjectProperty();
  212. }
  213. this.options.Locked = true;
  214. }
  215. this.init();
  216. }
  217. if (attrName.toLowerCase() === 'style' && newVal && newVal !== '') {
  218. if (!this.options) {
  219. this.options = new flexygo.api.ObjectProperty();
  220. }
  221. this.options.Style = newVal;
  222. if (element.attr('Control-Style') !== this.options.Style) {
  223. element.attr('Control-Style', this.options.Style);
  224. element.attr('Style', '');
  225. this.refresh();
  226. }
  227. }
  228. if (attrName.toLowerCase() === 'class' && element.attr('Control-Class') !== newVal && newVal != oldVal) {
  229. if (!this.options) {
  230. this.options = new flexygo.api.ObjectProperty();
  231. }
  232. this.options.CssClass = newVal;
  233. if (element.attr('Control-Class') !== this.options.CssClass) {
  234. if (newVal != '') {
  235. element.attr('Control-Class', this.options.CssClass);
  236. }
  237. element.attr('Class', '');
  238. this.refresh();
  239. }
  240. }
  241. if (attrName.toLowerCase() === 'hide' && newVal && newVal !== '') {
  242. if (!this.options) {
  243. this.options = new flexygo.api.ObjectProperty();
  244. }
  245. this.options.Hide = newVal;
  246. this.refresh();
  247. }
  248. if (attrName.toLowerCase() === 'tag' && newVal && newVal !== '') {
  249. if (!this.options) {
  250. this.options = new flexygo.api.ObjectProperty();
  251. }
  252. this.options.Tag = newVal;
  253. this.refresh();
  254. }
  255. if (attrName.toLowerCase() === 'imagecompression' && newVal && newVal !== '') {
  256. if (!this.options) {
  257. this.options = new flexygo.api.ObjectProperty();
  258. }
  259. this.options.ImageCompressionType = newVal;
  260. this.refresh();
  261. }
  262. }
  263. /**
  264. * Initializes component depending on init mode attribute.
  265. * @method init
  266. */
  267. init() {
  268. let me = $(this);
  269. if (me.attr('mode') && me.attr('mode').toLowerCase() === 'view') {
  270. this.initViewMode();
  271. }
  272. else {
  273. this.initEditMode();
  274. }
  275. }
  276. /**
  277. * Initializes in view mode.
  278. * @method initViewMode
  279. */
  280. initViewMode() {
  281. let me = $(this);
  282. let img = $('<img class="img-responsive" style="max-height:100%"/>');
  283. let container = $('<div class="cpr-view-container">');
  284. container.html(img);
  285. me.html(container);
  286. me.parent('div[data-tag="control"]').attr('style', 'height:inherit;');
  287. me.off();
  288. if (this.options && this.options.Style) {
  289. me.children('div.cpr-view-container img.img-responsive').attr('style', this.options.Style);
  290. }
  291. if (this.options && this.options.CssClass) {
  292. me.children('div').addClass(this.options.CssClass);
  293. }
  294. if (this.options && this.options.Hide) {
  295. me.addClass("hideControl");
  296. }
  297. let Value = me.attr('value');
  298. if (Value && Value !== '') {
  299. this.setValue(Value, me.attr('text'));
  300. }
  301. this.setValue(this.getValue());
  302. }
  303. /**
  304. * Initializes in edit mode.
  305. * @method initEditMode
  306. */
  307. initEditMode() {
  308. let me = $(this);
  309. let input;
  310. let img;
  311. let icon;
  312. if (me.attr('typemode') && me.attr('typemode') !== '') {
  313. this.TypeMode = me.attr('typemode').toLowerCase();
  314. }
  315. if (me.attr('defaultvalue') && me.attr('defaultvalue') !== '') {
  316. this.options.DefaultValue = me.attr('defaultvalue');
  317. }
  318. if (me.attr('rootpath') && me.attr('rootpath') !== '') {
  319. this.options.RootPath = me.attr('rootpath');
  320. }
  321. me.parent('div[data-tag="control"]').attr('style', 'height:94%;');
  322. this.control = $('<div class="ctl-container ctl-cpr-transition ctl-hover">');
  323. input = $('<input type="hidden"/>');
  324. icon = $('<i class="flx-icon icon-pencil ctl-icon ctl-cpr-transition" flx-fw=""></i> ');
  325. img = $('<img src="" class="img-responsive ctl-image ctl-cpr-transition"/>');
  326. this.control.append(input);
  327. this.control.append(icon);
  328. this.control.append(img);
  329. me.html(this.control);
  330. let Value = me.attr('value');
  331. if (Value && Value !== '') {
  332. this.setValue(Value, me.attr('text'));
  333. }
  334. me.off('click').on('click', () => {
  335. this.openDialog();
  336. });
  337. this.setOptions();
  338. }
  339. setOptions() {
  340. let me = $(this);
  341. let input = me.find('input');
  342. let img = me.find('img');
  343. input.on('change.refreshvalue', () => {
  344. me.attr('value', input.val());
  345. });
  346. if (this.options && this.options.Name && this.options.Name !== '') {
  347. input.attr('name', this.options.Name);
  348. }
  349. else {
  350. input.attr('name', flexygo.utils.uniqueName());
  351. }
  352. if (me.attr('tab') && me.attr('tab') !== '') {
  353. input.attr('tabindex', me.attr('tab'));
  354. }
  355. if (this.options && this.options.Locked) {
  356. input.prop('disabled', this.options.Locked);
  357. me.off();
  358. me.find('div.ctl-container').removeClass('ctl-hover').addClass('ctl-container-locked');
  359. img.addClass('ctl-image-locked');
  360. }
  361. if (this.options && this.options.ClientReadOnly) {
  362. me.find('i').removeClass('icon-pencil').addClass('icon-eye');
  363. }
  364. if (this.options && this.options.Style) {
  365. me.find('img').attr('style', this.options.Style);
  366. }
  367. if (this.options && this.options.CssClass) {
  368. me.children('div').addClass(this.options.CssClass);
  369. }
  370. if (this.options && this.options.Hide) {
  371. me.addClass("hideControl");
  372. }
  373. if (this.options && this.options.IsRequired) {
  374. input.prop('required', true);
  375. }
  376. if (this.options && this.options.CauseRefresh) {
  377. input.on('change', (e) => {
  378. //$(document).trigger('refreshProperty', [input.closest('flx-edit'), this.options.Name]);
  379. let ev = {
  380. class: "property",
  381. type: "changed",
  382. sender: this,
  383. masterIdentity: this.property
  384. };
  385. flexygo.events.trigger(ev);
  386. });
  387. }
  388. }
  389. refresh() {
  390. try {
  391. let val = this.getValue();
  392. this.init();
  393. if (val) {
  394. this.setValue(val);
  395. }
  396. }
  397. catch (e) {
  398. console.log(e.message);
  399. }
  400. }
  401. setValue(value, text) {
  402. let me = $(this);
  403. if (!text) {
  404. text = value;
  405. }
  406. if (me.attr('mode') && me.attr('mode').toLowerCase() === 'view') {
  407. this.setValueView(value);
  408. }
  409. else {
  410. try {
  411. let input = me.find('input');
  412. let img = me.find('img');
  413. let base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
  414. if (!value) {
  415. if (this.options.DefaultValue) {
  416. text = flexygo.utils.resolveUrl(this.addTime(this.options.DefaultValue));
  417. value = this.options.DefaultValue;
  418. }
  419. img.attr('src', text);
  420. me.attr('value', value).attr('text', text);
  421. input.val(value);
  422. }
  423. else {
  424. let test = value.split(',')[1];
  425. if (flexygo.utils.isBase64(test)) {
  426. img.attr('src', value);
  427. input.val(value);
  428. me.attr('value', value);
  429. }
  430. else {
  431. text = flexygo.utils.resolveUrl(this.addTime(text));
  432. img.attr('src', text);
  433. me.attr('value', value).attr('text', text);
  434. input.val(value);
  435. }
  436. }
  437. }
  438. catch (e) {
  439. console.log(e.message);
  440. }
  441. }
  442. }
  443. addTime(val) {
  444. return flexygo.utils.querystring.setParamValue(val, 'time', new Date().getTime().toString());
  445. }
  446. setValueView(value) {
  447. let me = $(this);
  448. this.value = value;
  449. me.find('div.cpr-view-container img.img-responsive').attr('src', flexygo.utils.resolveUrl(value));
  450. }
  451. getValue() {
  452. let me = $(this);
  453. if (me.attr('mode') && me.attr('mode').toLowerCase() === 'view') {
  454. return (this.value) ? this.value : me.attr('value');
  455. }
  456. try {
  457. let input = me.find('input');
  458. if (!input.val()) {
  459. return null;
  460. }
  461. else {
  462. return input.val();
  463. }
  464. }
  465. catch (e) {
  466. console.log(e.message);
  467. }
  468. }
  469. setResult(result) {
  470. try {
  471. let me = $(this);
  472. if (this.TypeMode === 'file') {
  473. let formValues = [];
  474. let module = $(this).closest('flx-edit');
  475. if (module.length > 0) {
  476. let props = module.find('[property]');
  477. if (props.length > 0) {
  478. for (var i = 0; i < props.length; i++) {
  479. let prop = $(props[i])[0];
  480. formValues.push({ "key": prop.property, "value": prop.getValue() });
  481. }
  482. }
  483. }
  484. let params = {
  485. Mode: this.mode,
  486. ObjectName: this.options.ProcessName || this.options.ReportName || this.options.ObjectName,
  487. PropertyName: this.options.Name,
  488. FileName: this.fileName,
  489. Base64: result.split(',')[1],
  490. CurrentValue: me.attr('value'),
  491. FormValues: formValues,
  492. Name: this.name
  493. };
  494. flexygo.ajax.post('~/api/Image', 'SaveFile', params, (ret) => {
  495. if (ret.Value != 'errorrootpath')
  496. this.setValue(ret.Value, ret.Text);
  497. else {
  498. flexygo.msg.error('image.errorrootpath');
  499. }
  500. });
  501. if (!this.fileName) {
  502. flexygo.msg.warning('image.errorfilename');
  503. }
  504. }
  505. else if (this.TypeMode === 'base64') {
  506. let extns = this.options.Extensions.toLowerCase().split("|");
  507. let fileExtension = this.name.substring(this.name.lastIndexOf(".")).toLowerCase();
  508. if (extns.indexOf(fileExtension) > -1 || this.options.ExtensionId == 'sysAll') {
  509. this.setValue(result);
  510. }
  511. else {
  512. flexygo.msg.error('image.extension');
  513. }
  514. }
  515. }
  516. catch (err) {
  517. console.log(err.message);
  518. }
  519. }
  520. openDialog() {
  521. let me = $(this);
  522. let eValue;
  523. let imageElement;
  524. let image;
  525. let rounded;
  526. let accept = '';
  527. if ((this.options && this.options.RegExp) || (this.options && this.options.Extensions)) {
  528. if (this.options.RegExp) {
  529. accept = this.options.RegExp;
  530. }
  531. else if (this.options.Extensions) {
  532. if (this.options.ExtensionId != 'sysAll') {
  533. accept = flexygo.utils.parser.replaceAll(this.options.Extensions, '|', ',');
  534. }
  535. }
  536. }
  537. image = me.find('img').attr("src");
  538. if (this.TypeMode === 'file') {
  539. this.name = this.getName(me.attr('value'), this.TypeMode);
  540. this.fileName = this.getFileName(me.attr('value'));
  541. }
  542. else {
  543. if (me.attr('value')) {
  544. this.name = "." + me.attr('value').substring(me.attr('value').indexOf("/") + 1, me.attr('value').indexOf(";"));
  545. }
  546. }
  547. rounded = false;
  548. this.pageContainer = $(`<div class="flx-cpr-image container cnt-Body pageContainerImage">
  549. <div class="bg-white cpr-subcontainer ctl-cpr-transition">
  550. <div class="panel panel-default panel-wizard col-md-12 cpr-panel">
  551. <div class="panel-heading cpr-heading">
  552. <div class="btn-group cpr-btn-group" data-toggle="buttons">
  553. <label class="btn btn-default cpr-btn cpr-defaultActive active cpr-setDragModeCrop cpr-setDragMode" data-original-title="" title="">
  554. <input type="radio" class="cpr-defaultCheck" name="setDragMode" value="crop" checked>
  555. <i class="fa fa-crop" flx-fw=""></i>
  556. </label>
  557. <label class="btn btn-default cpr-btn cpr-setDragModeMove cpr-setDragMode" data-original-title="" title="">
  558. <input type="radio" class="" name="setDragMode" value="move">
  559. <i class="fa fa-arrows" flx-fw=""></i>
  560. </label>
  561. </div>
  562. <div class="btn-group cpr-btn-group crp-zoom">
  563. <button type="button" method="zoom" value="0.1" class="btn btn-default cpr-btn" data-original-title="" title="">
  564. <i class="fa fa-search-plus" flx-fw=""></i>
  565. </button>
  566. <button type="button" method="zoom" value="-0.1" class="btn btn-default cpr-btn" data-original-title="" title="">
  567. <i class="fa fa-search-minus" flx-fw=""></i>
  568. </button>
  569. </div>
  570. <div class="btn-group cpr-btn-group crp-rotate">
  571. <button type="button" method="rotate" value="-45" class="btn btn-default cpr-btn" data-original-title="" title="">
  572. <i class="fa fa-rotate-left" flx-fw=""></i>
  573. </button>
  574. <button type="button" method="rotate" value="45" class="btn btn-default cpr-btn" data-original-title="" title="">
  575. <i class="fa fa-rotate-right" flx-fw=""></i>
  576. </button>
  577. </div>
  578. <div class="btn-group cpr-btn-group crp-scale">
  579. <button type="button" method="scaleX" value="-1" class="btn btn-default cpr-btn" data-original-title="" title="">
  580. <i class="fa fa-arrows-h" flx-fw=""></i>
  581. </button>
  582. <button type="button" method="scaleY" value="-1" class="btn btn-default cpr-btn" data-original-title="" title="">
  583. <i class="fa fa-arrows-v" flx-fw=""></i>
  584. </button>
  585. </div>
  586. <div class="btn-group cpr-btn-group cpr-setAspectRatio" data-toggle="buttons">
  587. <label class="btn btn-default cpr-btn cpr-defaultActive active" data-original-title="" title="">
  588. <input type="radio" class="cpr-defaultCheck" name="setAspectRatio" value="NaN" checked>
  589. ` + flexygo.localization.translate('image.free') + `
  590. </label>
  591. <label class="btn btn-default cpr-btn" data-original-title="" title="">
  592. <input type="radio" class="" name="setAspectRatio" value="1.7777777777777777">
  593. 16:9
  594. </label>
  595. <label class="btn btn-default cpr-btn" data-original-title="" title="">
  596. <input type="radio" class="" name="setAspectRatio" value="1.3333333333333333">
  597. 4:3
  598. </label>
  599. <label class="btn btn-default cpr-btn" data-original-title="" title="">
  600. <input type="radio" class="" name="setAspectRatio" value="0.6666666666666666">
  601. 2:3
  602. </label>
  603. <label class="btn btn-default cpr-btn" data-original-title="" title="">
  604. <input type="radio" class="" name="setAspectRatio" value="1">
  605. <i class="flx-icon icon-non-check" flx-fw=""></i>
  606. </label>
  607. <label class="btn btn-default cpr-btn" data-original-title="" title="">
  608. <input type="radio" class="" name="setAspectRatio" value="rounded">
  609. <i class="flx-icon icon-circle-1" flx-fw=""></i>
  610. </label>
  611. </div>
  612. <button type="button" method="reset" value="" class="btn btn-default cpr-btn" data-original-title="" title="">
  613. <i class="fa fa-refresh" flx-fw=""></i>
  614. </button>
  615. <button id="download" type="button" method="download" value="" class="btn btn-default cpr-btn" data-original-title="" title="">
  616. <i class="flx-icon icon-download" flx-fw=""></i>
  617. </button>
  618. </div>
  619. <div class="panel-body cpr-cropper">
  620. <span class="cpr-span">` + flexygo.localization.translate('image.infotostart') + `</span>
  621. <img class="img-responsive" src="` + image + `">
  622. </div>
  623. </div>
  624. <label class="btn btn-default btn-file bg-outstanding cpr-btn-browse">`
  625. + flexygo.localization.translate('image.browsebutton') + `<input type="file" class="hide" accept="${accept}"/>
  626. </label>
  627. <button type="button" method="save" value="" class="btn btn-default bg-info cpr-btn-save" data-original-title="" title="">
  628. <i class="flx-icon icon-save-2" flx-fw=""></i> ` + flexygo.localization.translate('image.savebutton') +
  629. `</button>
  630. <button type="button" method="remove" value="" class="btn btn-default bg-danger cpr-btn-remove" data-original-title="" title="">
  631. <i class="flx-icon icon-delete-2" flx-fw=""></i> ` + flexygo.localization.translate('image.removebutton') +
  632. `</button>
  633. </div>
  634. </div>`);
  635. if (this.options.ObjectName === 'sysObjectImage') {
  636. this.pageContainer.find('label.cpr-btn-browse').hide();
  637. this.pageContainer.find('button[method="save"]').addClass('cpr-btn-save-imagemanager');
  638. this.pageContainer.find('button[method="remove"]').hide();
  639. }
  640. if (!this.options.ClientReadOnly) {
  641. this.pageContainer.find('label.cpr-setDragModeCrop').tooltip({ title: flexygo.localization.translate('image.cropbutton'), placement: 'right', trigger: 'hover' });
  642. this.pageContainer.find('label.cpr-setDragModeMove').tooltip({ title: flexygo.localization.translate('image.movebutton'), placement: 'right', trigger: 'hover' });
  643. this.pageContainer.find('div.crp-zoom').tooltip({ title: flexygo.localization.translate('image.zoombutton'), placement: 'right', trigger: 'hover' });
  644. this.pageContainer.find('div.crp-rotate').tooltip({ title: flexygo.localization.translate('image.rotatebutton'), placement: 'right', trigger: 'hover' });
  645. this.pageContainer.find('div.crp-scale').tooltip({ title: flexygo.localization.translate('image.scalebutton'), placement: 'right', trigger: 'hover' });
  646. this.pageContainer.find('div.cpr-setAspectRatio').tooltip({ title: flexygo.localization.translate('image.aspectratiobutton'), placement: 'right', trigger: 'hover' });
  647. this.pageContainer.find('button[method="reset"]').tooltip({ title: flexygo.localization.translate('image.resetbutton'), placement: 'left', trigger: 'hover' });
  648. this.pageContainer.find('label.cpr-btn-browse').tooltip({ title: flexygo.localization.translate('image.browsebuttontooltip'), placement: 'top', trigger: 'hover' });
  649. this.pageContainer.find('button[method="save"]').tooltip({ title: flexygo.localization.translate('image.savebutton'), placement: 'top', trigger: 'hover' });
  650. this.pageContainer.find('button[method="remove"]').tooltip({ title: flexygo.localization.translate('image.removebutton'), placement: 'top', trigger: 'hover' });
  651. this.pageContainer.find('button[method="download"]').tooltip({ title: flexygo.localization.translate('image.downloadbutton'), placement: 'left', trigger: 'hover' });
  652. }
  653. else {
  654. this.pageContainer.find('.cpr-span').hide();
  655. this.pageContainer.find('.btn').prop("disabled", true).addClass('disabled');
  656. this.pageContainer.find('input').prop("disabled", true).addClass('disabled');
  657. }
  658. imageElement = this.pageContainer.find('img');
  659. let dialogWidth;
  660. let dialogHeight;
  661. if ($('body').width() < 850) {
  662. dialogWidth = $('body').width();
  663. }
  664. else {
  665. dialogWidth = 900;
  666. }
  667. if ($('body').height() < 830) {
  668. dialogHeight = $('body').height();
  669. }
  670. else {
  671. if (this.options.ObjectName === 'sysObjectImage') {
  672. dialogHeight = 780;
  673. }
  674. else {
  675. dialogHeight = 830;
  676. }
  677. }
  678. this.pageContainer.dialog({
  679. position: { my: "center top", at: "center top+70", of: $('body') },
  680. width: dialogWidth,
  681. height: dialogHeight,
  682. dialogClass: 'flx-dialog-modal',
  683. modal: true,
  684. close: (e) => { $(e.target).dialog('destroy').remove(); }
  685. }).dialogExtend({
  686. "closable": true,
  687. "maximizable": false,
  688. "minimizable": false,
  689. "collapsable": false,
  690. "dblclick": false,
  691. "modal": true,
  692. "close": (e) => { $(e.target).remove(); }
  693. });
  694. if (!this.options.ClientReadOnly && image) {
  695. let options = null;
  696. if (this.isJSON(this.options.Tag) && JSON.parse(this.options.Tag).options) {
  697. options = JSON.parse(this.options.Tag).options;
  698. }
  699. imageElement.cropper(options);
  700. }
  701. this.pageContainer.find('button').on('click', (e) => {
  702. let element = $(e.currentTarget);
  703. let method = element.attr('method');
  704. let value = element.attr('value');
  705. if (method === 'download') {
  706. var link = document.createElement('a');
  707. link.href = image;
  708. link.download = this.options.Name;
  709. link.click();
  710. }
  711. if (method === 'remove') {
  712. if (this.options.ObjectName != 'sysObjectImage') {
  713. this.setValue(value);
  714. this.pageContainer.dialog('destroy').remove();
  715. }
  716. }
  717. else if (method === 'save') {
  718. let options = {};
  719. let compression;
  720. if (this.isJSON(this.options.Tag) && JSON.parse(this.options.Tag).getCroppedCanvas) {
  721. options = JSON.parse(this.options.Tag).getCroppedCanvas;
  722. }
  723. if (this.options.ImageMaxWidth) {
  724. options.maxWidth = this.options.ImageMaxWidth;
  725. }
  726. if (this.options.ImageMaxHeight) {
  727. options.maxHeight = this.options.ImageMaxHeight;
  728. }
  729. let croppedCanvas = imageElement.cropper('getCroppedCanvas', options);
  730. if (rounded) {
  731. croppedCanvas = this.getRoundedCanvas(croppedCanvas);
  732. }
  733. if (imageElement[0].src.includes('.png') || imageElement[0].src.includes('image/png')) {
  734. if (this.options.ImageCompressionType && this.options.ImageCompressionType > 0) {
  735. switch (this.options.ImageCompressionType) {
  736. //Low
  737. case 1:
  738. compression = 192;
  739. break;
  740. //Medium
  741. case 2:
  742. compression = 128;
  743. break;
  744. //High
  745. case 3:
  746. compression = 64;
  747. break;
  748. }
  749. let optionsgRgb = {
  750. colors: compression
  751. };
  752. let rgbQuant = new RgbQuant(optionsgRgb);
  753. rgbQuant.sample(croppedCanvas);
  754. let img = rgbQuant.reduce(croppedCanvas);
  755. let canvas = croppedCanvas;
  756. let uint = new Uint8ClampedArray(img.buffer);
  757. let imageData = new ImageData(uint, croppedCanvas.width, croppedCanvas.height);
  758. let ctx = croppedCanvas.getContext('2d');
  759. ctx.putImageData(imageData, 0, 0);
  760. canvas.getContext('2d').drawImage(croppedCanvas, 0, 0, canvas.width, canvas.height);
  761. this.setResult(canvas.toDataURL('image/png'));
  762. }
  763. else {
  764. this.setResult(croppedCanvas.toDataURL());
  765. }
  766. }
  767. else {
  768. if (this.options.ImageCompressionType && this.options.ImageCompressionType > 0) {
  769. switch (this.options.ImageCompressionType) {
  770. //Low
  771. case 1:
  772. compression = 0.75;
  773. break;
  774. //Medium
  775. case 2:
  776. compression = 0.50;
  777. break;
  778. //High
  779. case 3:
  780. compression = 0.25;
  781. break;
  782. }
  783. this.setResult(croppedCanvas.toDataURL('image/jpeg', compression));
  784. }
  785. else {
  786. this.setResult(croppedCanvas.toDataURL());
  787. }
  788. }
  789. this.pageContainer.dialog('destroy').remove();
  790. }
  791. else {
  792. if (method === 'scaleX' && eValue.scaleX === -1 || method === 'scaleY' && eValue.scaleY === -1) {
  793. value = '1';
  794. }
  795. imageElement.cropper(method, value);
  796. }
  797. });
  798. this.pageContainer.find('input').on('change', (e) => {
  799. let element = $(e.currentTarget);
  800. if (element.attr('type') === 'file') {
  801. if (element[0].files && element[0].files[0]) {
  802. if (this.options.ObjectName != 'sysObjectImage') {
  803. this.name = element[0].files[0].name;
  804. let reader = new FileReader();
  805. reader.onload = (e) => {
  806. let options = null;
  807. if (this.isJSON(this.options.Tag) && JSON.parse(this.options.Tag).options) {
  808. options = JSON.parse(this.options.Tag).options;
  809. }
  810. imageElement.cropper('destroy').attr('src', e.target.result).cropper(options);
  811. };
  812. reader.readAsDataURL(element[0].files[0]);
  813. if (this.TypeMode === 'file') {
  814. this.fileName = this.getFileName(element[0].files[0].name);
  815. }
  816. this.pageContainer.find('label.active').removeClass('active');
  817. this.pageContainer.find('input:checked').prop("checked", false);
  818. this.pageContainer.find('label.cpr-defaultActive').addClass('active');
  819. this.pageContainer.find('input.cpr-defaultCheck').prop("checked", true);
  820. rounded = false;
  821. }
  822. }
  823. }
  824. else {
  825. let method = element.attr('name');
  826. let value = element.attr('value');
  827. if (method === 'setAspectRatio' && value === 'rounded') {
  828. rounded = true;
  829. value = '1';
  830. $(".cropper-view-box,.cropper-face").css("border-radius", "50%");
  831. }
  832. else if (method === 'setAspectRatio') {
  833. rounded = false;
  834. $(".cropper-view-box,.cropper-face").css("border-radius", "0");
  835. }
  836. imageElement.cropper(method, value);
  837. }
  838. });
  839. this.pageContainer.find('div.cpr-cropper').on('dblclick', (e) => {
  840. let inputChecked = this.pageContainer.find('input[name="setDragMode"]:checked');
  841. let inputNotChecked = this.pageContainer.find('input[name="setDragMode"]:not(:checked)');
  842. let labelActive = this.pageContainer.find('label.cpr-setDragMode.active');
  843. let labelNotActive = this.pageContainer.find('label.cpr-setDragMode:not(.active)');
  844. labelActive.removeClass('active');
  845. inputChecked.prop("checked", false);
  846. labelNotActive.addClass('active');
  847. inputNotChecked.prop("checked", true);
  848. });
  849. this.pageContainer.on('dragover', (e) => {
  850. if (this.options.ObjectName != 'sysObjectImage') {
  851. e.preventDefault();
  852. e.stopPropagation();
  853. this.pageContainer.find('div.cpr-subcontainer').addClass('cpr-dragging');
  854. }
  855. });
  856. this.pageContainer.on('dragleave', (e) => {
  857. if (this.options.ObjectName != 'sysObjectImage') {
  858. e.preventDefault();
  859. e.stopPropagation();
  860. this.pageContainer.find('div.cpr-subcontainer').removeClass('cpr-dragging');
  861. }
  862. });
  863. this.pageContainer.on('drop', (e) => {
  864. if (this.options.ObjectName != 'sysObjectImage') {
  865. if (e.originalEvent.dataTransfer) {
  866. if (e.originalEvent.dataTransfer.files.length) {
  867. e.preventDefault();
  868. e.stopPropagation();
  869. let file = e.originalEvent.dataTransfer.files;
  870. let imageType = /image.*/;
  871. if (file[0].type.match(imageType)) {
  872. this.pageContainer.find('input[type="file"]').prop("files", file);
  873. if (e.originalEvent.dataTransfer.files.length !== 1) {
  874. flexygo.msg.warning('image.errorfilenumber');
  875. }
  876. else {
  877. this.pageContainer.find('input[type="file"]').trigger('change');
  878. }
  879. }
  880. else {
  881. flexygo.msg.error('image.errorfiletype');
  882. }
  883. }
  884. }
  885. this.pageContainer.find('div.cpr-subcontainer').removeClass('cpr-dragging');
  886. }
  887. });
  888. if (this.options.ClientReadOnly) {
  889. this.pageContainer.off().find('*').off();
  890. }
  891. this.pageContainer.find('img').on('error', (e) => {
  892. $(e.currentTarget).hide();
  893. });
  894. }
  895. getRoundedCanvas(sourceCanvas) {
  896. let canvas = document.createElement('canvas');
  897. let context = canvas.getContext('2d');
  898. let width = sourceCanvas.width;
  899. let height = sourceCanvas.height;
  900. canvas.width = width;
  901. canvas.height = height;
  902. context.beginPath();
  903. context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI);
  904. context.strokeStyle = 'rgba(0,0,0,0)';
  905. context.stroke();
  906. context.clip();
  907. context.drawImage(sourceCanvas, 0, 0, width, height);
  908. return canvas;
  909. }
  910. getFileName(url) {
  911. if (url) {
  912. let index = url.lastIndexOf("\\") + 1;
  913. let filenameWithExtension = url.substr(index);
  914. let filename = filenameWithExtension.split(".")[0];
  915. return filename;
  916. }
  917. else {
  918. return url;
  919. }
  920. }
  921. getName(url, mode) {
  922. if (url) {
  923. let index = url.lastIndexOf("\\") + 1;
  924. let filenameWithExtension = url.substr(index);
  925. let filename;
  926. if (mode === 'file') {
  927. filename = filenameWithExtension;
  928. }
  929. else {
  930. filename = filenameWithExtension.split("?")[0];
  931. }
  932. return filename;
  933. }
  934. else {
  935. return url;
  936. }
  937. }
  938. isJSON(str) {
  939. if (typeof (str) !== 'string') {
  940. return false;
  941. }
  942. try {
  943. JSON.parse(str);
  944. return true;
  945. }
  946. catch (e) {
  947. return false;
  948. }
  949. }
  950. /**
  951. * Trigger Dependencies.
  952. * @method triggerDependencies
  953. */
  954. triggerDependencies() {
  955. let me;
  956. let input;
  957. me = $(this);
  958. input = me.find('input');
  959. input.trigger('change');
  960. }
  961. }
  962. wc.FlxImageElement = FlxImageElement;
  963. })(wc = ui.wc || (ui.wc = {}));
  964. })(ui = flexygo.ui || (flexygo.ui = {}));
  965. })(flexygo || (flexygo = {}));
  966. window.customElements.define('flx-image', flexygo.ui.wc.FlxImageElement);
  967. //# sourceMappingURL=flx-image.js.map