Welcome to part 1 of a new blog series, “Ext JS From Scratch”. Why start this series? Well, we have received a lot of feedback from customers regarding the learning curve time for Ext JS. One of the challenges I believe people face in learning Ext JS is that they’ve never learned the fundamentals, or they have not learned how Ext JS really works – they just learn a pattern and off they go.
In this series I will explain how and why Ext JS works the way it does. I will do this by providing simple examples and, over the course of this series, I will build up to a fully featured Ext JS application; essentially I will be ‘starting from scratch’.
For reference, the source code for this series will be available at:
https://github.com/mgusmano/ExtJSFromScratch
So, let’s get started!
The best place to start is with the simplest of HTML5 web applications. An HTML5 web application is data-oriented and is typically discussed in 3 parts:
- HTML – the ‘tags’ that are used to tell the web browser what to draw.
- CSS – Cascading Style Sheets; instructions to tell the browser how to style the HTML tags (fonts, colors, etc).
- JavaScript – the programming language used to manipulate the HTML when it is actually in the browser (typically called the DOM, or Document object Model).
Here is the simplest of HTML5 applications in 1 file, named ‘index.html’. Note that the indenting and spacing are optional, but good use of each makes things a lot more readable.
Basic Web Page:
<!DOCTYPE HTML>
<html>
<head>
<title>Ext JS From Scratch - Part 1, Demo 1</title>
<link href='theme.css' rel='stylesheet'/>
<script src='Ext-lite.js'></script>
<script src='app.js'></script>
</head>
<body>
<div id="ext-viewport" class="x-viewport">
<div id="ext-grid1" class="x-grid">
<div class="gridTitle">Users</div>
<table id="ext-table1" class="blueTable">
<thead>
<th>Name</th><th>Email Address</th><th>Phone Number</th>
</thead>
<tbody>
<tr>
<td>Lisa</td><td>lisa@simpsons.com</td><td>555-111-1224</td>
</tr>
<tr>
<td>Bart</td><td>bart@simpsons.com</td><td>555-111-1224</td>
</tr>
<tr>
<td>Homer</td><td>homer@simpsons.com</td><td>555-111-1224</td>
</tr>
<tr>
<td>Marge</td><td>marge@simpsons.com</td><td>555-111-1224</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
Let’s dissect this file – it is broken into a set of starting and ending HTML “tags”:
- Line 1 indicates that this file is an HTML5 file
- Lines 2 and 35 are the beginning and ending HTML tags – inside the HTML tags are the head and body tags
- Lines 3 and 8 are the head tags – it contains references to 3 files (which are currently empty) that will hold CSS and JavaScript we will soon write
- Lines 9 and 34 is the set of body tags – the contents of the body tags can have other tags to tell the browser what to display, or JavaScript code can ‘inject’ more tags programmatically (we will see that soon)
Opening this file in a browser produces the following page:

Static web page
This page represents a grid, with the top line being the title of the grid, the second line is column headers and the remaining lines are the data for the grid. There are several things to notice about this display. First, there is no ‘theme’ to this page, it is just black text on a white background. Secondly, the page is static – the data is hard-coded on the page. In the web applications we build, data is typically dynamic and based on data calls to a server. Let’s address both of these issues.
Using CSS to create our theme
CSS is used to add the ‘style’ or ‘theme’ to our application. I have added the following CSS to the theme.css file that is referenced by our HTML file and refreshed the browser.
.x-viewport {
margin: 0; border: 5px solid green;
width: 100%; height: 100%; right: 0; top: 0;
overflow: hidden;
position: absolute; box-sizing: border-box;
}
.x-grid {
font-family: Roboto, sans-serif;
font-weight: 400;font-size: 18px; width: 100%;
}
.gridTitle {
position: absolute;
top: 0;right: 0;bottom: 0;left: 0;
display: flex;
align-items: center;
justify-content: center;
background: #2196f3; color: #FFFFFF;
height: 48px;
}
.blueTable {
margin-top: 48px;
border-collapse: collapse;
font-weight: 100;font-size: 14px; width: 100%;
}
.blueTable td, .blueTable th {
border: 1px solid #E6E6E6; padding: 10px;
}
.blueTable th {
font-weight: 600;text-align: left;
}
The result is seen here:

