Monday, April 22, 2013

ExtJS passing parameters to a store proxy

I came across a need to pass parameters to a GET rest request. In my case, the server code was filtering which columns to return based on a parameter received. I started looking for a way to pass along such a parameter to my store proxy. Many solutions suggested to call the load method manually, which would allow you to pass in some parameters with it.

However, this was not possible for my application architecture because the store had to be on autoLoad: true. It is possible to pass an extraParams config to a proxy.



Ext.define('myStore', {
    extend: 'Ext.data.Store',
    model: 'myModel',
    storeId: 'mystore',
    proxy: {
        type: 'rest',
        url: buildServiceUrl('users'),
        simpleSortMode: true,
        extraParams: {
            inclProps: '{userId, shortDesc}'
        },
        reader: {
            type: 'json',
            root: 'data'
        },
        writer: {
            nameProperty: 'mapping'
        }
    },
    
    autoLoad: true
});

Thursday, April 18, 2013

Getting a form from an Ext.form.Panel

Using an Ext.form.Panel is an excellent choice for form-type screens as it can simplify some aspects of the interface. One such simplification is the ability to call isValid(), which allows you to validate all the fields in the form at once. This can, for example, check that fields with a vtype of email are in a format of name@server.com. The problem I ran into however, is that an Ext.form.Panel does not have the method isValid(). The object you want is the underlying Ext.form.BasicForm. To get the child form, you can simply call getForm().


var panel = Ext.create('Ext.form.Panel', {
    items: [...]
});

var validity = panel.getForm().isValid();

Monday, April 15, 2013

Getting a List of resources in Spring MVC

Say you have a resource you are using already similar to this, but you want to be able to work with a list of them:
public class Person extends AbstractWebResource<Person> {

    public String getName() {
        return _name;
    }

    public void setName(String name) {
     _name= name;
    }
    
    @Column(name="name")
    private String _name;
}

The solution is to create a separate resource that is a list of your original resource:
public class BatchPersons {
    
    public void setPolicies(List<person> people) {
     _people = people;
    }
    
    public List<person> getPolicies() {
        return Collections.unmodifiableList(_people);
    }
       
    private List<person> _people;
}

Then, in the controller:
 @RequestMapping(method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.OK)
    public void put(@RequestBody BatchPersons resources)
            throws Exception {
        for (Person r : resources.getPolicies()) {
            //work with person
        }
    }

Now, you can make a PUT to your endpoint with a request payload as such:
{
    "people": [{
        "name": "Ned Stark"
    }, {
        "name": "Rob Stark"
    }]
}

Wednesday, April 10, 2013

ExtJS custom textfield validation for natural numbers.

Suppose you have a text field on your form like this:

this.portField= Ext.create('Ext.form.field.Text', {
    fieldLabel: 'Port',
    labelAllign: 'top'
});

And that your goal is to make sure the user enters only a natural number. Here I am referring to a natural number as a non-negative integer.

Your first choice would be to look at the vtype config available for the text field. However, you will notice that there is no available choice to mark strictly an integer. That of course, means we get to write our own! Luckily this is not a difficult task:


Ext.apply(Ext.form.field.VTypes, {
    natural: function(val, field) {
        var reg= /^\d+$/i;
        return reg.test(val);
    },
    naturalText: 'Must be a natural number',
    naturalMask: /^[0-9]/i
});


What this does is apply a regular expression to the contents of the field to check for its validity. This statement will actually disallow any non-numeric characters from being entered into the field! The three configs must all start with the same string which will become your new vtype, here it is natural. Now we can simply add the new vtype to the text field:


this.portField= Ext.create('Ext.form.field.Text', {
    fieldLabel: 'Port',
    labelAllign: 'top',
    vtype: 'natural'
});