Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / examples / data / associations.js
diff --git a/examples/data/associations.js b/examples/data/associations.js
new file mode 100644 (file)
index 0000000..66936c2
--- /dev/null
@@ -0,0 +1,405 @@
+Ext.require([
+    'Ext.data.*',
+    'Ext.panel.Panel',
+    'Ext.layout.container.Card',
+    'Ext.tip.QuickTipManager'
+]);
+
+Ext.define('Customer', {
+    extend: 'Ext.data.Model',
+    fields: [{
+        name: 'id',
+        type: 'int'
+    }, 'name', 'phone'],
+    associations: [{
+        model: 'Order',
+        type: 'hasMany',
+        autoLoad: true
+    }],
+    proxy: {
+        type: 'ajax',
+        url: 'customer.php'
+    }
+});
+
+Ext.define('Order', {
+    extend: 'Ext.data.Model',
+    fields: [{
+        name: 'id',
+        type: 'int'
+    },{
+        name: 'customer_id',
+        type: 'int'
+    },{
+        name: 'date',
+        type: 'date',
+        dateFormat: 'Y-m-d'
+    }],
+    belongsTo: 'Customer',
+    associations: [{
+        model: 'OrderItem',
+        type: 'hasMany',
+        autoLoad: true
+    }],
+    proxy: {
+        type: 'ajax',
+        url: 'order.php'
+    }
+});
+
+Ext.define('OrderItem', {
+    extend: 'Ext.data.Model',
+    fields: [{
+        name: 'id',
+        type: 'int'
+    }, {
+        name: 'order_id',
+        type: 'int'
+    },'product', {
+        name: 'quantity',
+        type: 'int'
+    }, {
+        name: 'price',
+        type: 'float'
+    }],
+    belongsTo: 'Order',
+    proxy: {
+        type: 'ajax',
+        url: 'orderitem.php'
+    }
+});
+
+Ext.define('CustomerGrid', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.customergrid',
+    
+    title: 'Customers',
+    
+    initComponent: function(){
+        Ext.apply(this, {
+            store: {
+                autoLoad: true,
+                model: 'Customer',
+                listeners: {
+                    load: function() {
+                        Logger.log('Customer store loaded', false);
+                    }
+                }
+            },
+            columns: [{
+                text: 'Id',
+                dataIndex: 'id'
+            },{
+                text: 'Name',
+                dataIndex: 'name',
+                flex: 1
+            }, {
+                text: 'Phone',
+                dataIndex: 'phone'
+            }],
+            dockedItems: [{
+                xtype: 'toolbar',
+                items: {
+                    itemId: 'load',
+                    text: 'Load Orders',
+                    scope: this,
+                    handler: this.loadOrders,
+                    disabled: true
+                }
+            }]
+        });
+        this.callParent();
+        this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
+    },
+    
+    onSelectChange: function(selModel, selections) {
+        this.active = selections[0];
+        this.down('#load').setDisabled(!this.active);
+    },
+    
+    loadOrders: function(){
+        var rec = this.active,
+            name = rec.get('name'),
+            owner = this.ownerCt,
+            orders;
+         
+        
+        orders = rec.orders();
+        if (orders.isLoading()) {
+            Logger.log('Begin loading orders: ' + rec.getId(), true);
+        }
+        orders.on('load', function(){
+            Logger.log('Order store loaded - ' + rec.getId(), false);
+        });
+        owner.add({
+            title: 'Orders - ' + rec.getId(),
+            customer: rec,
+            xtype: 'ordergrid',
+            store: orders
+        });
+        owner.getLayout().next();
+    }    
+});
+
+Ext.define('OrderGrid', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.ordergrid',
+    
+    initComponent: function(){
+        Ext.apply(this, {
+            columns: [{
+                text: 'Id',
+                dataIndex: 'id'
+            },{
+                flex: 1,
+                text: 'Date',
+                dataIndex: 'date',
+                renderer: Ext.util.Format.dateRenderer('Y-m-d')
+            }],
+            dockedItems: [{
+                xtype: 'toolbar',
+                items: [{
+                    text: 'Back',
+                    scope: this,
+                    handler: this.onBackClick
+                },{
+                    itemId: 'load',
+                    text: 'Load Order Items',
+                    scope: this,
+                    handler: this.loadItems,
+                    disabled: true
+                }]
+            }]
+        });
+        this.callParent();
+        this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
+    },
+    
+    onBackClick: function(){
+        this.ownerCt.getLayout().prev();
+        this.destroy();    
+    },
+    
+    onSelectChange: function(selModel, selections) {
+        this.active = selections[0];
+        this.down('#load').setDisabled(!this.active);
+    },
+    
+    loadItems: function(){
+        var customerName = this.customer.get('name'),
+            rec = this.active,
+            date = Ext.Date.format(rec.get('date'), 'Y-m-d'),
+            owner = this.ownerCt,
+            orderitems;
+        
+        orderitems = rec.orderitems();
+        if (orderitems.isLoading()) {
+            Logger.log('Begin loading order items - ' + rec.getId(), true);
+        }
+        orderitems.on('load', function(){
+            Logger.log('Order items loaded - ' + rec.getId(), false);
+        });
+        owner.add({
+            title: 'Order Items - ' + rec.getId(),
+            xtype: 'orderitemgrid',
+            store: orderitems
+        });
+        owner.getLayout().next();
+    }    
+});
+
+Ext.define('OrderItemGrid', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.orderitemgrid',
+    
+    initComponent: function(){
+        Ext.apply(this, {
+            columns: [{
+                text: 'Id',
+                dataIndex: 'id'
+            },{
+                flex: 1,
+                text: 'Product',
+                dataIndex: 'product'
+            }, {
+                text: 'Quantity',
+                dataIndex: 'quantity'
+            }, {
+                text: 'Price',
+                dataIndex: 'price',
+                renderer: Ext.util.Format.usMoney
+            }],
+            dockedItems: [{
+                xtype: 'toolbar',
+                items: [{
+                    text: 'Back',
+                    scope: this,
+                    handler: this.onBackClick
+                }, {
+                    itemId: 'load',
+                    text: 'Parent association loader',
+                    tooltip: 'Demonstrate loading parent relationships - A new record will be created so we ignore any previous associations setup',
+                    scope: this,
+                    handler: this.onLoadClick,
+                    disabled: true
+                }]
+            }]
+        });
+        this.callParent();
+        this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
+    },
+    
+    onSelectChange: function(selModel, selections) {
+        this.active = selections[0];
+        this.down('#load').setDisabled(!this.active);
+    },
+    
+    onBackClick: function(){
+        this.ownerCt.getLayout().prev();
+        this.destroy();    
+    },
+    
+    onLoadClick: function(){
+        var rec = this.active,
+            id = rec.getId();
+        
+        new ItemLoader({
+            width: 400,
+            height: 400,
+            modal: true,
+            title: this.title.replace('Order Items', 'Order Item ' + id),
+            orderItemData: rec.data,
+            orderItemId: id
+        }).show();
+    }
+});
+
+Ext.define('ItemLoader', {
+    extend: 'Ext.window.Window',
+    
+    initComponent: function(){
+        Ext.apply(this, {
+            border: false,
+            dockedItems: [{
+                xtype: 'toolbar',
+                items: [{
+                    text: 'Print order detail',
+                    scope: this,
+                    handler: this.onOrderClick
+                }, {
+                    itemId: 'company',
+                    text: 'Print company detail',
+                    disabled: true,
+                    scope: this,
+                    handler: this.onCompanyClick
+                }]
+            }],
+            bodyPadding: 5,
+            tpl: '<div>{type} {id} - {value}</div>',
+            tplWriteMode: 'append'
+        });
+        this.callParent();
+        this.orderItem = new OrderItem(this.orderItemData, this.orderItemId);
+    },
+    
+    onOrderClick: function(){
+        var id = this.orderItem.get('order_id'),
+            hasOrder = !!this.order;
+            
+        if (!hasOrder) {
+            Logger.log('Begin loading order - ' + id, true);
+        }
+        this.orderItem.getOrder({
+            scope: this,
+            success: function(order){
+                this.order = order;
+                this.down('#company').enable();
+                if (!hasOrder) {
+                    Logger.log('Order loaded - ' + id, false);
+                }
+                this.update({
+                    type: 'Order',
+                    id: order.getId(),
+                    value: Ext.Date.format(order.get('date'), 'Y-m-d')
+                });
+            }
+        });
+    },
+    
+    onCompanyClick: function(){
+        var id = this.order.get('customer_id'),
+            hasCustomer = !!this.customer;
+            
+        if (!hasCustomer) {
+            Logger.log('Begin loading customer - ' + id, true);
+        }
+        this.order.getCustomer({
+            scope: this,
+            success: function(customer){
+                this.customer = customer;
+                if (!hasCustomer) {
+                    Logger.log('Customer loaded - ' + id, false);
+                }
+                this.update({
+                    type: 'Customer',
+                    id: customer.getId(),
+                    value: customer.get('name')
+                });
+            }
+        });
+    }    
+});
+
+Logger = (function(){
+    var panel;
+    
+    return {
+        init: function(log){
+            panel = log;
+        },
+        
+        log: function(msg, isStart){
+            panel.update({
+                now: new Date(),
+                cls: isStart ? 'beforeload' : 'afterload',
+                msg: msg
+            });
+            panel.body.scroll('b', 100000, true);
+        }    
+    };
+})();
+
+Ext.onReady(function(){
+    
+    var main = Ext.create('Ext.panel.Panel', {
+        renderTo: document.body,
+        width: 750,
+        height: 400,
+        border: false,
+        layout: {
+            type: 'vbox',
+            align: 'stretch'
+        },
+        items: [{
+            height: 200,
+            xtype: 'container',
+            layout: 'card',
+            margin: '0 0 5 0'
+        }, {
+            flex: 1,
+            title: 'Loader log',
+            tplWriteMode: 'append',
+            tpl: '<div class="{cls}">[{now:date("H:i:s")}] - {msg}</div>',
+            bodyPadding: 5,
+            autoScroll: true,
+            listeners: {
+                render: Logger.init
+            }
+        }]
+    });
+    Logger.log('Begin loading customer store', true);
+    main.items.first().add({
+        xtype: 'customergrid'
+    });
+    
+});