Static web page with CSS applied
Creating CSS that works well and works across browsers is not easy. We will see later that Ext JS comes with a complete set of ‘themes’ – and those themes can also be easily modified.
Bringing the page to life with JavaScript
Now let’s tackle the issues of providing for interaction on a page, things like ‘events’ (like a click on a row), and the use of static data tags in the grid. In fact, any HTML tags in the body of the page are static tags. Fortunately, with JavaScript, any part of the page can be manipulated and a dynamically drawn page can be created. This is something that we want a framework to do. So, let’s take a look at this in 2 steps.
Step 1: In ‘Ext-lite.js’ I have included some ‘framework’ code – defining this as ‘framework’ code means that this code will be the same for each application, containing helper functions, and anything else not specific to my application.
For this first iteration, I have included code that will add click event handlers to each row of a table (addRowHandlers). I have also added code that will wait for the DOM content to be loaded (meaning the page is ready for my code) and will call a ‘launch’ function – it is in this ‘launch’ function that I can write my application code.
document.addEventListener("DOMContentLoaded", function(event) {
launch();
});
function addRowHandlers(table, fn) {
var table = document.getElementById(table);
var rows = table.getElementsByTagName("tr");
for (var i = 1; i < rows.length; i++) {
var row = table.rows[i];
var cols = row.getElementsByTagName("td");
var o = {};
for (var j=0;j<cols.length;j++) {
o['c'+j]=cols[j].innerHTML;
}
var record=[];
record[0] = {};
record[0].data = o;
row.onclick = function() {return fn(row,record)};
}
}
Step 2: In the ‘launch’ function of the ‘app.js’ file, I have included code that is needed to call the addRowHandlers function. The key thing to understand here is that I only write the code in ‘app.js’. All of the ‘framework’ code in ‘Ext-lite.js’ is provided to me and allows me to focus on my application, not the inner workings of the framework.
function launch() {
console.log('page is loaded');
addRowHandlers("ext-table1", onSelect);
};
function onSelect(sender, record) {
var r = record[0].data;
var text = r.c0+' - '+r.c1+' - '+r.c2;
alert(text);
};
Refreshing the page and clicking on the row for Marge produces the following output:

