Bd conf sencha touch workshop

4,071 views

Published on

Published in: Technology, Design
1 Comment
10 Likes
Statistics
Notes
  • Schöne Folien am Anfang
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
4,071
On SlideShare
0
From Embeds
0
Number of Embeds
194
Actions
Shares
0
Downloads
180
Comments
1
Likes
10
Embeds 0
No embeds

No notes for slide

Bd conf sencha touch workshop

  1. 1. James Pearce Director, Developer Relations @ jamespearce jamesp@sencha.com
  2. 2. BuildingMobile Web Apps with HTML CSS JS
  3. 3. One PCMultiple devices
  4. 4. Sedentary usage Mobile usage
  5. 5. DocumentsApplications
  6. 6. Declarative HTMLProgrammatic JS
  7. 7. Thin clientThick client
  8. 8. HTML5 is a new version of HTML4, XHTML1,and DOM Level 2 HTML addressing many of the issues of those specifications while at the same time enhancing (X)HTMLto more adequately address Web applications.
  9. 9. A New Mobile App Stack WebFonts Video Audio GraphicsDevice Access Server & Services Camera CSS Styling & Layout HTTP Location AJAX JavaScript Contacts Events SMS Semantic HTML Sockets Orientation SSL File Systems Worker x-App Gyro DBs Parallel More... Messaging App Cache Processing
  10. 10. Rich Media & Styling E T IM UN Full ResourceRAccess N R Parallel MO DE Processing TEInter-App P LE Communication OM C O ine Capability Full A
  11. 11. WebKit FOEs
  12. 12. HTML5 Support IE 10 PR Chrome 10 Safari 5 Firefox 4 iOS4.31 Playbook Honeycomb@font-faceCanvasHTML5 Audio & Videorgba(), hsla()border-image:border-radius:box-shadow:text-shadow:opacity:Multiple backgroundsFlexible Box ModelCSS AnimationsCSS ColumnsCSS GradientsCSS ReflectionsCSS 2D TransformsCSS 3D TransformsCSS TransitionsGeolocation APIlocal/sessionStorageSVG/SVG ClippingSMILInline SVGDrag and DrophashchangeX-window MessagingHistory ManagementapplicationCacheWeb SocketsWeb WorkersWeb SQL DatabaseWebGLIndexedDB
  13. 13. Stay on top of diversityCan I Use?http://caniuse.comModernizrhttp://modernizr.comDeviceAtlashttp://deviceatlas.com
  14. 14. Pearce’s Universal Law of Mobile Web BrowsersDiversity (for all T) Capability
  15. 15. Pearce’s Universal Law of Mobile Web BrowsersSupport (for all T) Capability
  16. 16. JavaScript frameworks, polyfills & shimsSupport Capability
  17. 17. Evolving the web for mobile Views HTML, CSS... Controllers Models
  18. 18. Evolving the web for mobile Desktop Switcher HTML, CSS... Mobile Controllers Models
  19. 19. Evolving the web for mobile Desktop Switchers Mobile REST JSO on Controllers N ce Models
  20. 20. The classic web stack req/resUser interface RenderingBusiness logic Storage
  21. 21. An alternative web stack User interface syncSecurity Business logicStorage Storage
  22. 22. Write once,run anywhere?
  23. 23. The Mobile Web is not a 320px Web
  24. 24. Views Views Controllers Models Stores Proxies n jso
  25. 25. Thick client, thin serverThe shortfall in the cloud
  26. 26. Location Services Adaptation Analytics Web Fonts Data SyncVideo Serving Ad Serving Image Serving $ Commerce Network APIs
  27. 27. http://mysite.com/myimage.pnghttp://src.sencha.io/http://mysite.com/myimage.png
  28. 28. Sencha Touch A JavaScript framework for building rich mobile apps with web standardshttp://www.sencha.com/products/touch
  29. 29. Get Sencha Touch / sencha.c om/touchhttp:/
  30. 30. Components
  31. 31. Theming
  32. 32. Forms
  33. 33. Scrolling
  34. 34. Touch Events
  35. 35. Data access & MVC
  36. 36. Charts
  37. 37. Kitchen Sink ://sencha .com/x/5ehttp
  38. 38. Your First App<!DOCTYPE html><html> <head> <title>Hello World</title> <script src="sencha-touch.js" type="text/javascript"></script> <link href="sencha-touch.css" rel="stylesheet" type="text/css" /> <script type="text/javascript"> ... </script> </head> <body></body></html>
  39. 39. Your First Appnew Ext.Application({ launch: function() { new Ext.Panel({ fullscreen: true, dockedItems: [{xtype:toolbar, title:My First App}], layout: fit, styleHtmlContent: true, html: <h2>Hello World!</h2>I did it! }); }});
  40. 40. Listvar list = new Ext.List({ store: store, itemTpl: {firstName} {lastName}, grouped: true, indexBar: true});
  41. 41. Nested Listvar list = new Ext.NestedList({ store: store, displayField: name, title: My List, updateTitleText: true, getDetailCard: function(record, parent) {..}});
  42. 42. Carouselvar car = new Ext.Carousel({ direction: horizontal, indicator: true, items: [ .. ]});
  43. 43. Sheetsvar sheet = new Ext.ActionSheet({ items: [ { text: Delete draft, ui: decline }, { text: Save draft }, { text: Cancel, } ]});sheet.show();
  44. 44. Get Started! ://sencha .com/x/d5http
  45. 45. Pre-requisites for today 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/
  46. 46. The Nashville App ://sencha .com/x/dg http://sencha.com/x/bu http
  47. 47. http://github.com/jamesgpearce/nashville
  48. 48. Development sequence1 Structure the app 5 Detail page2 Layout the UI 6 Add a map3 Model the data 7 More data4 Load the list 8 Customize theme
  49. 49. 1 Structure the app
  50. 50. index.html<!doctype  html><html>        <head>                <title>Nashville  Guide</title>        </head> <body></body></html>
  51. 51. index.html<script  src="lib/touch/sencha-­‐touch.js"></script><script  src="app/yelp.js"></script><script  src="app/app.js"></script><link  href="lib/touch/resources/css/sencha-­‐touch.css"              rel="stylesheet"  type="text/css"  />
  52. 52. app.jsnv  =  new  Ext.Application({        launch:  function()  {                this.viewport  =  new  Ext.Panel({                        layout:  card,                        fullscreen:  true,                        html:  "Hello  world!"                        });        }});
  53. 53. 2 Layout the UI toolbar toolbar dataList listCard detailCard nv.viewport
  54. 54. The app...nv  =  new  Ext.Application({        launch:  function()  {                this.listCard  =  new  Ext.Panel({                        html:  I  am  the  list                });                this.detailCard  =  new  Ext.Panel({                        html:  I  am  the  detail                });                this.viewport  =  new  Ext.Panel({                        layout:  card,                        fullscreen:  true,                        cardSwitchAnimation:  slide,                        items:  [this.listCard,  this.detailCard]                });        }});
  55. 55. listCardthis.listCardToolbar  =  new  Ext.Toolbar({        dock:  top,        title:  Nashville  Guide});this.listCardDataList  =  new  Ext.List({        store:  null,        itemTpl:  });this.listCard  =  new  Ext.Panel({        dockedItems:  [this.listCardToolbar],        items:  [this.listCardDataList],        layout:  fit});
  56. 56. detailCardthis.detailCardToolbar  =  new  Ext.Toolbar({        dock:  top,        title:  ...});this.detailCard  =  new  Ext.Panel({        dockedItems:  [this.detailCardToolbar]});
  57. 57. 3 Model the datahttp://api.yelp.com/business_review_search?ywsid=YELP_KEY&term=Restaurants&location=Nashville,TN
  58. 58. Apigee console
  59. 59. "businesses":  [        {          "rating_img_url"  :  "http://media4.px.yelpcdn.com/...",          "country_code"  :  "US",          "id"  :  "BHpAlynD9dIGIaQDRqHCTA",          "is_closed"  :  false,          "city"  :  "Nashville",          "mobile_url"  :  "http://mobile.yelp.com/biz/...",          "review_count"  :  50,          "zip"  :  "11231",          "state"  :  "TN",          "latitude"  :  40.675758,          "address1"  :  "253  Conover  St",          "address2"  :  "",          "address3"  :  "",          "phone"  :  "7186258211",          "state_code"  :  "TN",          "categories":  [            ...",          ],          ...
  60. 60. A data namespacethis.data  =  {};
  61. 61. The ‘Business’ modelthis.data.Business  =  Ext.regModel(,  {        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"},        ]});
  62. 62. A store of those modelsthis.data.restaurants  =  new  Ext.data.Store({        model:  this.data.Business,        autoLoad:  true,        proxy:  {                type:  scripttag,                url:  http://api.yelp.com/business_review_search  +                        ?ywsid=  +  YELP_KEY  +                        &term=Restaurant  +                        &location=Nashville,TN,                reader:  {                        type:  json,                        root:  businesses                }        }});
  63. 63. 4 Load the listthis.listCardDataList  =  new  Ext.List({        store:  this.data.restaurants,        itemTpl:  {name}});
  64. 64. A more interesting templateitemTpl:        <img  class="photo"  src="{photo_url}"  width="40"  height="40"/>  +        {name}<br/>  +        <img  src="{rating_img_url_small}"/>&nbsp;  +        <small>{address1}</small>
  65. 65. Hack the style<style>        .photo  {                float:left;                margin:0  8px  16px  0;                border:1px  solid  #ccc;                -­‐webkit-­‐box-­‐shadow:                        0  2px  4px  #777;        }</style>
  66. 66. Get images resized... ...width="40"  height="40"  />
  67. 67. ...in the cloudsrc="http://src.sencha.io/40/{photo_url}"  width="40"  height="40"/>
  68. 68. 5 Detail pagethis.listCardDataList  =  new  Ext.List({        store:  this.data.restaurants,        itemTpl:  ...        listeners:  {                selectionchange:  function  (selectionModel,  records)  {                        if  (records[0])  {                                nv.viewport.setActiveItem(nv.detailCard);                                nv.detailCardToolbar.setTitle(                                        records[0].get(name)                                );                        }                }        }});
  69. 69. A back buttonthis.detailCardToolbar  =  new  Ext.Toolbar({        dock:  top,        title:  ...,        items:  [{                text:  Back,                ui:  back,                handler:  function  ()  {                        nv.viewport.setActiveItem(                                nv.listCard,                                {type:  slide,  direction:  right}                        );                }        }]});
  70. 70. Detail templatethis.detailCard  =  new  Ext.Panel({        dockedItems:  [this.detailCardToolbar],        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>        ]});
  71. 71. A little styling.x-­‐html  h2  {        margin-­‐bottom:0;}.phone,  .link  {        clear:both;        font-­‐weight:bold;        display:block;        text-­‐align:center;        margin-­‐top:8px;}
  72. 72. 6 Add a map toolbar toolbar dataList dataList detailCard listCard detailTabsnv.viewport
  73. 73. 6 Add a mapnv.viewport.setActiveItem(nv.detailTabs);...this.detailMap  =  new  Ext.Map({});this.detailTabs  =  new  Ext.TabPanel({        dockedItems:  [this.detailCardToolbar],        items:  [this.detailCard,  this.detailMap]});nv.viewport  =  new  Ext.Panel({        layout:  card,        fullscreen:  true,        cardSwitchAnimation:  slide,        items:  [this.listCard,  this.detailTabs]});
  74. 74. Tab titlesthis.detailCard  =  new  Ext.Panel({        ...        title:  Info});this.detailMap  =  new  Ext.Map({        title:  Map});
  75. 75. Google Maps script<script  type="text/javascript"    src="http://maps.google.com/maps/api/js?sensor=true"></script>
  76. 76. Update the map locationselectionchange:  function  (selectionModel,  records)  {        ...        var  map  =  nv.detailMap.map;        if  (!map.marker)  {                map.marker  =  new  google.maps.Marker();                map.marker.setMap(map);        }        map.setCenter(                new  google.maps.LatLng(                        records[0].get(latitude),                        records[0].get(longitude)                )        );        map.marker.setPosition(                map.getCenter()        );
  77. 77. Improve the tab barthis.detailTabs  =  new  Ext.TabPanel({        dockedItems:  [this.detailCardToolbar],        items:  [this.detailCard,  this.detailMap],        tabBar:  {                ui:  light,                layout:  {  pack:  center  }        }});
  78. 78. 7 More?
  79. 79. More data...[hotels,  bars,  restaurants].forEach(  function  (type)  {        nv.data[type]  =  new  Ext.data.Store({                model:  nv.data.Business,                autoLoad:  true,                proxy:  {                        type:  scripttag,                        url:  http://api.yelp.com/business_review_search  +                                ?ywsid=  +  YELP_KEY  +                                &term=  +  type  +                                &location=Nashville,TN,                        reader:  {                                type:  json,                                root:  businesses                        }                }        });});
  80. 80. Make list into a ‘class’this.ListCardDataList  =  Ext.extend(Ext.List,  {        store:  null,        itemTpl:                <img  class="photo"  ...
  81. 81. Instantiate that 3 timesthis.stayCardDataList  =  new  this.ListCardDataList({        store:  this.data.hotels});this.eatCardDataList  =  new  this.ListCardDataList({        store:  this.data.restaurants});this.drinkCardDataList  =  new  this.ListCardDataList({        store:  this.data.bars}); Consider lazy-loading...
  82. 82. Turn container into tabs toothis.listCard  =  new  Ext.TabPanel({        items:  [                this.stayCardDataList,                  this.eatCardDataList,                  this.drinkCardDataList        ],        tabBar:  {                ui:  light,                layout:  {  pack:  center  },                dock:  bottom        },        cardSwitchAnimation:  flip,...
  83. 83. And add titles & iconsthis.stayCardDataList  =  new  this.ListCardDataList({        store:  this.data.hotels,        title:  Stay,        iconCls:  home});this.eatCardDataList  =  new  this.ListCardDataList({        store:  this.data.restaurants,        title:  Eat,        iconCls:  locate});this.drinkCardDataList  =  new  this.ListCardDataList({        store:  this.data.bars,        title:  Drink,        iconCls:  star});
  84. 84. Pull-to-refreshthis.ListCardDataList  =  Ext.extend(Ext.List,  {        ...        plugins:  [{                ptype:  pullrefresh        }]});
  85. 85. 8 Customize theme
  86. 86. http://sass-lang.com/
  87. 87. Variables/* SCSS */ /* CSS */$blue: #3bbfce; .content-navigation {$margin: 16px; border-color: #3bbfce; color: #2b9eab;.content-navigation { } border-color: $blue; color: .border { darken($blue, 9%); padding: 8px;} margin: 8px; border-color: #3bbfce;.border { } padding: $margin / 2; margin: $margin / 2; border-color: $blue;}
  88. 88. $> sudo gem install compass http://rubyinstaller.org/
  89. 89. $> compass -vCompass 0.11.1 (Antares)Copyright (c) 2008-2011 Chris EppsteinReleased under the MIT License.$> sass -vSass 3.1.1 (Brainy Betty)
  90. 90. Start by copying sencha-touch.scss
  91. 91. config.rbdir  =  File.dirname(__FILE__)load  File.join(dir,  ..,  lib,  touch,  resources,  themes)#  Compass  configurationssass_path        =  dircss_path          =  direnvironment    =  :productionoutput_style  =  :compressed#  or  :nested,  :expanded,  :compact
  92. 92. Compile...$>  cd  theming$>  compass  compile  nashville.scss            create  nashville.css$>  compass  compile  nashville.scss            identical  nashville.css[edit  file]$>  compass  compile  nashville.scss            overwrite  nashville.css$>  compass  watch  nashville.scss            >>>  Change  detected  to:  nashville.scss            overwrite  nashville.css
  93. 93. Link...<link  href="theming/nashville.css"  rel="stylesheet"            type="text/css"  />
  94. 94. nashville.scss@import  sencha-­‐touch/default/all;@include  sencha-­‐panel;@include  sencha-­‐buttons;@include  sencha-­‐sheet;@include  sencha-­‐tabs;@include  sencha-­‐toolbar;@include  sencha-­‐list;@include  sencha-­‐list-­‐pullrefresh;@include  sencha-­‐layout;@include  sencha-­‐loading-­‐spinner;...
  95. 95. nashville.scss$base-­‐color:  #849;@import  sencha-­‐touch/default/all;@include  sencha-­‐panel;@include  sencha-­‐buttons;@include  sencha-­‐sheet;@include  sencha-­‐tabs;@include  sencha-­‐toolbar;@include  sencha-­‐list;@include  sencha-­‐list-­‐pullrefresh;@include  sencha-­‐layout;@include  sencha-­‐loading-­‐spinner;
  96. 96. Choose own icons$base-­‐color:  #849;$include-­‐default-­‐icons:  false;@import  sencha-­‐touch/default/all;@include  sencha-­‐panel;@include  sencha-­‐buttons;...@include  pictos-­‐iconmask(briefcase1);@include  pictos-­‐iconmask(heart);@include  pictos-­‐iconmask(music1);
  97. 97. Specify iconClsthis.stayCardDataList  =  new  this.ListCardDataList({        store:  this.data.hotels,        title:  Stay,        iconCls:  briefcase1});this.eatCardDataList  =  new  this.ListCardDataList({        store:  this.data.restaurants,        title:  Eat,        iconCls:  heart});this.drinkCardDataList  =  new  this.ListCardDataList({        store:  this.data.bars,        title:  Drink,        iconCls:  music1});
  98. 98. _variables.scss$include-html-style: true; $base-color: #354F6E;$include-default-icons: true; $base-gradient: matte;$include-form-sliders: true; $alert-color: red;$include-floating-panels: true; $confirm-color: #92cf00;$include-default-uis: true; $page-bg-color: #eee;$include-highlights: true; $global-row-height: 2.6em;$include-border-radius: true; $active-color: darken( saturate($base-color, 55%),$basic-slider: false; 10%);
  99. 99. http://dev.sencha.com/deploy/touch/docs/theme/
  100. 100. Sass is a superset of CSS$base-­‐color:  #849;$include-­‐default-­‐icons:  false;@import  sencha-­‐touch/default/all;...@include  pictos-­‐iconmask(briefcase1);@include  pictos-­‐iconmask(heart);@include  pictos-­‐iconmask(music1);.photo  {        float:left;        margin:0  8px  16px  0;        border:1px  solid  #ccc;        -­‐webkit-­‐box-­‐shadow:                0  2px  4px  #777;}...
  101. 101. WebFonts@import  url(http://fonts.googleapis.com/css?family=Smokum);.x-­‐toolbar-­‐title  {    font-­‐family:  Smokum;    font-­‐weight:  normal;    font-­‐size:  1.7em;    line-­‐height:  1.7em;    letter-­‐spacing:  0.05em;}
  102. 102. Done?
  103. 103. Development sequence1 Structure the app 5 Detail page2 Layout the UI 6 Add a map3 Model the data 7 More data4 Load the list 8 Customize theme
  104. 104. A ‘responsive’ app... /sencha.c om/x/cv http:/
  105. 105. And if we’d had time... Add to home screen - Icon - Splash screen Hybrid app; PhoneGap / NimbleKit - Contacts API - Geolocation - Packaging //sencha .com/x/cy http: ://sencha .com/x/de http
  106. 106. O ine app$>  phantomjs  confess.js  http://github/nashville/CACHE  MANIFEST#  This  manifest  was  created  by  confess.js#                    Time:  Wed  Sep  14  2011  10:14:45  GMT-­‐0700  (PDT)#        User-­‐agent:  Mozilla/5.0  ...CACHE:app/app.jsapp/yelp.jshttp://cdn.sencha.io/touch/1.1.0/sencha-­‐touch.jshttp://maps.google.com/maps/api/js?sensor=truehttp://maps.gstatic.com/intl/en_us/mapfiles/api-­‐3/6/4/main.jstheming/nashville.cssNETWORK: ce/c onfess* hub .com/ jamesgpear http://git
  107. 107. O ine dataTaking Yelp data o ineTaking images o ine- src.sencha.io to generate cross-origin B64Detecting network connection changes /sencha.c om/x/df http:/
  108. 108. Weinre .github.c om/weinre/ p http ://phonega
  109. 109. built withApps vs Web technology
  110. 110. James Pearce Director, Developer Relations @ jamespearce jamesp@sencha.com

×