| Summary: Panduan Penggunaan Umum Library Ext. Pengguna baru sebaiknya memulai dari tempat ini. |
| Author: Brian Moeskau |
| Published: November 1, 2007 |
| Ext Version: 2.0 |
Languages: English
|
Tutorial ini ditujukan untuk Ext versi 2.0. Panduan untuk Ext Versi 1.x masih tersedia pada link ini 1.x version
Bila anda pengguna baru library ExtJS atau sedang mencoba untuk mengetahui lebih jauh tentang ExtJs, anda telah datang pada tempat yang tepat. Tutorial ini akan menjelaskan konsep dasar Ext dan menemukan bagaimana cara untuk membuat sebuah halaman dinamis dan menampilkannya dengan cepat. Diasumsikan para pembaca telah memiliki pengetahuan dasar javascript dan HTML document object model (DOM).
Jika anda belum pernah melakukan hal ini, sebaiknya anda melihat halaman Start Up Guide.
| Download File Contoh |
Kita awali sesuai dengan flow umum yang biasa orang selesaikan dengan javascript dan bagaimana cara melakukannya pada Ext. sebagai percobaan anda dapat mendownload starter file di : IntroToExt2.zip File ini akan kita gunakan untuk membangun sebuah halaman menggunakan kode Ext.
IntroToExt2.zip berisi empat file: ExtStart.html, ExtStart.js, ExtStart.css dan ajax-example.php.
Sekarang bukalah file ExtStart.js dengan editor favorit anda, lihat potongan kode berikut :
Ext.onReady(function() { alert("Congratulations! You have Ext configured correctly!"); });
Ext.onReady mungkin adalah method pertama yang akan sering anda lihat di setiap halaman. Method ini secara otomatis dipanggil satu kali saat DOM berhasil dimuat seluruhnya,sebagai jaminan bahwa setiap element yang akan dijadikan referensi telah tersedia saat script dijalankan. Sekarang anda dapat bergerak maju !, hapuslah satu baris alert(),agar kita dapat memulai menambahkan suatu kode yang berguna.
Saat anda bermain dengan JavaScript, anda pasti sering menspesifikasi suatu element untuk dijadikan referensi agar dapat melakukan suatu hal yang menarik. Kode berikut adalah contoh menseleksi sebuah DOM node berdasarkan ID:
var myDiv = document.getElementById('myDiv');
Kode ini memang berjalan dengan baik, tetapi objek yang dihasilkan (sebuah DOM node) tidak memberikan suatu kekuatan ataupun kenyamanan. Masih banyak kode tambahan harus ditulis bila anda ingin berkreasi dengan objek tersebut ditambah anda harus yakin bahwa kode tersebut berjalan baik di berbagai web browser.
Sekarang mari kita bahas Objek Ext.Element. Ext.Element adalah inti dari Ext saat anda melibatkan akses untuk mendapatkan suatu element dan memberikan aksi kepadanya. Element API adalah aspek paling mendasar dari keseluruhan Library Ext, bila anda ingin menghabiskan waktu untuk mempelajari sebuah class di Ext dengan baik, anda harus mulai dari sini, Element !
Halaman ExtStart.html memiliki sebuah tag div dengan id "myDiv") Berikut ini adalah cara mendapatkan myDiv menggunakan ExtJs.
Ext.onReady(function() { var myDiv = Ext.get('myDiv'); });
Nah, sekarang hal apakah yang menarik dari kode Ext di atas ?
This means that you can do all kinds of useful stuff with very minimal code. Here are just a few simple examples (see the Element API documentation for the complete list of everything that you can do). Go ahead and try adding some of these to ExtStart.js after the previous line where we got the 'myDiv' Element:
myDiv.highlight(); // The element's background will highlight to yellow then fade back myDiv.addClass('red'); // Add a custom CSS class (defined in ExtStart.css) myDiv.center(); // Center the element in the viewport myDiv.setOpacity(.25); // Make the element partially-transparent
Often it is either impractical or impossible to select DOM nodes by ID. Maybe the ID is not set, or you don't know it, or there are too many elements to practically reference directly by ID. Sometimes you may want to select nodes based on something other than ID, like an attribute or a CSS classname. For these reasons, Ext ships with an extremely powerful DOM selector library called DomQuery.
DomQuery can be used as a standalone library, but more often when using Ext, you'll use it in the context of selecting Elements so that you can then act on them via the Element interface. Luckily, the Element object itself supports querying via the Element.select method, which internally uses DomQuery to select elements. As a simple example of how you might use this, the ExtStart.html file contains several paragraph (<p>) tags, none of which have ids. If you wanted to easily select every paragraph and perform an action on all of them at once, you could do something like this:
// Highlights every paragraph Ext.select('p').highlight();
This example demonstrates a very handy aspect of Element.select—it returns a CompositeElement, which provides access to every underlying Element via the Element interface. This allows you to easily act on every Element instance returned by Element.select without looping and touching each one individually.
DomQuery supports a wide array of selection options, including most of the W3C CSS3 DOM selectors, basic XPath, HTML attributes and a lot more. Please see the DomQuery API documentation for complete details on this powerful library.
So far in our examples, all of the code we've written has been directly inside the onReady function, which means that it always executes immediately after the page loads. This doesn't give us much control—you will most commonly want your code to execute in response to specific actions or events that you choose to handle. To do this, you define event handlers that can respond to events using functions that you assign.
Let's start off with a simple example. Open up ExtStart.js and edit it so that your code looks like this:
Ext.onReady(function() { Ext.get('myButton').on('click', function(){ alert("You clicked the button"); }); });
The code still executes when the page loads, but there's an important difference. The function containing the alert() is defined, but is not actually executed immediately—it is assigned as the "handler" of the button click event. Spelled out in plain English, this code might read: "Get a reference to the Element with id 'myButton' and assign a function to be called anytime someone clicks on the Element."
Not surprisingly, Element.select allows you to do the same thing, but with an entire group of Elements at once. For example, to show our message when any paragraph in our test page is clicked, we could do this:
Ext.onReady(function() { Ext.select('p').on('click', function() { alert("You clicked a paragraph"); }); });
In these two examples, the event handling function is simply declared inline, without giving it a function name. The term for this type of function is an "anonymous function" since it is declared without ever being named. You can also assign an event to be handled by a named function, which is especially useful if you want to reuse the function and have it handle multiple events. For example, this code is functionally equivalent to the previous example:
Ext.onReady(function() { var paragraphClicked = function() { alert("You clicked a paragraph"); } Ext.select('p').on('click', paragraphClicked); });
So far we have looked at performing a generic action when our event is raised, but how do we actually know which specific Element raised the event so that we can perform some action on it? It turns out to be pretty easy—the Element.on method passes three extremely useful parameters to the event handling function (we're only going to look at the first one here, but you should explore the API documentation to learn more about event handling details). In our previous examples our handling function was ignoring these parameters, but with one simple change, we can provide an additional level of functionality. The first, and most important, parameter is the event that occurred. This is actually an Ext.EventObject, which is both normalized across browsers and provides more information than the standard browser event. For example, the event's target DOM node can be retrieved with this simple addition:
Ext.onReady(function() { var paragraphClicked = function(e) { Ext.get(e.target).highlight(); } Ext.select('p').on('click', paragraphClicked); });
Note that target is a DOM node, so we first retrieve the corresponding Element, then perform whatever action we want on it. In this case, we are visually highlighting the paragraph.
In addition to the core javascript library that we've been discussing, Ext also includes one of the richest sets of Javascript UI widgets available today. There are far too many to cover in this introduction, but let's take a look at a couple of the widgets that people use most commonly and how easy they are to work with.
Rather than a boring "Hello World" message box, let's add a little twist. We already have code that we wrote in the previous section that highlights each paragraph when you click on it. Let's modify that code to also show the text of the paragraph that was clicked in a message box. In the paragraphClicked function above, replace the line:
Ext.get(e.target).highlight();
...with this code:
var paragraph = Ext.get(e.target); paragraph.highlight(); Ext.MessageBox.show({ title: 'Paragraph Clicked', msg: paragraph.dom.innerHTML, width:400, buttons: Ext.MessageBox.OK, animEl: paragraph });
There are a couple of new concepts being shown here that are worth discussing. In the first line, we are now creating a local variable named paragraph that will hold a reference to the Element representing the DOM node that was clicked (in this case we know it will always be a paragraph since our click event is only associated with <p> tags). Why are we doing this? Well, looking ahead for a moment, we will need a reference to the Element to highlight it, and we'll also use the same Element for some of the MessageBox parameters. In general, it is bad practice to make the same function call multiple times to retrieve the same value or object reference, so by assigning it to a local variable and reusing the variable, we are being good object-oriented developers!
Now, on to the MessageBox call, which demonstrates the other new concept for us to discuss. At first glance, this may look simply like a list of parameters being passed to a method, but if you look closely, there is a very specific syntax. What is actually being passed to MessageBox.show() in this case is only one parameter: an object literal that contains a set of properties and values. In JavaScript, an object literal is a dynamic, generic object that is created anytime you use the { and } characters surrounding a list of name/value properties, and the format for those properties is [property name] : [property value]. You'll see this pattern used extensively throughout Ext, so you should learn it well!
Why use an object literal? The main reason is flexibility. New properties can be added or removed from the object literal at any time, or defined in any order, while the method signature (the number and types of parameters expected by a method) never has to change. It also makes it far more convenient from the end developer's perspective when using methods with many optional parameters (as in the case of MessageBox.show). For example, let's say that a fictional method foo.action has four optional parameters, but you only need to pass one of them. In this case, your code might look like this: foo.action(null, null, null, 'hello'). However, if that method instead took an object literal, the code would look like this: foo.action({ param4: 'hello' }). Much easier to use, much more readable.
The grid is one of the most popular widgets in Ext, and usually the first one that people want to see, so let's take a look at how easy it is to get a basic grid up and running. Replace any existing code you have in ExtStart.js so that it looks like this:
Ext.onReady(function() { var myData = [ ['Apple',29.89,0.24,0.81,'9/1 12:00am'], ['Ext',83.81,0.28,0.34,'9/12 12:00am'], ['Google',71.72,0.02,0.03,'10/1 12:00am'], ['Microsoft',52.55,0.01,0.02,'7/4 12:00am'], ['Yahoo!',29.01,0.42,1.47,'5/22 12:00am'] ]; var myReader = new Ext.data.ArrayReader({}, [ {name: 'company'}, {name: 'price', type: 'float'}, {name: 'change', type: 'float'}, {name: 'pctChange', type: 'float'}, {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'} ]); var grid = new Ext.grid.GridPanel({ store: new Ext.data.Store({ data: myData, reader: myReader }), columns: [ {header: 'Company', width: 120, sortable: true, dataIndex: 'company'}, {header: 'Price', width: 90, sortable: true, dataIndex: 'price'}, {header: 'Change', width: 90, sortable: true, dataIndex: 'change'}, {header: '% Change', width: 90, sortable: true, dataIndex: 'pctChange'}, {header: 'Last Updated', width: 120, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'} ], viewConfig: { forceFit: true }, renderTo: 'content', title: 'My First Grid', width: 500, autoHeight: true, frame: true }); grid.getSelectionModel().selectFirstRow(); });
While this looks like a lot, it is really only 4 lines of code in total (3 if you don't count the test data)!
How easy was that? If all went well, you should end up with something that looks close to this:
Of course, there will probably be some details about this code that you may not fully understand at this point. The intent of this example is to show how it's possible to create an extremely rich, visually-complex user interface component with very few lines of code—learning the details will be left as an exercise for the reader. There are many resources to help you with learning the grid, including the interactive grid demos and the GridPanel API documentation.
We've only seen the tip of the iceberg here. There are literally dozens of UI widgets to choose from in Ext, including automatic page layouts, tabs, menus, toolbars, dialogs, a tree view and many more. Please explore the interactive examples for a glimpse of everything that's available.
Once you have your page created and you know how to interact with it through Javascript, you'll probably want to know how to get data to and from a remote server, most commonly to load and save data from a database on the server. Doing this asynchronously via Javascript without reloading the page is known commonly as Ajax, and Ext has excellent Ajax support built right in. For example, a common goal is to handle a user interaction, post something to the server asynchronously, then update an element of the UI in response to the action. Here's an example of a very simple HTML form containing a text input field, a button, and a div used to display a message (Note: you can add this code to ExtStart.html if you'd like to follow along, but you'll have to have access to a web server in order to run the server code below):
<div> Name: <input type="text" id="name" /> <input type="button" id="okButton" value="OK" /> </div> <div id="msg"></div>
Next, we'll add the Javascript required to get our data and post it to a server-based process (replace any existing code in ExtStart.js with this):
Ext.onReady(function(){ Ext.get('okButton').on('click', function(){ var msg = Ext.get('msg'); msg.load({ url: 'ajax-example.php', // <-- change if necessary params: 'name=' + Ext.get('name').dom.value, text: 'Updating...' }); msg.show(); }); });
Note: This example will only run from a web server. The URL in your browser should start with http:// and not file:// or the Ajax transaction will not work! Localhost will work fine, but it must be via http.
Hopefully the general pattern is starting to look familiar by now! The code is wrapping the okButton input with an Element object and attaching an anonymous function that will handle the event if anyone clicks on the button. Inside the click handler, we're using a special class built into Ext called the Updater—this class makes sending an Ajax request, receiving a response and updating another Element extremely trivial. The Updater can be used directly, or as we're doing here, it can be accessed via the Element that we want to update (in this case the 'msg' div) using the Element.load method. When Element.load is used, the server's response automatically replaces the innerHTML of the Element. Simply pass it the URL to the server-based process that will handle the request, the querystring parameters to process (in this case passing in the value of the 'name' field) and the text to display in the Element's innerHTML while the request is being processed. Show the msg div (since it starts hidden by default) and that's it! Of course, as with most things in Ext, there are many more Updater options supported, as well as different ways to process Ajax requests in different situations (see the Ext.Ajax class for more direct access to Ajax functionality), but this shows how easy it is to get a basic example up and running.
The last piece of the Ajax puzzle is the process on the web server that actually handles the request and returns a response to the page. This process could be a server page, a servlet, an HTTP handler, a web service, even a Perl or CGI script—just about anything that can reside on a web server and process HTTP requests. Unfortunately, because of this variety there is no way to give a standard example that would cover all possibilities. Here are some examples in a few common languages to hopefully get you started (this code simply echoes whatever was passed from the 'name' field back to the client with 'From Server: ' added at the beginning, and that gets written to the 'msg' div). The PHP example has been included in the download as 'ajax-example.php' but feel free to replace that with your server code of choice:
<?php if(isset($_POST['name'])) { echo 'From Server: '.$_POST['name']; } ?>
<?php if(isset($this->data['name'])) { $this->flash('From Server: '.$this->data['name']); } ?>
from django.http import HttpResponse def ajax_request(request): return HttpResponse('From Server: %s' % request.POST.get('name', 'nada'))
#!/usr/bin/perl use strict; use warnings; use CGI; my $Query = new CGI; print $Query->header(); print "Hello from : ".$Query->param('name'); exit;
protected void Page_Load(object sender, EventArgs e) { if (Request["name"] != null) { Response.Write("From Server: " + Request["name"]); Response.End(); //Note: the call to Response.End() will throw an //exception (that's what it's designed to do). It's //OK to simply catch it and ignore it; depending on //your use case, you may find that necessary. } }
<cfif StructKeyExists(form, "name")> <cfoutput>From Server: #form.name#</cfoutput> </cfif>
if (StructKeyExists(form, "name")) {
writeoutput("From Server : " & form.name);
}
From Server: ${param.name}
render :text => "From Server: #{params[name]}"
The real challenges when dealing with Ajax processing involve all of the plumbing code required to properly process and format real structured data on the server. There are several formats to choose from that people use commonly (most often either JSON or XML). There are also many language-specific libraries available to deal with Ajax processing that can work well with Ext, as Ext is language-neutral with regard to the server. As long as the result is sent to the page in the proper data format, Ext does not care what happens on the server! Please see our list of platform-specific resources for additional information about server-side frameworks and tools.
Now that you've had a small taste of what Ext is and what it has to offer, there are many resources available to help you really dive into the next level: