Difference between revisions of "Ext JS"
m |
|||
Line 306: | Line 306: | ||
Ext.JS adds a fourth concept to the MVC pattern: '''stores'''. A "store" is a collection of models. In a lot of ways, if a model in Ext.JS is like a row in SQL, then a store in Ext.JS is like a table in SQL. | Ext.JS adds a fourth concept to the MVC pattern: '''stores'''. A "store" is a collection of models. In a lot of ways, if a model in Ext.JS is like a row in SQL, then a store in Ext.JS is like a table in SQL. | ||
− | Ext.JS also introduces the concept of '''proxies''': a mechanism that syncs the data in your front-end application to the server. In Ext.JS, a proxy is typically associated with a store. | + | Ext.JS also introduces the concept of '''proxies''': a mechanism that syncs the data in your front-end application to the server. In Ext.JS, a proxy is typically associated with a store. Ext.JS conforms to the ''RESTful paradigm'' in web application development. |
For an example of models, stores, and proxies, see [[Extensible Calendar]]. | For an example of models, stores, and proxies, see [[Extensible Calendar]]. | ||
[[Category:Module 6]] | [[Category:Module 6]] |
Revision as of 21:49, 19 October 2013
Ext JS is a JavaScript Framework. It serves two main functions:
- Simplifies common operations that would take many lines in pure JavaScript
- Provides a selection of APIs for client-side gadgets
As you read through this article, you might find it helpful to play with some of the examples. Feel free to open up a new JSFiddle, and where it says "Choose a Framework", select a recent version of Ext JS (version 4+).
Contents
Using Ext JS in Your Site
For the purposes of this class, you can go ahead and hot-link Ext JS from Sencha's CDN (Content Delivery Network) by putting the following line in your <head> section:
<script src="//cdn.sencha.io/ext-4.2.0-gpl/ext-all-dev.js"></script>
That's it! You can now use Ext in your web application and follow along with the examples below.
A Note about File Size
While convenient, the above version of Ext JS from Sencha's CDN is huge, over 5 MB. There are two main reasons for this:
- The above version is the dev version, which will give you helpful errors in the WebKit Inspector.
- The above version comes with a whole bunch of GUI tools that you probably will never be using.
A functionally equivalent version (minus the dev tools) that is 1 MB in size is also available from Sencha's CDN:
<script src="//cdn.sencha.io/ext-4.2.0-gpl/ext-all.js"></script>
However, if you don't plan on using the GUI features of Ext JS, you can use this 213 KB version:
<script src="//cdn.sencha.io/ext-4.2.0-gpl/ext.js"></script>
A Note about Licensing
Sencha's Ext JS platform, as well as most Ext APIs like Extensible's Calendar Pro, is dual-licensed: you can use it under either the free GNU GPL or a paid commercial license.
For the purposes of this course, you may use both Ext and all of its APIs for free under the terms of the GNU GPL. Indeed, you may continue using them for free even when you're developing a finished commercial application in real life. The catch is that it is not legal to use GNU GPL components in a finished product unless that project is also released under the GNU GPL. At that point, if you don't want to post your source code for others to see and modify, you'll need to pay Sencha for the license.
Selecting an Element
In pure JavaScript, you used functions like document.getElementById() in order to select elements. The functions provided by the W3C work fine, but they are often limiting. Ext Core provides functionality that lets you make more advanced element selections in fewer lines.
Select by ID
To select an element by its ID and then perform an action on it, use Ext.fly(id):
// Add the class "required" to the element with id "myDiv":
Ext.fly("myDiv").addCls("required");
If you need to pass the element by reference, use Ext.get(id) instead:
// Add the class "required" to an element passed as an argument:
function setElementRequired( element ){
element.addCls("required");
}
// Call the above function, passing the element with id "myDiv" as the argument:
setElementRequired( Ext.get("myDiv") );
Note: Ext.fly() is faster than Ext.get(). However, Ext.fly() does not return a useful reference like Ext.get() does.
Note: element.addCls() adds a CSS class to that element. Prior to version 4 of Ext JS, it was simply element.addClass().
Calls to most Ext Element methods can be chained:
// Add the class "required" to the element with id "myDiv", then make it slowly fade away,
// all in one line:
Ext.fly("myDiv").addClass("required").ghost();
// The above line is functionally equivalent to:
Ext.fly("myDiv").addClass("required");
Ext.fly("myDiv").ghost();
Example: Ext Core Select
This example illustrates one use of Ext.select(). Notice how the Ext selector for the "games" list works exactly the same as the selector for the "movies" list.
Select by CSS Selector
CSS provides a syntax with which you are already familiar for selecting elements. Ext enables us to use CSS selectors within JavaScript to select elements via Ext.select(selector). For example:
Ext.select("ul.games li:nth-child(2n)").addClass("required");
Document Ready
When a browser loads JavaScript from a server, it runs the code as soon as it is treated. This can cause problems if your JavaScript depends on content later in the document. Consider the following example:
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Execution Order</title>
<script>
alert( Ext.fly("myDiv").getHTML() );
</script>
</head>
<body>
<div id="myDiv">Hello World</div>
</body>
</html>
This raises the following exception: "Uncaught TypeError: Cannot read property 'textContent' of null." Why? Because the JavaScript is run before the Div is created!
Ext solves this problem by enabling us to bind JavaScript code to the DOMContentLoaded event, which fires as soon as the document is loaded. (This is different from the load event, which fires when the entire web page is loaded, including images.) Simply use Ext.onReady:
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Execution Order</title>
<script>
Ext.onReady(function(){
alert( Ext.fly("myDiv").getHTML() );
});
</script>
</head>
<body>
<div id="myDiv">Hello World</div>
</body>
</html>
While you could do this in pure JavaScript, there are backwards compatibility issues with that approach which Ext handles behind the scenes.
Utility Methods
Ext JS provides a variety of tools that enable you to perform other common tasks more easily.
Strings
Example: String Utility Functions
Demonstration of some of Ext's string utility functions.
You can access Ext's String utility functions inside Ext.String. See the JSFiddle example for a demonstration. Some of the useful functions include:
- Ext.String.trim(str) trims str of leading whitespace.
- Ext.String.ellipsis(str, len) puts a (fake) ellipsis after len characters in str
- Ext.String.escape(str) escapes ' and \ characters from str
- Ext.String.format(format, arg0, arg1, ...) is Ext's version of sprintf (see the example for a demonstration)
- Ext.String.htmlEncode(str) encodes HTML special characters to make a string safe for display; similar to PHP's htmlentities() or htmlspecialchars()
- Note: This is aliased as Ext.util.Format.htmlEncode(str)
A complete list is available in the Ext JS documentation.
Creating DOM Elements
Example: Creating Elements
Demonstration of how Ext can create elements for the DOM.
Ext JS makes it easy to create new DOM elements on the fly. The following code creates a new list item inside the unordered list with ID "myList":
Ext.DomHelper.useDom = true; // See next section for an explanation of this line
Ext.fly("myList").createChild({
tag: "li",
children: [
{
tag: "strong",
children: [
"To Do: "
]
},
"Water the garden"
]
});
The HTML generated by the above example would be:
<li><strong>To Do: </strong>Water the Garden</li>
See the JSFiddle example for a demonstration.
Preventing HTML Injection
If you pass a string where Ext JS expects a child element, Ext will treat the string as an HTML string by default. This may open your application to XSS vulnerabilities if you are not careful. It is therefore recommended that you force Ext to create text nodes (thereby displaying strings literally) by putting this line at the top of your JavaScript file:
Ext.DomHelper.useDom = true;
Event Binding
Example: Event Binding
How to use Ext to bind events. Gives examples of the `scope` and `options` parameters.
Event binding is relatively straightforward using Ext:
Ext.fly("myButton").on("click", function(){
alert("You clicked my button");
});
The Ext.Element.on() method takes four parameters: the event type, the callback function, the scope of the callback function, and an options object. The callback function is passed three parameters: the event object, the target element, and the options object. For example:
var myObject = {
say: function(message){
alert(message);
}
};
Ext.fly("myButton").on("click", function(event, element, options){
this.say(options.message);
}), myObject, {
message: "Hello World"
});
Other Helpful Utilities
- Ext.Number.constrain(num, min, max) returns num iff it is between min and max, or otherwise min if the number was smaller or max if the number was bigger
- Ext.Number.randomInt(min, max) returns a random integer between min and max inclusive.
- Ext.Object.getKeys(obj) returns all keys from the object literal obj
- Ext.Object.each(obj, fn) iterates through the object literal obj, calling fn(key, value) on each key/value pair.
- Ext.each(arr, fn) iterates through the array arr, calling fn(value, index) on each item in the array.
- Ext.Array.map(arr, fn) returns an array containing the return value of fn(value, index) on each item in arr.
- Ext.Array.min(arr) and .max(arr) and .mean(arr) return the maximum value, minimum value, and average value of arr, respectively.
- Ext.toArray(non_arr) converts the iterable non_arr into a true Array. Especially useful for dealing with the arguments non-array:
alert( Ext.Array.toArray(arguments).join(" - ") );
AJAX
Ext Core makes AJAX easy. The following code fetches and parses the contents of data.json and then displays it on the page:
Ext.Ajax.request({
url: "data.json",
success: function(response){
var jsonData = Ext.decode(response);
Ext.fly("myDiv").setHTML( jsonData.description );
},
failure: function(respose){
console.log( "Error loading data; received error code " + response.status );
}
});
The following code sends a comment ID to comment_ajax.php, which responds with a JSON object containing the comment's HTML:
Ext.Ajax.request({
url: "comment_ajax.php",
params: {
comment_id: 45
},
success: function(response){
var jsonData = Ext.decode(response);
// Sanitize the response before displaying it on the page:
var sanitizedComment = Ext.util.Format.htmlEncode( jsonData.contents );
Ext.fly("myDiv").setHTML( sanitizedComment );
},
failure: function(respose){
console.log( "Error loading data; received error code " + response.status );
}
});
Note: When parameters are given, Ext sends a POST request by default. If no parameters are given, Ext sends a GET request. If you want to send a GET request but also prevent caching, set the disableCaching option to true.
Note: We use Ext.util.Format.htmlEncode(str) in the above example. This is Ext's closest equivalent to PHP's htmlencode($str).
Submitting an Entire Form over AJAX
Ext gives us another handy feature for AJAX requests: it enables us to automatically send the entire contents of a form. For example, suppose we had the following form in HTML:
<form id="myForm" action="login.php">
<label>Username: <input type="text" name="usr" /></label>
<label>Password: <input type="password" name="pwd" /></label>
</form>
We can submit this form asynchronously in just one line of Ext:
Ext.Ajax.request({ form: "myForm" });
Model View Controller
What really sets Ext.JS apart from other JavaScript libraries is the toolset it gives you to create GUI components. Ext.JS has an MVC engine that works on the front end of your application.
Models, Stores, and Proxies
Ext.JS adds a fourth concept to the MVC pattern: stores. A "store" is a collection of models. In a lot of ways, if a model in Ext.JS is like a row in SQL, then a store in Ext.JS is like a table in SQL.
Ext.JS also introduces the concept of proxies: a mechanism that syncs the data in your front-end application to the server. In Ext.JS, a proxy is typically associated with a store. Ext.JS conforms to the RESTful paradigm in web application development.
For an example of models, stores, and proxies, see Extensible Calendar.