associations.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. Ext.require([
  2. 'Ext.data.*',
  3. 'Ext.panel.Panel',
  4. 'Ext.layout.container.Card',
  5. 'Ext.tip.QuickTipManager'
  6. ]);
  7. Ext.define('Customer', {
  8. extend: 'Ext.data.Model',
  9. fields: [{
  10. name: 'id',
  11. type: 'int'
  12. }, 'name', 'phone'],
  13. associations: [{
  14. model: 'Order',
  15. type: 'hasMany',
  16. autoLoad: true
  17. }],
  18. proxy: {
  19. type: 'ajax',
  20. url: 'customer.php'
  21. }
  22. });
  23. Ext.define('Order', {
  24. extend: 'Ext.data.Model',
  25. fields: [{
  26. name: 'id',
  27. type: 'int'
  28. },{
  29. name: 'customer_id',
  30. type: 'int'
  31. },{
  32. name: 'date',
  33. type: 'date',
  34. dateFormat: 'Y-m-d'
  35. }],
  36. belongsTo: 'Customer',
  37. associations: [{
  38. model: 'OrderItem',
  39. type: 'hasMany',
  40. autoLoad: true
  41. }],
  42. proxy: {
  43. type: 'ajax',
  44. url: 'order.php'
  45. }
  46. });
  47. Ext.define('OrderItem', {
  48. extend: 'Ext.data.Model',
  49. fields: [{
  50. name: 'id',
  51. type: 'int'
  52. }, {
  53. name: 'order_id',
  54. type: 'int'
  55. },'product', {
  56. name: 'quantity',
  57. type: 'int'
  58. }, {
  59. name: 'price',
  60. type: 'float'
  61. }],
  62. belongsTo: 'Order',
  63. proxy: {
  64. type: 'ajax',
  65. url: 'orderitem.php'
  66. }
  67. });
  68. Ext.define('CustomerGrid', {
  69. extend: 'Ext.grid.Panel',
  70. alias: 'widget.customergrid',
  71. title: 'Customers',
  72. initComponent: function(){
  73. Ext.apply(this, {
  74. store: {
  75. autoLoad: true,
  76. model: 'Customer',
  77. listeners: {
  78. load: function() {
  79. Logger.log('Customer store loaded', false);
  80. }
  81. }
  82. },
  83. columns: [{
  84. text: 'Id',
  85. dataIndex: 'id'
  86. },{
  87. text: 'Name',
  88. dataIndex: 'name',
  89. flex: 1
  90. }, {
  91. text: 'Phone',
  92. dataIndex: 'phone'
  93. }],
  94. dockedItems: [{
  95. xtype: 'toolbar',
  96. items: {
  97. itemId: 'load',
  98. text: 'Load Orders',
  99. scope: this,
  100. handler: this.loadOrders,
  101. disabled: true
  102. }
  103. }]
  104. });
  105. this.callParent();
  106. this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
  107. },
  108. onSelectChange: function(selModel, selections) {
  109. this.active = selections[0];
  110. this.down('#load').setDisabled(!this.active);
  111. },
  112. loadOrders: function(){
  113. var rec = this.active,
  114. name = rec.get('name'),
  115. owner = this.ownerCt,
  116. orders;
  117. orders = rec.orders();
  118. if (orders.isLoading()) {
  119. Logger.log('Begin loading orders: ' + rec.getId(), true);
  120. }
  121. orders.on('load', function(){
  122. Logger.log('Order store loaded - ' + rec.getId(), false);
  123. });
  124. owner.add({
  125. title: 'Orders - ' + rec.getId(),
  126. customer: rec,
  127. xtype: 'ordergrid',
  128. store: orders
  129. });
  130. owner.getLayout().next();
  131. }
  132. });
  133. Ext.define('OrderGrid', {
  134. extend: 'Ext.grid.Panel',
  135. alias: 'widget.ordergrid',
  136. initComponent: function(){
  137. Ext.apply(this, {
  138. columns: [{
  139. text: 'Id',
  140. dataIndex: 'id'
  141. },{
  142. flex: 1,
  143. text: 'Date',
  144. dataIndex: 'date',
  145. renderer: Ext.util.Format.dateRenderer('Y-m-d')
  146. }],
  147. dockedItems: [{
  148. xtype: 'toolbar',
  149. items: [{
  150. text: 'Back',
  151. scope: this,
  152. handler: this.onBackClick
  153. },{
  154. itemId: 'load',
  155. text: 'Load Order Items',
  156. scope: this,
  157. handler: this.loadItems,
  158. disabled: true
  159. }]
  160. }]
  161. });
  162. this.callParent();
  163. this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
  164. },
  165. onBackClick: function(){
  166. this.ownerCt.getLayout().prev();
  167. this.destroy();
  168. },
  169. onSelectChange: function(selModel, selections) {
  170. this.active = selections[0];
  171. this.down('#load').setDisabled(!this.active);
  172. },
  173. loadItems: function(){
  174. var customerName = this.customer.get('name'),
  175. rec = this.active,
  176. date = Ext.Date.format(rec.get('date'), 'Y-m-d'),
  177. owner = this.ownerCt,
  178. orderitems;
  179. orderitems = rec.orderitems();
  180. if (orderitems.isLoading()) {
  181. Logger.log('Begin loading order items - ' + rec.getId(), true);
  182. }
  183. orderitems.on('load', function(){
  184. Logger.log('Order items loaded - ' + rec.getId(), false);
  185. });
  186. owner.add({
  187. title: 'Order Items - ' + rec.getId(),
  188. xtype: 'orderitemgrid',
  189. store: orderitems
  190. });
  191. owner.getLayout().next();
  192. }
  193. });
  194. Ext.define('OrderItemGrid', {
  195. extend: 'Ext.grid.Panel',
  196. alias: 'widget.orderitemgrid',
  197. initComponent: function(){
  198. Ext.apply(this, {
  199. columns: [{
  200. text: 'Id',
  201. dataIndex: 'id'
  202. },{
  203. flex: 1,
  204. text: 'Product',
  205. dataIndex: 'product'
  206. }, {
  207. text: 'Quantity',
  208. dataIndex: 'quantity'
  209. }, {
  210. text: 'Price',
  211. dataIndex: 'price',
  212. renderer: Ext.util.Format.usMoney
  213. }],
  214. dockedItems: [{
  215. xtype: 'toolbar',
  216. items: [{
  217. text: 'Back',
  218. scope: this,
  219. handler: this.onBackClick
  220. }, {
  221. itemId: 'load',
  222. text: 'Parent association loader',
  223. tooltip: 'Demonstrate loading parent relationships - A new record will be created so we ignore any previous associations setup',
  224. scope: this,
  225. handler: this.onLoadClick,
  226. disabled: true
  227. }]
  228. }]
  229. });
  230. this.callParent();
  231. this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
  232. },
  233. onSelectChange: function(selModel, selections) {
  234. this.active = selections[0];
  235. this.down('#load').setDisabled(!this.active);
  236. },
  237. onBackClick: function(){
  238. this.ownerCt.getLayout().prev();
  239. this.destroy();
  240. },
  241. onLoadClick: function(){
  242. var rec = this.active,
  243. id = rec.getId();
  244. new ItemLoader({
  245. width: 400,
  246. height: 400,
  247. modal: true,
  248. title: this.title.replace('Order Items', 'Order Item ' + id),
  249. orderItemData: rec.data,
  250. orderItemId: id
  251. }).show();
  252. }
  253. });
  254. Ext.define('ItemLoader', {
  255. extend: 'Ext.window.Window',
  256. initComponent: function(){
  257. Ext.apply(this, {
  258. border: false,
  259. autoScroll: true,
  260. dockedItems: [{
  261. xtype: 'toolbar',
  262. items: [{
  263. text: 'Print order detail',
  264. scope: this,
  265. handler: this.onOrderClick
  266. }, {
  267. itemId: 'company',
  268. text: 'Print company detail',
  269. disabled: true,
  270. scope: this,
  271. handler: this.onCompanyClick
  272. }]
  273. }],
  274. bodyPadding: 5,
  275. tpl: '<div>{type} {id} - {value}</div>',
  276. tplWriteMode: 'append'
  277. });
  278. this.callParent();
  279. this.orderItem = new OrderItem(this.orderItemData, this.orderItemId);
  280. },
  281. onOrderClick: function(){
  282. var id = this.orderItem.get('order_id'),
  283. hasOrder = !!this.order;
  284. if (!hasOrder) {
  285. Logger.log('Begin loading order - ' + id, true);
  286. }
  287. this.orderItem.getOrder({
  288. scope: this,
  289. success: function(order){
  290. this.order = order;
  291. this.down('#company').enable();
  292. if (!hasOrder) {
  293. Logger.log('Order loaded - ' + id, false);
  294. }
  295. this.update({
  296. type: 'Order',
  297. id: order.getId(),
  298. value: Ext.Date.format(order.get('date'), 'Y-m-d')
  299. });
  300. }
  301. });
  302. },
  303. onCompanyClick: function(){
  304. var id = this.order.get('customer_id'),
  305. hasCustomer = !!this.customer;
  306. if (!hasCustomer) {
  307. Logger.log('Begin loading customer - ' + id, true);
  308. }
  309. this.order.getCustomer({
  310. scope: this,
  311. success: function(customer){
  312. this.customer = customer;
  313. if (!hasCustomer) {
  314. Logger.log('Customer loaded - ' + id, false);
  315. }
  316. this.update({
  317. type: 'Customer',
  318. id: customer.getId(),
  319. value: customer.get('name')
  320. });
  321. }
  322. });
  323. }
  324. });
  325. Logger = (function(){
  326. var panel;
  327. return {
  328. init: function(log){
  329. panel = log;
  330. },
  331. log: function(msg, isStart){
  332. panel.update({
  333. now: new Date(),
  334. cls: isStart ? 'beforeload' : 'afterload',
  335. msg: msg
  336. });
  337. panel.body.scroll('b', 100000, true);
  338. }
  339. };
  340. })();
  341. Ext.onReady(function(){
  342. var main = Ext.create('Ext.panel.Panel', {
  343. renderTo: document.body,
  344. width: 750,
  345. height: 400,
  346. border: false,
  347. layout: {
  348. type: 'vbox',
  349. align: 'stretch'
  350. },
  351. items: [{
  352. height: 200,
  353. xtype: 'container',
  354. layout: 'card',
  355. margin: '0 0 5 0'
  356. }, {
  357. flex: 1,
  358. title: 'Loader log',
  359. tplWriteMode: 'append',
  360. tpl: '<div class="{cls}">[{now:date("H:i:s")}] - {msg}</div>',
  361. bodyPadding: 5,
  362. autoScroll: true,
  363. listeners: {
  364. render: Logger.init
  365. }
  366. }]
  367. });
  368. Logger.log('Begin loading customer store', true);
  369. main.items.first().add({
  370. xtype: 'customergrid'
  371. });
  372. });