addRowHandlers function – results
Finally, let’s tackle the issue of the static tags in the body. As I mentioned, with JavaScript you can completely construct the HTML on the page dynamically.
If you take a look at the structure of the static HTML, you essentially see a logical structure similar to this:
<body> <viewport> <grid>
the viewport is common to each application, and the grid itself has just a few dynamic items:
- xtype (the type of an object, referred to as xtype in Ext JS)
- title (what goes in the header panel
- columns (description of all columns in the grid
- data (the data to populate the grid)
- listeners (the set of events the object is listening to)
What if we could remove all of the static HTML in the page (allowing the framework to create it dynamically with JavaScript) and just create a logical ‘grid’ in the launch function as a child of the viewport, with a definition of xtype, title, columns, data and events? Say something like this:
{ xtype: 'grid', title: 'Users', columns: [ { name: 'Name' }, { name: 'Email' }, { name: 'Phone number' } ], data: data, listeners: { select: onSelect } }
First, we add a few functions to ‘Ext-lite.js’ to handle the dynamic creation of the HTML – to see the code that was added, go to:
https://github.com/mgusmano/ExtJSFromScratch/blob/master/Part01/03/Ext-lite.js
You will notice that there is quite a bit of code in this file – this code represents the type of code that is in the Ext JS framework, and will be code that you will NOT have to write – the framework does all of this for you! We only have to write code in the ‘launch’ function of ‘app.js’ – you will see that below.
The ‘index.html’ file now looks like this (notice that now there are NO tags in the body):
<!DOCTYPE HTML>
<html>
<head>
<link href='theme.css' rel='stylesheet'/>
<script src='Ext-lite.js'></script>
<script src='app.js'></script>
</head>
<body></body>
</html>
Then, in ‘app.js’, we modify the ‘launch’ function so that it looks like this:
function launch() {
Viewport.add({
xtype: 'grid',
title: 'Users',
columns: [
{text: 'Name', width: 100, dataIndex: 'name'},
{text: 'Email Address', flex: 1, dataIndex: 'email'},
{text: 'Phone Number', width: 200, dataIndex: 'phone'}
],
data: data,
listeners: {
select: onSelect
}
});
}
function onSelect(sender, record) {
var r = record[0].data;
var text = r.name+' - '+r.email+' - '+r.phone;
alert(text);
};
var 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' }
]
So now I have a way to define WHAT I want the user interface to look like and should do, not having to worry about HOW the specific HTML is constructed. I would say that makes creating a web application a lot simpler – and that’s exactly what Ext JS is!
Using the Ext JS Framework to create our application
So now (finally!) let’s use the Ext JS Theme and Framework libraries instead of our own libraries – to see the final files, take a look here: https://github.com/mgusmano/ExtJSFromScratch/tree/master/Part01/05
For this example, I have a copy of the Ext JS 6.5.2 framework in a folder called ‘ext-6.5.2’ – to try this, you can use your licensed version of Ext JS or get a trial of the framework at: https://staging.sencha.com/products/extjs/evaluate
First, lets look at the ‘index.html’ file. Line 5 is a link to one of the Ext JS themes, the ‘Material Theme’ (modeled after the Google Material specification). Line 6 is a link to the Ext JS ‘modern’ toolkit (this example refers to the entire framework – in future blog posts (as part of this series) we will look at better ways to include the Ext JS framework in your application). The resulting ‘index.html’ page now looks like this:
<!DOCTYPE HTML>
<html>
<head>
<title>Ext JS From Scratch - Part 1, Demo 5</title>
<link href='ext-6.5.2/build/modern/theme-material/resources/theme-material-all-debug.css' rel='stylesheet'/>
<script src='ext-6.5.2/build/ext-modern-all.js'></script>
<script src='app.js'></script>
</head>
<body></body>
</html>
The only change in the ‘app.js’ file is that we wrap the launch function in an object parameter to an Ext.application instance (we will explain the reason for that in a future blog).
Ext.application({
launch: function () {
Ext.Viewport.add({
xtype: 'grid',
title: 'Users',
columns: [
{text: 'Name', width: 100, dataIndex: 'name'},
{text: 'Email Address', flex: 1, dataIndex: 'email'},
{text: 'Phone Number', width: 200, dataIndex: 'phone'}
],
data: data,
listeners: {
select: onSelect
}
});
}
});
function onSelect(sender, record) {
var r = record[0].data;
var text = r.name+' - '+r.email+' - '+r.phone;
alert(text);
};
var 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' }
]
and the app now looks like this:

