Ext-JS
Ext-JS is a open source JavaScript library for building interactive web applications using techniques such as AJAX , DHTML and DOM scripting.It is easy to use, rich user interface and more it can be a desktop application.It includes:
· High performance,customizable UI widgets
· Well designed and extensible Component model
· An intuitive,easy to use API
· Commercial and Open Source licenses available
Versions:
Ext JS 2.0
Ext JS version 2.0 was released on 4 December 2007. This version was promoted as providing an interface and features more similar to those traditionally associated with desktop applications. Also promoted were the new user documentation, API documentation, and samples.Ext JS 2.0 did not provide backward compatibility with version 1.1. A migration guide was developed to address this.
Ext JS 3.0
Ext JS version 3.0 was released on 6 July 2009. This version added communication support for REST and a new Ext.Direct server side platform. New flash charting and List View elements were added to the standard display components. It was backwards compatible with version 2.0 code.
Ext JS 4.0
Version 4.0 of the Ext framework was released on April 26th, 2011. It includes a completely revised class structure, a revised data package, an animation and drawing package that uses SVG and VML, and revised charting and theming. It also includes an optional architecture that provides a Model-View-Controller style of code organization.
Application support
Ext JS includes web application support with features such as:
Ø modal dialog boxes
Ø interactive user-input validation prompts
Ø state management
Other features include a DOM selector class allowing operations to be performed on elements within the page, data stores that can be used to manage data, and classes to create and manage data in JSON and XML formats.
Ext: Not just another JavaScript library
Ext is not just another JavaScript library—in fact, Ext can work alongside other JavaScript libraries by using adapters Typically, we would use Ext in a web site that requires a high level of user Interaction—something more complex than your typical web site.
Ext makes web application development simple by:
1) Providing easy-to-use cross-browser compatible widgets such as windows, grids, and forms. The widgets are already fine-tuned to handle the intricacies of each web browser on the market, without us needing to change a thing.
2) Interacting with the user and browser via the EventManager, responding to the users keystrokes, mouse clicks, and monitoring events in a browser such as a window resize, or font size changes.
3) Communicating with the server in the background without the need to refresh the page. This allows you to request or post data to or from your web server using AJAX and process the feedback in real time.
Cross-browser DOM (Document Object Model)
I am sure I don't need to explain the pitfalls of browser compatibility. From the first time you create a DIV tag and apply a style to it, it becomes apparent that it's not going to look the same in every browser unless you are very diligent. When we use Ext widgets, the browser compatibility is taken care of by the Ext library, so that each widget looks exactly the same in most of the popular browsers, which are:
Internet Explorer 6+
Firefox 1.5+ (PC, Mac)
Safari 2+
Opera 9+ (PC, Mac)
Google chrome
Event-driven interfaces
Events describe when certain actions happen. An event could be a user action such as a click on an element, or it could be a response to an AJAX call. When a user interacts with a button, there is a reaction, with not just one but many events happening There is an event for the cursor hovering over the button, and an event for the cursor clicking on the button, and an event for the cursor leaving the button. We can add an event listener to execute some code block when any or all of these events take place. Listening for events is not strictly related to the user interface. There are also system events happening all the time. When we make AJAX calls, there are events attached to the status of that AJAX call to listen for the start, the completion, and the failure.
Ext and AJAX
The term AJAX (Asynchronous JavaScript and XML) is an overly-complicated acronym for saying that processes can take place in the background while the user is performing other tasks. A user could be filling out a form while a grid of data is loading—both can happen at the same time, with no waiting around for the page to reload.
Getting Ext
Everything we will need can be downloaded from the Ext website, at http://www.extjs.com/download. Grab the Ext SDK (Software Development Kit), which contains a ton of useful examples and the API reference. Most importantly, it contains the resources that Ext needs to run properly.
The adapter and resources folders shown in bold are required for Ext to work properly; everything else is just for development purposes. adapter: Files that allow you to use other libraries along side Ext
build: Files that can be used to custom-build an ext-all.js
docs: The documentation center (this will only work when run on a web server)
examples: Plenty of amazing and insightful examples
resources: Dependencies of the Ext library, such as CSS and images
source: The complete source code for Ext
When you're ready to host your page on a web server, the adapter and resources folders will need to be uploaded to the server.
Base
Class System
Support
Application Architecture
DOM & Browser
View
Containers & Panels
Layouts
Draw
Components
Components
Form
Charts
Tree
Form Actions
Drag & Drop
Toolbar
Grid
Component Utilities
Data
Data Models
Data Proxies
Data Stores
Direct
Data Readers & Writers
Utilities
Native Extensions
Utility
Events
What else extjs can do?
Ø Ajax support
Ø Dom traversing
Ø Dom manipulation
Ø Event Handling
Ø Selectors
Ø OOP emulation
Ø Animation
Including Ext in your pages
Before we can use Ext in our pages, we need to reference the Ext library files. To do
this, we need to include a few of the files provided in the SDK download in the HEAD
portion of our HTML page.
<html>
<head>
<title>Getting Started Example</title>
<link rel="stylesheet" type="text/css"
href="lib/extjs/resources/css/ext-all.css" />
<script src="lib/extjs/adapter/ext/ext-base.js"></script>
<script src="lib/extjs/ext-all-debug.js"></script>
</head>
<body>
<!-- Nothing in the body -->
</body>
</html>
ext-all.css: The main Ext CSS file
An external js library file, if needed
ext-base.js: The Ext 'adapter' ext-all.js or ext-all-debug.js: The primary Ext library file
A theme file could also be included here, or at any point after the main Ext
CSS file
What do those files do?
We have included the following three files that Ext requires to run in our page:
ext-all.css: A style sheet file that controls the look and feel of Ext widgets. This file must always be included as-is, with no modifications. Any changes to the CSS in this file would break future upgrades. If the look and feel of Ext needs to be adjusted, another style sheet containing the overrides should be included after the ext-all.css file.
ext-base.js: This file provides the core functionality of Ext. It's the engine of the Ext car. This is the file that we would change if we wanted to use another library, such as jQuery, along with Ext.
ext-all-debug.js/ext-all.js: All of the widgets live in this file. The debug version is used for development, and then swapped out for the non-debug version for production.
Once these files are in place, we can start to actually use the Ext library and have some fun.
Note: If you are working with a server-side language such as PHP or ASP.NET, You might choose to "include" these lines in the header dynamically.
Using the Ext library
Now that we've added the Ext library to our page, we can start writing the code that uses the Ext library. In the first example, we will use Ext to display a message dialog. This might not sound like much, but it's a start.
Time for action
We can run some Ext code by adding a script section in the head of our document, right after where the Ext library has been included. Our example will bring up an Ext style alert dialog:
<html>
<head>
<title>Hello World Window</title>
<link rel="stylesheet" type="text/css" href="ext-3.0.0/resources/css/ext-all.css" />
<script type="text/javascript" src="ext-3.0.0/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext-3.0.0/ext-all.js"></script>
</head>
<script type="text/javascript" src="ext-3.0.0/ext-all-debug.js"></script>
<script>
Ext.onReady(function(){
Ext.Msg.alert('Hello', 'World');
});
</script>
</head>
<body>
<!-- Nothing in the body -->
</body>
</html>
Just like a "real" dialog, you can drag it around, but only within the constraints of the page. This is because this isn't a real dialog; it's a collection of DIV tags and images put together to imitate a dialog. You can also see that the Close and Ok buttons get highlighted when you move the cursor over them—not bad for one line of code! Ext is taking care of a lot of the work for us here.
Note:
You may have noticed that we are working with an empty document that has no elements in the body. Ext does not require any pre-existing markup for it to function properly; it generates everything it needs on its own.
The example
Let's take a look at that example code we just ran. Every Ext component we use will start with "Ext" and will most likely be contained within an onReady function
Ext.onReady(function(){
Ext.Msg.alert('Hello', 'World');
});
Ext has a very human-readable interface. You can almost read it as a sentence—when Ext is ready, it displays a message box in the alert style with Hello for a title and World as the body.
Our alert message starts with Ext.Msg, which is the starting point for all message style windows, and is shorthand for "MessageBox". The alert portion tells Ext exactly which style of message window to use.
Not working?
If the library is not set up correctly, we might receive an 'Ext' is undefined error. This message means the Ext library was not loaded. Usually, this is caused by having an incorrect path to one or more of the Ext library files that are included in our document. Double-check the paths to the included library files, and make sure they are pointing to the right folders and that the files exist.
Another common problem is that the CSS file is either missing or is not referenced correctly, which will result in a page that looks awkward, as shown in the example below:.
Adapters
When Ext was first being developed (initially called "yui-ext"), it required the YUI library to be in place to do the behind-the-scenes work. Later on, Ext was given the option of using two other frameworks—jQuery or Prototype with Scriptaculous (Protaculous). This means that if we were using other libraries already or if we felt some other base library was somehow superior or better suited your needs, we could continue using that library in conjunction with Ext by using the appropriate adapter. Either way, Ext will function the same, and all of the components will work identically, no matter which adapter you choose. Ext also has its own adapter, an adapter to itself. If you have no preference for another library or framework, then go with the Ext built-in the adapter.
Using adapters
To use an adapter, you must fifirst include the external library that you want to use,
and then include the related adapter file that is located in the adapters folder of the
Ext SDK. Our example code uses the Ext adapter. To use any of the other libraries,
just replace the default Ext adapter script include line with the lines for the specific
libraries, as shown below:
Default Ext adapter:
<script src="lib/extjs/adapter/ext/ext-base.js"></script>
For jQuery, include these files in the head of your document:
<script src="jquery.js"></script>
<script src="jquery-plugins.js"></script>
<script src="extjs3.0.0/adapter/jquery/ext-jquery-adapter.js">
</script>
For YUI, include these files in the head. The utilities file is located in the build/ utilities folder of the YUI Library download:
<script src="utilities.js"></script>
<script src="extjs3.0.0/adapter/yui/ext-yui-adapter.js"></script>
For "Prototype + Scriptaculous", include these files in the head:
<script src="prototype.js"></script>
<script src="scriptaculous.js?load=effects"></script>
<script src="extjs3.0.0/adapter/prototype/ext-prototype-adapter.js"></script>
After the adapter and base libraries have been included, we just need to include the
ext-all.js or ext-all-debug.js file.
I'm asynchronous!
The Web 1.0 way of doing things has all of our code happening in succession—waiting for each line of code to complete before moving on to the next. Much like building a house, the foundation must be complete before the walls can be built, then the walls must be complete before the roof is built. With Ext, we can easily start working on the roof of our house before the foundation has even been thought about. Imagine the roof of our house is being built in a factory, while at the same time we are building the foundation, then the walls, and we come in when all of this is done and set the roof that has already been built on top of it all.
This introduces some things we're not use to having to cope with, such as the roof being complete before the walls are done. No longer are we forced to take a line-by-line approach to web development. Ext helps us out by giving us events and handlers to which we can attach our functionality. We can set up an event that waits around, watching to see when the walls of the house are built, and then sets the roof on top once this has happened. This method of thinking about web pages is hard for most people who have grown up in web development. But it won't be long before you are an expert at it.
Note: Standard JavaScript alert messages pause the code execution, which can cause unexpected results. You should not be using the built in JavaScript alert messages, and instead use Ext's Message Box widget, which does not pause that code execution.
Localization
Ext objects can be displayed in your specific language, and currently there are over 40 translations (unfortunately, Klingon is not yet available). All of these translations are created by the community—users like you and I who have the need to use Ext in their own native language. The included language files are to be used as a starting point. So let's take the language we want to use and copy it to our lib folder. By copying the language file to our lib folder, we can edit it and add translated text to it without it getting overwritten when we upgrade the Ext library files.
There are three scenarios for localization that require three separate approaches:
- English only
- A single language other than English
- Multiple languages
English only
This requires no modifications to the standard setup, and there are no extra files to include because the English translation is already included in the ext-all.js file.
A language other than English
The second option requires that we include one of the language files from the build/locale folder. This option works by overwriting the English text strings, so it should be included after all of the other library files, as shown below:
<link rel="stylesheet" type="text/css"
href="lib/extjs/resources/css/ext-all.css" />
<script src="lib/extjs/adapter/ext/ext-base.js"></script>
<script src="lib/extjs/ext-all-debug.js"></script>
<script src="lib/extjs/build/locale/ext-lang-es.js"></script>
I have included the Spanish translations for this example. Let's see what our test
page looks like now:
Elements that are part of the UI have been localized—these generally include calendar text, error messages, tool tip info messages, paging info, and loading indicators. Messages that are specific to your application, such as the Hi title, and Hello World Example text will need to be translated and added to the ext-lang-XX.js file (where 'XX' is your two letter language code) or added to a new language file of your own. The preferred method is to create a language file of our own with just the additions and changes we need, this leaves us prepared for upgrades and fixes in the primary language file.
Multiple languages
The third method of switching between different languages is basically the same as the second. We would just need to add some server-side scripting to our page to enable the switching between language files. Unfortunately, switching between languages cannot be done entirely dynamically. In other words, we can't do it in real time and watch it happen on the screen.
The following core functions of Ext will be used on every project that we work on during
the course of this book:
Ext.onReady: This function makes sure that our document is ready to be thrashed out
Ext.Msg: This function creates application-style message boxes for us configuration objects: This function defines how Ext widgets will act
Ext.get: This function accesses and manipulates elements in the DOM
Spacer image
Before we proceed any further, we should provide Ext with something it needs—a spacer image. Ext needs a 1 pixel by 1 pixel, transparent, GIF image to stretch in different ways, giving a fixed width to its widgets. We need to set the location of this spacer image using the following line:
Ext.onReady(function(){
Ext.BLANK_IMAGE_URL = 'images/s.gif';
});
You're probably wondering why we need a spacer image at all. The user interface of Ext is created using CSS, but the CSS needs underlying HTML elements to style so that it can create the look and feel of Ext components. The one HTML element that is an exact, predictable size across all browsers is an image. So an image is used to define how an Ext component is drawn. This is a part of how Ext maintains its cross-browser compatibility.
Main extjs classes
Ø Component
Ø Panel
Ø Observable
Ø Store
Component
All widgets extends component class
Provide base widget functions like
enable()/disable()
show()/hide()
addClass()/removeClass()
update(data/html) – update content area
getEl() return element
getId()
getXType()
render(target)
focus()
XType – alternate way to define component
Lazy component creation
var panel1 = {
xtype : 'panel',
title : 'Plain Panel',
html : 'Panel with an xtype specified'
}
var myPanel = new Ext.Panel({
renderTo : document.body,
height : 50,
width : 150,
title : 'Panel',
frame : true
Components are managed by Ext.ComponentMgr
get(componentId)
registerType(xtype, object) (shorthand Ext.reg())
Containers
handle the basic behavior of containing items, namely adding, inserting and removing items
Main functions
add()
remove()/removeAll()
insert()
find()/findBy()/findById()/findByType
doLayout()
get(index or id)/getComponent(component or index or id)
Main prop
Items - MixedCollection of children components
Panels
Main panel functions/prop/conf prop
load()
– panel.load({
– url: 'your-url.php',
– params: {param1: 'foo', param2: 'bar'}, // or a URL encoded string
– callback: yourFunction,
– scope: yourObject, // optional scope for the callback
– discardUrl: false,
– nocache: false,
– text: 'Loading...',
– timeout: 30,
– scripts: false
– });
body – prop
html – conf prop
autoLoad – conf prop
Toolbar and Bottombar
Panel subclasses
TabPanel
Window
FormPanel
GridPanel
TreePanel
Layouts
Layouts manages by containers – there is no need to create Layouts directly
The most useful are Fit, VBox, HBox, Border
Only VBox, HBox, Border layouts supports margins
Flex prop of VBox, HBox
BorderLayout must have center item
Table layout does not support resizing of items
Viewport
A specialized container representing the viewable application area
Automaticaly resize itself when browser is resized
Example of creation
new Ext.Viewport({
layout : 'border',
items : [
{
height : 75,
region : 'north',
title : 'Does Santa live here?'
},
{
width : 150,
region : 'west',
title : 'The west region rules'
},
{
region : 'center',
title : 'No, this region rules!'
}
]
});
Main Ext static functions
extend(Function superclass, Object overrides) : Function
get/fly(StringId, HTMLElement) - returns element
These methods does not retrieve Components
getBody() - returns element body
apply(obj, config, defaults)
applyIf(obj, config, defaults)
getCmp(id) – returns component
GridPanel
Store
contains grid data
GridView
Display store data
ColumnModel - is a class that models how the columns are organized, sized and displayed for the GridPanel widget.
– var colModel = new Ext.grid.ColumnModel([ // 1
– {
– sortable : true,
– header : 'Full Name',
– dataIndex : 'fullName' // 2
– },
– {
– header : 'State',
– dataIndex : 'state'
– }]);
– Selection model
Define how user is able to select rows
– var selModel = new Ext.grid.RowSelectionModel({ // 4
– singleSelect : true
– })
Grid Features: sorting, paging, columns moving / hidding/ resizing
Example of configuration
– var grid = new Ext.grid.GridPanel({ // 5
– title : 'Our first grid',
– renderTo : Ext.getBody(),
– autoHeight : true,
– width : 250,
– store : store, // 6
– view : gridView,
– colModel : colModel,
– selModel : selModel
– });
EditableGridPanel – support editing of data
Alternatives
DataView consumes data from a Store and “paints” it on screen using templates
ListView lightweight version of gridpanel – does not support ColumnModel
Stores
The main purposes of the stores classes are data storage/loading
Store contains records object which contain a server data directly
Store is able to insert/update/add records
SubClasses
ArrayStore: Store + ArrayReader –
• plain js array can be loaded into the array store
DirectStore: Store + DirectProxy + JsonReader
• CRUD operation is going thought custom js method
GroupingStore: store for grid rows grouping
JsonStore: Store + JsonReader
XmlStore: Store + XmlReader
Stores configuration example
this.tableDataStore = new Ext.data.Store({
// destroy a store if destroy the component to which the store was bounded
//autoDestroy: true,
restful: false,
autoSave: false,
autoLoad: {params: {start: 0, limit: One.ErrorReview.PAGE_SIZE } },
batch: true,
storeId : 'tableDataStore',
// load remote data using HTTP
proxy : new One.PagingHttpProxy({
method: 'GET',
prettyUrls: false,
url: '/oms/rest/ErrorReview/TableData/' + Url.getParam('csvInboundInterfaceName'), // see options parameter for Ext.Ajax.request
totalUrl: '/oms/rest/ErrorReview/TotalCount/' + Url.getParam('csvInboundInterfaceName'),
api: {
destroy : {url: '/oms/rest/ErrorReview/DeleteErrorRow/' + Url.getParam('csvInboundInterfaceName'), method: 'DELETE'},
update : {url: '/oms/rest/ErrorReview/UpdateErrorRow/' + Url.getParam('csvInboundInterfaceName'), method: 'PUT'}
}
}),
reader: new Ext.data.JsonReader({
root: 'rows',
idProperty: 'ErrorSysId',
totalProperty: 'results',
// use an Array of field definition objects to implicitly create a Record constructor
fields: OneExt.getStoreFields(fieldsArr)
}),
writer : new Ext.data.JsonWriter({
encode: false,
writeAllFields: true,
listful : true
}),
listeners: {
write: {fn : this.onSuccessWrite, scope : this},
update: {fn : this.onUpdate, scope : this},
exception: OneExt.showStoreErrorMsg,
datachanged: {fn : this.onDataChanged, scope : this}
}
});
Proxies
HttpProxy
CRUD operation are processed via ap config or url prop to a server
DirectProxy
CRUD operation is going thought custom js function
MemoryProxy
ctor of MemoryProxy takes data js array as argument and the class does not invoke any requests to a server
ScriptTagProxy
Provide possibility to make request to other domain
Other domain server must return valid js text data
OnePagingHttpProxy
Reader conf example:
var myReader = new Ext.data.JsonReader({
// metadata configuration options:
idProperty: 'id'
root: 'rows',
totalProperty: 'results',
Ext.data.DataReader.messageProperty: "msg" // The element within the response that provides a user-feedback message (optional)
// the fields config option will internally create an Ext.data.Record
// constructor that provides mapping for reading the record data objects
fields: [
// map Record's 'firstname' field to data object's key of same name
{name: 'name'},
// map Record's 'job' field to data object's 'occupation' key
{name: 'job', mapping: 'occupation'}
]
});
{
results: 2000, // Reader's configured totalProperty
rows: [ // Reader's configured root
// record data objects:
{ id: 1, firstname: 'Bill', occupation: 'Gardener' },
{ id: 2, firstname: 'Ben' , occupation: 'Horticulturalist' },
...
]
}
Events:
If class should support events this class must extends Observable
Observable methods
addListener (shorthand on())
removeListener (shorthand un())
addEvent()
fireEvent
relayEvent(eventName, targetObj)
enableBubble()
Ext.EventObject – each event callback have this obj as argument
stopPropagation()
preventDefault()
stopEvent()
Plugins:
All components support plugins customization
Plugin is a plain js object with init method, after component is initialized the init() method of plugin is called
Plugin can add listeners to component therefore customize behavior of the component
Other widgets:
Menus
Buttons
Dialogs
Ext.MessageBox.show
JSON and the config object:
We are utilizing what's called a config object, which is the primary way to get Ext to do what you want. This is what provides the configuration of the different options that are available for the function that is being used.
The old way
We used to call functions with a pre-determined set of arguments. This means that we had to remember the order of the arguments every time the function was used.
var test = new TestFuntion(
'three',
'fixed',
'arguments'
);
This old way of using functions can create many problems:
It requires us to remember the order of the arguments
It does not describe about what the arguments represent It provides less flexibility in dealing with optional arguments
The new way—config objects
Using a config object, we are able to have a larger level of flexibility, and can tell what our variables are in descriptive plain text. The order of our arguments no longer matters—firstWord could be the last item, and thirdWord could be the first, or they could be in any random order. With the config object method of passing arguments to your functions, the arguments no longer needs to be tied down to a specific place.
var test = new TestFunction({
firstWord: 'three',
secondWord: 'fixed',
thirdWord: 'arguments'
});
This method also allows for unlimited expansion of our function's arguments. Using fewer arguments or adding new arguments is simple. Another great result that comes by using a config object is that the prior usage of your functions will not be harmed by the addition or subtraction of arguments at a later point.
var test = new TestFunction({
secondWord: 'three'
});
What is a config object?
Config objects are just ways of structuring data so that it can easily be read by programming languages—in our case, JavaScript.
For an example, let's take a look at the config portion of our example code:
{
title: 'Milton ',
msg: 'Have you seen my stapler?',
buttons: {
yes: true,
no: true,
cancel: true
},
icon: 'milton-icon',
fn: function(btn) {
Ext.Msg.alert('You Clicked', btn);
}
}
The particular config that we are using here may appear complex at first, but once we get to know it, it becomes an extremely fast way of configuring widgets. Just about every Ext widget uses a configuration object, so this is something that we will want to become very familiar with.
Here are some key things to remember when working with a config object:
Curly brackets wrap around your whole record set, which symbolizes the records inside the brackets as being part of an object—{records}.
Each record consists of a set of name/value pair, with the name and value separated by a colon, and pairs separated by commas—{name0: value0, name1: value1}.
The records' values can contain any type of data, including boolean, array, function, or even another object—{ name0: true, name1: { name2: value2 } }.
Square brackets identify an array—{name: [ 'one', 'two', 'three' ] }.
An array can also contain objects with records, values, or any number of other things.
The best thing about using JSON to configure our widgets is that if we want more options, we just start typing them out. Presto! Unlike a typical function call, the order of your config options has become irrelevant, and there can be as few or as many as necessary.
How does JSON work?
Sometimes, you will hear people talk about eval, which generally refers to JSON. The eval function is what JavaScript uses to interpret a JSON string, converting it into the objects, arrays, and functions that we are using.
A switch statement can take care of deciding what to do in each case:
fn: function(btn) {
switch(btn){
case 'yes':
Ext.Msg.prompt('Milton ', 'Where is it?');
break;
case 'no':
Ext.Msg.alert('Milton ',
'Im going to burn the building down!');
break;
case 'cancel':
Ext.Msg.wait('Saving tables to disk...','File Copy');
break;
}
}
They let us accomplish some common tasks without spending time writing the config needed for each standard scenario. Click OK and you get a prompt. A prompt is the common name for a small window that allows you to enter a single value, and is a standard element in almost every
user interface.
Click No and you get an alert. I'm sure you are familiar with the standard alert dialog i JavaScript. I remember the first time I used an alert dialog in JavaScript. I was so excited to have an alert message on my home page that I made it pop up and say "Click OK if you are
yaa moron.
Click the Cancel button(or click the close button or press the Escape key) and you will get a wait message that's using a progress dialog.
The progress dialog we are using can be controlled by Ext and be notified when it should disappear. But for the sake of simplicity, in this example, we are letting it run forever.
Forms
Ext forms, which are similar to the HTML forms that we use, without the usability restrictions and boring user interface. We use some different form field types to create a form that validates and submits asynchronously. Then we will create a database-driven, drop-down menu (ComboBox), and add some more complex field validation and masking. We will then finish it off with a few advanced topics that will give our forms some serious 'wow' factor.
Now we are going through:
Creating a form that uses AJAX submission
Validating field data and creating custom validation
Loading form data from a database
The core components of a form
The possibilities are endless with Ext forms. Key listeners, validation, error messages, and value restrictions are all built in with simple config options. Extending a form option for your own specific needs can be done easily, which is something we will cover later on in this chapter. Here are some of the core form components that you should become familiar with:
Ext.form.FormPanel: Groups fields together in a panel, much as the FORM tag does for a standard HTML form
Ext.form.Field: As the primary handler of form field creation and interaction, it can be compared to the INPUT tag in HTML
To start with, let's create a form with multiple field types, a date picker, validation, error messages, and AJAX submission—just a simple one for our first try.
Eg:
Ext.onReady(function(){
var movie_form = new Ext.FormPanel({
url: 'movie-form-submit.php',
renderTo: document.body,
frame: true,
title: 'Movie Information Form',
width: 250,
items: [{
xtype: 'textfield',
fieldLabel: 'Title',
name: 'title'
},{
xtype: 'textfield',
fieldLabel: 'Director',
name: 'director'
},{
xtype: 'datefield',
fieldLabel: 'Released',
name: 'released'
}]
});
});
When we run this code in a browser, we end up with a form panel that looks like this:
how does it work?
The FormPanel is very similar to an HTML form. It acts as the container for our form fields. Our form has a url config so the form knows where to send the data when it is submitted. It also has a renderTo config, which defines where the form is displayed on the page. The items config element is the important one as it contains all of our form fields. The items config element is an array of fields. Each field element has an xtype that defines which type of Ext component will be used: text, date, or number. This could even be a grid or some other type of Ext component.
Form fields
Now we know that each type of field is defined by its xtype. But where do xtypes come from, and how many of them are there? An xtype is just a reference to a particular Ext component, so a 'textfield' xtype is the same as its Ext.form.TextField counterpart. Here are examples of some of the xtypes that are available to us:
textfield
timefield
numberfield
datefield
combo
textarea
Because these are all just Ext components, we could easily be using a grid, toolbar, or button—pretty much anything! A recurring theme in Ext components is that everything is interchangeable, and everything shares the same core functions. This ensures that just about any scenario can be handled with the Ext library.
Our basic field config is set up like this:
{
xtype: 'textfield',
fieldLabel: 'Title',
name: 'title'
}
Of course, we have the xtype that defines what type of a field it is—in our case it is a textfield. The fieldLabel is the text label that is displayed to the leftof the field, although this can also be configured to be displayed on the top or the right side of the field. The name config is just the same as its HTML counterpart and will be used as the variable name when sending the form data to the server.
Making our date field isn't much different from making the text field. Change the xtype to a datefield, and we're done.
{
xtype: 'datefield',
fieldLabel: 'Released',
name: 'released'
}
Validation
A few of our sample fields could have validations that present the users with errors if the user does something wrong. Let's add some validation to our first form. One of the most commonly-used types of validation is checking to see if the user has entered any value at all. We will use this for our movie title field. In other words, let's make this field a required one:
{
xtype: 'textfield',
fieldLabel: 'Title',
name: 'title',
allowBlank: false
}
For instance, a date field has ways to disable certain days of the week, or to use a regular xpression to disable specific dates. The following code disables every day except Saturday and Sunday:
{
xtype: 'datefield',
fieldLabel: 'Released',
name: 'released',
disabledDays: [1,2,3,4,5]
}
olu � s - � �� -family:Symbol;color:black'> Window
FormPanel
GridPanel
TreePanel
Layouts
Layouts manages by containers – there is no need to create Layouts directly
The most useful are Fit, VBox, HBox, Border
Only VBox, HBox, Border layouts supports margins
Flex prop of VBox, HBox
BorderLayout must have center item
Table layout does not support resizing of items
In this example, everyday except Saturday and Sunday is disabled. Keep in mind that the week starts on 0 for Sunday, and ends on 6 for Saturday.
Built-in validation—vtypes
Another more complex type of validation is the vtype. This can be used to validate and restrict user input, and report back error messages. It will work in just about any scenario you can imagine because it uses regular expressions to do the grunt work. Here are some built-in vTypes that can come in handy:
email
url
alpha
alphanum
These built-in vtypes are intended to be simplistic, and mostly used as a starting point for creating your own vtypes. Here is an alpha vtype being used with a QuickTips balloon error message:
Ext.onReady(function(){
var movie_form = new Ext.FormPanel({
url: 'movie-form-submit.php',
renderTo: document.body,
frame: true,
title: 'Movie Information Form',
width: 250,
items: [{
xtype: 'textfield',
fieldLabel: 'Title',
name: 'title',
allowBlank: false
},{
xtype: 'textfield',
fieldLabel: 'Director',
name: 'director',
vtype: 'alpha'
},{
xtype: 'datefield',
fieldLabel: 'Released',
name: 'released',
disabledDays: [1,2,3,4,5]
}]
});
});
All we did was add a vtype to the director field. This will validate that the value entered is composed of only alphabetic characters.
in; ma� j - e � �� rgin-bottom:.0001pt;text-align:justify;line-height:normal; mso-layout-grid-align:none;text-autospace:none'>}
Styles for displaying errors
Forms are set up by default with a very bland error display which shows any type of error with a squiggly red line under the form field. This error display closely mimics the errors shown in programs like Microsoft Word when you spell a word incorrectly. We do have other options for displaying our error messages, but we will need to tell Ext JS to use it. The preferred option is to display the error message in a balloon. This utilizes the standard squiggly line, but also adds a balloon message that pops up when you mouse over the field.
We just need to add a line of code before our form is created that will initialize the balloon messages. Typically this is the first line within the OnReady function.
For example:
Ext.onReady(function(){
Ext.QuickTips.init();
// our form here
});
This is all that needs to happen for your form fields to start displaying error messages in a fancy balloon.
Custom validation—create your own vtype
To create our own vtype, we need to add it to the vtype definitions. Each definition has a value, mask, error text, and a function used for testing:
xxxVal: This is the regular expression to match against
xxxMask: This is the masking to restrict user input
xxxText:This is the error message that is displayed
As soon as we figure out the regular expressions we need to use, it's fairly straight forward creating our own vType—so lets try one out. Here is a validation for our director's name field. The regular expression matches a pair of alpha strings,separated by a space, and each starting with a capital letter. Sounds like a good way to validate a name—right?
Ext.form.VTypes['nameVal'] = /^[A-Z][A-Za-z\-]+
[A-Z][A-Za-z\-]+$/;
Ext.form.VTypes['nameMask'] = /[A-Za-z\- ]/;
Ext.form.VTypes['nameText'] = 'In-valid Director Name.';
Ext.form.VTypes['name'] = function(v){
return Ext.form.VTypes['nameVal'].test(v);
}
It's hard to look at this all at once, so let's break it down into its main parts. We first start with the regular expression that validates the data entered into our form field:
Ext.form.VTypes['nameVal'] = /^([A-Z]{1})[A-Za-z\-]+([A-Z]{1})[A-Za-z\-]+/;
Next, we add the masking, which defines what characters can be typed into our form field. This is also in the form of a regular expression:
Ext.form.VTypes['nameMask'] = /[A-Za-z]/;
Then, we have the text to be displayed in a balloon if there is an error:
Ext.form.VTypes['nameText'] = 'In-valid Director Name.';
Masking—don't press that key!
Masking is used when a particular field is forced to accept only certain keystrokes, such as numbers only, or letters only, or just capital letters. The possibilities are limitless, because regular expressions are used to decide what keys to filter out. This mask example would allow an unlimited string of capital letters:
maskRe: /[A-Z]/ Instead of using the masking config, consider creating a vType to accomplish
your masking. If the formatting requirements should happen to change, it will be
centrally-located for easy changing.
Radio buttons and check boxes
Radio buttons and check boxes are a necessary evil. They are clumsy, and hard to work with.
It's not a button, it's a radio button
Lets first add a set of radio buttons to our form:
{
xtype: 'radio',
fieldLabel: 'Filmed In',
name: 'filmed_in',
boxLabel: 'Color'
},
{
xtype: 'radio',
hideLabel: false,
labelSeparator: '',
name: 'filmed_in',
boxLabel: 'Black & White'
}
These radio buttons work much like their HTML counterparts. Give them all the same name, and they will work together for you. I also like to hide the labels for the trailing radio buttons by setting hideLabel to true and labelSeperator to an empty value. This gives the form a cleaner look.
X marks the check box
Sometimes, we need to use check boxes for boolean values—sort of an on/off switch.
{
xtype: 'checkbox',
fieldLabel: 'Bad Movie',
name: 'bad_movie'
}
The ComboBox
The ComboBox, or SELECT as its known in HTML, also called a drop-down menu, is a highly-useful form element. It reduces the users' need to touch the keys on their keyboards. The Ext ComboBox has a ton of practical uses, and just as many configuration options to keep track of.
First, let's make a combo using local data. To do this, we need to create a data store. There are a few different types of data store, each of which can be used for different situations. However, for this one, we are going to use a simple store:
var genres = new Ext.data.SimpleStore({
fields: ['id', 'genre'],
data : [['1','Comedy'],['2','Drama'],['3','Action']]
});
Just like the other fields in our form, we add it to the items config. A few otherconfig options are needed when we are setting up a combo box. The store is the obvious one-this is the data that populates the options for our combo. The other things we need are the mode, which determines if the data is coming from a local source or a remote source, and the displayField, which etermines which columnof data is displayed in the combo options:
{
xtype: 'combo',
name: 'genre',
fieldLabel: 'Genre',
mode: 'local',
store: genres,
displayField:'genre',
width: 120
}
This gives us a combo box that uses local data, which is good for small lists, or lists that don't change often.
TextArea and HTMLEditor
We are going to add a text field to our movie information form, and Ext has a couple of options for this. We can either use the standard textarea that we were familiar with from using HTML, or we can use the HTMLEditor field, which provides rich text editing:
textarea: Similar to a typical HTML textarea field htmleditor: A rich text editor with a button bar for common formatting tasks If we set hideLabel to true and clear out the label separator then we can have a textarea that spans the entire width of our form panel. This gives a nice look to
the form:
{
xtype: 'textarea',
name: 'description',
hideLabel: true,
labelSeparator: '',
height: 100,
anchor: '100%'
}
By changing just the xtype, as shown below, we now have a fairly simple HTML editor with built-in options for font face, size, color, italics, bold, and so on. This is the first Ext component we have used that requires the QuickTips component to be initialized before we can use it.
{
xtype: 'htmleditor',
name: 'description',
hideLabel: true,
labelSeparator: '',
height: 100,
anchor: '100%'
}
Listening for form field events
Ext makes it extremely simple to listen for particular user actions, such as clicking on an element or pressing a particular key. A common task would be listening for the Enter key to be pressed, and then submitting the form. So let's see how this is accomplished:
{
xtype: 'textfield',
fieldLabel: 'Title',
name: 'title',
allowBlank: false,
listeners: {
specialkey: function(f,e){
if (e.getKey() == e.ENTER) {
movie_form.getForm().submit();
}
}
}
}
The specialkey listener is called whenever a key related to navigation is pressed. This listener is also called every time the arrow keys are pressed, along with Tab, Esc, and so on. That's why we have to check to see if it was the Enter key before we take action. Now the form will only be submitted when you press Enter.
ComboBox events
It seems that combo boxes commonly need to have events attached to them. Let's take our genre combo box and attach a listener to it that will run when an item in the list is selected.
First let's add a dummy item to our data as the first item in the list and call it New Genre:
var genres = new Ext.data.SimpleStore({
fields: ['id', 'genre'],
data : [
['0','New Genre'],
['1','Comedy'],
['2','Drama'],
['3','Action']
]
});
This material is copyright and is licensed for the sole use by Roman Heinrich on 25th December 2008
Am Hilligenbusch 47, , Paderborn , NRW, 33098
Forms
[ 52 ]
Then, we add the listener to our combo:
{
xtype: 'combo',
name: 'genre',
fieldLabel: 'Genre',
mode: 'local',
store: genres,
displayField:'genre',
width: 130,
listeners: {
select: function(f,r,i){
if (i == 0){
Ext.Msg.prompt('New Genre','Name',Ext.emptyFn);
}
}
}
}
The listener is set up to wait for a select event and then run the function that is specified. Each listener type has its own set of variables that is passed to the function—these can be looked up in the API reference. For the select event, our function is passed three things:
The form field
The data record of the selected combo item
The index number of the item that was clicked on
Once the list item is selected, we can see which item in the list was selecte . The third argument in our listener function is the index of the item that was clicked. If that has an index of zero (the first item in the list), then we will prompt the user to enter a new genre using the prompt dialog.
Buttons and form action
Now, we have quite a mess of a form with only one problem – it doesn't send data to the server, which was the actual point behind creating our form in the first place. To do, this we are going to add some buttons. Our buttons are added to a buttons config object, similar to the way that the form fields were added. These buttons really only need two things: the text to be displayed
on the button, and the function(which is called the handler) to execute when the button is clicked.
buttons: [{
text: 'Save',
handler: function(){
movie_form.getForm().submit({
success: function(f,a){
Ext.Msg.alert('Success', 'It worked');
},
failure: function(f,a){
Ext.Msg.alert('Warning', 'Error');
}
});
}
}, {
text: 'Reset',
handler: function(){
movie_form.getForm().reset();
}
}]
The handler is provided with a function—or a reference to a function—that will be executed once the button is clicked. In this case, we are providing an anonymous function.
Form submission
Our FormPanel has a url option that contains the name of the file that the form data will be sent to. This is simple enough—just like an HTML form, all of our fields will be posted to this url, so they can be processed on the server side. Inside our Save button, we have an anonymous function that runs the following code. This will run the actual submission function for our form, which sends the data to the server using AJAX . No page refresh is needed to submit the form. It all happens in the background, while the page you are looking at remains the same:
movie_form.getForm().submit({
success: function(f,a){
Ext.Msg.alert('Success', 'It worked');
},
failure: function(f,a){
Ext.Msg.alert('Warning', 'Error');
}
})
Object reference or component config
we have started to use more and more configuration objects to set up our Ext JS components, instead of instantiating them.Let's do a quick comparison of the two methods.
Instantiated
var test = new Ext.form.TextField({
fieldLabel: 'Title',
name: 'title',
allowBlank: false
});
Here, the component has been created and memory used right away, even if it is not displayed on the screen yet. Depending on how your end users work with your application, they might never even need or use this particular text field. However, when it is the time to display this field to the end users, it shows up really fast.
Component config
{
xtype: 'textfield',
fieldLabel: 'Title',
name: 'title',
allowBlank: false
}
With the component config, we have a 'description' of what has to happen when it is time to use the field. No memory is used right away. It's only when the user needs it that the memory is used. At that point, the field is rendered after the user has clicked on or interacted with something else, which can slow the initial display slightly Buttons, Menus, and Toolbars
A toolbar for every occasion
Just about every Ext component—panels, windows, grids can accept a toolbar on either the top or the bottom. The option is also available to render the toolbar standalone into any DOM element in our document. The toolbar is an extremely flexible and useful component that will no doubt be used in every application. Ext.Toolbar: The main container for the buttons Ext.Button: The primary handler for button creation and interaction Ext.menu: A menu
Toolbars
Our first toolbar is going to be rendered standalone in the body of our document. We will add one of each of the main button types, so we can experiment with each: Button—tbbutton: This is the standard button that we are all familiar with. Split Button—tbsplit: A split button is where you have a default button action and an optional menu. These are used in cases where you need to have many options in the same category as your button, of which there is a most
commonly used default option.
Menu—tbbutton+menu: A menu is just a button with the menu config filled in with options.
Ext.onReady(function(){
new Ext.Toolbar({
renderTo: document.body,
items: [{
xtype: 'tbbutton',
text: 'Button'
},{
xtype: 'tbbutton',
text: 'Menu Button',
menu: [{
text: 'Better'
},{
text: 'Good'
},{
text: 'Best'
}]
},{
xtype: 'tbsplit',
text: 'Split Button',
menu: [{
text: 'Item One'
},{
text: 'Item Two'
},{
text: 'Item Three'
}]
}]
});
});
The button
Creating a button is fairly straightforward; the main config option is the text that is displayed on the button. We can also add an icon to be used alongside the text if we want to. Here is a stripped-down button:
{
xtype: 'tbbutton',
text: 'Button'
}
Menu
A menu is just a button with the menu config populated—it's that simple. The menu items work along the same principles as the buttons. They can have icons, classes, and handlers assigned to them. The menu items could also be grouped together to form a set of option buttons, but first let's create a standard menu.
This is the config for a typical menu config:
{
xtype: 'tbbutton',
text: 'Button',
menu: [{
text: 'Better'
},{
text: 'Good'
},{
text: 'Best'
}]
}
As we can see, once the menu array config is populated, the menu comes to life. To group these menu items together, we would need to set the group config and the boolean checked value for each item:
menu: [{
text: 'Better',
checked: true,
group: 'quality'
}, {
text: 'Good',
checked: false,
group: 'quality'
}, {
text: 'Best',
checked: false,
group: 'quality'
}]
The split button sounds like a complex component, but it's just like a button and a menu combined, with a slight twist. By using this type of button, you get to use the functionality of a button while adding the option to select an item from the attached menu. Clicking the left portion of the button that contains the text triggers the button action. However, clicking the right side of the button, which contains a small down arrow, triggers the menu.
{
xtype: 'tbsplit',
text: 'Split Button',
menu: [{
text: 'Item One'
},{
text: 'Item Two'
},{
text: 'Item Three'
}]
}
Toolbar item alignment, dividers, and spacers
By default, every toolbar aligns elements to the leftmost side. There is no alignment config for a toolbar, so if we want to align all of the toolbar buttons to the rightmost side, we need to add a fill as the first item in the toolbar. If we want to have items split up between both the left and right sides, we can also use a fill:
{
xtype: 'tbfill'
}
Pop this little guy in a tool-bar wherever you want to add space and he will push items on either side of the fill to the ends of the tool bar, as shown below:
We also have elements that can add space or vertical dividers, like the one used between the Menu Button and the Split Button. The spacer adds a few pixels of empty space that can be used to space out buttons, or move elements away from the edge of the toolbar:
{
xtype: 'tbspacer'
}
A divider can be added in the same way:
{
xtype: 'tbseparator'
}
Shortcuts
Ext has many shortcuts that can be used to make coding faster. Shortcuts are a character or two that can be used in place of a configuration object. For example,
consider the standard toolbar filler configuration:
{
xtype: 'tbfill'
}
The shortcut for a toolbar filler is a hyphen and a greater than symbol:
'->'
Not all of these shortcuts are documented. So be adventurous, poke around the source code, and see what you can find. Here is a list of the commonly-used shortcuts:
Component Shortcut Description
Fill '->' The fill that is used to push items to the right side of the toolbar.
Separator '-' or 'separator' A vertical bar used to visually separate items. Spacer ' ' Empty space used to separate items visually.
The space is two pixels wide, but can be changed by overriding the ytb-spacer CSS class.
TextItem 'Your Text' Add any text or HTML directly to a toolbar by simply placing it within quotes.
Icon buttons
The standard button can act as an icon button like the ones you see used in text editors to make text bold or italic. Two steps need to be taken to make an icon button—defining an image to be used as the icon and applying the appropriate class to the button.
{
xtype: 'tbbutton',
cls: 'x-btn-icon',
icon: 'images/bomb.png'
}
This could just as easily be an icon beside text by changing the style class and adding the text config.
{
xtype: 'tbbutton',
cls: 'x-btn-text-icon',
icon: 'images/bomb.png',
text: 'Tha Bomb'
}
Button handlers—click me!
A button needs to do more than just look pretty—it needs to react to the user. This is where handlers come in. A handler is a function that is executed when a button or menu item is clicked.
The handler config is where we add our function:
{
xtype: 'tbbutton',
text: 'Button',
handler: function(){
Ext.Msg.alert('Boo', 'Here I am');
}
}
This code will pop up an alert message when the button is clicked. Sometimes, we need to make changes to the button when it's clicked, so each button handler passes a reference to itself for this purpose. The first argument of our handler is a reference to the component that triggered the event.
{
xtype: 'tbbutton',
text: 'Button',
handler: function(f){
f.disable();
}
}
We can take this reference to the button—a reference to itself—and access all of the properties and functions of that button. For this sample, we have called the disable function which grays out the button and makes it unselectable.
Load content on menu item click
Lets take our button click and do something more useful with it. For this example, we are going to add a config option to each menu item that will be used to determine what content file to load in the body of our page:
{
xtype: 'tbsplit',
text: 'Help',
menu: [{
text: 'Genre',
helpfile: 'genre',
handler: Movies.showHelp
},{
text: 'Director',
helpfile: 'director',
handler: Movies.showHelp
},{
text: 'Title',
helpfile: 'title',
handler: Movies.showHelp
}]
}
Note the helpfile config option that we have added to each of the menu items config. We have made this config property up so that we have a way to store a variable that is unique to each menu item. This is possible because config properties can be anything we need them to be, and can be created on the fly. In this case, we are using a config property as a variable that holds the name of the file we want to load. The other new thing we are doing is creating a collection of functions to handle the menu item click. These functions are all organized into a Movies class.
var Movies = function() {
return {
showHelp : function(btn){
var helpbody = Ext.get('helpbody');
if (!helpbody) {
Ext.DomHelper.append(Ext.getBody(), {
tag:'div',
id:'helpbody'
});
}
Movies.doLoad(btn.helpfile);
},
doLoad : function(file){
Ext.get('helpbody').load({
url: 'html/' + file + '.txt'
});
}
};
}();
Form fields in a toolbar
Like most things in Ext, a tool bar can accept just about any Ext component. Naturally, form fields and combo boxes are very useful items to have on a toolbar.
{
xtype: 'textfield'
}
In the same way as we created form fields in the last chapter, we have added the form fields to the items array, which will place the form fields within the toolbar. Now let's make the form field do something useful, by having it perform the same functionality as our help menu, but in a more dynamic way.
{
xtype: 'textfield',
listeners: {
specialkey: Movies.doSearch
}
}
This listener is added directly to the form field's confififig. For this, we are using a specialkey listener, which we used in the previous chapter. This is the listener that is used to capture edit keystrokes, such as Enter and Delete among others. The handler function will be added to our small Movies class created earlier:
doSearch : function(frm,evt){
if (evt.getKey() == evt.ENTER) {
Movies.doLoad(frm.getValue());
}
}
Toolbars in windows, grids, and panels
All of the toolbars we have been working with have an items config. If we want to place one of these toolbars into another Ext component, such as a panel or a window, we can simply take the contents of the items config for a toolbar, and place it within one of the two pre-set containers that exist for panel-type components.
Panel-type components, such as the window and the grid, have a top and bottom toolbar config:
tbar: The top toolbar
bbar: The bottom toolbar
If we wanted to place a toolbar at the top of a window, filling the tbar config with an array of toolbar items would give us what we wanted:
new Ext.Window({
title: 'Help',
id: 'helpwin',
width: 300,
height: 300,
tbar: [{
text: 'Close',
handler: function(){
Ext.getCmp('helpwin').close();
}
},{
text: 'Disable',
handler: function(t){
t.disable();
}
}],
autoLoad: 'html/' + btn.helpfile + '.txt'
}).show();
Ext also has a custom toolbar for paged grids that contains all of the buttons for moving through pages of results
Displaying Data with Grids
The grid is, without doubt, one of the most widely-used components of Ext. We all have data, and this needs to be presented to the end user in an easy-to-understand manner. The spreadsheet (a.k.a.: grid) is the perfect way to do this—the concept has been around for quite a while because it works. Ext takes that concept and makes it flexible and downright amazing!
In this chapter we shall be: Using a GridPanel to display structured data in a user-friendly grid
Paging data in a grid
We will cover how to define the rows and columns, but more importantly, we will learn how to make the grid flashier. We can do this by adding custom rendered cells that contain images, and change styles based on data values. In doing this we are adding real value to our grid by breaking out of the boundaries of spreadsheets!
What is a grid anyway?
Ext grids are similar to a spreadsheet; there are two main parts to each spreadsheet:
Columns
Rows
Here our columns are Title, Released, Genre, and Price. Each of the rows contains movies such as The Big Lebowski, Super Troopers, and so on. The rows are really our data; each row in the grid represents a record of data.
Displaying structured data with a GridPanel
Displaying data in a grid requires two Ext components:
A store that acts like an in-memory database, keeping track of the data we want to display
A grid panel that provides a way to display the data stored in a data store
Example On Grid Package(GridPanel Class):
VF Page:
<apex:page showHeader="false" standardStylesheets="false" controller="ExtJSDataGrid1Controller" >
<apex:includeScript value="{!$Resource.ExtJs}"/> <!-- ext-all.js j avaScript file in static resources-->
<apex:stylesheet value="{!$Resource.ExtCss}"/> <!-- ext-all.css CSS file in static resources-->
<script type="text/javascript">
Ext.onReady(function(){
//Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
var myDataString = 'var myData = [ ';
<apex:repeat value="{!myAccounts}" var="con" id="ContactRepeat">
myDataString += "['{!con.Id}','{!con.Name}','{!con.Industry}','{!con.Type}'],";
</apex:repeat>
myDataString += "];";
//evaluating the string(create the extjs object.)
eval(myDataString);
//Small helper class to make creating Stores from Array data easier.
var store = new Ext.data.SimpleStore({fields:[{name:'ID'},{name:'Name'},{name:'Industry'},{name:'Type'}]});
store.loadData(myData);//Loads the Record cache from the configured Proxy using the configured Reader.
// Creating the grid
var grid = new Ext.grid.GridPanel({store: store, columns: [
{id: 'ID', header: "ID", width: 150, sortable: false, dataIndex: 'ID'},
{id: 'Name', header: "AccountName", width: 200, sortable: true, dataIndex: 'Name'},
{id: 'Industry', header: "Industry", width: 150, sortable: true, dataIndex: 'Industry'},
{id:'Type',header:"Type",width:150,sortable:true,dataIndex:'Type'}
],
autoExpandColumn: 'ID', height: 350, width:650, title: 'All Account Details'});
grid.render('myContactList-grid');
});
</script>
<div id="myContactList-grid"></div>
</apex:page>
Controller:
public class ExtJSDataGrid1Controller {
public list<account> getMyAccounts() {
list<account> lstacc=[select id,name,type,phone,industry from account];
return lstacc;
}
}
Example On Grid Package(GridPanel Class):
VF Page:
<apex:page showHeader="false" standardStylesheets="false" controller="ExtJSDataGrid1Controller" >
<apex:includeScript value="{!$Resource.ExtJs}"/> <!-- ext-all.js j avaScript file in static resources-->
<apex:stylesheet value="{!$Resource.ExtCss}"/> <!-- ext-all.css CSS file in static resources-->
<script type="text/javascript">
Ext.onReady(function(){
//Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
var myDataString = 'var myData = [ ';
<apex:repeat value="{!myAccounts}" var="con" id="ContactRepeat">
myDataString += "['{!con.Id}','{!con.Name}','{!con.Industry}','{!con.Type}'],";
</apex:repeat>
myDataString += "];";
//evaluating the string(create the extjs object.)
eval(myDataString);
//Small helper class to make creating Stores from Array data easier.
var store = new Ext.data.SimpleStore({fields:[{name:'ID'},{name:'Name'},{name:'Industry'},{name:'Type'}]});
store.loadData(myData);//Loads the Record cache from the configured Proxy using the configured Reader.
// Creating the grid
var grid = new Ext.grid.GridPanel({store: store, columns: [
{id: 'ID', header: "ID", width: 150, sortable: false, dataIndex: 'ID'},
{id: 'Name', header: "AccountName", width: 200, sortable: true, dataIndex: 'Name'},
{id: 'Industry', header: "Industry", width: 150, sortable: true, dataIndex: 'Industry'},
{id:'Type',header:"Type",width:150,sortable:true,dataIndex:'Type'}
],
autoExpandColumn: 'ID', height: 350, width:650, title: 'All Account Details'});
grid.render('myContactList-grid');
});
</script>
<div id="myContactList-grid"></div>
</apex:page>
Controller:
public class ExtJSDataGrid1Controller {
public list<account> getMyAccounts() {
list<account> lstacc=[select id,name,type,phone,industry from account];
return lstacc;
}
}
JS/CreateagridwithfromanexistingunformattedHTMLtable.htm(Examples)
internationalization-i18n/
"Great blog created by you. I read your blog, its best and useful information. You have done a great work. Super blogging and keep it up.php jobs in hyderabad.
ReplyDelete"