How to use a date field with a Sencha ExtJS model, grid, and store

Today I’m just sharing some Sencha ExtJS code that shows how to use a date field in several Sencha ExtJS components.

First, here’s a Sencha model class where I define a date field:

Ext.define('Finance.model.Transaction', {
    extend: 'Ext.data.Model',

    idProperty: 'id',

    // `ttype` is B (buy) or S (sell)
    fields: [
        { name: 'id' },
        { name: 'symbol' },
        { name: 'ttype' },
        { name: 'quantity' },
        { name: 'price' },
        { name: 'datetime', type: "date", format: 'Y-m-d' },
        { name: 'notes' }
    ]

});

The Sencha Ext.grid.Panel code

Next, I show the date field in a Sencha Grid (Ext.grid.Panel) with the date column defined like this:

{
    text: 'Date',
    width: 150,
    dataIndex: 'datetime',    // the name of the field in the model
    xtype: 'datecolumn',      // the column type
    format: 'Y-m-d'           // the displayed format
},

The Sencha Store code

The Sencha Store code is pretty boring, and knows nothing about the date field, or other fields:

Ext.define('Finance.store.Transactions', {
    extend: 'Ext.data.Store',

    requires: [
        'Finance.model.Transaction'
    ],

    model: 'Finance.model.Transaction',

    proxy: {
        type: 'ajax',
        url: 'php/transactions.php',  // a pass-thru method to my Play Framework code

        reader: {
            type: 'json'
        }
    },

    init: function(application) {
        console.log('Transactions Store created');
    }

});

The server side code

On the server side of my application, my Play Framework code looks like this:

import play.api.libs.json.Json
import play.api.libs.json._

implicit object TransactionFormat extends Format[Transaction] {

    // convert from Transaction object to JSON (serializing to JSON)
    def writes(transaction: Transaction): JsValue = {
        val sdf = new SimpleDateFormat("yyyy-MM-dd")
        val transactionSeq = Seq(
            "id" -> JsNumber(transaction.id),
            "symbol" -> JsString(transaction.symbol),
            "ttype" -> JsString(transaction.ttype),
            "price" -> JsNumber(transaction.price),
            "quantity" -> JsNumber(transaction.quantity),
            "datetime" -> JsString(sdf.format(transaction.datetime)),  // `datetime` is a java.util.Date
            "notes" -> JsString(transaction.notes)
        )
        JsObject(transactionSeq)
    }

    // convert from a JSON string to a Transaction object (de-serializing from JSON)
    def reads(json: JsValue): JsResult[Transaction] = {
        val id = (json \ "id").as[Long]
        val symbol = (json \ "symbol").as[String]
        val ttype = (json \ "ttype").as[String]
        val price = (json \ "price").as[BigDecimal]
        val quantity = (json \ "quantity").as[Int]
        val datetime = (json \ "datetime").as[java.util.Date]
        val notes = (json \ "notes").as[String]
        JsSuccess(Transaction(id, symbol, ttype, price, quantity, datetime, notes))
    }
}

If you look at that code you’ll see that I return the datetime field as a JsString. This seems to work well with Sencha on the client side.

Notes

A few more notes:

  • The datetime field is a MySQL timestamp field
  • My Scala code handles the field as a java.util.Date
  • As noted, I return the field in JSON as a JsString; could maybe use JsObject instead, but this works