Learning Ext JS 3

Reading information in XML Más videos

Descripción del tema

Today we will learn how to read the content from a XML through a "reader" and manipulate the information with a Store, we're going to use Ajax to load the information inside of the Store.

Resources

Before we start, you need to download the resources, unzip them and copy the files to the folder "ajax" (the same folder we used in the previous tutorial), this folder is found inside of the Web server we installed at the beginning of this course. For this tutorial we're going to use the same code we wrote in the previous tutorial, that means we'll do the same thing (visually and same functionality), the difference is that we're going to make the Store load the information through an Ajax request to the server and the response will be in XML format. I'm not going to explain the code we have in the resources because I already did it in the previous tutorial, so if you have any questions about the functionality I recommend you to read it again.

General Structure

Let's edit the file "xml.js", once you open the file you'll see something similar to this:
//the namespace for this tutorial
Ext.ns('com.quizzpot.tutorial');

com.quizzpot.tutorial.Store = {
	init: function(){
		
		//we will write code only between the asterisks
		//*************************************************************//
		//code here the record
		
		//code here the xml reader
		
		//code here the proxy
		
		//code here the Store
		
		//load the data with an Ajax call
		
		//*************************************************************//	
		//the next code is the same as the last tutorial
		//listeners for the buttons
		Ext.fly('personBtn').on('click',this.find,this);
		Ext.fly('txt').on('keyup',function(event,cmd){
			if(event.getKey() === event.ENTER){ //when press ENTER
				this.find(); // perform the search
			}
		},this);
		Ext.fly('ascBtn').on('click',this.orderAsc,this);
		Ext.fly('descBtn').on('click',this.orderDesc,this);
		Ext.fly('older2030Btn').on('click',this.query,this);
		Ext.fly('older30Btn').on('click',this.filter,this);
		Ext.fly('countBtn').on('click',this.count,this);
		
	},
	
	orderAsc: function(){
		this.store.sort('name','ASC'); // sort the store ASC
		this.store.each(function(record){
			this.log(record.get('name')); //print each name
		},this);
		this.log('___________________________________');
	},
	
	orderDesc: function(){
		this.store.sort('name','DESC'); //sort the store DESC
		this.store.each(function(record){
			this.log(record.get('name')); //print each name
		},this);
		this.log('___________________________________');
	},
	
	filter: function(){
		//filter people...
		this.store.filterBy(function(record,id){
			return record.get('age') >= 30; //older than 30 years old
		});
		
		this.store.each(function(record){
			//print on screen
			this.log(record.get('name')+' is older than 30 '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age'));
		},this);
		//clear the filters
		this.store.clearFilter();
		this.log('___________________________________');
	},
	
	query: function(){
		//query the store, search for people older than 20 and younger than 30
		var collection = this.store.queryBy(function(record,id){
			return record.get('age') >20 && record.get('age')<30;
		});
		
		//for each item found...
		collection.each(function(item,index){
			//print the info on the screen
			this.log(item.get('name')+' is '+item.get('age')+ ' and '+(item.get('gender')=='f'?'she':'he')+' is younger than 30');
		},this);
		this.log('___________________________________');
	},
	
	count: function(){
		//count the records in the store
		this.log('<strong>Total records: '+this.store.getCount()+'</strong>');
	},
	
	find: function(){
		var value = Ext.fly('txt').getValue();
		if(Ext.isEmpty(value)) return;
		//if the value is a number
		if(/^\d+$/.test(value)){
			//find by ID
			var record = this.store.getById(value);
			if(!Ext.isEmpty(record)){
				//if found, log it
				this.log(record.get('name')+' work as a '+record.get('occupation')+' and '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age')+' years old');
			}else{
				//alert the user if nothing is found
				this.log('<strong>Record with id: '+value+' was not found!</strong>');
			}
		}else{
			//if it is text, search the name property
			var index = this.store.find('name',value,0,true,false);
			//if something is found...
			if(index>=0){
				//get the record by the index...
				var record = this.store.getAt(index);
				//and print the information
				this.log(record.get('name')+' work as a '+record.get('occupation')+' and '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age')+' years old');
			}else{
				//alert the user if nothing is found
				this.log('<strong>'+value+' not found!</strong>');
			}
		}
	},
	
	log: function(txt){
		var el = Ext.get('response'); // get the LOG
		el.select('p.newest').removeClass('newest'); // remove last update
		Ext.DomHelper.append(el,'<p class="newest">'+txt+'</p>'); //update the log
		el.scrollTo('top',el.dom.scrollHeight); //scroll down
		el.select('p.newest').highlight('F5FC49',{duration:0.5}); //highlight the last message
	}
}

Ext.onReady(com.quizzpot.tutorial.Store.init,com.quizzpot.tutorial.Store);
The previous code is very well packaged and it has methods that invoke the store, which by the way we haven't define yet so if you click on any button right now you'll get an error. In this tutorial we're only going to write between the asterisks that are in the beginning of the file, I have written comments about what we're going to do.

The XML

Ext JS provides an easy way to manipulate the information in a XML; we don't have to move through the generated tree to access the properties and attributes and we don't have to loop through the nodes, this is a great advantage because it saves a lot of time during the development phase. The XML we're going to use in this tutorial is in the file "data.php", we'll only modify the headers for the response and we'll print the information in XML; just remember that in the "real world" the information will come from a database, web service or some other source.
<?php
	header("Content-Type: text/xml"); 
	
	echo '<?xml version="1.0" encoding="UTF-8"?>';
?>

<dataset>
	<results>9</results>
	<person active="true">
		<id>1</id>
		<name>Crysfel</name>
		<occupation>Software developer</occupation>
		<gender>m</gender>
		<age>25</age>
	</person>
	<person active="false">
		<id>2</id>
		<name>Sasha</name>
		<occupation>Figure skater</occupation>
		<gender>f</gender>
		<age>24</age>
	</person>
	<person active="true">
		<id>3</id>
		<name>Jack</name>
		<occupation>Software Architect</occupation>
		<gender>m</gender>
		<age>35</age>
	</person>
	<person active="true">
		<id>4</id>
		<name>John</name>
		<occupation>JavaScript developer</occupation>
		<gender>f</gender>
		<age>24</age>
	</person>
	<person active="true">
		<id>5</id>
		<name>Sara</name>
		<occupation>Designer</occupation>
		<gender>f</gender>
		<age>31</age>
	</person>
	<person active="true">
		<id>6</id>
		<name>Nicole</name>
		<occupation>Tester</occupation>
		<gender>f</gender>
		<age>28</age>
	</person>
	<person active="false">
		<id>7</id>
		<name>Carl</name>
		<occupation>Photographer</occupation>
		<gender>m</gender>
		<age>45</age>
	</person>
	<person active="true">
		<id>8</id>
		<name>Will</name>
		<occupation>Actor</occupation>
		<gender>m</gender>
		<age>32</age>
	</person>
	<person active="false">
		<id>9</id>
		<name>Penny</name>
		<occupation>Waitress</occupation>
		<gender>f</gender>
		<age>29</age>
	</person>
</dataset>
I'm going to explain in the following steps what we need to do in order to manipulate the information we have in the XML.

Step 1: Create the record Person

The first thing we need to do is define the fields and mapping for each record; the mapping is optional if the field's value is the same as the field name, but required otherwise.
//create the "Person" record
var Person = Ext.data.Record.create([
	{name: 'active', mapping:'@active', type:'boolean'}, // mapping an attribute and setting a type for this field
	{name: 'name', mapping: 'name'},// "mapping" property not needed if it's the same as "name"
	{name: 'occupation'}, // This field will use "occupation" as the mapping.
	{name: 'age', type:'float'}, // this field will use "age" as the mapping and its a float type
	{name: 'gender'}
]);
To create a record we need to use the method "create" from the object “Ext.data.Record”, this method receives as a parameter an array with the fields that the record is going to have, with the property "name" we specify the name we will give to the field and we can even specify the data type (boolean, date, float, etc...) and as I mentioned before we can use the property "mapping" to link the record with the information in the XML. I would like to point out that the property "active" has a "mapping" which was linked to an attribute that is in the node "person" of the XML, just remember to add an "@" before to indicate that is an attribute and not a node.

Step 2: Create the "reader" for the XML

Once we have defined the properties of the record we need to create the "reader" that will manipulate the XML.
//creates the reader for the XML data
var reader = new Ext.data.XmlReader({
   totalRecords: "results", // The element which contains the total dataset size (optional)
   record: "person",        // The repeated element which contains row information
   id: "id"                 // The element within the row that provides an ID for the record (optional)
}, Person);
The XMLReader's constructor receives as a first parameter a configuration object, in this object we define the node (in the xml) where the total number of records is, by specifying the property "totalRecords". We need to define the "id" that will be used for the records and the property "record" which is the XML node from where we get the information to fill the records, this is actually where we defined the properties of the records. As second parameter the constructor receives the record that will be used and loaded with the information.

Step 3: Create the Proxy

If we wish to load the information inside of the store through Ajax calls we have to define the place where we're going to get that information and the HTTP method used to make those Ajax calls (GET or POST).
//creates the proxy
var proxy = new Ext.data.HttpProxy({
	method:'POST', //configure the http method GET or POST
	url: 'data.php' //the URL for the Ajax call
});
The previous code defines the method used and the URL that will be invoked.

Step 4: Create the Store

After defining the "ready" and the "proxy" we can create the store like this:
//creates the Ext.data.Store
this.store = new Ext.data.Store({
	proxy: proxy, //setting the proxy
	reader: reader //setting the reader
});
This is enough for now, but don't forget that the Store accepts different implementations of "readers", for example the JsonReader or in this case XmlReader.

Step 5: Load the information in the Store

The last thing we need to do is request the information to the server with Ajax like this:
//loading the data
this.store.load({params:{param1:'value'}});
The method "load" makes the request to the server using Ajax, optionally we can pass the parameters we need through an object that has the property "params", this is very useful if the information we requested is dynamic, for example I could send the "id" of a person to the server expecting only a record with that id in return. In the following code I'm going to show a waiting message to notify the user that the information is being loaded and because the information is loaded very fast I will set a delay so we can see the message a little bit longer.
//loading the data
Ext.Msg.wait('Loading... please wait!','Wait');
this.store.load({params:{param1:'value'}});
this.store.on('load',function(){
	//delay the message 2 seconds
	setTimeout(function(){ 
		Ext.Msg.hide(); // just to see the waiting message XD (don't do it in the real world)
	},2000);
});
Notice I have created a "listener" for the event "load" in the store, in there I defined a function to be executed as soon as the information is loaded in the store, inside of that function I hid the waiting message.

Conclusions

In this chapter we learned not only how to manipulate an XML but also the modularity of the Framework. If you noticed, the code of the previous tutorial was not modified at all and the reason is because we're using the same information but contained in a XML, so we only changed the information's source and the rest of the application is working the same, this is one of the advantages of using Ext JS. As always, if you have any questions or suggestions please leave a comment or join the forum.

Te gustaría recibir más tutoriales como este en tu correo?

Este tutorial pertenece al curso Learning Ext JS 3, te recomiendo revises el resto de los tutoriales ya que están en secuencia de menor a mayor complejidad.

Si deseas recibir más tutoriales como este en tu correo te recomiendo registrarte al curso, si ya eres miembro solo identifícate y registrate al curso, si no eres miembro te puedes registrar gratuitamente!

Si no gustas registrarte en este momento no es necesario! Aún así puedes recibir los nuevos tutoriales en tu correo! Jamás te enviaremos Spam y puedes cancelar tu suscripción en cualquier momento.

¿Olvidaste tu contraseña?

2Comentarios

Instructor del curso

Crysfel3

Autor: Crysfel Villa

Software engineer with more than 7 years of experience in web development.

Descarga Código Fuente Ver Demostración

Regístrate a este curso

Este tutorial pertenece al curso Learning Ext JS 3, revisa todos los tutoriales que tenemos en este mismo curso ya que están en secuencia y van de lo más sencillo a lo más complicado.

Tendrás acceso a descargar los videos, códigos y material adicional.

Podrás resolver los ejercicios incluidos en el curso así como los Quizzes.

Llevarás un registro de tu avance.