city bars workshop

58
James Pearce Director, Developer Relations @ jamespearce [email protected]

Upload: james-pearce

Post on 12-Jan-2015

3.864 views

Category:

Technology


0 download

DESCRIPTION

The mobile web app workshop at Flash and the City, June 2011.

TRANSCRIPT

Page 1: City bars workshop

James Pearce Director, Developer Relations @ jamespearce [email protected]

Page 2: City bars workshop

Build AMobile Web App

with

CSSHTML JS

Page 3: City bars workshop

http://www.sencha.com/products/touch

Sencha TouchA JavaScript framework for building

rich mobile apps with web standards

Page 4: City bars workshop

Pre-requisitesSencha Touch SDK:

  http://sencha.com/products/touch/

 Yelp developer API key:  http://www.yelp.com/developers/getting_started/

api_overview

 Install Sass and Compass:  http://sass-lang.com/download.html

http://compass-style.org/install/

Page 5: City bars workshop

CityBars

http://sencha.com/x/bu

Page 6: City bars workshop
Page 7: City bars workshop

http://sencha.com/x/bv

Page 8: City bars workshop

Development sequence

1 Structure the app

2 Layout the UI

3 Model the data

4 Load the list

5 Attach events

6 Detail page

7 Add mapping

8 Customize theme

Page 9: City bars workshop
Page 10: City bars workshop

1 Structure the app

Page 11: City bars workshop

index.html

<!doctype  html><html>        <head>                <title>City  Guide</title>        </head>

<body></body></html>

Page 12: City bars workshop

index.html<script  src="lib/touch/sencha-­‐touch.js"                  type="text/javascript"></script>

<script  type="text/javascript">        YELP_KEY  =  'G3HueY_I5a8WZX-­‐_bFo3Mw';        ...</script>

<script  src="app/app.js"                type="text/javascript"></script>

<link  href="lib/touch/resources/css/sencha-­‐touch.css"              rel="stylesheet"  type="text/css"  />

Page 13: City bars workshop

app.jscb  =  new  Ext.Application({

       launch:  function()  {                new  Ext.Panel({

                       layout        :  'card',                        fullscreen:  true,

                       html:  "Hello  world!"                        });        }

});

Page 14: City bars workshop
Page 15: City bars workshop

cb.cards

2 Layout the UI

listCard detailCard

toolbar toolbar

dataList

Page 16: City bars workshop

index.htmlcb  =  new  Ext.Application({        launch:  function()  {                cb.cards  =  new  Ext.Panel({                        layout        :  'card',                        fullscreen:  true,

                       cardSwitchAnimation:  'slide',

                       items:  [                                {id:  'listCard'  ...},                                  {id:  'detailCard'  ...}                        ]                        });        }});

Page 17: City bars workshop

listCard{        id:  'listCard',        layout:  'fit',        dockedItems:  [{                dock  :  'top',                xtype:  'toolbar',                title:  'Please  wait'        }],        items:  [{                id:  'dataList',                xtype:  'list',                store:  null,                itemTpl:  '{name}'        }]}

Page 18: City bars workshop

detailCard{        id:  'listCard',        dockedItems:  [{                dock  :  'top',                xtype:  'toolbar',                title:  ''        }]}

Page 19: City bars workshop
Page 20: City bars workshop

3 Model the data

http://api.yelp.com/business_review_search?ywsid=YELP_KEY&term=BUSINESS_TYPE&location=CITY

Page 21: City bars workshop

Apigee console

Page 22: City bars workshop

