Stivlo'st in Asia

Programming and Travel

Browsing Posts in Javascript

Ajax request with Ext Js

No comments

An Ajax request allows to “retrieve data from the server asynchronously in the background without interfering with the display and behavior of the existing page.” [Ajax (programming) - From Wikipedia]

Every Ajax framework has its own way of simplifying the direct use of the XMLHttpRequest object, and Ext Js has Ext.Ajax.request for coding Ajax requests. There are also other ways to send Ajax requests with Ext Js, but this one is the hand coded one which leaves you the maximum flexibility.

It’s quite straightforward and I’ll explain it with a simple working example. First we need to prepare our params object with the variables to send to the server. If we don’t need any variable we can omit it and omit the corresponding line in the request. One interesting consequence is that a request without parameter will be sent in GET method, while a request with parameter will be sent with the POST method.

With the url parameter we’re telling Ext Js where to fetch the data and according to the same origin policy it should be a url on the same website.

With success: and failure: hooks we can define callbacks, i.e. functions that will get called when the data will be ready. It’s important to stress again that the request is asynchronous, any code after the request will be processed and only later, one of the callback will be executed.

        Ext.Ajax.request({
            params: {greeting: 'Hello', who: 'Everybody'},
            url: '/extjs/ajax1.php',
            success: function (resp) {
                var data;
                data = Ext.decode(resp.responseText);
                if (data.success === true) {
                    Ext.MessageBox.alert('Message', data.msg);
                } else {
                    Ext.MessageBox.alert('Error', 'Some problem occurred');
                }
            },
            failure: function () {
                Ext.MessageBox.alert('Error', 'Some problem occurred');
            }
        });

The corresponding PHP code on the server is the following:

function main() {
    if (!isset($_POST['greeting']) || !isset($_POST['who'])) {
        $res = array('success' => false, 'msg' => 'Missing parameters');
        echo json_encode($res);
        return;
    }
    $res = array('success' => true,
        'msg' => $_POST['greeting'] . ' ' . $_POST['who']);
    echo json_encode($res);
}

To run this example code, click on the run button, it should show the message ‘Hello Everybody’ composed by the two strings passed as parameter. Of course for such a trivial task there is no need to send an Ajax request, but I wanted to show a simple example of an Ajax request with Ext Js.

Dynamic Form in Ext JS

No comments

I spent some time trying to add check boxes dynamically to a form. In particular I wanted to add check boxes whose names and ids were retrieved from an Ajax call.

When you build a form, form items in Ext JS are contained into a property named “items” inside the Ext.form.FormPanel. So I thought that adding elements to that array and calling the method doLayout() on the form would do the trick, but instead it doesn’t work.

I found out that to do this, I have to call the method insert() on the FormPanel. Here is the description of insert() and remove() function from Ext JS documentation:

insert( Number index, Ext.Component component ) : Ext.Component

Inserts a Component into this Container at a specified index. Fires the beforeadd event before inserting, then fires the add event after the Component has been inserted.

remove( Component/String component, [Boolean autoDestroy] ) : Ext.Component

Removes a component from this container. Fires the beforeremove event before removing, then fires the remove event after the component has been removed.

To test this out I wrote a small JavaScript application that allows you to add or remove check boxes to a form. There are two callbacks linked to the two form buttons that will add and remove check boxes. When there are no more check boxes, pressing the remove button will try to remove the object undefined, but since there is no such object in the array, nothing happens. That’s why I didn’t have to check for the empty list.

var obliquid = {}; //creates the namespace

obliquid.CheckboxExample = function () {
    var counter = 1; //label number counter
    var myCheckb = {
        xtype: 'checkbox'
    };
    var myForm = new Ext.form.FormPanel({
        renderTo: 'CheckboxDiv', //id of the div to render to
        width: 300,
        height: 'auto',
        title: 'Dynamic form',
        frame: true,
        bodyStyle: 'padding: 5px',
        buttons: [
            {
                text: 'Add Checkbox',
                handler: function () {
                    myCheckb.boxLabel = 'Label ' + counter;
                    myCheckb.inputValue = counter;
                    counter++;
                    myForm.insert(myForm.items.length, myCheckb);
                    myForm.doLayout();
                }
            }, {
                text: 'Delete Checkbox',
                handler: function () {
                    myForm.remove(myForm.get(0), true);
                    myForm.doLayout();
                }
            }
        ]
    });
};

Ext.onReady(function () {
    obliquid.CheckboxExample();
});

And here is the Form application defined above:

It’s useful to be able to set field content programmatically, for example I’d want to show the results of an Ajax call. Since I am learning Ext Js, I had a hard time to find how to do it, and I found two ways to do it.

First here is the code for the simplest form, with just one text input.

Ext.onReady(function () {
    new Ext.FormPanel({
        id: 'myForm',
        renderTo: 'myFormDiv',
        frame: true,
        title: 'This is the form title',
        width: 590,
        height: 80,
	items: [ {
            xtype: 'textfield',
            width: 470,
            fieldLabel: 'myField',
            name: 'myField',
            id: 'myFieldId'
        } ]
    });
});

And here is how it looks:

We just need one line of Javascript:

Ext.getCmp('myForm').getForm().findField('myField').setValue('Virtues of programmers: laziness, impatience and hubris');

You can run the code by copying this line in firebug console and pressing the Run button, or you can press the Run button below.

The above code sets the field searching it by field name. A simpler way to set the text input is using its id. Normally I would put both id and name and they would be the same, but to be more clear on which one I am using, I choose ‘myField’ for the name and ‘myFieldId’ for the id.

If you know the field id, it’s simpler to set the value. To try it, copy it in firebug, or press the Run button below.

Ext.getCmp('myFieldId').setValue('Simplicity is prerequisite for reliability');

Basic ExtJs cheat sheet

No comments

I learnt the basic of Ext JS in the book “Ext JS in action” – Jesus Garcia – Manning” and then proceeded to read “Ext JS 3.0 Cookbook” – Jorge Ramon – Packt Publishing.

I wrote a kind of cheatsheet to remember the basic functions. For more details you can buy the books or look in the API docs.

DOM

Ext.onReady(function () { }); //callback to execute when the DOM is ready
var myDiv = Ext.get('divId'); //retrieve a Ext.Element
var combo = Ext.getCmp('colorsCombo'); //retrieve a Ext.Component
Ext.getBody(); //return the body of the document as an Ext.Element
Ext.getDom(id) ; //return the DOM node as HTMLElement

//Dom Query to return an Array of Ext.Element, includes selector/XPath processing
var nodes = Ext.query('div'); //Ext.query('.msg'); for all elements with msg class
Ext.each(nodes, function (item, index, allItems) {
   document.write(index + '<br/>');
});

JSON and URL encoding

Ext.USE_NATIVE_JSON = true;
JSON Encoding: var objectJson  = Ext.encode(myObject);
JSON Decoding: var myObject = Ext.decode(objectJson);

var encodedUrl = Ext.urlEncode(selectedColors); //URL Encoding
var decodedUrl = Ext.urlDecode(encodedUrl); //URL Decode

Reflection

Ext.type(myObject); //Determine object type: array, object, number
Ext.isArray(myObject);  Ext.isNumber(myObject); Ext.isString(myObject);

Array functions

var position = myArray.indexOf('Duck');  //find an object in an array
//0 is the first element, -1 is not found
myArray.remove('Dog'); //remove an object from an array

String functions

var newString = String.escape(myString);
var newString = beforeTrim.trim();
var newString = String.format('You have {0} messages', msgCount);
var newString = Ext.util.Format.uppercase(myString);
//Other functions with one argument:  Ext.util.Format.lowercase(),
//Ext.util.Format.capitalize(),  Ext.util.Format.stripScripts(),
//Ext.util.Format.nl2br(), Ext.util.Format.usMoney()
var newString = Ext.util.Format.ellipsis(myString, 20);
var newString = Ext.util.Format.substr(myString, 0, 5);
var newString = Ext.util.Format.leftPad('23', 4, '0');

Value checking

Ext.num(myObject, 0); //provide a default value it's not a number
var allowZeroLen = false; //this is the default and you can omit
Ext.value(myObject, 'default', allowZeroLen); //provide a default value for the string
var constrained = number1.constrain(25, 50); //force it in the range

Dates

var now = new Date();
var formatted = now.format('Y-m-d');
var aDate = Date.parseDate('2010-12-09', 'Y-m-d');
var inRange = now.between(lowDate, highDate);

JavaScript can be fun

No comments

Really. I’ve always hated JavaScript, struggling with it and cursing it. Now I’m changing my mind. It’s the most ubiquitous programming language. Every computer who has a web browser has JavaScript and is very compatible among different implementations. The bigger problems come from the DOM, but are nowadays nicely hidden by JavaScript libraries. One of the biggest frustrations working with JavaScript comes from working with it without understanding it. Since the syntax is similar to Java/C++ I’ve also committed the mistake to start working with it without studying it.

JavaScript is an object oriented language that doesn’t have classes but has objects and has prototypes. Prototypes are a way to dynamic link objects. The syntax is weird so it’s better to have a Object.create helper function defined as follows:

if (typeof Object.create !== 'function' ) {
     Object.create = function (o) {
         var F = function () {};
         F.prototype = o;
         return new F() ;
     };
}

This is really powerful, we augmented the basic type Object with a new method create() and as a consequence, now all objects have this new method! We will try this by declaring an object called mork and create a new object called mindy based on it.

var mork = {
    "name": "Mork",
    "greet": function() {
        alert("Hi, I'm "+this.name);
    }
};
var mindy = Object.create(mork);

This is not the same as saying var mork2 = mork, because in this latter case we are simply copying the object reference, so if we change any property of mork2, we are actually changing mork. With Object.create we are actually creating a new object, as the name suggests.

mindy.name="Mindy";
mindy.greet();
mork.greet();

You can run the code by clicking on the Run button, and as expected it will say “Hi, I’m Mork” and “Hi, I’m Mindy”.

Now the fun part: if we delete mindy.name, mork anchestor property will be visible again:

delete mindy.name;
mindy.greet();

To run mindy.greet() after deleting mindy.name use the run button below:

In this case mindy will say: “Hi, I’m Mork” because the original property of the prototype can be seen again. What is even more fun is adding a new property or even method to mork:

mork.mood = "happy";
alert(mindy.mood);

In this example mindy mood will be also happy because it will get it from its prototype, with a very late binding. The property mood will actually be only in mork memory because when I call mindy.mood, the interpreter will have to go to the prototype object to read it.

Powered by WordPress Web Design by SRS Solutions © 2010 Stivlo'st in Asia Design by SRS Solutions