You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
extJS Cheat Sheet with the most needed stuff
Notifications You must be signed in to change notification settings
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Go to file# We recommend extracting Ext JS in a fixed location in your "home" directory: C:\Users\Me\sencha-sdks # Windows /Users/Me/sencha-sdks # Mac OS X /home/me/sencha-sdks # Linux # After unzipping Ext JS in this folder, you should see a sub-folder such as the following (on Windows): C:\Users\Myname\sencha-sdks\ext-6.5.3 # Now that Sencha Cmd is installed and the Ext JS SDK is extracted, let's configure Sencha Cmd with this location. For example (on Windows): sencha config --prop sencha.sdk.path=C:\Users\Me\sencha-sdks --save
# To create the application, open a terminal or command prompt and create an empty directory and "cd" into it: md ~/myapp # On Windows, replace "~" with "C:\Users\Me" cd ~/myapp # From this directory, we run "sencha app init" to create the application on disk: sencha app init --ext@6.5.3 --modern MyApp
This will produce a few lines of output as the application code is generated and the necessary pieces of Ext JS are copied into the current directory. The current directory should now contain:
Ext.getCmp(id) Ext.ComponentQuery.query(attribute)
Ext.getApplication().getMainView().getViewModel().get(‘user’)
sencha app watch
You will see a few lines of information as Sencha Cmd builds the application, but there are two to take note of:
. [INF] Application available at http://localhost:1841 … [INF] Waiting for changes...
While app watch is running, a basic web server is serving the application directory. Now we can load http://localhost:1841 in the browser and see the application.
Sencha Cmd is also monitoring your application directory for changes. Should you make changes to the styling or JavaScript code, Sencha Cmd will detect these changes and update the necessary build outputs to keep the application rendering correctly in the browser. As your changes are detected, Sencha Cmd will log a few lines of output and (in typically a couple seconds) end with "Waiting for changes…" to let you know everything is ready.
Ext.application( name: 'MyApp', requires: [ 'Ext.MessageBox' ], launch: function () Ext.Msg.alert('Hello Ext JS', 'Hello! Welcome to Ext JS.'); > >);
In an MVC architecture, most classes are either Models, Views or Controllers. The user interacts with Views, which display data held in Models. Those interactions are monitored by a Controller, which then responds to the interactions by updating the View and Model, as necessary.
The View and the Model are generally unaware of each other because the Controller has the sole responsibility of directing updates. Generally speaking, Controllers will contain most of the application logic within an MVC application. Views ideally have little (if any) business logic. Models are primarily an interface to data and contain business logic to manage changes to said data.
The goal of MVC is to clearly define the responsibilities for each class in the application. Because every class has clearly defined responsibilities, they implicitly become decoupled from the larger environment. This makes the app easier to test and maintain, and its code more reusable.
The key difference between MVC and MVVM is that MVVM features an abstraction of a View called the ViewModel. The ViewModel coordinates the changes between a Model’s data and the View's presentation of that data using a technique called “data binding”.
The result is that the Model and framework perform as much work as possible, minimizing or eliminating application logic that directly manipulates the View.
The Ext namespace (global object) encapsulates all classes, singletons, and utility methods provided by Sencha's libraries.
Most user interface Components are at a lower level of nesting in the namespace, but many common utility functions are provided as direct properties of the Ext namespace.
Also many frequently used methods from other classes are provided as shortcuts within the Ext namespace. For example Ext.getCmp aliases Ext.ComponentManager.get.
Many applications are initiated with Ext.application which is called once the DOM is ready. This ensures all scripts have been loaded, preventing dependency issues. For example:
Ext.application( name: 'MyApp', // Once the required classes are loaded and the browser is ready, the launch method is called. This is where the application performs its startup sequence. To get things started, let's define an application class and our main view.Once the required classes are loaded and the browser is ready, the launch method is called. This is where the application performs its startup sequence. To get things started, let's define an application class and our main view. launch: function () Ext.Msg.alert(this.name, 'Ready to go!'); > >);
Ext.application( name: 'MyApp', requires: [ 'Ext.MessageBox' ], launch: function () Ext.Msg.alert('Hello Ext JS', 'Hello! Welcome to Ext JS.'); > >);
Ext.application( name: 'MyApp', extend: 'MyApp.Application', // requires: [ 'MyApp.*' // tell Cmd to include all app classes ] >);
Ext.application( name: 'MyApp', requires: [ 'Ext.MessageBox' ], launch: function () Ext.Msg.alert('Hello Ext JS', 'Hello! Welcome to Ext JS.'); > >);
When a view controller is specified on a view, events and other handlers that use strings as values will be automatically connected with the appropriate methods in the controller's class.
Ext.define('MyViewController', extend : 'Ext.app.ViewController', alias: 'controller.myview', // This method is called as a "handler" for the Add button in our view onAddClick: function() Ext.Msg.alert('Add', 'The Add button was clicked'); > >); Ext.define('MyView', extend: 'Ext.Panel', controller: 'myview', items: [ xtype: 'button', text: 'Add', handler: 'onAddClick', // calls MyViewController's onAddClick method >] >); Ext.onReady(function() new MyView( renderTo: Ext.getBody(), width: 400, height: 200 >); >);
formulas: xy: function (get) return get('x') * get('y'); > >
formulas: xy: get: function (get) return get('x') * get('y'); > > >
Ext.define('My.awesome.Class', someProperty: 'something', someMethod: function(s) alert(s + this.someProperty); > ... >); var obj = new My.awesome.Class(); obj.someMethod('Say '); // alerts 'Say something'
Ext.define(null, constructor: function () // . > >);
./app/Application.js Ext.define('MyApp.Application', extend: 'Ext.app.Application', mainView: 'MyApp.view.main.Main' >);
If Ext.Loader is enabled and the class has not been defined yet, it will attempt to load the class via synchronous loading.
For example, all these three lines return the same result:
// xtype var window = Ext.create( xtype: 'window', width: 600, height: 800, . >); // alias var window = Ext.create('widget.window', width: 600, height: 800, . >); // alternate name var window = Ext.create('Ext.Window', width: 600, height: 800, . >); // full class name var window = Ext.create('Ext.window.Window', width: 600, height: 800, . >); // single object with xclass property: var window = Ext.create( xclass: 'Ext.window.Window', // any valid value for 'name' (above) width: 600, height: 800, . >);
Ext.define('App.util.Thing', extend: 'App.util.Other', alias: 'util.thing', config: foo: 42 > >);
Ext.define('Mother', requires: ['Child'], giveBirth: function() // we can be sure that child class is available. return new Child(); > >);
Ext.define('Person', say: function(text) alert(text); > >); Ext.define('Developer', extend: 'Person', say: function(text) this.callParent(["print "+text]); > >);
Ext.define('MyApp.CoolPanel', extend: 'Ext.panel.Panel', alias: ['widget.coolpanel'], title: 'Yeah!' >); // Using Ext.create Ext.create('widget.coolpanel'); // Using the shorthand for defining widgets by xtype Ext.widget('panel', items: [ xtype: 'coolpanel', html: 'Foo'>, xtype: 'coolpanel', html: 'Bar'> ] >);
// User in this case is the Class we will create. Ext.define('User', extend: 'Ext.data.Model', fields: [ name: 'name', type: 'string'>, name: 'age', type: 'int', convert: null>, name: 'phone', type: 'string'>, name: 'alive', type: 'boolean', defaultValue: true, convert: null> ], changeName: function() var oldName = this.get('name'), newName = oldName + " The Barbarian"; this.set('name', newName); > >); const user = Ext.create('User', id : 'ABCD12345', name : 'Conan', age : 24, phone: '555-555-5555' >); user.changeName(); user.get('name'); //returns "Conan The Barbarian"
To alter which field is the identifying field, use the idProperty config.
Models have built-in support for field validators. Validators are added to models as in the follow example:
Ext.define('User', extend: 'Ext.data.Model', fields: [ name: 'name', type: 'string' >, name: 'age', type: 'int' >, name: 'phone', type: 'string' >, name: 'gender', type: 'string' >, name: 'username', type: 'string' >, name: 'alive', type: 'boolean', defaultValue: true > ], validators: age: 'presence', name: type: 'length', min: 2 >, gender: type: 'inclusion', list: ['Male', 'Female'] >, username: [ type: 'exclusion', list: ['Admin', 'Operator'] >, type: 'format', matcher: /([a-z]+)[0-9]/i > ] > >);
var instance = Ext.create('User', name: 'Ed', gender: 'Male', username: 'edspencer' >); var validation = instance.getValidation();
The returned object is an instance of Ext.data.Validation and has as its fields the result of the field validators. The validation object is "dirty" if there are one or more validation errors present.
Ext.define('User', extend: 'Ext.data.Model', fields: ['id', 'name', 'email'], proxy: type: 'rest', url : '/users' > >); var user = Ext.create('User', name: 'Ed Spencer', email: 'ed@sencha.com'>); user.save(); //POST /users // Loading data via the Proxy is accomplished with the static load method: // Uses the configured RestProxy to make a GET request to /users/123 User.load(123, success: function(user) console.log(user.getId()); //logs 123 > >);
var store = Ext.create('Ext.data.Store', autoLoad: true, model: "User", proxy: type: 'ajax', url: 'users.json', reader: type: 'json', rootProperty: 'users' > > >);
//the user Model we loaded in the last snippet: user.set('name', 'Edward Spencer'); //tells the Proxy to save the Model. In this case it will perform a PUT request to /users/123 as this Model already has an id user.save( success: function() console.log('The User was updated'); > >); //tells the Proxy to destroy the Model. Performs a DELETE request to /users/123 user.erase( success: function() console.log('The User was destroyed!'); > >);
Ext.define('MyApp.model.User', extend: 'Ext.data.Model', fields: [ name: 'id', type: 'int'>, name: 'name', type: 'string'> ], proxy: type: 'ajax', url: 'server.url' > >); var user = new MyApp.model.User( name: 'Foo' >); // pass the phantom record data to the server to be saved user.save( failure: function(record, operation) // do something if the save failed >, success: function(record, operation) // do something if the save succeeded >, callback: function(record, operation, success) // do something whether the save succeeded or failed > >);
Creating a Store is easy - we just tell it the Model and the Proxy to use for loading and saving its data:
// ---- EXAMPLE #1 - .create() ---- Ext.define('User', extend: 'Ext.data.Model', fields: [ name: 'firstName', type: 'string'>, name: 'lastName', type: 'string'>, name: 'age', type: 'int'>, name: 'eyeColor', type: 'string'> ] >); var myStore = Ext.create('Ext.data.Store', model: 'User', proxy: type: 'ajax', url: '/users.json', reader: type: 'json', rootProperty: 'users' > >, autoLoad: true >); /* ---- EXAMPLE #2 - .define() ---- */ // MainVM.js (ViewModel) Ext.define('MyFirstApp.MainVM', extend: 'Ext.app.ViewModel', stores: chartstore: type: 'chartstore'> >, alias: 'viewmodel.mainvm' >); // UserChart.js (View) Ext.define('MyFirstApp.user.UserChart', extend: 'Ext.chart.PolarChart', width: 400, height: 400, theme: 'green', interactions: ['rotate', 'itemhighlight'], requires: ['MyFirstApp.user.UserChartStore'], bind: store: ''>, series: type: 'pie', highlight: true, angleField: 'data1', label: field: 'name', display: 'rotate' >, donut: 30 >, alias: 'widget.chartcustom' >); // UserChartStore.js (Store) Ext.define('MyFirstApp.user.UserChartStore', extend: 'Ext.data.Store', autoLoad: true, fields: ['name', 'data1'], data: [ name: 'metric one', data1: 14 >, name: 'metric two', data1: 16 >, name: 'metric three', data1: 14 >, name: 'metric four', data1: 6 >, name: 'metric five', data1: 36 >], alias: 'store.chartstore' >);
Ext.define('MyFirstApp.user.UserChartStore', extend: 'Ext.data.Store', autoLoad: true, listeners: load: function(store) console.log("MyFirstApp.user.UserChartStore loaded..") console.log("store.data.items: " + store.data) Ext.each(store.data.items,function(rec) console.log('rec name: ' + rec.data.name); >); > >, proxy: type: 'ajax', url: 'User.json' >, alias: 'store.chartstore' >);
var store = Ext.getStore('hobbystore') store.load( params: group: 3, type: 'user' >, callback: function(records, operation, success) // do something after the load finishes >, scope: this >); // When you are inside of the ViewController it looks like this Ext.define('MyFirstApp.MainVC', extend: 'Ext.app.ViewController', alias: 'controller.mainvc', addDuplicatedProperties(store) var store = this.getStore('hobbystore').loadData(yourNewDatahere); > >);
var store = Ext.create('Ext.data.Store', model: 'User', sorters: [ property: 'age', direction: 'DESC' >, property: 'firstName', direction: 'ASC' >], filters: [ property: 'firstName', value: /Peter/ >] >); store.filter('eyeColor', 'Brown'); store.sort('height', 'ASC');
var store = Ext.create('Ext.data.Store', autoLoad: true, model: "User", proxy: type: 'ajax', url: 'users.json', reader: type: 'json', rootProperty: 'users' > > >); /* "users": [ "id": 1, "name": "Peter", "orders": [ "id": 10, "total": 10.76, "status": "invoiced" >, "id": 11, "total": 13.45, "status": "shipped" >] >] > */
Ext.create('Ext.form.Panel', title: 'Simple Form', bodyPadding: 5, width: 350, // The form will submit an AJAX request to this URL when submitted url: 'save-form.php', // Fields will be arranged vertically, stretched to full width layout: 'anchor', defaults: anchor: '100%' >, // The fields defaultType: 'textfield', items: [ fieldLabel: 'First Name', name: 'first', allowBlank: false >, fieldLabel: 'Last Name', name: 'last', allowBlank: false >], // Reset and Submit buttons buttons: [ text: 'Reset', handler: function() this.up('form').getForm().reset(); > >, text: 'Submit', formBind: true, //only enabled once the form is valid disabled: true, handler: function() var form = this.up('form').getForm(); if (form.isValid()) form.submit( success: function(form, action) Ext.Msg.alert('Success', action.result.msg); >, failure: function(form, action) Ext.Msg.alert('Failed', action.result.msg); > >); > > >], renderTo: Ext.getBody() >);
var store = Ext.create('Ext.data.Store', fields: ['name', 'email', 'phone', 'active'], data: [ name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224', active: true >, name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234', active: true >, name: 'Homer', email: 'homer@simpsons.com', phone: '555-222-1244', active: false >, name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254', active: true > ] >); Ext.create('Ext.grid.Panel', title: 'Simpsons', height: 200, width: 400, renderTo: Ext.getBody(), store: store, columns: [ text: 'Name', dataIndex: 'name' >, text: 'Email', dataIndex: 'email', flex: 1 >, text: 'Phone', dataIndex: 'phone' >, xtype: 'checkcolumn', text: 'Active', dataIndex: 'active' > ] >);
Grids are composed of two main pieces - a Ext.data.Store full of data and a set of columns to render.
Ext.create('Ext.data.Store', storeId: 'simpsonsStore', fields:[ 'name', 'email', 'phone'], data: [ name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224' >, name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234' >, name: 'Homer', email: 'homer@simpsons.com', phone: '555-222-1244' >, name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254' > ] >); Ext.create('Ext.grid.Panel', title: 'Simpsons', store: Ext.data.StoreManager.lookup('simpsonsStore'), columns: [ text: 'Name', dataIndex: 'name' >, text: 'Email', dataIndex: 'email', flex: 1 >, text: 'Phone', dataIndex: 'phone' > ], height: 200, width: 400, renderTo: Ext.getBody() >);
columns: [ text: 'Name', dataIndex: 'name', sortable: false, hideable: false, flex: 1 >, text: 'Email', dataIndex: 'email', hidden: true >, text: 'Phone', dataIndex: 'phone', width: 100 > ]
columns: [ text: 'Email', dataIndex: 'email', renderer: function(value) return Ext.String.format('"> ', value, value); > > ]
var myGrid = Ext.create('Ext.grid.Panel', store: fields: ['name', 'email', 'phone'], sorters: ['name', 'phone'] >, columns: [ text: 'Name', dataIndex: 'name' >, text: 'Email', dataIndex: 'email' > ] >); // Sorting at run time is easily accomplished by simply clicking each column header. If you need to perform sorting on more than one field at run time it's easy to do so by adding new sorters to the store: myGrid.store.sort([ property: 'name', direction: 'ASC' >, property: 'email', direction: 'DESC' > ]);
new Ext.panel.Panel( width: 400, height: 200, dockedItems: [ xtype: 'toolbar' >], listeners: click: element: 'el', //bind to the underlying el property on the panel fn: function() console.log('click el'); > >, dblclick: element: 'body', //bind to the underlying body property on the panel fn: function() console.log('dblclick body'); > > > >);
// row is this // record are field from the model listeners: itemClick: fn: function(row, record) Ext.Msg.alert('Details', ` Name: $record.get('name')> Description: $record.get('description')> Image URL: $record.get('profileImg')> ` ) > > >
Panels are, by virtue of their inheritance from Ext.container.Container, capable of being configured with a layout, and containing child Components.
When either specifying child cfg-items of a Panel, or dynamically adding Components to a Panel, remember to consider how you wish the Panel to arrange those child elements, and whether those child elements need to be sized using one of Ext's built-in layout schemes. By default, Panels use the Ext.layout.container.Auto scheme. This simply renders child components, appending them one after the other inside the Container, and does not apply any sizing at all.
Ext.create('Ext.panel.Panel', title: 'Hello', width: 200, html: 'World!
', renderTo: Ext.getBody() >);
var panel = new Ext.panel.Panel( dockedItems: [ xtype: 'toolbar', dock: 'top', items: [ text: 'Docked to the top' >] >] >);
dockedItems: [ xtype: 'toolbar', dock: 'top', items: [ xtype: 'button', text: 'save', handler: 'doSave', bind: disabled: '' > >] >],
Ext.create( xtype: 'polar', renderTo: document.body, width: 400, height: 400, theme: 'green', interactions: ['rotate', 'itemhighlight'], store: fields: ['name', 'data1'], data: [ name: 'metric one', data1: 14 >, name: 'metric two', data1: 16 >, name: 'metric three', data1: 14 >, name: 'metric four', data1: 6 >, name: 'metric five', data1: 36 >] >, series: type: 'pie', highlight: true, angleField: 'data1', label: field: 'name', display: 'rotate' >, tooltip: trackMouse: true, width: 140, height: 28, renderer: function (toolTip, record, ctx) var percent = 0; var total = 0; record.store.each(function(rec) total += rec.get('data1'); >); percent = Math.round(record.get('data1') / total * 100) + '%'; toolTip.setHtml(percent); > >, donut: 30 > >);