Learning some Sencha touch MVC code fu at sourcedevcon 2011

This week I had pleasure to attend sourcedevcon 2011 at the awesome resort  Le meridien Split together with  @virdun ,@jakobkruse and @stureandersen . I have been lurking for a couple of years in the ExtJS community  since attending  the extjs conference in Orlando back in 2009, keeping up to date on things at our local Öresund ExtJS meetup , so it was nice to get in touch with some of the regular faces in the ExtJS community.

Near the Dicoletian’s Palace

sourcedevcon 2011 was in the lovely town of Split, near Dicoletian’s Palace.

 

Flying into Split I had some doubts on how many ExtJS devs would take their time to fly to split, this being the first community-driven sencha conference in Europe. After arriving I quickly put all my doubts aside – since the venue and conference organization was carefully laid  out.  Split itself is a very charming city, and we had an easy time arriving (leaving was another problem though). I was impressed by the fact that 200+ attendees had chosen to show up (that figure somewhat resembles the first Orlando conference in the US).

At the venue , the first thing we noticed was the outstanding bar with an overview of the local marina and the ExtJS swedes @FredricBerling , @EmilPenlov (and @bryntum when he was not to busy hanging out in some other bars).

Learning some  Sencha touch MVC  Code fu.

At some point Johan (@virdun)  decided that he wanted  to get a Sencha Touch application up and running  . So we kind of lost him for a moment there in the bar.  I don’t remember if it started before @jamespearce introducing sencha touch  – but Johan started hacking furiously on this app for his site http://citypolarna.se somewhat right about  that session.

Johan playing with his mobile phone

Being Johan, he just wouldn’t let go, so I had to answer a lot of questions  about how sencha touch applications worked.

When I discovered that Johan was not being satisfied by the answer “but hey, I haven’t coded a line of sencha touch yet” we walked through the basic shopping list example for sencha touch and Johan modified it a bit, so it could serve as as base for implementing an event viewer for citypolarna. Combining the info found on http://sencha.com and info from the sessions by @_jdg and @edspencer this was an easy task, so modifying the shopping list example to a working application could be done during the conference. Oh yes, it also helped that we remember  to use extraParams instead of baseParams .

A good thing  about exploring sencha touch and mobile user interfaces is that it can be done in the bar while drinking Mojitos

Learning to migrate to ExtJS 4

Besides learning more about sencha touch I learned a lot from @bmoskeau‘s session on migrating from to ExtJS 4.

Here I especially noted that using the MVC pattern can be postponed to a last optional step and that during migration to ExtJS 4, the old “new” constructor syntax should be able to work (but that the new Ext.define and Ext.create constructs is the preferred way to go).  Brian laid out a migration strategy using the   4 R’s  “Rendering , Running, Ready, Refactor” describing the 4 stages the migration should go through.

@bmoskeau talking about migration

ExtJS Scheduler and Calendar

The session by @bmoskeau and bryntum on Ext Calendar and Ext Scheduler  was supposed to be a showcase of the two products, but to me the main value of the session was seing how easy it was to integrate such complex ExtJS  components. My jaw dropped when I saw Brian demonstrate him using his component updating the data model simultaneously in ExtJS scheduler. This is a testament to two very well designed components .

Wrapup

All in all sourcedevcon 2011 left me with the impression of a very vibrant ExtJS community  – I also got the impression of the strong commercial focus Sencha has. Sencha presented   Sencha.IO as a product – I look forward to exploring that  more indepth in the future. I chose to focus more on learning about Sencha touch and the MVC parts of ExtJS 4 during the conference..

“The Irish guys” has posted some writeups of their experiences at sourcedevcon . Well worth a read:

The lowdown of sourcdevcon

http://www.joelennon.ie/2011/05/05/source-dev-con-day-1/

@nielsdehl has posted pictures from the conference at flickr here :

http://www.flickr.com/photos/nils-dehl/sets/72157626648487744/ (sourcedevcon day1)

http://www.flickr.com/photos/nils-dehl/sets/72157626533490549/ (sourcedevcon day2)

http://www.flickr.com/photos/nils-dehl/sets/72157626544637927/ (sourcedevcon day3)

http://www.flickr.com/photos/nils-dehl/sets/72157626672433598/ (sourcedevcon day4)

http://www.joelennon.ie/2011/05/05/source-dev-con-day-1/

icanhas javascript OOP?

In javascript we can express objects using the prototype notation:

  var Cat = function () {
     this.furry = true;
  }
 Cat.prototype.greet = function () {
   return "meeow";
 }

using class mimicking from prototype-js it would be :

 var Cat = new Class({
  initialize: function (){
    this.furry = true;
    },
  ask: function (item) {
   return "icanhas "+item+" ?";
 });

This example should be pretty clear. But when we get into real-life application scenarios we need to interact with users and databases.

Let’s say we had a panel and a button for interacting with lolcats:

var CatInformationPanel = Class.create({
   initialize: function (container) {
     $(container.id+'_furry').checked = true;
     $('petButton').observe('click',  this.ask.bindAsEventListener(this));
  },
  ask:  function (item) {
    $(container.id+'_text').value ="icanhas "+item+" ?";
  }
});

Note that we need to bind “this” to the the function scope for “ask”. this is one of the intricacies of object oriented javascript. Here are some badass ninja examples to explain why.

Now, after interacting with user , you probably want to save the result to a database. let’s assume that you have a resource /lol/cat/questions you can issue a HTTP post to (you can create this using rubyonrails or something similar).

var CatInformationPanel = Class.create({
   initialize: function (container,name) {
     this.name = name;
     $(container.id+'_furry').checked = true;
     $('petButton').observe('click',  this.ask.bindAsEventListener(this));
  },
  ask:  function (item) {
    var question = "icanhas "+item+" ?"
    $(container.id+'_text').value =question;
   var request = new Ajax.Request ({
      "/lol/cat/question", {
        method:'post',
        params:{ name:name, question:question },
        onSuccess: function (json) {
           alert("saved question");
           }
     }
    });
  }
});

openlayers 2.8 supports WFS-T

if you are in a organisation where you store data with geographical information associated with it , then you have the option of sharing your data using the following standards specified by OGC:

One way to leverage these standards is to use the geoserver project for data storage and the openlayers project web for showing and editing maps.update 2009-09-03: When integrating with the extjs framework , then it is worth using the geoext project.

An example snippet from geoserver shows the use of WFS-T for inserting geometric data with associated metadata for an alley in Tasmania. I’ll just bring it here:

xmlns:wfs="http://www.opengis.net/wfs"
xmlns:topp="http://www.openplans.org/topp"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd http://www.openplans.org/topp http://localhost:8080/geoserver/wfs/DescribeFeatureType?typename=topp:tasmania_roads">

494475.71056415,5433016.8189323 494982.70115662,5435041.95096618

alley

Note that oracle has a well supported ways of extracting GML from spatial datatypes if you need to construct the wfs transactions yourself ( oracle locator )

At the first glance wfs can seem a bit complicated. Luckily openlayers has nice wrappings for it that is easily accessed from code as shown in one of their examples running here :

closures -oh yeah?

Hvad mon der sker her :


var a=1;
function foo() {
var a;
function bar() {
a=2;
return a;
}
return bar;
}

a=3;
var b=foo();
var c=b();
alert(c);
alert(a);

ext.data.writer og CRUD

Jeg har kigget lidt nærmere på ext.data.writer og har delt nogle noter her :

http://pedant.dk/archive/CRUD_in_extjs_3_0.pdf

Basalt set kan man nu på en nem måde foretage sig de fleste operationer man kunne forvente sig i en webapplikation der snakker med en database. Det er der jo sådan set ikke noget banebrydende i – nu kan man det også fra extjs . Jeg eksperimenterer i øjeblikket med hvordan man bruger denne nye funktionalitet nemmest – det gør jeg iøjeblikket i :

http://github.com/jacobandresen/yase/tree/master

Lowpro og behaviour

Det er meget vigtigt at udskille javascript fra HTML når man koder webapplikationer. På den facon bliver koden nemmere at vedligeholde og overskue. Prøv at søge efter “unobtrusive javascript”.

Morgan Roderick har givet en introduktion til “Lowpro” . Morgan har bemærket at selv om Dan Webb kommer fra den rigtige side af bæltet, så staver han “Behavior” forkert . Hvis du har de tilbøjeligheder så kan du hente en ny udgave af Ben Nolans “Behaviour” , der er tilrettet af Jakob Kruse her : http://www.kruse-net.dk/behaviour/.

Begge biblioteker gør nogenlunde det samme. Det ser dog ud til at man kan pille event callbacks væk fra “lowpro” efter at man har puttet dem på. Det kan man vist ikke i “Behaviour”.

Bemærk at begge biblioteker er gode at anvende sammen med prototypejs.

Introduktion til Ext.Direct

Jeg har lavet en præsentation af hovedtrækkene i Extjs 3.0 :  Extjs 3.0  The good stuff

Der er mange flotte farver og kode i ! ;)

