SlideShare uma empresa Scribd logo
1 de 58
Baixar para ler offline
James Pearce
Director, Developer Relations
@jamespearce
jamesp@sencha.com
Build A
Mobile Web App
with
CSS
HTML JS
http://www.sencha.com/products/touch
Sencha Touch
A JavaScript framework for building
rich mobile apps with web standards
Pre-requisites
Sencha 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/
CityBars
http://sencha.com/x/bu
http://sencha.com/x/bv
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
1 Structure the app
index.html
<!doctype  html>
<html>
        <head>
                <title>City  Guide</title>
        </head>
<body></body>
</html>
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"  />
app.js
cb  =  new  Ext.Application({
        launch:  function()  {
                new	
  Ext.Panel({
                        layout        :  'card',
                        fullscreen:  true,
                        html:	
  "Hello	
  world!"
        
                });
        }
});
cb.cards
2 Layout the UI
listCard detailCard
toolbar toolbar
dataList
index.html
cb  =  new  Ext.Application({
        launch:  function()  {
                cb.cards  =  new  Ext.Panel({
                        layout        :  'card',
                        fullscreen:  true,
                        cardSwitchAnimation:	
  'slide',
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  items:	
  [
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {id:	
  'listCard'	
  ...},	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {id:	
  'detailCard'	
  ...}
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ]
        
                });
        }
});
listCard
{
        id:  'listCard',
	
  	
  	
  	
  layout:	
  'fit',
	
  	
  	
  	
  dockedItems:  [{
                dock  :  'top',
                xtype:	
  'toolbar',
                title:  'Please  wait'
        }],
        items:  [{
                id:  'dataList',
	
  	
  	
  	
  	
  	
  	
  	
  xtype:	
  'list',
                store:  null,
                itemTpl:  '{name}'
        }]
}
detailCard
{
        id:  'listCard',
        dockedItems:  [{
                dock  :  'top',
                xtype:  'toolbar',
                title:  ''
        }]
}
3 Model the data
http://api.yelp.com/business_review_search
?ywsid=YELP_KEY
&term=BUSINESS_TYPE
&location=CITY
Apigee console
"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":  [
            ...",
          ],
          ...
index.html
<script  type="text/javascript">
        YELP_KEY  =  'G3HueY_I5a8WZX-­‐_bFo3Mw';
        DEFAULT_CITY  =  'New  York';
        BUSINESS_TYPE  =  'Bars';
</script>
app.js
Ext.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"},
        ]
});
app.js
Ext.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'
                }
        },
app.js
listeners:  {
        'afterrender':  function  ()  {
                cb.getCity(function  (city)  {
                        cb.getBusinesses(city,  function  (store)  {
                                console.log(store.data.items);
                        });
                });
        }
}
app.js
getCity:  function  (callback)  {
        callback(DEFAULT_CITY);
},
getBusinesses:  function  (city,  callback)  {
        Ext.regModel("Business",  {...});
        Ext.regStore("businesses",  {
                ...
                listeners:  {
                        'load':  function  (store)  {
                                callback(store);
                        }
                }
        })
}
4 Load the list
app.js
var  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);
        });
});
app.js
cards.setLoading(true);
...
cards.setLoading(false);
5 Attach events
A more interesting list template
‘selection’ event to switch to detail
app.js
itemTpl:
    '<img  class="photo"  src="{photo_url}"  width="40"  height="40"/>'  +
    '{name}<br/>'  +
    '<img  src="{rating_img_url_small}"/>&nbsp;'  +
    '<small>{address1}</small>'
index.html
<style>
        .photo  {
                float:left;
                margin:0  8px  16px  0;
                border:1px  solid  #ccc;
                -­‐webkit-­‐box-­‐shadow:
                        0  2px  4px  #777;
        }
