-/*!
- * Ext JS Library 3.0.0
- * Copyright(c) 2006-2009 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
-// Application instance for showing user-feedback messages.
-var App = new Ext.App({});
-
-// Create HttpProxy instance. Notice new configuration parameter "api" here instead of load. However, you can still use
-// the "url" paramater -- All CRUD requests will be directed to your single url instead.
-var proxy = new Ext.data.HttpProxy({
- api: {
- read : 'app.php/users/view',
- create : 'app.php/users/create',
- update: 'app.php/users/update',
- destroy: 'app.php/users/destroy'
- }
-});
+Ext.define('Writer.Form', {
+ extend: 'Ext.form.Panel',
+ alias: 'widget.writerform',
-// Typical JsonReader. Notice additional meta-data params for defining the core attributes of your json-response
-var reader = new Ext.data.JsonReader({
- totalProperty: 'total',
- successProperty: 'success',
- idProperty: 'id',
- root: 'data'
-}, [
- {name: 'id'},
- {name: 'email', allowBlank: false},
- {name: 'first', allowBlank: false},
- {name: 'last', allowBlank: false}
-]);
+ requires: ['Ext.form.field.Text'],
-// The new DataWriter component.
-var writer = new Ext.data.JsonWriter({
- encode: true,
- writeAllFields: false
-});
+ initComponent: function(){
+ this.addEvents('create');
+ Ext.apply(this, {
+ activeRecord: null,
+ iconCls: 'icon-user',
+ frame: true,
+ title: 'User -- All fields are required',
+ defaultType: 'textfield',
+ bodyPadding: 5,
+ fieldDefaults: {
+ anchor: '100%',
+ labelAlign: 'right'
+ },
+ items: [{
+ fieldLabel: 'Email',
+ name: 'email',
+ allowBlank: false,
+ vtype: 'email'
+ }, {
+ fieldLabel: 'First',
+ name: 'first',
+ allowBlank: false
+ }, {
+ fieldLabel: 'Last',
+ name: 'last',
+ allowBlank: false
+ }],
+ dockedItems: [{
+ xtype: 'toolbar',
+ dock: 'bottom',
+ ui: 'footer',
+ items: ['->', {
+ iconCls: 'icon-save',
+ itemId: 'save',
+ text: 'Save',
+ disabled: true,
+ scope: this,
+ handler: this.onSave
+ }, {
+ iconCls: 'icon-user-add',
+ text: 'Create',
+ scope: this,
+ handler: this.onCreate
+ }, {
+ iconCls: 'icon-reset',
+ text: 'Reset',
+ scope: this,
+ handler: this.onReset
+ }]
+ }]
+ });
+ this.callParent();
+ },
-// Typical Store collecting the Proxy, Reader and Writer together.
-var store = new Ext.data.Store({
- id: 'user',
- proxy: proxy,
- reader: reader,
- writer: writer, // <-- plug a DataWriter into the store just as you would a Reader
- autoSave: true, // <-- false would delay executing create, update, destroy requests until specifically told to do so with some [save] buton.
- listeners: {
- write : function(store, action, result, res, rs) {
- App.setAlert(res.success, res.message); // <-- show user-feedback for all write actions
- },
- exception : function(proxy, type, action, options, res, arg) {
- if (type === 'remote') {
- Ext.Msg.show({
- title: 'REMOTE EXCEPTION',
- msg: res.message,
- icon: Ext.MessageBox.ERROR,
- buttons: Ext.Msg.OK
- });
- }
+ setActiveRecord: function(record){
+ this.activeRecord = record;
+ if (record) {
+ this.down('#save').enable();
+ this.getForm().loadRecord(record);
+ } else {
+ this.down('#save').disable();
+ this.getForm().reset();
+ }
+ },
+
+ onSave: function(){
+ var active = this.activeRecord,
+ form = this.getForm();
+
+ if (!active) {
+ return;
+ }
+ if (form.isValid()) {
+ form.updateRecord(active);
+ this.onReset();
+ }
+ },
+
+ onCreate: function(){
+ var form = this.getForm();
+
+ if (form.isValid()) {
+ this.fireEvent('create', this, form.getValues());
+ form.reset();
}
+
+ },
+
+ onReset: function(){
+ this.setActiveRecord(null);
+ this.getForm().reset();
}
});
+Ext.define('Writer.Grid', {
+ extend: 'Ext.grid.Panel',
+ alias: 'widget.writergrid',
+
+ requires: [
+ 'Ext.grid.plugin.CellEditing',
+ 'Ext.form.field.Text',
+ 'Ext.toolbar.TextItem'
+ ],
+
+ initComponent: function(){
-// A new generic text field
-var textField = new Ext.form.TextField();
+ this.editing = Ext.create('Ext.grid.plugin.CellEditing');
-// Let's pretend we rendered our grid-columns with meta-data from our ORM framework.
-var userColumns = [
- {header: "ID", width: 40, sortable: true, dataIndex: 'id'},
- {header: "Email", width: 100, sortable: true, dataIndex: 'email', editor: textField},
- {header: "First", width: 50, sortable: true, dataIndex: 'first', editor: textField},
- {header: "Last", width: 50, sortable: true, dataIndex: 'last', editor: textField}
-];
+ Ext.apply(this, {
+ iconCls: 'icon-grid',
+ frame: true,
+ plugins: [this.editing],
+ dockedItems: [{
+ xtype: 'toolbar',
+ items: [{
+ iconCls: 'icon-add',
+ text: 'Add',
+ scope: this,
+ handler: this.onAddClick
+ }, {
+ iconCls: 'icon-delete',
+ text: 'Delete',
+ disabled: true,
+ itemId: 'delete',
+ scope: this,
+ handler: this.onDeleteClick
+ }]
+ }, {
+ weight: 2,
+ xtype: 'toolbar',
+ dock: 'bottom',
+ items: [{
+ xtype: 'tbtext',
+ text: '<b>@cfg</b>'
+ }, '|', {
+ text: 'autoSync',
+ enableToggle: true,
+ pressed: true,
+ tooltip: 'When enabled, Store will execute Ajax requests as soon as a Record becomes dirty.',
+ scope: this,
+ toggleHandler: function(btn, pressed){
+ this.store.autoSync = pressed;
+ }
+ }, {
+ text: 'batch',
+ enableToggle: true,
+ pressed: true,
+ tooltip: 'When enabled, Store will batch all records for each type of CRUD verb into a single Ajax request.',
+ scope: this,
+ toggleHandler: function(btn, pressed){
+ this.store.getProxy().batchActions = pressed;
+ }
+ }, {
+ text: 'writeAllFields',
+ enableToggle: true,
+ pressed: false,
+ tooltip: 'When enabled, Writer will write *all* fields to the server -- not just those that changed.',
+ scope: this,
+ toggleHandler: function(btn, pressed){
+ this.store.getProxy().getWriter().writeAllFields = pressed;
+ }
+ }]
+ }, {
+ weight: 1,
+ xtype: 'toolbar',
+ dock: 'bottom',
+ ui: 'footer',
+ items: ['->', {
+ iconCls: 'icon-save',
+ text: 'Sync',
+ scope: this,
+ handler: this.onSync
+ }]
+ }],
+ columns: [{
+ text: 'ID',
+ width: 40,
+ sortable: true,
+ dataIndex: 'id'
+ }, {
+ header: 'Email',
+ flex: 1,
+ sortable: true,
+ dataIndex: 'email',
+ field: {
+ type: 'textfield'
+ }
+ }, {
+ header: 'First',
+ width: 100,
+ sortable: true,
+ dataIndex: 'first',
+ field: {
+ type: 'textfield'
+ }
+ }, {
+ header: 'Last',
+ width: 100,
+ sortable: true,
+ dataIndex: 'last',
+ field: {
+ type: 'textfield'
+ }
+ }]
+ });
+ this.callParent();
+ this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
+ },
+
+ onSelectChange: function(selModel, selections){
+ this.down('#delete').setDisabled(selections.length === 0);
+ },
-// load the store immeditately
-store.load();
+ onSync: function(){
+ this.store.sync();
+ },
+ onDeleteClick: function(){
+ var selection = this.getView().getSelectionModel().getSelection()[0];
+ if (selection) {
+ this.store.remove(selection);
+ }
+ },
-Ext.onReady(function() {
- Ext.QuickTips.init();
+ onAddClick: function(){
+ var rec = new Writer.Person({
+ first: '',
+ last: '',
+ email: ''
+ }), edit = this.editing;
- // create user.Form instance (@see UserForm.js)
- var userForm = new App.user.Form({
- renderTo: 'user-form',
+ edit.cancelEdit();
+ this.store.insert(0, rec);
+ edit.startEditByPosition({
+ row: 0,
+ column: 1
+ });
+ }
+});
+
+Ext.define('Writer.Person', {
+ extend: 'Ext.data.Model',
+ fields: [{
+ name: 'id',
+ type: 'int',
+ useNull: true
+ }, 'email', 'first', 'last'],
+ validations: [{
+ type: 'length',
+ field: 'email',
+ min: 1
+ }, {
+ type: 'length',
+ field: 'first',
+ min: 1
+ }, {
+ type: 'length',
+ field: 'last',
+ min: 1
+ }]
+});
+
+Ext.require([
+ 'Ext.data.*',
+ 'Ext.tip.QuickTipManager',
+ 'Ext.window.MessageBox'
+]);
+
+Ext.onReady(function(){
+ Ext.tip.QuickTipManager.init();
+ var store = Ext.create('Ext.data.Store', {
+ model: 'Writer.Person',
+ autoLoad: true,
+ autoSync: true,
+ proxy: {
+ type: 'ajax',
+ api: {
+ read: 'app.php/users/view',
+ create: 'app.php/users/create',
+ update: 'app.php/users/update',
+ destroy: 'app.php/users/destroy'
+ },
+ reader: {
+ type: 'json',
+ successProperty: 'success',
+ root: 'data',
+ messageProperty: 'message'
+ },
+ writer: {
+ type: 'json',
+ writeAllFields: false,
+ root: 'data'
+ },
+ listeners: {
+ exception: function(proxy, response, operation){
+ Ext.MessageBox.show({
+ title: 'REMOTE EXCEPTION',
+ msg: operation.getError(),
+ icon: Ext.MessageBox.ERROR,
+ buttons: Ext.Msg.OK
+ });
+ }
+ }
+ },
listeners: {
- create : function(fpanel, data) { // <-- custom "create" event defined in App.user.Form class
- var rec = new userGrid.store.recordType(data);
- userGrid.store.insert(0, rec);
+ write: function(proxy, operation){
+ if (operation.action == 'destroy') {
+ main.child('#form').setActiveRecord(null);
+ }
+ Ext.example.msg(operation.action, operation.resultSet.message);
}
}
});
- // create user.Grid instance (@see UserGrid.js)
- var userGrid = new App.user.Grid({
- renderTo: 'user-grid',
- store: store,
- columns : userColumns,
- listeners: {
- rowclick: function(g, index, ev) {
- var rec = g.store.getAt(index);
- userForm.loadRecord(rec);
- },
- destroy : function() {
- userForm.getForm().reset();
+ var main = Ext.create('Ext.container.Container', {
+ padding: '0 0 0 20',
+ width: 500,
+ height: 450,
+ renderTo: document.body,
+ layout: {
+ type: 'vbox',
+ align: 'stretch'
+ },
+ items: [{
+ itemId: 'form',
+ xtype: 'writerform',
+ height: 150,
+ margins: '0 0 10 0',
+ listeners: {
+ create: function(form, data){
+ store.insert(0, data);
+ }
}
- }
+ }, {
+ itemId: 'grid',
+ xtype: 'writergrid',
+ title: 'User List',
+ flex: 1,
+ store: store,
+ listeners: {
+ selectionchange: function(selModel, selected) {
+ main.child('#form').setActiveRecord(selected[0] || null);
+ }
+ }
+ }]
});
});