Our first Ext JS application
That’s it – you now have an actual Ext JS application! And it is much more functional than the one we were creating from scratch. The Ext JS Grid has things like sorting, big data handling, column hiding, and much more! If you are curious about all that the Ext JS Grid can do, check out our Kitchen Sink Example at: http://examples.sencha.com/extjs/6.5.1/examples/kitchensink/?modern#grids
All you need to do is modify what is in the ‘launch’ function – the Ext JS framework does the rest.
I assume you’ll want to write a much more complex application that what we wrote here. We’ll have plenty more to cover in the series, but we’ve made a lot of progress so far. Stay tuned for Part 2 of the “Ext JS from Scratch” series, coming soon!
Excellent post!
This is exactly the sort of content the Sencha ecosystem has always been lacking to help web developers get their bearings
Thank you Marc
Thanks Chris, I appreciate the feedback, look for part 2 after Thanksgiving – and keep the feedback coming as I get through the series!
Great beginners guide!
Any idea when we’ll see part 2?
I think it’s great also for OOP developers to much easier enter JS / ExtJS world. Great job Marc! I look forward to the second part. More! More! :-)
thanks for the feedback – I agree, OOP developers should be very comfortable with Ext JS – that will be a focus of one of the future parts to this series
Great to see these sorts of posts again.
How frequent are these posts going to be, monthly, fortnightly?
There always seemed to be enough basic tutorials, but always stopped before the details came through.
I got most of the knowledge from personal blogs from now ex-employees of Sencha as these were updated much more frequently,
I’ve just learned about network development. I’ve recently come into contact with jQuery and ExtJS, which are the best for me.
Thanks Marc,
If there will be a Part 2 could you please do some testing.
Your Ext-lite.js code only ever came up with the last row of the ‘var i’ loop.
check http://jsfiddle.net/oh16h7cj/
my adaptation for Ext-lite.js is below
document.addEventListener(“DOMContentLoaded”, function(event) {
launch();
});
function addRowHandlers(table, fn) {
var table = document.getElementById(table);
var rows = table.getElementsByTagName(“tr”);
for (var i = 1; i < rows.length; i++) {
var row = table.rows[i];
var createClickHandler =
function(row)
{
return function() {
var cols = row.getElementsByTagName("td");
var o = {};
for (var j=0;j<cols.length;j++) {
o['c'+j]=cols[j].innerHTML;
}
var record=[];
record[0] = {};
record[0].data = o;
fn(row,record)
};
}
row.onclick = createClickHandler(row);
}
}
same problem for Part 01/03
Below is a bad solution for Ext-lite,js as I knew the grid had only name, email, phone as columns to go into the record
function create(item) {
var createditem = {};
switch(item.xtype) {
case “grid”:
var grid = document.createElement(“div”);
grid.setAttribute(“id”, “ext-grid1”);
grid.setAttribute(“class”, “x-grid”);
var title = document.createElement(“div”);
title.setAttribute(“class”, “gridTitle”);
title.innerHTML = item.title;
var table = document.createElement(“table”);
table.setAttribute(“class”, “blueTable”);
var header = table.createTHead();
var row = header.insertRow(0);
for (i=0;i<item.columns.length;i++) {
th = document.createElement('th');
th.innerHTML = item.columns[i].text;
row.appendChild(th);
}
var body = table.createTBody();
for (var i=0;i<item.data.length;i++) {
var row = body.insertRow(i);
var o = {};
for(var prop in item.data[i]) {
o[prop] = item.data[i][prop]
td = document.createElement('td');
td.innerHTML = item.data[i][prop];
row.appendChild(td);
}
var createClickHandler =
function(row)
{
return function() {
var record=[];
record[0] = {};
record[0].data = {'name':'n','email':'e','phone':'p'};
record[0].data.name=row.getElementsByTagName("td")[0].innerHTML;
record[0].data.email=row.getElementsByTagName("td")[1].innerHTML;
record[0].data.phone=row.getElementsByTagName("td")[2].innerHTML;
item.listeners.select(row,record)
};
}
row.onclick = createClickHandler(row);
};
grid.appendChild(title);
grid.appendChild(table);
createditem = grid;
break;
default:
break;
}
return createditem;
};
var Viewport;
document.addEventListener("DOMContentLoaded", function(event) {
Viewport = document.createElement("DIV");
Viewport.setAttribute("id", "ext-viewport");
Viewport.setAttribute("class", "x-viewport");
document.body.appendChild(Viewport);
Viewport.add = function(item) {
Viewport.appendChild(create(item));
};
launch();
});
// function addRowHandlers(table) {
// var table = document.getElementById(table);
// var rows = table.getElementsByTagName("tr");
// for (i = 1; i < rows.length; i++) {
// var row = table.rows[i];
// row.onclick = function(myrow){
// return function() {
// var cell = myrow.getElementsByTagName("td")[0];
// var id = cell.innerHTML;
// alert("id:" + id);
// };
// }(row);
// }
// }
Thank you so much for writing the article Marc learnt so much and really appreciated for sharing all the codes and references. Keep writing the indepth articles I love Sencha blog because of these articles.
Ken Smith
https://tweakbox.mobi/
No matter what you click on in the example table it alerts “Marge Simpson”.
+100 for this tutorial. Finally, I found the one and only simple example not on sencha fiddle