ext 2009 konference

Jeg er iøjeblikket i Orlando til den første extjs brugerkonference. extjs blev startet af Jack Slocum mens han var hos Yahoo   – biblioteket er nu kommet i 3. version . Hele vejen igennem har det været Jacks vision at skabe et sammenhængende rammeværktøj  til at lave komplekse webapplikationer.

extjs 3.0 RC1 er tilgængelig  fra http://extjs.com/products/extjs/download.php

Den største nyhed for extjs 3.0 er introduktionen af Ext.direct , der introducerer en sammenhængende model for at opdatere data vha forskellige serverside teknologier . Ifbm launch af 3.0 vil der blive præsenteret Routers for Ruby/merb , java, C# og php.  Jeg snakker iøjeblikket med Data access om at de bør introducere en ext 3.0 router  for visual dataflex..

En af de mere visuelt imponerende ting er introduktionen af en RowEditor , der introducerer inplace redigering i et extjs grid vha extjs DataStore arkitektur .

Mit indtryk herfra er at extjs firmaet har gode forbindelser til Adobe , Sun  og Dell samt en større liste af amerikanske virksomheder (bestbuy som et eksempel) . Det virker som at  folk begyndte at bruge extjs for omkring et år siden ifbm extjs 2.0..

Brug af java reflection til at generere JSON data

Jeg arbejder iøjeblikket på en opgave , hvor jeg har behov for at bringe datamodellen ud til behandling i javascript på en nem facon . Ifbm med denne opgave har jeg tænkt på hvordan man kunne gøre det vha reflection.

Hvis vi antager flg klasser :


class A{
public int B;
public int C;
public D F;
public D G;
};

class D {
public String E;
}

og at de var initialiseret således:

A a=new A();
a.B=1;
a.C=2;
a.F=new D();
a.F.E="test";
a.G=new D();
a.G.E="test2";

Så kunne man kigge på selve java objekterne vha reflection for at generere JSON output til bruge i javascript således:


public class JsonEmit{
public static String emit(Object target) throws Exception{
StringBuilder sb=new StringBuilder();
sb.append("{");
Class targetClass=target.getClass();
Field[] publicFields = targetClass.getFields();
for (int i=0;i String sFieldName = publicFields[i].getName();
Class typeClass = publicFields[i].getType();
String sFieldType = typeClass.getName();
Object value = publicFields[i].get(target);
if(value!=null){
sb.append(sFieldName+":");
if(typeClass.isPrimitive()
||sFieldType=="java.lang.String"){
sb.append("""+value.toString()+""");
}else{
sb.append(JsonEmit.emit(value));
}
}
if(i!=(publicFields.length-1))
sb.append(",");
}
sb.append("}");
return(sb.toString());
}

På den facon vil man kunne genere JSON ved et simpelt kald til

JsonEmit.emit(a)

hvorefter man vil se

{B:"1",C:"2",F:{E:"test"},G:{E:"test2"}}

hvordan man omgår 'this' scope problemer for closures

Man kan ikke uden videre bruge ‘this’ i en indre anonym funktion der bruger information fra en ydre. (se en god beskrivelse ifbm closures i  kapitel 4 i “Javascript: the good parts” ).

Problemet kan omgåes ved at benytte “bind” fra prototypejs på flg. facon:


ComboBox.prototype.loader= function (){
if(this.dataStore[this.paramName]===undefined){
new Ajax.Request (
this.url,{
method: 'post',
asynchronous: true,
parameters: this.parameters,
onSuccess: function (transport){
var response=transport.responseText;
this.dataStore.data[this.paramName]=response.evalJSON();
this.render();
}.bind(this),
onFailure: function (transport){
alert('failed to retrieve '+this.paramName+' data');
}.bind(this)
}
}