</style>
app.js
listeners:  {
        selectionchange:  function  (selectionModel,  records)  {
                if  (records[0])  {
                        cb.cards.setActiveItem(cb.cards.detailCard);
                        cb.cards.detailCard.update(records[0].data);
                }
        }
}
6 Detail page
Template for the detail card
Back button with tap to switch back to list
app.js
styleHtmlContent:  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>'
]
app.js
dockedItems:  [{
        dock  :  'top',
        xtype:  'toolbar',
        title:  '',
        items:  [{
                text:  'Back',
                ui:  'back',
                listeners:  {
                        tap:  function  ()  {
                                cb.cards.setActiveItem(
                                        cb.cards.listCard,
                                        {type:'slide',  direction:  'right'}
                                );
                        }
                }
        }]
}],
index.html
.x-­‐html  h2  {
        margin-­‐bottom:0;
}
.phone,  .link  {
        clear:both;
        font-­‐weight:bold;
        display:block;
        text-­‐align:center;
        margin-­‐top:8px;
}
7 Add mapping
Change detail page to tabbed
Add map control
Update data on both tabs
app.js
{
        id:  'detailCard',
        xtype:	
  'tabpanel',
        dockedItems:  [...]
        items:  [
                {
                        title:  'Contact',
                        tpl:  [...]
                },
                {
                        title:  'Map',
                        xtype:	
  'map',
                        ...
                        marker:
                        new  google.maps.Marker()
                }
        ]
}
index.html
<script  src="http://maps.google.com/maps/api/js?sensor=true"
                type="text/javascript">