"businesses":  [        {          "rating_img_url"  :  "http://media4.px.yelpcdn.com/...",          "country_code"  :  "US",          "id"  :  "BHpAlynD9dIGIaQDRqHCTA",          "is_closed"  :  false,          "city"  :  "Brooklyn",          "mobile_url"  :  "http://mobile.yelp.com/biz/...",          "review_count"  :  50,          "zip"  :  "11231",          "state"  :  "NY",          "latitude"  :  40.675758,          "address1"  :  "253  Conover  St",          "address2"  :  "",          "address3"  :  "",          "phone"  :  "7186258211",          "state_code"  :  "NY",          "categories":  [            ...",          ],          ...

Page 23: City bars workshop

index.html<script  type="text/javascript">        YELP_KEY  =  'G3HueY_I5a8WZX-­‐_bFo3Mw';        DEFAULT_CITY  =  'New  York';        BUSINESS_TYPE  =  'Bars';</script>

Page 24: City bars workshop

app.jsExt.regModel("Business",  {        fields:  [                {name:  "id",  type:  "int"},                {name:  "name",  type:  "string"},                {name:  "latitude",  type:  "string"},                {name:  "longitude",  type:  "string"},                {name:  "address1",  type:  "string"},                {name:  "address2",  type:  "string"},                {name:  "address3",  type:  "string"},                {name:  "phone",  type:  "string"},                {name:  "state_code",  type:  "string"},                {name:  "mobile_url",  type:  "string"},                {name:  "rating_img_url_small",  type:  "string"},                {name:  "photo_url",  type:  "string"},        ]});

Page 25: City bars workshop

app.jsExt.regStore("businesses",  {        model:  'Business',        autoLoad:  true,        proxy:  {                type:  'scripttag',                url:  'http://api.yelp.com/business_review_search'  +                        '?ywsid='  +  YELP_KEY  +                        '&term='  +  escape(BUSINESS_TYPE)  +                        '&location='  +  escape(city)                ,                reader:  {                        type:  'json',                        root:  'businesses'                }        },

Page 26: City bars workshop

app.jslisteners:  {

       'afterrender':  function  ()  {

               cb.getCity(function  (city)  {

                       cb.getBusinesses(city,  function  (store)  {

                               console.log(store.data.items);

                       });                });

       }}

Page 27: City bars workshop

app.jsgetCity:  function  (callback)  {        callback(DEFAULT_CITY);},

getBusinesses:  function  (city,  callback)  {        Ext.regModel("Business",  {...});

       Ext.regStore("businesses",  {                ...                listeners:  {                        'load':  function  (store)  {                                callback(store);                        }                }        })}

Page 28: City bars workshop
Page 29: City bars workshop

4 Load the list

Page 30: City bars workshop

app.jsvar  cards  =  this;cards.listCard  =  cards.getComponent('listCard');cards.dataList  =  cards.listCard.getComponent('dataList');cards.detailCard  =  cards.getComponent('detailCard');

cb.getCity(function  (city)  {

       cards.listCard.getDockedItems()[0]                  .setTitle(city  +  '  '  +  BUSINESS_TYPE);

       cb.getBusinesses(city,  function  (store)  {

               cards.dataList.bindStore(store);                cards.setActiveItem(cards.listCard);

       });});

Page 31: City bars workshop

app.jscards.setLoading(true);

...

cards.setLoading(false);

Page 32: City bars workshop
Page 33: City bars workshop

5 Attach events

A more interesting list template

‘selection’ event to switch to detail

Page 34: City bars workshop

app.jsitemTpl:    '<img  class="photo"  src="{photo_url}"  width="40"  height="40"/>'  +    '{name}<br/>'  +    '<img  src="{rating_img_url_small}"/>&nbsp;'  +    '<small>{address1}</small>'

Page 35: City bars workshop

index.html<style>        .photo  {                float:left;                margin:0  8px  16px  0;                border:1px  solid  #ccc;                -­‐webkit-­‐box-­‐shadow:                        0  2px  4px  #777;        }</style>

Page 36: City bars workshop

app.jslisteners:  {

       selectionchange:  function  (selectionModel,  records)  {

               if  (records[0])  {                        cb.cards.setActiveItem(cb.cards.detailCard);                        cb.cards.detailCard.update(records[0].data);                }

       }

}

Page 37: City bars workshop

6 Detail page

Template for the detail card

Back button with tap to switch back to list

Page 38: City bars workshop

app.jsstyleHtmlContent:  true,cls:  'detail',tpl:  [        '<img  class="photo"  src="{photo_url}"            width="100"  height="100"/>',        '<h2>{name}</h2>',        '<div  class="info">',                '{address1}<br/>',                '<img  src="{rating_img_url_small}"/>',        '</div>',        '<div  class="phone  x-­‐button">',                '<a  href="tel:{phone}">{phone}</a>',        '</div>',        '<div  class="link  x-­‐button">',                '<a  href="{mobile_url}">Read  more</a>',        '</div>']

Page 39: City bars workshop

app.jsdockedItems:  [{        dock  :  'top',        xtype:  'toolbar',        title:  '',        items:  [{                text:  'Back',                ui:  'back',                listeners:  {                        tap:  function  ()  {                                cb.cards.setActiveItem(                                        cb.cards.listCard,                                        {type:'slide',  direction:  'right'}                                );                        }                }        }]}],

Page 40: City bars workshop

index.html.x-­‐html  h2  {        margin-­‐bottom:0;}.phone,  .link  {        clear:both;        font-­‐weight:bold;        display:block;        text-­‐align:center;        margin-­‐top:8px;}

Page 41: City bars workshop

7 Add mapping

Change detail page to tabbed

Add map control

Update data on both tabs

Page 42: City bars workshop

app.js{        id:  'detailCard',        xtype:  'tabpanel',        dockedItems:  [...]        items:  [                {                        title:  'Contact',                        tpl:  [...]                },                {                        title:  'Map',                        xtype:  'map',                        ...                        marker:                        new  google.maps.Marker()                }        ]}

Page 43: City bars workshop

index.html<script  src="http://maps.google.com/maps/api/js?sensor=true"                type="text/javascript"></script>

Page 44: City bars workshop

app.js{        xtype:  'map',        ...        update:  function  (data)  {

               this.map.setCenter(                        new  google.maps.LatLng(data.latitude,  data.longitude                ));                this.marker.setPosition(                        this.map.getCenter()                );

               this.marker.setMap(this.map);        },}

Page 45: City bars workshop

app.jstabBar:  {        dock:  'top',        ui:  'light',        layout:  {  pack:  'center'  }}

Page 46: City bars workshop
Page 47: City bars workshop

app.jsupdate:  function(data)  {

       Ext.each(this.items.items,  function(item)  {                item.update(data);        });

       this.getDockedItems()[0].setTitle(data.name);

}

Page 48: City bars workshop

8 Customize theme

Sass & Compass

Compile & link new theme

Page 49: City bars workshop

http://sass-lang.com/

Page 50: City bars workshop

/* SCSS */

$blue: #3bbfce;$margin: 16px;

.content-navigation { border-color: $blue; color: darken($blue, 9%);}

.border { padding: $margin / 2; margin: $margin / 2; border-color: $blue;}

/* CSS */

.content-navigation { border-color: #3bbfce; color: #2b9eab;}

.border { padding: 8px; margin: 8px; border-color: #3bbfce;}

Variables

Page 51: City bars workshop

$> sudo gem install compass

http://rubyinstaller.org/

Page 52: City bars workshop

$> compass -v

Compass 0.11.1 (Antares)Copyright (c) 2008-2011 Chris EppsteinReleased under the MIT License.

$> sass -v

Sass 3.1.1 (Brainy Betty)

Page 53: City bars workshop
Page 54: City bars workshop

citybars.scss$base-­‐color:  #666;$base-­‐gradient:  'glossy';$include-­‐default-­‐icons:  false;

@import  'sencha-­‐touch/default/all';

@include  sencha-­‐panel;@include  sencha-­‐buttons;@include  sencha-­‐tabs;@include  sencha-­‐toolbar;@include  sencha-­‐list;@include  sencha-­‐layout;@include  sencha-­‐loading-­‐spinner;

Page 55: City bars workshop

$>  compass  compile  citybars.scss

overwrite  citybars.css  

Page 56: City bars workshop

index.html<link    href="theming/citybars.css"    rel="stylesheet"  type="text/css"/>

Page 57: City bars workshop
Page 58: City bars workshop

James Pearce Director, Developer Relations @ jamespearce [email protected]