panel.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. fred.panel.Element = function (config) {
  2. config = config || {};
  3. config.id = config.id || 'fred-panel-element';
  4. Ext.applyIf(config, {
  5. border: false,
  6. cls: 'container',
  7. url: fred.config.connectorUrl,
  8. baseParams: {
  9. action: 'mgr/elements/update'
  10. },
  11. useLoadingMask: true,
  12. items: this.getItems(config),
  13. listeners: {
  14. 'setup': {
  15. fn: this.setup,
  16. scope: this
  17. },
  18. 'success': {
  19. fn: this.success,
  20. scope: this
  21. }
  22. }
  23. });
  24. this.theme_folder = '';
  25. fred.panel.Element.superclass.constructor.call(this, config);
  26. };
  27. Ext.extend(fred.panel.Element, MODx.FormPanel, {
  28. setup: function () {
  29. if (this.config.isUpdate) {
  30. MODx.Ajax.request({
  31. url: this.config.url,
  32. params: {
  33. action: 'mgr/elements/get',
  34. id: MODx.request.id
  35. },
  36. listeners: {
  37. 'success': {
  38. fn: function (r) {
  39. if (Array.isArray(r.object.options_override) && r.object.options_override.length === 0) {
  40. r.object.options_override = '';
  41. } else {
  42. if (typeof r.object.options_override === 'object') {
  43. r.object.options_override = JSON.stringify(r.object.options_override, null, 2);
  44. }
  45. }
  46. if (r.object.option_set === 0) {
  47. Ext.getCmp('fred-element-panel-preview-option-set').disable();
  48. }
  49. this.getForm().setValues(r.object);
  50. var category = this.find('name', 'category');
  51. if (category[0]) {
  52. category = category[0];
  53. category.baseParams.theme = r.object.theme;
  54. }
  55. var optionSet = this.find('name', 'option_set');
  56. if (optionSet[0]) {
  57. optionSet = optionSet[0];
  58. optionSet.baseParams.theme = r.object.theme;
  59. }
  60. if (r.object.image) {
  61. this.theme_folder = r.object.theme_folder;
  62. r.object.image = fred.prependBaseUrl(r.object.image, r.object.theme_folder);
  63. } else {
  64. r.object.image = "https://via.placeholder.com/300x150?text=No+image";
  65. }
  66. Ext.getCmp('image_preview').el.dom.querySelector('img').src = r.object.image;
  67. this.fireEvent('ready', r.object);
  68. MODx.fireEvent('ready');
  69. },
  70. scope: this
  71. }
  72. }
  73. });
  74. } else {
  75. Ext.getCmp('fred-element-panel-preview-option-set').disable();
  76. var theme = MODx.request.theme;
  77. if (theme) {
  78. var categoryField = this.find('name', 'category');
  79. if (!categoryField[0]) return;
  80. var optionSetField = this.find('name', 'option_set');
  81. if (!optionSetField[0]) return;
  82. var category = MODx.request.category;
  83. this.getForm().setValues({theme: theme, category: category});
  84. optionSetField = optionSetField[0];
  85. optionSetField.enable();
  86. optionSetField.baseParams.theme = theme;
  87. }
  88. this.fireEvent('ready');
  89. MODx.fireEvent('ready');
  90. }
  91. },
  92. success: function (o, r) {
  93. if (this.config.isUpdate == false) {
  94. fred.loadPage('element/update', {id: o.result.object.id});
  95. }
  96. },
  97. getItems: function (config) {
  98. return [
  99. {
  100. html: '<h2>' + ((config.isUpdate == true) ? _('fred.elements.update') : _('fred.elements.create')) + '</h2>',
  101. border: false,
  102. cls: 'modx-page-header'
  103. },
  104. {
  105. name: 'id',
  106. xtype: 'hidden'
  107. },
  108. this.getGeneralFields(config),
  109. {
  110. html: '<br />',
  111. bodyCssClass: 'transparent-background'
  112. },
  113. this.getColumnsGrid(config)
  114. ];
  115. },
  116. getGeneralFields: function (config) {
  117. return [
  118. {
  119. deferredRender: false,
  120. border: true,
  121. defaults: {
  122. autoHeight: true,
  123. layout: 'form',
  124. labelWidth: 150,
  125. bodyCssClass: 'main-wrapper',
  126. layoutOnTabChange: true
  127. },
  128. items: [
  129. {
  130. defaults: {
  131. msgTarget: 'side',
  132. autoHeight: true
  133. },
  134. cls: 'form-with-labels',
  135. border: false,
  136. items: [
  137. {
  138. layout: 'column',
  139. border: false,
  140. height: 100,
  141. defaults: {
  142. layout: 'form',
  143. labelAlign: 'top',
  144. labelSeparator: '',
  145. anchor: '100%',
  146. border: false
  147. },
  148. items: [
  149. {
  150. columnWidth: 0.7,
  151. border: false,
  152. defaults: {
  153. msgTarget: 'under'
  154. },
  155. items: [
  156. {
  157. xtype: 'textfield',
  158. fieldLabel: _('fred.elements.name'),
  159. name: 'name',
  160. anchor: '100%',
  161. allowBlank: false
  162. },
  163. {
  164. xtype: 'textarea',
  165. fieldLabel: _('fred.elements.description'),
  166. name: 'description',
  167. anchor: '100%',
  168. height: 100
  169. }
  170. ]
  171. },
  172. {
  173. columnWidth: 0.3,
  174. border: false,
  175. defaults: {
  176. msgTarget: 'under'
  177. },
  178. items: [
  179. {
  180. xtype: 'fred-combo-themes',
  181. fieldLabel: _('fred.elements.theme'),
  182. name: 'theme',
  183. hiddenName: 'theme',
  184. anchor: '100%',
  185. listeners: {
  186. select: function(combo, record) {
  187. var category = this.find('name', 'category');
  188. if (!category[0]) return;
  189. this.theme_folder = record.data.theme_folder;
  190. category = category[0];
  191. category.setValue();
  192. category.enable();
  193. category.baseParams.theme = record.id;
  194. category.store.load();
  195. var optionSet = this.find('name', 'option_set');
  196. if (!optionSet[0]) return;
  197. optionSet = optionSet[0];
  198. optionSet.setValue(0);
  199. optionSet.enable();
  200. optionSet.baseParams.theme = record.id;
  201. optionSet.store.load();
  202. var previewButton = Ext.getCmp('fred-element-panel-preview-option-set');
  203. if (previewButton) previewButton.disable();
  204. var image = Ext.getCmp('fred-element-image-field');
  205. if (image) {
  206. image.updatePreview(this.theme_folder);
  207. }
  208. },
  209. scope: this
  210. },
  211. allowBlank: false,
  212. isUpdate: config.isUpdate
  213. },
  214. {
  215. xtype: 'fred-combo-element-categories',
  216. fieldLabel: _('fred.elements.category'),
  217. name: 'category',
  218. hiddenName: 'category',
  219. anchor: '100%',
  220. disabled: !config.isUpdate,
  221. allowBlank: false
  222. },
  223. {
  224. xtype: 'numberfield',
  225. allowDecimals: false,
  226. allowNegative: false,
  227. fieldLabel: _('fred.elements.rank'),
  228. name: 'rank',
  229. anchor: '100%',
  230. allowBlank: true
  231. }
  232. ]
  233. }
  234. ]
  235. },
  236. {
  237. layout: 'column',
  238. border: false,
  239. anchor: '100%',
  240. defaults: {
  241. layout: 'form',
  242. labelAlign: 'top',
  243. labelSeparator: '',
  244. anchor: '100%',
  245. border: false
  246. },
  247. items: [
  248. {
  249. columnWidth: 1,
  250. border: false,
  251. defaults: {
  252. msgTarget: 'under',
  253. anchor: '100%'
  254. },
  255. items: [
  256. {
  257. id: 'fred-element-image-field',
  258. xtype: 'modx-combo-browser',
  259. fieldLabel: _('fred.elements.image'),
  260. triggerClass: 'x-form-image-trigger',
  261. name: 'image',
  262. anchor: '100%',
  263. allowBlank: true,
  264. updatePreview: function (theme_folder = '') {
  265. var value = this.getValue();
  266. if (value) {
  267. value = fred.prependBaseUrl(value, theme_folder);
  268. } else {
  269. value = "https://via.placeholder.com/300x150?text=No+image";
  270. }
  271. Ext.getCmp('image_preview').el.dom.querySelector('img').src = value;
  272. },
  273. listeners: {
  274. 'select': {
  275. fn: function (data) {
  276. this.setValue(data.fullRelativeUrl);
  277. this.updatePreview('');
  278. }
  279. },
  280. 'change': {
  281. fn: function (cb, nv) {
  282. cb.updatePreview(this.theme_folder);
  283. },
  284. scope: this
  285. }
  286. }
  287. },
  288. {
  289. id: 'image_preview',
  290. html: '<img src="' + "https://via.placeholder.com/800x100?text=No+image" + '" style="max-height: 800px;max-width: 100%;margin-top: 15px;">',
  291. listeners: {
  292. render: function () {
  293. this.el.dom.style.textAlign = 'center';
  294. }
  295. }
  296. }
  297. ]
  298. }
  299. ]
  300. }
  301. ]
  302. }
  303. ]
  304. }
  305. ];
  306. },
  307. getColumnsGrid: function (config) {
  308. var items = [
  309. {
  310. xtype: 'modx-tabs',
  311. forceLayout: true,
  312. deferredRender: false,
  313. collapsible: false,
  314. defaults: {
  315. layout: 'form',
  316. labelAlign: 'top',
  317. labelSeparator: '',
  318. anchor: '100%',
  319. border: false
  320. },
  321. items: [
  322. {
  323. title: _('fred.elements.markup'),
  324. layout: 'form',
  325. bodyCssClass: 'tab-panel-wrapper main-wrapper',
  326. autoHeight: true,
  327. defaults: {
  328. border: false,
  329. msgTarget: 'under',
  330. width: 400
  331. },
  332. items: [
  333. {
  334. xtype: Ext.ComponentMgr.isRegistered('modx-texteditor') ? 'modx-texteditor' : 'textarea',
  335. mimeType: 'text/html',
  336. name: 'content',
  337. id: 'fred-element-content',
  338. hideLabel: true,
  339. anchor: '100%',
  340. height: 400,
  341. grow: false,
  342. value: '',
  343. listeners: {
  344. render: function () {
  345. if ((this.xtype === 'modx-texteditor') && this.editor)
  346. this.editor.getSession().setMode('ace/mode/twig')
  347. }
  348. }
  349. }
  350. ]
  351. },
  352. {
  353. title: _('fred.elements.options'),
  354. layout: 'form',
  355. bodyCssClass: 'tab-panel-wrapper main-wrapper',
  356. autoHeight: true,
  357. defaults: {
  358. layout: 'form',
  359. labelAlign: 'top',
  360. labelSeparator: '',
  361. anchor: '100%',
  362. border: false,
  363. msgTarget: 'under',
  364. width: 400
  365. },
  366. items: [
  367. {
  368. layout: 'column',
  369. border: false,
  370. anchor: '100%',
  371. defaults: {
  372. layout: 'form',
  373. labelAlign: 'top',
  374. labelSeparator: '',
  375. anchor: '100%',
  376. border: false
  377. },
  378. items: [
  379. {
  380. columnWidth: .8,
  381. border: false,
  382. defaults: {
  383. msgTarget: 'under',
  384. anchor: '100%'
  385. },
  386. items: [
  387. {
  388. xtype: 'fred-combo-element-option-sets',
  389. name: 'option_set',
  390. hiddenName: 'option_set',
  391. baseParams: {
  392. action: 'mgr/element_option_sets/getlist',
  393. addEmpty: 1,
  394. complete: 1
  395. },
  396. fieldLabel: _('fred.elements.option_set'),
  397. listeners: {
  398. select: {
  399. fn: function(combo) {
  400. var previewButton = Ext.getCmp('fred-element-panel-preview-option-set');
  401. if (combo.getValue() === 0) {
  402. previewButton.disable();
  403. } else {
  404. previewButton.enable();
  405. }
  406. },
  407. scope: this
  408. }
  409. }
  410. }
  411. ]
  412. },
  413. {
  414. columnWidth: .2,
  415. border: false,
  416. defaults: {
  417. msgTarget: 'under',
  418. anchor: '100%'
  419. },
  420. items: [
  421. {
  422. xtype: 'button',
  423. id: 'fred-element-panel-preview-option-set',
  424. text: _('fred.element_option_sets.preview'),
  425. fieldLabel: '&nbsp;',
  426. handler: this.previewOptionSet,
  427. scope: this
  428. }
  429. ]
  430. }
  431. ]
  432. },
  433. {
  434. xtype: Ext.ComponentMgr.isRegistered('modx-texteditor') ? 'modx-texteditor' : 'textarea',
  435. fieldLabel: _('fred.elements.options_override'),
  436. mimeType: 'application/json',
  437. name: 'options_override',
  438. id: 'fred-element-options-override',
  439. anchor: '100%',
  440. height: 400,
  441. grow: false,
  442. }
  443. ]
  444. }
  445. ]
  446. }
  447. ];
  448. return items;
  449. },
  450. previewOptionSet: function(btn, e) {
  451. var optionSetId = this.getField('option_set').getValue();
  452. if (optionSetId === 0) return;
  453. MODx.Ajax.request({
  454. url: this.config.url,
  455. params: {
  456. action: 'mgr/element_option_sets/get',
  457. id: optionSetId
  458. },
  459. listeners: {
  460. 'success': {
  461. fn: function (r) {
  462. var record = {data: ''};
  463. if (Array.isArray(r.object.data) && r.object.data.length === 0) {
  464. record.data = '';
  465. } else {
  466. if (typeof r.object.data === 'object') {
  467. record.data = JSON.stringify(r.object.data, null, 2);
  468. }
  469. }
  470. var updateElementOptionSet = MODx.load({
  471. xtype: 'fred-window-element-option-set-preview',
  472. record: record,
  473. listeners: {
  474. success: {
  475. fn: function () {
  476. this.refresh();
  477. },
  478. scope: this
  479. }
  480. }
  481. });
  482. updateElementOptionSet.fp.getForm().reset();
  483. updateElementOptionSet.fp.getForm().setValues(record);
  484. updateElementOptionSet.show(e.target);
  485. },
  486. scope: this
  487. }
  488. }
  489. });
  490. }
  491. });
  492. Ext.reg('fred-panel-element', fred.panel.Element);