</script>
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);
        },
}
app.js
tabBar:  {
        dock:  'top',
        ui:  'light',
        layout:  {  pack:  'center'  }
}
app.js
update:  function(data)  {
        Ext.each(this.items.items,  function(item)  {
                item.update(data);
        });
        this.getDockedItems()[0].setTitle(data.name);
}
8 Customize theme
Sass & Compass
Compile & link new theme
http://sass-lang.com/
/* 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
$> sudo gem install compass
http://rubyinstaller.org/
$> compass -v
Compass 0.11.1 (Antares)
Copyright (c) 2008-2011 Chris Eppstein
Released under the MIT License.
$> sass -v
Sass 3.1.1 (Brainy Betty)
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;
$>  compass  compile  citybars.scss
overwrite  citybars.css  
index.html
<link
    href="theming/citybars.css"
    rel="stylesheet"  type="text/css"
/>
James Pearce
Director, Developer Relations
@jamespearce
jamesp@sencha.com

Mais conteúdo relacionado

Mais procurados

Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...irwinvifxcfesre
 
Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012
Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012
Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012OPITZ CONSULTING Deutschland
 
JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...
JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...
JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...OPITZ CONSULTING Deutschland
 
Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...
Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...
Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...OPITZ CONSULTING Deutschland
 
JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012
JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012
JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012OPITZ CONSULTING Deutschland
 
10 Programación Web con .NET y C#
10 Programación Web con .NET y C#10 Programación Web con .NET y C#
10 Programación Web con .NET y C#guidotic
 
Javascript and jQuery for Mobile
Javascript and jQuery for MobileJavascript and jQuery for Mobile
Javascript and jQuery for MobileIvano Malavolta
 
Check out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro showCheck out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro showchicagonewsyesterday
 

Mais procurados (13)

Web components v1 intro
Web components v1 introWeb components v1 intro
Web components v1 intro
 
jQuery入門
jQuery入門jQuery入門
jQuery入門
 
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
 
Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012
Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012
Entwurfsmuster für mobile JavaScript-Web-Apps - WebTechConference 2012
 
JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...
JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...
JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 ...
 
Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...
Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...
Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 A...
 
JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012
JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012
JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012
 
10 Programación Web con .NET y C#
10 Programación Web con .NET y C#10 Programación Web con .NET y C#
10 Programación Web con .NET y C#
 
Javascript and jQuery for Mobile
Javascript and jQuery for MobileJavascript and jQuery for Mobile
Javascript and jQuery for Mobile
 
Check out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro showCheck out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro show
 
Asp .net Jquery
Asp .net JqueryAsp .net Jquery
Asp .net Jquery
 
Load2
Load2Load2
Load2
 
Get more votes!
Get more votes!Get more votes!
Get more votes!
 

Mais de James Pearce

Mobile Device APIs
Mobile Device APIsMobile Device APIs
Mobile Device APIsJames Pearce
 
The City Bars App with Sencha Touch 2
The City Bars App with Sencha Touch 2The City Bars App with Sencha Touch 2
The City Bars App with Sencha Touch 2James Pearce
 
An Intro to Mobile HTML5
An Intro to Mobile HTML5An Intro to Mobile HTML5
An Intro to Mobile HTML5James Pearce
 
A Snapshot of the Mobile HTML5 Revolution
A Snapshot of the Mobile HTML5 RevolutionA Snapshot of the Mobile HTML5 Revolution
A Snapshot of the Mobile HTML5 RevolutionJames Pearce
 
A mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutesA mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutesJames Pearce
 
HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1James Pearce
 
HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2James Pearce
 
Building a Mobile App with Sencha Touch
Building a Mobile App with Sencha TouchBuilding a Mobile App with Sencha Touch
Building a Mobile App with Sencha TouchJames Pearce
 
Create a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchCreate a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchJames Pearce
 
Cross platform mobile web apps
Cross platform mobile web appsCross platform mobile web apps
Cross platform mobile web appsJames Pearce
 
Bd conf sencha touch workshop
Bd conf sencha touch workshopBd conf sencha touch workshop
Bd conf sencha touch workshopJames Pearce
 
San Diego Hackathon
San Diego HackathonSan Diego Hackathon
San Diego HackathonJames Pearce
 
Building Cross Platform Mobile Web Apps
Building Cross Platform Mobile Web AppsBuilding Cross Platform Mobile Web Apps
Building Cross Platform Mobile Web AppsJames Pearce
 
Creating and Distributing Mobile Web Applications with PhoneGap
Creating and Distributing Mobile Web Applications with PhoneGapCreating and Distributing Mobile Web Applications with PhoneGap
Creating and Distributing Mobile Web Applications with PhoneGapJames Pearce
 
An Introduction to Sencha Touch
An Introduction to Sencha TouchAn Introduction to Sencha Touch
An Introduction to Sencha TouchJames Pearce
 
Source Dev Con Keynote
Source Dev Con KeynoteSource Dev Con Keynote
Source Dev Con KeynoteJames Pearce
 
Building Cloud-Based Cross-Platform Mobile Web Apps
Building Cloud-Based Cross-Platform Mobile Web AppsBuilding Cloud-Based Cross-Platform Mobile Web Apps
Building Cloud-Based Cross-Platform Mobile Web AppsJames Pearce
 
Building cross platform mobile web apps
Building cross platform mobile web appsBuilding cross platform mobile web apps
Building cross platform mobile web appsJames Pearce
 
Building tomorrow's web with today's tools
Building tomorrow's web with today's toolsBuilding tomorrow's web with today's tools
Building tomorrow's web with today's toolsJames Pearce
 

Mais de James Pearce (20)

Mobile Device APIs
Mobile Device APIsMobile Device APIs
Mobile Device APIs
 
The City Bars App with Sencha Touch 2
The City Bars App with Sencha Touch 2The City Bars App with Sencha Touch 2
The City Bars App with Sencha Touch 2
 
An Intro to Mobile HTML5
An Intro to Mobile HTML5An Intro to Mobile HTML5
An Intro to Mobile HTML5
 
A Snapshot of the Mobile HTML5 Revolution
A Snapshot of the Mobile HTML5 RevolutionA Snapshot of the Mobile HTML5 Revolution
A Snapshot of the Mobile HTML5 Revolution
 
A mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutesA mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutes
 
HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1
 
HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2
 
Building a Mobile App with Sencha Touch
Building a Mobile App with Sencha TouchBuilding a Mobile App with Sencha Touch
Building a Mobile App with Sencha Touch
 
Create a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchCreate a mobile web app with Sencha Touch
Create a mobile web app with Sencha Touch
 
Cross platform mobile web apps
Cross platform mobile web appsCross platform mobile web apps
Cross platform mobile web apps
 
Bd conf sencha touch workshop
Bd conf sencha touch workshopBd conf sencha touch workshop
Bd conf sencha touch workshop
 
San Diego Hackathon
San Diego HackathonSan Diego Hackathon
San Diego Hackathon
 
Building Cross Platform Mobile Web Apps
Building Cross Platform Mobile Web AppsBuilding Cross Platform Mobile Web Apps
Building Cross Platform Mobile Web Apps
 
Creating and Distributing Mobile Web Applications with PhoneGap
Creating and Distributing Mobile Web Applications with PhoneGapCreating and Distributing Mobile Web Applications with PhoneGap
Creating and Distributing Mobile Web Applications with PhoneGap
 
Theming and Sass
Theming and SassTheming and Sass
Theming and Sass
 
An Introduction to Sencha Touch
An Introduction to Sencha TouchAn Introduction to Sencha Touch
An Introduction to Sencha Touch
 
Source Dev Con Keynote
Source Dev Con KeynoteSource Dev Con Keynote
Source Dev Con Keynote
 
Building Cloud-Based Cross-Platform Mobile Web Apps
Building Cloud-Based Cross-Platform Mobile Web AppsBuilding Cloud-Based Cross-Platform Mobile Web Apps
Building Cloud-Based Cross-Platform Mobile Web Apps
 
Building cross platform mobile web apps
Building cross platform mobile web appsBuilding cross platform mobile web apps
Building cross platform mobile web apps
 
Building tomorrow's web with today's tools
Building tomorrow's web with today's toolsBuilding tomorrow's web with today's tools
Building tomorrow's web with today's tools
 

City bars workshop

  • 1. James Pearce Director, Developer Relations @jamespearce jamesp@sencha.com
  • 2. Build A Mobile Web App with CSS HTML JS
  • 3. http://www.sencha.com/products/touch Sencha Touch A JavaScript framework for building rich mobile apps with web standards
  • 4. Pre-requisites Sencha 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/
  • 6.
  • 8. 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
  • 9.
  • 11. index.html <!doctype  html> <html>        <head>                <title>City  Guide</title>        </head> <body></body> </html>
  • 12. 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"  />
  • 13. app.js cb  =  new  Ext.Application({        launch:  function()  {                new  Ext.Panel({                        layout        :  'card',                        fullscreen:  true,                        html:  "Hello  world!"                        });        } });
  • 14.
  • 15. cb.cards 2 Layout the UI listCard detailCard toolbar toolbar dataList
  • 16. index.html cb  =  new  Ext.Application({        launch:  function()  {                cb.cards  =  new  Ext.Panel({                        layout        :  'card',                        fullscreen:  true,                        cardSwitchAnimation:  'slide',                        items:  [                                {id:  'listCard'  ...},                                  {id:  'detailCard'  ...}                        ]                        });        } });
  • 17. listCard {        id:  'listCard',        layout:  'fit',        dockedItems:  [{                dock  :  'top',                xtype:  'toolbar',                title:  'Please  wait'        }],        items:  [{                id:  'dataList',                xtype:  'list',                store:  null,                itemTpl:  '{name}'        }] }
  • 18. detailCard {        id:  'listCard',        dockedItems:  [{                dock  :  'top',                xtype:  'toolbar',                title:  ''        }] }
  • 19.
  • 20. 3 Model the data http://api.yelp.com/business_review_search ?ywsid=YELP_KEY &term=BUSINESS_TYPE &location=CITY
  • 22. "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":  [            ...",          ],          ...
  • 23. index.html <script  type="text/javascript">        YELP_KEY  =  'G3HueY_I5a8WZX-­‐_bFo3Mw';        DEFAULT_CITY  =  'New  York';        BUSINESS_TYPE  =  'Bars'; </script>
  • 24. app.js Ext.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"},        ] });
  • 25. app.js Ext.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'                }        },
  • 26. app.js listeners:  {        'afterrender':  function  ()  {                cb.getCity(function  (city)  {                        cb.getBusinesses(city,  function  (store)  {                                console.log(store.data.items);                        });                });        } }
  • 27. app.js getCity:  function  (callback)  {        callback(DEFAULT_CITY); }, getBusinesses:  function  (city,  callback)  {        Ext.regModel("Business",  {...});        Ext.regStore("businesses",  {                ...                listeners:  {                        'load':  function  (store)  {                                callback(store);                        }                }        }) }
  • 28.
  • 29. 4 Load the list
  • 30. app.js var  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);        }); });
  • 32.
  • 33. 5 Attach events A more interesting list template ‘selection’ event to switch to detail
  • 34. app.js itemTpl:    '<img  class="photo"  src="{photo_url}"  width="40"  height="40"/>'  +    '{name}<br/>'  +    '<img  src="{rating_img_url_small}"/>&nbsp;'  +    '<small>{address1}</small>'
  • 35. index.html <style>        .photo  {                float:left;                margin:0  8px  16px  0;                border:1px  solid  #ccc;                -­‐webkit-­‐box-­‐shadow:                        0  2px  4px  #777;        } </style>
  • 36. app.js listeners:  {        selectionchange:  function  (selectionModel,  records)  {                if  (records[0])  {                        cb.cards.setActiveItem(cb.cards.detailCard);                        cb.cards.detailCard.update(records[0].data);                }        } }
  • 37. 6 Detail page Template for the detail card Back button with tap to switch back to list
  • 38. app.js styleHtmlContent:  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>' ]
  • 39. app.js dockedItems:  [{        dock  :  'top',        xtype:  'toolbar',        title:  '',        items:  [{                text:  'Back',                ui:  'back',                listeners:  {                        tap:  function  ()  {                                cb.cards.setActiveItem(                                        cb.cards.listCard,                                        {type:'slide',  direction:  'right'}                                );                        }                }        }] }],
  • 40. index.html .x-­‐html  h2  {        margin-­‐bottom:0; } .phone,  .link  {        clear:both;        font-­‐weight:bold;        display:block;        text-­‐align:center;        margin-­‐top:8px; }
  • 41. 7 Add mapping Change detail page to tabbed Add map control Update data on both tabs
  • 42. app.js {        id:  'detailCard',        xtype:  'tabpanel',        dockedItems:  [...]        items:  [                {                        title:  'Contact',                        tpl:  [...]                },                {                        title:  'Map',                        xtype:  'map',                        ...                        marker:                        new  google.maps.Marker()                }        ] }
  • 43. index.html <script  src="http://maps.google.com/maps/api/js?sensor=true"                type="text/javascript"> </script>
  • 44. 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);        }, }
  • 45. app.js tabBar:  {        dock:  'top',        ui:  'light',        layout:  {  pack:  'center'  } }
  • 46.
  • 47. app.js update:  function(data)  {        Ext.each(this.items.items,  function(item)  {                item.update(data);        });        this.getDockedItems()[0].setTitle(data.name); }
  • 48. 8 Customize theme Sass & Compass Compile & link new theme
  • 50. /* 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
  • 51. $> sudo gem install compass http://rubyinstaller.org/
  • 52. $> compass -v Compass 0.11.1 (Antares) Copyright (c) 2008-2011 Chris Eppstein Released under the MIT License. $> sass -v Sass 3.1.1 (Brainy Betty)
  • 53.
  • 54. 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;
  • 55. $>  compass  compile  citybars.scss overwrite  citybars.css  
  • 56. index.html <link    href="theming/citybars.css"    rel="stylesheet"  type="text/css" />
  • 57.
  • 58. James Pearce Director, Developer Relations @jamespearce jamesp@sencha.com