modx.component.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. MODx.Component = function(config) {
  2. config = config || {};
  3. MODx.Component.superclass.constructor.call(this,config);
  4. this.config = config;
  5. this._loadForm();
  6. if (this.config.tabs) {
  7. this._loadTabs();
  8. }
  9. this._loadComponents();
  10. this._loadActionButtons();
  11. MODx.activePage = this;
  12. };
  13. Ext.extend(MODx.Component,Ext.Component,{
  14. fields: {}
  15. ,form: null
  16. ,action: false
  17. ,_loadForm: function() {
  18. if (!this.config.form) { return false; }
  19. this.form = new Ext.form.BasicForm(Ext.get(this.config.form),{ errorReader : MODx.util.JSONReader });
  20. if (this.config.fields) {
  21. for (var i in this.config.fields) {
  22. if (this.config.fields.hasOwnProperty(i)) {
  23. var f = this.config.fields[i];
  24. if (f.xtype) {
  25. f = Ext.ComponentMgr.create(f);
  26. }
  27. this.fields[i] = f;
  28. this.form.add(f);
  29. }
  30. }
  31. }
  32. return this.form.render();
  33. }
  34. ,_loadActionButtons: function() {
  35. if (!this.config.buttons) { return false; }
  36. this.ab = MODx.load({
  37. xtype: 'modx-actionbuttons'
  38. ,form: this.form || null
  39. ,formpanel: this.config.formpanel || null
  40. ,actions: this.config.actions || null
  41. ,items: this.config.buttons || []
  42. });
  43. return this.ab;
  44. }
  45. ,_loadTabs: function() {
  46. if (!this.config.tabs) { return false; }
  47. var o = this.config.tabOptions || {};
  48. Ext.applyIf(o,{
  49. xtype: 'modx-tabs'
  50. ,renderTo: this.config.tabs_div || 'tabs_div'
  51. ,items: this.config.tabs
  52. });
  53. return MODx.load(o);
  54. }
  55. ,_loadComponents: function() {
  56. if (!this.config.components) { return false; }
  57. var l = this.config.components.length;
  58. var cp = Ext.getCmp('modx-content');
  59. for (var i=0;i<l;i=i+1) {
  60. var a = MODx.load(this.config.components[i]);
  61. if (cp) {
  62. cp.add(a);
  63. }
  64. }
  65. if (cp) {
  66. cp.doLayout();
  67. }
  68. return true;
  69. }
  70. ,submitForm: function(listeners,options,otherParams) {
  71. listeners = listeners || {};
  72. otherParams = otherParams || {};
  73. if (!this.config.formpanel || !this.config.action) { return false; }
  74. f = Ext.getCmp(this.config.formpanel);
  75. if (!f) { return false; }
  76. for (var i in listeners) {
  77. if (typeof listeners[i] == 'function') {
  78. f.on(i,listeners[i],this);
  79. } else if (listeners[i] && typeof listeners[i] == 'object' && listeners[i].fn) {
  80. f.on(i,listeners[i].fn,listeners[i].scope || this);
  81. }
  82. }
  83. Ext.apply(f.baseParams,{
  84. 'action':this.config.action
  85. });
  86. Ext.apply(f.baseParams,otherParams);
  87. options = options || {};
  88. options.headers = {
  89. 'Powered-By': 'MODx'
  90. ,'modAuth': MODx.siteId
  91. };
  92. f.submit(options);
  93. return true;
  94. }
  95. });
  96. Ext.reg('modx-component',MODx.Component);
  97. MODx.toolbar.ActionButtons = function(config) {
  98. config = config || {};
  99. Ext.applyIf(config,{
  100. actions: { 'close': 'welcome' }
  101. ,formpanel: false
  102. ,id: 'modx-action-buttons'
  103. ,params: {}
  104. ,items: []
  105. ,renderTo: Ext.get('modx-action-buttons-container') ? 'modx-action-buttons-container' : 'modx-container'
  106. });
  107. if (config.formpanel) {
  108. this.setupDirtyButtons(config.formpanel);
  109. }
  110. this.checkDirtyBtns = [];
  111. MODx.toolbar.ActionButtons.superclass.constructor.call(this,config);
  112. this.config = config;
  113. };
  114. Ext.extend(MODx.toolbar.ActionButtons,Ext.Toolbar,{
  115. id: ''
  116. ,buttons: []
  117. ,options: { a_close: 'welcome' }
  118. ,add: function() {
  119. var a = arguments, l = a.length;
  120. for(var i = 0; i < l; i++) {
  121. var el = a[i];
  122. var ex = ['-','->','<-','',' '];
  123. if (ex.indexOf(el) != -1 || (el.xtype && el.xtype == 'switch')) {
  124. MODx.toolbar.ActionButtons.superclass.add.call(this,el);
  125. continue;
  126. }
  127. var id = el.id || Ext.id();
  128. Ext.applyIf(el,{
  129. xtype: 'button'
  130. ,cls: (el.icon ? 'x-btn-icon bmenu' : 'x-btn-text bmenu')
  131. ,scope: this
  132. ,disabled: el.checkDirty ? true : false
  133. ,listeners: {}
  134. ,id: id
  135. });
  136. if (el.button) {
  137. MODx.toolbar.ActionButtons.superclass.add.call(this,el);
  138. }
  139. if (el.handler === null && el.menu === null) {
  140. el.handler = this.checkConfirm;
  141. } else if (el.confirm && el.handler) {
  142. el.handler = function() {
  143. Ext.Msg.confirm(_('warning'),el.confirm,function(e) {
  144. if (e === 'yes') { Ext.callback(el.handler,this); }
  145. },el.scope || this);
  146. };
  147. } else if (el.handler) {} else { el.handler = this.handleClick; }
  148. /* if javascript is specified, run it when button is click, before this.checkConfirm is run */
  149. if (el.javascript) {
  150. el.listeners['click'] = {fn:this.evalJS,scope:this};
  151. }
  152. /* if checkDirty, disable until field change */
  153. if (el.xtype == 'button') {
  154. el.listeners['render'] = {fn:function(btn) {
  155. if (el.checkDirty && btn) {
  156. this.checkDirtyBtns.push(btn);
  157. }
  158. },scope:this}
  159. }
  160. if (el.keys) {
  161. el.keyMap = new Ext.KeyMap(Ext.get(document));
  162. for (var j = 0; j < el.keys.length; j++) {
  163. var key = el.keys[j];
  164. Ext.applyIf(key,{
  165. scope: this
  166. ,stopEvent: true
  167. ,fn: function(e) {
  168. var b = Ext.getCmp(id);
  169. if (b) this.checkConfirm(b,e);
  170. }
  171. });
  172. el.keyMap.addBinding(key);
  173. }
  174. el.listeners['destroy'] = {fn:function(btn) {
  175. btn.keyMap.disable();
  176. },scope:this}
  177. }
  178. /* add button to toolbar */
  179. MODx.toolbar.ActionButtons.superclass.add.call(this,el);
  180. }
  181. }
  182. ,evalJS: function(itm,e) {
  183. if (!eval(itm.javascript)) {
  184. e.stopEvent();
  185. e.preventDefault();
  186. }
  187. }
  188. ,checkConfirm: function(itm,e) {
  189. if (itm.confirm !== null && itm.confirm !== undefined) {
  190. this.confirm(itm,function() {
  191. this.handleClick(itm,e);
  192. },this);
  193. } else { this.handleClick(itm,e); }
  194. return false;
  195. }
  196. ,confirm: function(itm,callback,scope) {
  197. /* if no message go ahead and redirect...we dont like blank questions */
  198. if (itm.confirm === null) { return true; }
  199. Ext.Msg.confirm('',itm.confirm,function(e) {
  200. /* if the user is okay with the action */
  201. if (e === 'yes') {
  202. if (callback === null) { return true; }
  203. if (typeof(callback) === 'function') { /* if callback is a function, run it, and pass Button */
  204. Ext.callback(callback,scope || this,[itm]);
  205. } else { location.href = callback; }
  206. }
  207. return true;
  208. },this);
  209. return true;
  210. }
  211. ,reloadPage: function() {
  212. location.href = location.href;
  213. }
  214. ,handleClick: function(itm,e) {
  215. var o = this.config;
  216. if (o.formpanel === false || o.formpanel === undefined || o.formpanel === null) return false;
  217. if (itm.method === 'remote') { /* if using connectors */
  218. MODx.util.Progress.reset();
  219. o.form = Ext.getCmp(o.formpanel);
  220. if (!o.form) return false;
  221. var f = o.form.getForm ? o.form.getForm() : o.form;
  222. var isv = true;
  223. if (f.items && f.items.items) {
  224. for (var fld in f.items.items) {
  225. if (f.items.items[fld] && f.items.items[fld].validate) {
  226. var fisv = f.items.items[fld].validate();
  227. if (!fisv) {
  228. f.items.items[fld].markInvalid();
  229. isv = false;
  230. }
  231. }
  232. }
  233. }
  234. if (isv) {
  235. Ext.applyIf(o.params,{
  236. action: itm.process
  237. });
  238. Ext.apply(f.baseParams,o.params);
  239. o.form.on('success',function(r) {
  240. if (o.form.clearDirty) o.form.clearDirty();
  241. /* allow for success messages */
  242. MODx.msg.status({
  243. title: _('success')
  244. ,message: r.result.message || _('save_successful')
  245. ,dontHide: r.result.message != '' ? true : false
  246. });
  247. if (itm.redirect != false) {
  248. var redirect = this.redirect;
  249. if (typeof itm.redirect == 'function') {
  250. redirect = itm.redirect;
  251. }
  252. Ext.callback(redirect,this,[o,itm,r.result],1000);
  253. }
  254. this.resetDirtyButtons(r.result);
  255. },this);
  256. o.form.submit({
  257. headers: {
  258. 'Powered-By': 'MODx'
  259. ,'modAuth': MODx.siteId
  260. }
  261. });
  262. } else {
  263. o.form.fireEvent('failureSubmit');
  264. Ext.Msg.alert(_('error'),_('correct_errors'));
  265. }
  266. } else {
  267. // if just doing a URL redirect
  268. var params = itm.params || {};
  269. Ext.applyIf(params, o.baseParams || {});
  270. MODx.loadPage('?' + Ext.urlEncode(params));
  271. }
  272. return false;
  273. }
  274. ,resetDirtyButtons: function(r) {
  275. for (var i=0;i<this.checkDirtyBtns.length;i=i+1) {
  276. var btn = this.checkDirtyBtns[i];
  277. btn.setDisabled(true);
  278. }
  279. }
  280. ,redirect: function(o,itm,res) {
  281. o = this.config;
  282. itm.params = itm.params || {};
  283. Ext.applyIf(itm.params,o.baseParams);
  284. var url;
  285. var process = itm.process.substr(itm.process.lastIndexOf('/') + 1);
  286. if ((process === 'create' || process === 'duplicate' || itm.reload) && res.object.id) {
  287. itm.params.id = res.object.id;
  288. if (MODx.request.parent) { itm.params.parent = MODx.request.parent; }
  289. if (MODx.request.context_key) { itm.params.context_key = MODx.request.context_key; }
  290. url = Ext.urlEncode(itm.params);
  291. var action;
  292. if (o.actions && o.actions.edit) {
  293. // If an edit action is given, use it (BC)
  294. action = o.actions.edit;
  295. } else {
  296. // Else assume we want the 'update' controller
  297. action = itm.process.replace('create', 'update');
  298. }
  299. MODx.loadPage(action, url);
  300. } else if (process === 'delete') {
  301. itm.params.a = o.actions.cancel;
  302. url = Ext.urlEncode(itm.params);
  303. MODx.loadPage('?'+url);
  304. }
  305. }
  306. ,refreshTreeNode: function(tree,node,self) {
  307. var t = parent.Ext.getCmp(tree);
  308. t.refreshNode(node,self || false);
  309. return false;
  310. }
  311. ,setupDirtyButtons: function(f) {
  312. var fp = Ext.getCmp(f);
  313. if (fp) {
  314. fp.on('fieldChange',function(o) {
  315. for (var i=0;i<this.checkDirtyBtns.length;i=i+1) {
  316. var btn = this.checkDirtyBtns[i];
  317. btn.setDisabled(false);
  318. }
  319. },this);
  320. }
  321. }
  322. });
  323. Ext.reg('modx-actionbuttons',MODx.toolbar.ActionButtons);