Tuesday, January 27, 2009

SplitButton and MenuButton

Probably, somebody also experiences difficulties with dealing with SplitButton and MenuButton when you add new items, select an item, replace it with new items. To deal with those items, you need to call getMenu().

1. To clear existing items, call clearContent() of getMenu()

   split.getMenu().clearContent();
   split.set("label", "Choose One");


2. To add item(s), call addItem() or addItems(). Remember each item has three properties: "text", "value", and "onclick". After calling this method, you need to call render by passing the container of this button, otherwise it won't appear on the browser.

   split.getMenu().addItems(splitData);
   split.getMenu().render(split.get('container'));


3. To replace with new data, just combine two previous snippet codes

   split.getMenu().clearContent();
   split.set("label", "Choose One");
   split.getMenu().addItems(splitData);
   split.getMenu().render(split.get('container'));


4. To enable selection when clicking on each item, each item must have onclick property with an object literal as shown below:

splitData = {
   fn: function(type, args, item) {
      split_group.set("label", item.cfg.getProperty("text"));
   }
}

Handle DateTime field in Gears

SQLite in Gears supports DATETIME data type, but it works differently from JavaScript context. SQLite only support the following formats as shown on SQLite Date and Time Functions. If you provide invalid format, SQLite will not give an error, but the function call (SQLite DateTime function) will return null, or record could not be inserted/updated. There are two ways to handle this situation.

1. If you don't use ORM JavaScript library such JazzRecord or JStORM, you could make this field an Integer field and call getTime() of JavaScript Date object to store. For displaying data back, you can still sort by ascending/descending order. Pass value that get from getTime() to a constructor of Date object to convert a Date object.

var db = google.gears.factory.create('beta.database');
db.open('database-test');
db.execute('create table if not exists Test (Phrase text, Timestamp int)');
//store in db
db.execute('insert into Test values (?, ?)', ['Monkey!', new Date().getTime()]);
var rs = db.execute('select * from Test order by Timestamp desc');

while (rs.isValidRow()) {
//convert to date object
   var date = new Date(rs.field(1));
   alert(rs.field(0) + '@' + date.getDate() + "/" + (date.getMonth()+1) + "/" + date.getFullYear());
   rs.next();
}
rs.close();

One exception with this is that you can use SQLite DateTime functions when querying back because the format you store is not recognized by SQLite. You have to loop through in JavaScript and an if statement.

2. This way is preferable because it supports full SQLite Date and Time Functions, but it needs some helper method to transform format between SQLite and JavaScript back and forth.


var Util = {
   fromJSDateToSQLiteDate: function(date) {
      var toTwoCharacters = function(number) {
         return (number.toString().length == 2) ? number.toString() : '0' + number.toString();
      };
      var strYear = date.getFullYear();
      var strMonth = toTwoCharacters(date.getMonth() + 1);
      var strDate = toTwoCharacters(date.getDate());
      var strHour = toTwoCharacters(date.getHours());
      var strMinute = toTwoCharacters(date.getMinutes());
      var strSecond = toTwoCharacters(date.getSeconds());
      return strYear + '-' + strMonth + '-' + strDate + ' ' + strHour + ':' + strMinute + ':' + strSecond;
   },

   fromSQLiteDateToJSDate: function(strDateTime) {
      var strDate = strDateTime.split(' ')[0];
      var strTime = strDateTime.split(' ')[1];
      var arrDate = strDate.split('-');
      var arrTime = strTime.split(':');
      return new Date(arrDate[0], arrDate[1]-1, arrDate[2], arrTime[0], arrTime[1], arrTime[2]);
   }
};

Friday, January 23, 2009

Refresh DataSource of DataTable

I have been using YUI as a UI framework for my projects recently. I found the documentation of YUI is very bad since it just tells that you do this, you will get this. It doesn't tell why I need to do this, and it still misses some common examples. Most often, I need to check what are methods and properties do this object have.

In order to reset new data when your data have been updated by somewhere, you need to call reset() from getRecordSet() of datatable object. Then, call setRecords() by passing your new data. If you have paginator, you also have to update it by calling setPage() to its current page and reset the total number of record.


dataTable.getRecordSet().reset();
dataTable.getRecordSet().setRecords(newData);
dataTable.refreshView();

//refresh paginator
dataTable.get("paginator").setPage(dataTable.get("paginator").getCurrentPage());
dataTable.get("paginator").set("totalRecords", dataTable.getRecordSet().getLength());

Friday, January 9, 2009

Progress uploads in Rails Passenger

I found a screencast on railsillustrated that show how to do progress upload in rails passenger. It is nice handling and simple. Have a look on

http://www.railsillustrated.com/screencast-file-uploads-progress-in-rails-passenger.html

Subscribe in a Reader