modx.grid.source.properties.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. MODx.grid.SourceProperties = function(config) {
  2. config = config || {};
  3. this.exp = new Ext.grid.RowExpander({
  4. tpl : new Ext.Template(
  5. '<p class="modx-property-description"><i>{desc_trans}</i></p>'
  6. )
  7. });
  8. Ext.applyIf(config,{
  9. title: _('properties')
  10. ,id: 'modx-grid-source-properties'
  11. ,maxHeight: 300
  12. ,fields: ['name','desc','xtype','options','value','lexicon','overridden','desc_trans']
  13. ,autoExpandColumn: 'value'
  14. ,sortBy: 'name'
  15. ,width: '100%'
  16. ,sm: new Ext.grid.RowSelectionModel({singleSelect:false})
  17. ,loadMask: true
  18. ,lockProperties: true
  19. ,panel: 'modx-panel-source'
  20. ,plugins: [this.exp]
  21. ,columns: [this.exp,{
  22. header: _('name')
  23. ,dataIndex: 'name'
  24. ,width: 200
  25. ,sortable: true
  26. ,renderer: this._renderName
  27. },{
  28. header: _('type')
  29. ,dataIndex: 'xtype'
  30. ,width: 100
  31. ,renderer: this._renderType
  32. ,sortable: true
  33. },{
  34. header: _('value')
  35. ,dataIndex: 'value'
  36. ,id: 'value'
  37. ,width: 250
  38. ,renderer: this.renderDynField.createDelegate(this,[this],true)
  39. ,sortable: true
  40. }]
  41. ,tbar: [{
  42. text: _('property_create')
  43. ,id: 'modx-btn-property-create'
  44. ,cls: 'primary-button'
  45. ,handler: this.create
  46. ,scope: this
  47. },{
  48. text: _('property_revert_all')
  49. ,id: 'modx-btn-property-revert-all'
  50. ,handler: this.revertAll
  51. ,scope:this
  52. }]
  53. ,collapseFirst: false
  54. ,tools: [{
  55. id: 'plus'
  56. ,qtip: _('expand_all')
  57. ,handler: this.expandAll
  58. ,scope: this
  59. },{
  60. id: 'minus'
  61. ,hidden: true
  62. ,qtip: _('collapse_all')
  63. ,handler: this.collapseAll
  64. ,scope: this
  65. }]
  66. });
  67. MODx.grid.SourceProperties.superclass.constructor.call(this,config);
  68. this.on('afteredit', this.propertyChanged, this);
  69. this.on('afterRemoveRow', this.propertyChanged, this);
  70. this.on('celldblclick',this.onDirty,this);
  71. this.on('render',function() {
  72. this.mask = new Ext.LoadMask(this.getEl());
  73. },this);
  74. };
  75. Ext.extend(MODx.grid.SourceProperties,MODx.grid.LocalProperty,{
  76. defaultProperties: []
  77. ,onDirty: function() {
  78. if (this.config.panel) {
  79. Ext.getCmp(this.config.panel).fireEvent('fieldChange');
  80. }
  81. }
  82. ,_renderType: function(v,md,rec,ri) {
  83. switch (v) {
  84. case 'combo-boolean': return _('yesno'); break;
  85. case 'datefield': return _('date'); break;
  86. case 'numberfield': return _('integer'); break;
  87. }
  88. return _(v);
  89. }
  90. ,_renderName: function(v,md,rec,ri) {
  91. switch (rec.data.overridden) {
  92. case 1:
  93. return '<span style="color: green;">'+v+'</span>'; break;
  94. case 2:
  95. return '<span style="color: purple;">'+v+'</span>';
  96. default:
  97. return '<span>'+v+'</span>';
  98. }
  99. }
  100. ,create: function(btn,e) {
  101. this.loadWindow(btn,e,{
  102. xtype: 'modx-window-source-property-create'
  103. ,blankValues: true
  104. ,listeners: {
  105. 'success': {fn:function(r) {
  106. var rec = new this.propRecord({
  107. name: r.name
  108. ,desc: r.desc
  109. ,desc_trans: r.desc
  110. ,xtype: r.xtype
  111. ,options: r.options
  112. ,value: r.value
  113. ,lexicon: r.lexicon
  114. ,overridden: 2
  115. });
  116. this.getStore().add(rec);
  117. this.propertyChanged();
  118. this.onDirty();
  119. },scope:this}
  120. }
  121. });
  122. }
  123. ,update: function(btn,e) {
  124. this.loadWindow(btn,e,{
  125. xtype: 'modx-window-source-property-update'
  126. ,record: this.menu.record
  127. ,listeners: {
  128. 'success': {fn:function(r) {
  129. var s = this.getStore();
  130. var ri = this.menu.recordIndex;
  131. var d = this.defaultProperties[ri];
  132. d = (d && d[4]) ? d[4] : r.value;
  133. var rec = s.getAt(this.menu.recordIndex);
  134. rec.set('name',r.name);
  135. rec.set('desc',r.desc);
  136. rec.set('desc_trans', r.desc);
  137. rec.set('xtype',r.xtype);
  138. rec.set('options',r.options);
  139. rec.set('value',r.value);
  140. rec.set('lexicon',r.lexicon);
  141. rec.set('overridden',r.overridden == 2 ? 2 : (d.toString() == r.value.toString() ? 0 : 1));
  142. this.getView().refresh();
  143. this.onDirty();
  144. },scope:this}
  145. }
  146. });
  147. }
  148. ,revert: function(btn,e) {
  149. Ext.Msg.confirm(_('warning'),_('property_revert_confirm'),function(e) {
  150. if (e == 'yes') {
  151. var ri = this.menu.recordIndex;
  152. var d = this.defaultProperties[ri];
  153. if (d) {
  154. var rec = this.getStore().getAt(ri);
  155. rec.set('name',d[0]);
  156. rec.set('desc',d[1]);
  157. rec.set('xtype',d[2]);
  158. rec.set('options',d[3]);
  159. rec.set('value',d[4]);
  160. rec.set('overridden',0);
  161. rec.commit();
  162. }
  163. }
  164. },this);
  165. }
  166. ,revertAll: function(btn,e) {
  167. Ext.Msg.confirm(_('warning'),_('property_revert_all_confirm'),function(e) {
  168. if (e == 'yes') {
  169. this.getStore().loadData(this.defaultProperties);
  170. }
  171. },this);
  172. }
  173. ,removeMultiple: function(btn,e) {
  174. var rows = this.getSelectionModel().getSelections();
  175. var rids = [];
  176. for (var i=0;i<rows.length;i=i+1) {
  177. rids.push(rows[i].data.id);
  178. }
  179. Ext.Msg.confirm(_('warning'),_('properties_remove_confirm'),function(e) {
  180. if (e == 'yes') {
  181. for (var f=0;f<rows.length;f=f+1) {
  182. this.store.remove(rows[f]);
  183. }
  184. }
  185. },this);
  186. }
  187. ,_showMenu: function(g,ri,e) {
  188. var sm = this.getSelectionModel();
  189. if (sm.getSelections().length > 1) {
  190. e.stopEvent();
  191. e.preventDefault();
  192. this.menu.removeAll();
  193. this.addContextMenuItem([{
  194. text: _('properties_remove')
  195. ,handler: this.removeMultiple
  196. ,scope: this
  197. }]);
  198. this.menu.show(e.target);
  199. } else {
  200. MODx.grid.SourceProperties.superclass._showMenu.call(this,g,ri,e);
  201. }
  202. }
  203. ,getMenu: function() {
  204. var def = false;
  205. var r = this.menu.record;
  206. var m = []
  207. m.push({
  208. text: _('property_update')
  209. ,scope: this
  210. ,handler: this.update
  211. });
  212. if (r.overridden) {
  213. m.push({
  214. text: _('property_revert')
  215. ,scope: this
  216. ,handler: this.revert
  217. });
  218. }
  219. if (r.overridden != 1) {
  220. m.push({
  221. text: _('property_remove')
  222. ,scope: this
  223. ,handler: this.remove.createDelegate(this,[{
  224. title: _('warning')
  225. ,text: _('property_remove_confirm')
  226. }])
  227. });
  228. }
  229. return m;
  230. }
  231. ,propertyChanged: function() {
  232. var ep = Ext.getCmp(this.config.panel);
  233. if (!ep) return false;
  234. var hf = ep.getForm().findField((this.config.hiddenPropField || 'props'));
  235. if (hf) {
  236. hf.setValue('1');
  237. ep.fireEvent('fieldChange',{
  238. field: hf
  239. ,form: ep.getForm()
  240. });
  241. }
  242. return true;
  243. }
  244. });
  245. Ext.reg('modx-grid-source-properties',MODx.grid.SourceProperties);
  246. MODx.grid.SourcePropertyOption = function(config) {
  247. config = config || {};
  248. Ext.applyIf(config,{
  249. title: _('property_options')
  250. ,id: 'modx-grid-source-property-options'
  251. ,autoHeight: true
  252. ,maxHeight: 300
  253. ,width: '100%'
  254. ,fields: ['text','value','name']
  255. ,data: []
  256. ,columns: [{
  257. header: _('name')
  258. ,dataIndex: 'text'
  259. ,width: 150
  260. ,editor: { xtype: 'textfield' ,allowBlank: false }
  261. },{
  262. header: _('value')
  263. ,dataIndex: 'value'
  264. ,id: 'value'
  265. ,width: 250
  266. ,editor: { xtype: 'textfield' ,allowBlank: true }
  267. }]
  268. ,tbar: [{
  269. text: _('property_option_create')
  270. ,cls: 'primary-button'
  271. ,handler: this.create
  272. ,scope: this
  273. }]
  274. });
  275. MODx.grid.SourcePropertyOption.superclass.constructor.call(this,config);
  276. this.optRecord = Ext.data.Record.create([{name: 'text'},{name: 'value'}]);
  277. };
  278. Ext.extend(MODx.grid.SourcePropertyOption,MODx.grid.LocalGrid,{
  279. create: function(btn,e) {
  280. this.loadWindow(btn,e,{
  281. xtype: 'modx-window-source-property-option-create'
  282. ,listeners: {
  283. 'success': {fn:function(r) {
  284. var rec = new this.optRecord({
  285. text: r.text
  286. ,value: r.value
  287. });
  288. this.getStore().add(rec);
  289. },scope:this}
  290. }
  291. });
  292. }
  293. ,getMenu: function() {
  294. return [{
  295. text: _('property_option_remove')
  296. ,scope: this
  297. ,handler: this.remove.createDelegate(this,[{
  298. title: _('warning')
  299. ,text: _('property_option_remove_confirm')
  300. }])
  301. }];
  302. }
  303. });
  304. Ext.reg('modx-grid-source-property-options',MODx.grid.SourcePropertyOption);
  305. /**
  306. * @class MODx.window.CreateSourceProperty
  307. * @extends MODx.Window
  308. * @param {Object} config An object of configuration properties
  309. * @xtype modx-window-source-property-create
  310. */
  311. MODx.window.CreateSourceProperty = function(config) {
  312. config = config || {};
  313. Ext.applyIf(config,{
  314. title: _('property_create')
  315. ,id: 'modx-window-source-property-create'
  316. // ,height: 250
  317. // ,width: 450
  318. ,saveBtnText: _('done')
  319. ,fields: [{
  320. fieldLabel: _('name')
  321. ,name: 'name'
  322. ,id: 'modx-cep-name'
  323. ,xtype: 'textfield'
  324. ,anchor: '100%'
  325. ,allowBlank: false
  326. },{
  327. fieldLabel: _('description')
  328. ,name: 'desc'
  329. ,id: 'modx-cep-desc'
  330. ,xtype: 'textarea'
  331. ,anchor: '100%'
  332. },{
  333. fieldLabel: _('type')
  334. ,name: 'xtype'
  335. ,id: 'modx-cep-xtype'
  336. ,xtype: 'modx-combo-xtype'
  337. ,anchor: '100%'
  338. ,listeners: {
  339. 'select': {fn:function(cb,r,i) {
  340. var g = Ext.getCmp('modx-cep-grid-source-property-options');
  341. if (!g) return;
  342. if (cb.getValue() == 'list') {
  343. g.show();
  344. } else {
  345. g.hide();
  346. }
  347. this.syncSize();
  348. },scope:this}
  349. }
  350. },{
  351. xtype: 'textfield'
  352. ,fieldLabel: _('lexicon')
  353. ,name: 'lexicon'
  354. ,id: 'modx-cep-lexicon'
  355. ,anchor: '100%'
  356. ,allowBlank: true
  357. },{
  358. xtype: 'modx-source-value-field'
  359. ,xtypeField: 'modx-cep-xtype'
  360. ,id: 'modx-cep-value'
  361. ,anchor: '100%'
  362. },{
  363. xtype: 'modx-grid-source-property-options'
  364. ,id: 'modx-cep-grid-source-property-options'
  365. }]
  366. });
  367. MODx.window.CreateSourceProperty.superclass.constructor.call(this,config);
  368. this.on('show',this.onShow,this);
  369. };
  370. Ext.extend(MODx.window.CreateSourceProperty,MODx.Window,{
  371. submit: function() {
  372. var v = this.fp.getForm().getValues();
  373. var g = Ext.getCmp('modx-cep-grid-source-property-options');
  374. var opt = eval(g.encode());
  375. Ext.apply(v,{
  376. options: opt
  377. });
  378. if (this.fp.getForm().isValid()) {
  379. if (this.fireEvent('success',v)) {
  380. this.fp.getForm().reset();
  381. this.hide();
  382. return true;
  383. }
  384. }
  385. return false;
  386. }
  387. ,onShow: function() {
  388. var g = Ext.getCmp('modx-cep-grid-source-property-options');
  389. g.getStore().removeAll();
  390. g.hide();
  391. this.syncSize();
  392. this.center();
  393. }
  394. });
  395. Ext.reg('modx-window-source-property-create',MODx.window.CreateSourceProperty);
  396. /**
  397. * @class MODx.window.UpdateSourceProperty
  398. * @extends MODx.Window
  399. * @param {Object} config An object of configuration properties
  400. * @xtype modx-window-source-property-update
  401. */
  402. MODx.window.UpdateSourceProperty = function(config) {
  403. config = config || {};
  404. Ext.applyIf(config,{
  405. title: _('property_update')
  406. ,id: 'modx-window-source-property-update'
  407. // ,height: 250
  408. // ,width: 450
  409. ,saveBtnText: _('done')
  410. ,forceLayout: true
  411. ,fields: [{
  412. fieldLabel: _('name')
  413. ,name: 'name'
  414. ,id: 'modx-uep-name'
  415. ,xtype: 'textfield'
  416. ,anchor: '100%'
  417. },{
  418. fieldLabel: _('description')
  419. ,name: 'desc'
  420. ,id: 'modx-uep-desc'
  421. ,xtype: 'textarea'
  422. ,anchor: '100%'
  423. },{
  424. fieldLabel: _('type')
  425. ,name: 'xtype'
  426. ,xtype: 'modx-combo-xtype'
  427. ,id: 'modx-uep-xtype'
  428. ,anchor: '100%'
  429. ,listeners: {
  430. 'select': {fn:function(cb,r,i) {
  431. var g = Ext.getCmp('modx-uep-grid-source-property-options');
  432. if (!g) return;
  433. var v = cb.getValue();
  434. if (v == 'list') {
  435. g.show();
  436. } else {
  437. g.hide();
  438. }
  439. this.syncSize();
  440. },scope:this}
  441. }
  442. },{
  443. xtype: 'textfield'
  444. ,fieldLabel: _('lexicon')
  445. ,name: 'lexicon'
  446. ,id: 'modx-uep-lexicon'
  447. ,anchor: '100%'
  448. ,allowBlank: true
  449. },{
  450. xtype: 'hidden'
  451. ,name: 'overridden'
  452. ,id: 'modx-uep-overridden'
  453. },{
  454. xtype: 'modx-source-value-field'
  455. ,xtypeField: 'modx-uep-xtype'
  456. ,name: 'value'
  457. ,anchor: '100%'
  458. ,id: 'modx-uep-value'
  459. },{
  460. id: 'modx-uep-grid-source-property-options'
  461. ,xtype: 'modx-grid-source-property-options'
  462. ,autoHeight: true
  463. }]
  464. });
  465. MODx.window.UpdateSourceProperty.superclass.constructor.call(this,config);
  466. this.on('show',this.onShow,this);
  467. };
  468. Ext.extend(MODx.window.UpdateSourceProperty,MODx.Window,{
  469. submit: function() {
  470. var v = this.fp.getForm().getValues();
  471. var g = Ext.getCmp('modx-uep-grid-source-property-options');
  472. var opt = eval(g.encode());
  473. Ext.apply(v,{
  474. options: opt
  475. });
  476. if (this.fp.getForm().isValid()) {
  477. if (this.fireEvent('success',v)) {
  478. this.fp.getForm().reset();
  479. this.hide();
  480. return true;
  481. }
  482. }
  483. return false;
  484. }
  485. ,onShow: function() {
  486. var g = Ext.getCmp('modx-uep-grid-source-property-options');
  487. if (!g) return;
  488. if (this.fp.getForm().findField('xtype').getValue() == 'list') {
  489. g.show();
  490. } else {
  491. g.hide();
  492. }
  493. g.getStore().removeAll();
  494. var gp = Ext.getCmp('modx-grid-source-properties');
  495. var rec = gp.getSelectionModel().getSelected();
  496. if (rec) {
  497. var opt = rec.data.options;
  498. var opts = [];
  499. for (var x in opt) {
  500. if (opt.hasOwnProperty(x)) {
  501. opts.push([opt[x].text,opt[x].value]);
  502. }
  503. }
  504. g.getStore().loadData(opts);
  505. }
  506. this.syncSize();
  507. this.center();
  508. }
  509. });
  510. Ext.reg('modx-window-source-property-update',MODx.window.UpdateSourceProperty);
  511. /**
  512. * @class MODx.window.CreateSourcePropertyOption
  513. * @extends MODx.Window
  514. * @param {Object} config An object of configuration properties
  515. * @xtype modx-window-source-property-option-create
  516. */
  517. MODx.window.CreateSourcePropertyOption = function(config) {
  518. config = config || {};
  519. Ext.applyIf(config,{
  520. title: _('property_option_create')
  521. ,id: 'modx-window-source-property-option-create'
  522. // ,height: 250
  523. // ,width: 450
  524. ,saveBtnText: _('done')
  525. ,fields: [{
  526. fieldLabel: _('name')
  527. ,name: 'text'
  528. ,id: 'modx-cepo-text'
  529. ,xtype: 'textfield'
  530. ,anchor: '100%'
  531. },{
  532. fieldLabel: _('value')
  533. ,name: 'value'
  534. ,id: 'modx-cepo-value'
  535. ,xtype: 'textfield'
  536. ,anchor: '100%'
  537. }]
  538. });
  539. MODx.window.CreateSourcePropertyOption.superclass.constructor.call(this,config);
  540. };
  541. Ext.extend(MODx.window.CreateSourcePropertyOption,MODx.Window,{
  542. submit: function() {
  543. if (this.fp.getForm().isValid()) {
  544. if (this.fireEvent('success',this.fp.getForm().getValues())) {
  545. this.fp.getForm().reset();
  546. this.hide();
  547. return true;
  548. }
  549. }
  550. return false;
  551. }
  552. });
  553. Ext.reg('modx-window-source-property-option-create',MODx.window.CreateSourcePropertyOption);
  554. /**
  555. * Displays a xtype combobox
  556. *
  557. * @class MODx.combo.xType
  558. * @extends Ext.form.ComboBox
  559. * @param {Object} config An object of configuration properties
  560. * @xtype modx-combo-xtype
  561. */
  562. MODx.combo.xType = function(config) {
  563. config = config || {};
  564. Ext.applyIf(config,{
  565. store: new Ext.data.SimpleStore({
  566. fields: ['d','v']
  567. ,data: [
  568. [_('textfield'),'textfield']
  569. ,[_('textarea'),'textarea']
  570. ,[_('yesno'),'combo-boolean']
  571. ,[_('date'),'datefield']
  572. ,[_('list'),'list']
  573. ,[_('integer'),'numberfield']
  574. ]
  575. })
  576. ,displayField: 'd'
  577. ,valueField: 'v'
  578. ,mode: 'local'
  579. ,name: 'xtype'
  580. ,hiddenName: 'xtype'
  581. ,triggerAction: 'all'
  582. ,editable: false
  583. ,selectOnFocus: false
  584. ,value: 'textfield'
  585. });
  586. MODx.combo.xType.superclass.constructor.call(this,config);
  587. };
  588. Ext.extend(MODx.combo.xType,Ext.form.ComboBox);
  589. Ext.reg('modx-combo-xtype',MODx.combo.xType);
  590. MODx.form.SourceValueField = function(config) {
  591. config = config || {};
  592. Ext.applyIf(config,{
  593. fieldLabel: _('value')
  594. ,name: 'value'
  595. ,xtype: 'textfield'
  596. ,anchor: '100%'
  597. });
  598. MODx.form.SourceValueField.superclass.constructor.call(this,config);
  599. this.config = config;
  600. this.on('change',this.checkValue,this);
  601. };
  602. Ext.extend(MODx.form.SourceValueField,Ext.form.TextField,{
  603. checkValue: function(fld,nv,ov) {
  604. var t = Ext.getCmp(this.config.xtypeField).getValue();
  605. var v = fld.getValue();
  606. if (t == 'combo-boolean') {
  607. v = (v == '1' || v == 'true' || v == 1 || v == true || v == _('yes') || v == 'yes') ? 1 : 0;
  608. fld.setValue(v);
  609. }
  610. }
  611. });
  612. Ext.reg('modx-source-value-field',MODx.form.SourceValueField);