SlideShare ist ein Scribd-Unternehmen logo
1 von 85
Downloaden Sie, um offline zu lesen
The City Bars App
       with

Sencha Touch 2
Sencha Touch

 A JavaScript framework for building
rich mobile apps with web standards
http://sencha.com/x/d5
http://sencha.com/x/ed
Basically...

Get a WebKit-based desktop browser
  Get some emulators & real devices
Download the Sencha Touch 2 PR2 SDK
  Develop against a local web server

           Optional, but highly recommended!
http://sencha.com/touch
stylesheet




script framework
Introducing the
 City Bars App
http://sencha.com/x/ee

http://senchalearn.github.com/citybars2
Pre-requisites

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


        Install Sass and Compass:
  http://sass-lang.com/download.html
   http://compass-style.org/install/
http://github.com/
senchalearn/citybars2
Development sequence
1 App Architecture   5 List Event Handler

2 UI Structure       6 Detail Page

3 Data Modeling      7 Customize Theme

4 List Binding
Application Architecture

1_app_architecture
application
entry point



JS + CSS in SDK
index.html
<!doctype	
  html>
<html>
	
  	
  	
  	
  <head>
                                      yay! HTML5
	
  	
  	
  	
  	
  	
  	
  	
  <title>City	
  Guide</title>               JS + CSS*
	
  	
  	
  	
  	
  	
  	
  	
  <script	
  src="lib/touch2/sencha-­‐touch-­‐all-­‐debug.js"></script>
	
  	
  	
  	
  	
  	
  	
  	
  <link	
  href="lib/touch2/resources/css/sencha-­‐touch.css"
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  rel="stylesheet"	
  />

	
  	
  	
  	
  	
  	
  	
  	
  <script	
  src="app/app.js"></script>

	
  	
  	
  	
  </head>                                        our app
	
  	
  	
  	
  <body></body>
</html>
                                      don’t panic

                                                                               *or from CDN
app.js
 global namespace
                                             instantiates application
               var	
  CB;
               Ext.application({

            	
  	
  	
  	
  launch:	
  function()	
  {
                                                                          create main UI panel
            	
  	
  	
  	
  	
  	
  	
  	
  CB	
  =	
  this;
            	
  	
  	
  	
  	
  	
  	
  	
  CB.cards	
  =	
  Ext.create('Ext.Panel',	
  {
launch   event
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  fullscreen:	
  true,
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  html:	
  'Hello	
  world'
            	
  	
  	
  	
  	
  	
  	
  	
  });
            	
  	
  	
  	
  }
                                         config object
               });
UI Structure

2_ui_structure
toolbar        back      toolbar
dataList

           click

listCard              detailCard
           CB.cards
var	
  CB;
                     Ext.application({

            	
  	
  	
  	
  launch:	
  function()	
  {
variable ref	
  	
  	
  	
  	
  	
  	
  	
  CB	
  =	
  this;
            	
  	
  	
  	
  	
  	
  	
  	
  CB.cards	
  =	
  Ext.create('Ext.Panel',	
  {
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  fullscreen:	
  true,
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  layout:	
  'card',
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  items:	
  [{                         how children lay out
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  id:	
  'listCard',
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  html:	
  'List'
     UI children
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  },	
  {
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  id:	
  'detailCard',
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  html:	
  'Detail'         id-based ref
            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }]
            	
  	
  	
  	
  	
  	
  	
  	
  });
            	
  	
  	
  	
  }

                     });
<aside>
 about layouts
and components
Layouts
card             vbox




fit              hbox
Child component patterns I

     var	
  list	
  =	
  new	
  Ext.List({
     	
  	
  	
  	
  store:	
  store,
     	
  	
  	
  	
  ...
     });
                                        instantiate component
     var	
  panel	
  =	
  new	
  Ext.Panel({
     	
  	
  	
  	
  items:	
  [list,	
  ...],
     	
  	
  	
  	
  ...
     });

                             reference component by var
Child component patterns II
                                       preferable in ST2

      var	
  list	
  =	
  Ext.create('Ext.List',	
  {
      	
  	
  	
  	
  store:	
  store,
      	
  	
  	
  	
  ...
      });


      var	
  panel	
  =	
  Ext.create('Ext.Panel',	
  {
      	
  	
  	
  	
  items:	
  [list,	
  ...]
      	
  	
  	
  	
  ...
      });
Child component patterns III

      var	
  panel	
  =	
  Ext.create('Ext.Panel',	
  {
      	
  	
  	
  	
  items:	
  [
      	
  	
  	
  	
  	
  	
  	
  	
  {
      	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  xtype:	
  'list',
      	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  store:	
  store,
      	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ...
      	
  	
  	
  	
  	
  	
  	
  	
  },	
  ...                         deferred   creation*
      	
  	
  	
  	
  ],
      	
  	
  	
  	
  ...
      });




                                                         * a lightweight object until then
</aside>
The list card
     {
     	
  	
  	
  	
  //	
  the	
  list	
  card
     	
  	
  	
  	
  id:	
  'listCard',                           list should fill whole card
     	
  	
  	
  	
  layout:	
  'fit',
     	
  	
  	
  	
  items:	
  [{
     	
  	
  	
  	
  	
  	
  	
  	
  //	
  main	
  top	
  toolbar
                                                                             docked top toolbar
     	
  	
  	
  	
  	
  	
  	
  	
  xtype:	
  'toolbar',
     	
  	
  	
  	
  	
  	
  	
  	
  docked:	
  'top',
     	
  	
  	
  	
  	
  	
  	
  	
  title:	
  'Please	
  wait'
     	
  	
  	
  	
  	
  	
  	
  	
  //	
  will	
  get	
  added	
  once	
  city	
  known
     	
  	
  	
  	
  },	
  {
     	
  	
  	
  	
  	
  	
  	
  	
  //	
  the	
  list	
  itself
list*	
  	
  	
  	
  	
  	
  	
  	
  //	
  gets	
  bound	
  to	
  the	
  store	
  once	
  city	
  known
     	
  	
  	
  	
  	
  	
  	
  	
  id:	
  'dataList',
     	
  	
  	
  	
  	
  	
  	
  	
  xtype:	
  'list'
     	
  	
  	
  	
  }]
     }
                                                                          * list will be bound to a store later
The detail card
    {
    	
  	
  	
  	
  //	
  the	
  details	
  card
    	
  	
  	
  	
  id:	
  'detailCard',
    	
  	
  	
  	
  items:	
  [{
    	
  	
  	
  	
  	
  	
  	
  	
  //	
  detail	
  page	
  also	
  has	
  a	
  toolbar
    	
  	
  	
  	
  	
  	
  	
  	
  docked	
  :	
  'top',
    	
  	
  	
  	
  	
  	
  	
  	
  xtype:	
  'toolbar',
    	
  	
  	
  	
  	
  	
  	
  	
  title:	
  ''                          another docked   toolbar*
    	
  	
  	
  	
  },	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  //	
  textual	
  detail
    	
  	
  	
  	
  }]
    }

detail page to come later...

                                                            * title will be dynamically set
note:
list already
   scrollable
Data modeling

3_data_modeling
The YELP API...

   http://api.yelp.com/business_review_search

   ?ywsid=YELP_KEY

   &term=BUSINESS_TYPE    free, rate limited
   &location=CITY



business type, and city name
...returns a nested JSON array




            mmm, json
Apigee API console


                     ‘businesses’
                      array
"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":	
  [...],                    some fields are
	
  	
  	
  	
  ...
	
  	
  },	
  ...
                                                           useful for our app
]
Create a data model
                                   give the ‘class’ a name
Ext.define("Business",	
  {
	
  	
  	
  	
  extend:	
  "Ext.data.Model",
	
  	
  	
  	
  fields:	
  [
                                                                      extending base model
	
  	
  	
  	
  	
  	
  	
  	
  {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"},
	
  	
  	
  	
  ]
});
                      and with these named, typed fields
<aside>
      Models can be associated
         with other models


 Fields can also have default values,
 conversion functions, and validation


                          </aside>
Create a model store
create the store
         var	
  store	
  =	
  Ext.create('Ext.data.Store',	
  {
         	
  	
  	
  	
  model:	
  "Business",
         	
  	
  	
  	
  ...
         });

                                             containing this
                                             type of model




Think of a store as a ‘table’ of model instance ‘rows’
Configure data source
                                                                    loads as soon as possible
     var	
  store	
  =	
  Ext.create('Ext.data.Store',	
  {
     	
  	
  	
  	
  model:	
  'Business',
     	
  	
  	
  	
  autoLoad:	
  true,
     	
  	
  	
  	
  proxy:	
  {                                                                     JSONP
     	
  	
  	
  	
  	
  	
  	
  	
  //	
  call	
  Yelp	
  to	
  get	
  business	
  data
     	
  	
  	
  	
  	
  	
  	
  	
  type:	
  'scripttag',
source
     	
  	
  	
  	
  	
  	
  	
  	
  url:	
  'http://api.yelp.com/business_review_search'	
  +
     	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '?ywsid='	
  +	
  YELP_KEY	
  +
     	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '&term='	
  +	
  escape(BUSINESS_TYPE)	
  +
     	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '&location='	
  +	
  escape(DEFAULT_CITY)
     	
  	
  	
  	
  	
  	
  	
  	
  ,
     	
  	
  	
  	
  	
  	
  	
  	
  reader:	
  {
     	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  type:	
  'json',
     	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  root:	
  'businesses'               construct API URL
     	
  	
  	
  	
  	
  	
  	
  	
  }
     	
  	
  	
  	
  }
     });
                                          read array from inside JSON
Create constants
                                              please change this!
<script>
	
  	
  	
  	
  YELP_KEY	
  =	
  'G3HueY_I5a8WZX-­‐_bAAAA';
	
  	
  	
  	
  DEFAULT_CITY	
  =	
  'San	
  Francisco';
	
  	
  	
  	
  BUSINESS_TYPE	
  =	
  'Bars';
</script>
We can make the proxy URL dynamic,
   which would allow geolocation.


     But this requires an async
         callback sequence.
Two-phase async sequence
                  getCity:	
  function	
  (callback)	
  {
                  	
  	
  	
  	
  callback(DEFAULT_CITY);
call when         	
  	
  	
  	
  //	
  this	
  could	
  now	
  be	
  a	
  geo	
  lookup	
  to
                  	
  	
  	
  	
  //	
  get	
  the	
  nearest	
  city
 UI ready         },                                                                use this     in the URL
                  getBusinesses:	
  function	
  (city,	
  callback)	
  {

                 	
  	
  	
  	
  Ext.define("Business",	
  {
                 	
  	
  	
  	
  	
  	
  	
  	
  ...
                 	
  	
  	
  	
  });
   the data code
                 	
  	
  	
  	
  
   we just wrote
                 	
  	
  	
  	
  var	
  store	
  =	
  Ext.create('Ext.data.Store',	
  {
                 	
  	
  	
  	
  	
  	
  	
  	
  ...
                 	
  	
  	
  	
  });

                  }                       and this will need to fire the callback
                                          with store when it autoloads
event
          var	
  store	
  =	
  Ext.create('Ext.data.Store',	
  {                                       listeners
          	
  	
  	
  	
  ...
          	
  	
  	
  	
  listeners:	
  {
          	
  	
  	
  	
  	
  	
  	
  	
  //	
  when	
  the	
  records	
  load,	
  fire	
  the	
  callback
          	
  	
  	
  	
  	
  	
  	
  	
  load:	
  function	
  (store)	
  {
          	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  callback(store);
when   loaded
          	
  	
  	
  	
  	
  	
  	
  	
  }
          	
  	
  	
  	
  }
          });
                                                                   fire the callback with store
cheeky callback

store



records
List Binding

4_list_binding
our 2 async functions
//	
  get	
  the	
  city
CB.getCity(function	
  (city)	
  {

	
  	
  	
  	
  //	
  then	
  use	
  Yelp	
  to	
  get	
  the	
  businesses
	
  	
  	
  	
  CB.getBusinesses(city,	
  function	
  (store)	
  {

	
  	
  	
  	
  	
  	
  	
  	
  //	
  then	
  bind	
  data	
  to	
  list	
  and	
  show	
  it
	
  	
  	
  	
  	
  	
  	
  	
  CB.cards.query('#dataList')[0].setStore(store);

	
  	
  	
  	
  });
});
                      get dataList                       bind the store to it
                          by its id
:-(




but we haz
  records!
another component query
CB.getCity(function	
  (city)	
  {

	
  	
  	
  	
  cards.query('#listCard	
  toolbar')[0]
	
  	
  	
  	
  	
  	
  	
  	
  .setTitle(city	
  +	
  '	
  '	
  +	
  BUSINESS_TYPE);

	
  	
  	
  	
  ...

                               now title will always match city
List items are templated

 {
 	
  	
  	
  	
  id:	
  'dataList',
 	
  	
  	
  	
  xtype:	
  'list',
 	
  	
  	
  	
  store:	
  null,
 	
  	
  	
  	
  itemTpl:	
  '{name}'
 }



   model fields in curly braces
Spinner bound to store
instantiate mask                               over body

        Ext.create('Ext.LoadMask',	
  Ext.getBody(),	
  {
        	
  	
  	
  	
  store:	
  store,
        	
  	
  	
  	
  msg:	
  ''
        });
                                will show when store is loading
A more interesting template
itemTpl:
	
  	
  	
  	
  '<img	
  class="photo"	
  src="{photo_url}"	
  width="40"	
  height="40"/>'	
  +
	
  	
  	
  	
  '{name}<br/>'	
  +
	
  	
  	
  	
  '<img	
  src="{rating_img_url_small}"/>&nbsp;'	
  +
	
  	
  	
  	
  '<small>{address1}</small>'




             HTML allowed
Hack the style
<style>
	
  	
  	
  	
  .photo	
  {
	
  	
  	
  	
  	
  	
  	
  	
  float:left;
	
  	
  	
  	
  	
  	
  	
  	
  margin:0	
  8px	
  16px	
  0;
	
  	
  	
  	
  	
  	
  	
  	
  border:1px	
  solid	
  #ccc;
	
  	
  	
  	
  	
  	
  	
  	
  -­‐webkit-­‐box-­‐shadow:	
  0	
  2px	
  4px	
  #777;
	
  	
  	
  	
  }
</style>
...width="40"	
  height="40"	
  />




                                     seems like
                                     a waste
src.sencha.io
<img	
  src="http://src.sencha.io/40/{photo_url}"
	
  	
  	
  	
  	
  width="40"	
  height="40"
/>




                                           4 times
                                           smaller
List Event Handler

5_list_event_handler
{                                                                 when list items
                                                                                                                       selection
       	
  	
  	
  	
  id:	
  'dataList',
       	
  	
  	
  	
  ...
                                                                         are selected
       	
  	
  	
  	
  listeners:	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  selectionchange:	
  function	
  (selectionModel,	
  records)	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  if	
  selection	
  made,	
  slide	
  to	
  detail	
  card
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (records[0])	
  {

       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  CB.cards.setActiveItem(1);
also fires on                                                                                        detail card
 deselection
    	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  CB.cards.getActiveItem().setData(
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  records[0].data
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  );
                                                                                                         ...to detail
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
       	
  	
  	
  	
  	
  	
  	
  	
  }                           apply record data...                  page template
       	
  	
  	
  	
  }
       }
A back button
       items:	
  [{                                                                            children of toolbars
       	
  	
  	
  	
  //	
  detail	
  page	
  also	
  has	
  a	
  toolbar                     are implicitly
       	
  	
  	
  	
  docked	
  :	
  'top',
       	
  	
  	
  	
  xtype:	
  'toolbar',                                                    xtype: ‘button’
       	
  	
  	
  	
  title:	
  '',
       	
  	
  	
  	
  items:	
  [{
       	
  	
  	
  	
  	
  	
  	
  	
  //	
  containing	
  a	
  back	
  button
arrow style
       	
  	
  	
  	
  	
  	
  	
  	
  //	
  that	
  slides	
  back	
  to	
  list	
  card
       	
  	
  	
  	
  	
  	
  	
  	
  text:	
  'Back',
       	
  	
  	
  	
  	
  	
  	
  	
  ui:	
  'back',                                                back to list
       	
  	
  	
  	
  	
  	
  	
  	
  listeners:	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  tap:	
  function	
  ()	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  CB.cards.setActiveItem(0);
 when tapped
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
       	
  	
  	
  	
  	
  	
  	
  	
  }
       	
  	
  	
  	
  }],	
  ...
Detail Page

6_detail_page
style this card as
                                                                 regular HTML
         {
         	
  	
  	
  	
  //	
  textual	
  detail
         	
  	
  	
  	
  styleHtmlContent:	
  true,
         	
  	
  	
  	
  cls:	
  'detail',                                            CSS class for      styling
         	
  	
  	
  	
  tpl:	
  [
         	
  	
  	
  	
  	
  	
  	
  	
  '<img	
  class="photo"	
  src="{photo_url}"	
  />',
         	
  	
  	
  	
  	
  	
  	
  	
  '<h2>{name}</h2>',
 template for
         	
  	
  	
  	
  	
  	
  	
  	
  '<div	
  class="info">',
         	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '{address1}<br/>',
a whole panel
         	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '<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>'
         	
  	
  	
  	
  ]
         }]
:-(
Remember this?
setData does not cascade into child items!


      CB.cards.getActiveItem().setData(
      	
  	
  	
  	
  records[0].data
      );
Override setData
                                        set title on toolbar

setData:	
  function	
  (data)	
  {
	
  	
  	
  	
  this.query('toolbar')[0].setTitle(data.name);
	
  	
  	
  	
  this.query('[cls="detail"]')[0].setData(data);
},



        apply data to template on inner panel
good




not so much
A little styling
            .x-­‐html	
  h2	
  {
            	
  	
  	
  	
  margin-­‐bottom:0;
            }
            .phone,	
  .link	
  {
            	
  	
  	
  	
  clear:both;                        formatting
            	
  	
  	
  	
  font-­‐weight:bold;                the buttons
            	
  	
  	
  	
  display:block;
            	
  	
  	
  	
  text-­‐align:center;
            	
  	
  	
  	
  margin-­‐top:8px;
            }
temporary   .detail	
  {
fixes       	
  	
  	
  	
  -­‐webkit-­‐box-­‐orient:	
  vertical;
            }
            .detail	
  .photo	
  {
            	
  	
  	
  	
  float:none;
            }
One final tweak
move from        {
inner panel...   	
  	
  	
  	
  //	
  textual	
  detail
                 	
  	
  	
  	
  cls:	
  'detail',
                 	
  	
  	
  	
  styleHtmlContent:	
  true,
                 	
  	
  	
  	
  ...




                 {
                 	
  	
  	
  	
  //	
  the	
  details	
  card   ...to outer card
                 	
  	
  	
  	
  id:	
  'detailCard',
                 	
  	
  	
  	
  styleHtmlContent:	
  true,
complete with
<h2> </h2>
Development sequence
1 App Architecture   5 List Event Handler

2 UI Structure       6 Detail Page

3 Data Modeling      7 Customize Theme

4 List Binding
Other ideas...
‘Responsive’ Apps




http://sencha.com/x/cv
Packaging

Add to home screen
- Icon
- Splash screen

Hybrid app; PhoneGap / NimbleKit
- Contacts API
- Geolocation

http://sencha.com/x/cy
http://sencha.com/x/de
Geolocation
O ine app




http://github.com/jamesgpearce/confess
O ine data
Taking Yelp data o ine

Taking images o ine
- src.sencha.io to generate cross-origin B64

Detecting network connection changes




 http://sencha.com/x/df
Debugging




http://phonegap.github.com/weinre
James Pearce
@ jamespearce

Weitere ähnliche Inhalte

Was ist angesagt?

Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoMohamed Mosaad
 
Connecting Custom Post Types
Connecting Custom Post TypesConnecting Custom Post Types
Connecting Custom Post TypesJoe Casabona
 
Drupal 9 training ajax
Drupal 9 training ajaxDrupal 9 training ajax
Drupal 9 training ajaxNeelAndrew
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryCleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryRebecca Murphey
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money Newseminentoomph4388
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalFredric Mitchell
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money Newsacousticassista07
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Formsdrubb
 
PythonでJWT生成からボット作成、投稿までやってみた
PythonでJWT生成からボット作成、投稿までやってみたPythonでJWT生成からボット作成、投稿までやってみた
PythonでJWT生成からボット作成、投稿までやってみたitoxdev
 
Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1Acquia
 
Drupal 8 Sample Module
Drupal 8 Sample ModuleDrupal 8 Sample Module
Drupal 8 Sample Moduledrubb
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
Layout discovery. Drupal Summer Barcelona 2017
Layout discovery. Drupal Summer Barcelona 2017Layout discovery. Drupal Summer Barcelona 2017
Layout discovery. Drupal Summer Barcelona 2017Atenea tech
 
Javascript foundations: variables and types
Javascript foundations: variables and typesJavascript foundations: variables and types
Javascript foundations: variables and typesJohn Hunter
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money Newsnichevidswilson85
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form componentSamuel ROZE
 
WooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda BagusWooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda BagusWordCamp Indonesia
 

Was ist angesagt? (20)

Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
 
Connecting Custom Post Types
Connecting Custom Post TypesConnecting Custom Post Types
Connecting Custom Post Types
 
Drupal 9 training ajax
Drupal 9 training ajaxDrupal 9 training ajax
Drupal 9 training ajax
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryCleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQuery
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money News
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in Drupal
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money News
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Forms
 
PythonでJWT生成からボット作成、投稿までやってみた
PythonでJWT生成からボット作成、投稿までやってみたPythonでJWT生成からボット作成、投稿までやってみた
PythonでJWT生成からボット作成、投稿までやってみた
 
Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1
 
Drupal 8 Sample Module
Drupal 8 Sample ModuleDrupal 8 Sample Module
Drupal 8 Sample Module
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 
Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
 
Layout discovery. Drupal Summer Barcelona 2017
Layout discovery. Drupal Summer Barcelona 2017Layout discovery. Drupal Summer Barcelona 2017
Layout discovery. Drupal Summer Barcelona 2017
 
Javascript foundations: variables and types
Javascript foundations: variables and typesJavascript foundations: variables and types
Javascript foundations: variables and types
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money News
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
WooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda BagusWooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda Bagus
 

Ähnlich wie The City Bars App with Sencha Touch 2

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
 
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
 
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
 
RIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JSRIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JSDominik Jungowski
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your CodeDrupalDay
 
Rails GUI Development with Ext JS
Rails GUI Development with Ext JSRails GUI Development with Ext JS
Rails GUI Development with Ext JSMartin Rehfeld
 
Sencha Touch meets TYPO3
Sencha Touch meets TYPO3Sencha Touch meets TYPO3
Sencha Touch meets TYPO3Nils Dehl
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensionserwanl
 
JavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptJavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptLaurence Svekis ✔
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant TrainingAidIQ
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than WebHeiko Behrens
 
Aprimorando sua Aplicação com Ext JS 4 - BrazilJS
Aprimorando sua Aplicação com Ext JS 4 - BrazilJSAprimorando sua Aplicação com Ext JS 4 - BrazilJS
Aprimorando sua Aplicação com Ext JS 4 - BrazilJSLoiane Groner
 
Nick: A Nearly Headless CMS
Nick: A Nearly Headless CMSNick: A Nearly Headless CMS
Nick: A Nearly Headless CMSRob Gietema
 
maincpp Build and procees a sorted linked list of Patie.pdf
maincpp   Build and procees a sorted linked list of Patie.pdfmaincpp   Build and procees a sorted linked list of Patie.pdf
maincpp Build and procees a sorted linked list of Patie.pdfadityastores21
 
Enterprise workflow with Apps Script
Enterprise workflow with Apps ScriptEnterprise workflow with Apps Script
Enterprise workflow with Apps Scriptccherubino
 
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"South Tyrol Free Software Conference
 
Already given code from 4 files- 1-app-ctrl-js code- -- include expres.pdf
Already given code from 4 files- 1-app-ctrl-js code- -- include expres.pdfAlready given code from 4 files- 1-app-ctrl-js code- -- include expres.pdf
Already given code from 4 files- 1-app-ctrl-js code- -- include expres.pdfas1mobiles
 

Ähnlich wie The City Bars App with Sencha Touch 2 (20)

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
 
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
 
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
 
RIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JSRIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JS
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Rails GUI Development with Ext JS
Rails GUI Development with Ext JSRails GUI Development with Ext JS
Rails GUI Development with Ext JS
 
Sencha Touch meets TYPO3
Sencha Touch meets TYPO3Sencha Touch meets TYPO3
Sencha Touch meets TYPO3
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
JavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptJavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScript
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
 
Aprimorando sua Aplicação com Ext JS 4 - BrazilJS
Aprimorando sua Aplicação com Ext JS 4 - BrazilJSAprimorando sua Aplicação com Ext JS 4 - BrazilJS
Aprimorando sua Aplicação com Ext JS 4 - BrazilJS
 
Nick: A Nearly Headless CMS
Nick: A Nearly Headless CMSNick: A Nearly Headless CMS
Nick: A Nearly Headless CMS
 
Intro to sencha touch
Intro to sencha touchIntro to sencha touch
Intro to sencha touch
 
JQuery Flot
JQuery FlotJQuery Flot
JQuery Flot
 
Intro to Ember.JS 2016
Intro to Ember.JS 2016Intro to Ember.JS 2016
Intro to Ember.JS 2016
 
maincpp Build and procees a sorted linked list of Patie.pdf
maincpp   Build and procees a sorted linked list of Patie.pdfmaincpp   Build and procees a sorted linked list of Patie.pdf
maincpp Build and procees a sorted linked list of Patie.pdf
 
Enterprise workflow with Apps Script
Enterprise workflow with Apps ScriptEnterprise workflow with Apps Script
Enterprise workflow with Apps Script
 
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
 
Already given code from 4 files- 1-app-ctrl-js code- -- include expres.pdf
Already given code from 4 files- 1-app-ctrl-js code- -- include expres.pdfAlready given code from 4 files- 1-app-ctrl-js code- -- include expres.pdf
Already given code from 4 files- 1-app-ctrl-js code- -- include expres.pdf
 

Mehr von James Pearce

Mobile Device APIs
Mobile Device APIsMobile Device APIs
Mobile Device APIsJames 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
 
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
 
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
 
City bars workshop
City bars workshopCity bars workshop
City bars 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
 
HTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applicationsHTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applicationsJames Pearce
 
Sencha Touch for Rubyists
Sencha Touch for RubyistsSencha Touch for Rubyists
Sencha Touch for RubyistsJames Pearce
 
Serving Mobile Apps from Content Management Systems
Serving Mobile Apps from Content Management SystemsServing Mobile Apps from Content Management Systems
Serving Mobile Apps from Content Management SystemsJames Pearce
 

Mehr von James Pearce (20)

Mobile Device APIs
Mobile Device APIsMobile Device APIs
Mobile Device APIs
 
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
 
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
 
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
 
City bars workshop
City bars workshopCity bars workshop
City bars 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
 
HTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applicationsHTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applications
 
Sencha Touch for Rubyists
Sencha Touch for RubyistsSencha Touch for Rubyists
Sencha Touch for Rubyists
 
Serving Mobile Apps from Content Management Systems
Serving Mobile Apps from Content Management SystemsServing Mobile Apps from Content Management Systems
Serving Mobile Apps from Content Management Systems
 

Kürzlich hochgeladen

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 

Kürzlich hochgeladen (20)

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 

The City Bars App with Sencha Touch 2

  • 1. The City Bars App with Sencha Touch 2
  • 2. Sencha Touch A JavaScript framework for building rich mobile apps with web standards
  • 4. Basically... Get a WebKit-based desktop browser Get some emulators & real devices Download the Sencha Touch 2 PR2 SDK Develop against a local web server Optional, but highly recommended!
  • 5.
  • 6.
  • 10.
  • 11.
  • 13. Pre-requisites  Yelp developer API key:   http://www.yelp.com/developers/  Install Sass and Compass:   http://sass-lang.com/download.html http://compass-style.org/install/
  • 15. Development sequence 1 App Architecture 5 List Event Handler 2 UI Structure 6 Detail Page 3 Data Modeling 7 Customize Theme 4 List Binding
  • 16.
  • 19. index.html <!doctype  html> <html>        <head> yay! HTML5                <title>City  Guide</title> JS + CSS*                <script  src="lib/touch2/sencha-­‐touch-­‐all-­‐debug.js"></script>                <link  href="lib/touch2/resources/css/sencha-­‐touch.css"                              rel="stylesheet"  />                <script  src="app/app.js"></script>        </head> our app        <body></body> </html> don’t panic *or from CDN
  • 20. app.js global namespace instantiates application var  CB; Ext.application({        launch:  function()  { create main UI panel                CB  =  this;                CB.cards  =  Ext.create('Ext.Panel',  { launch event                        fullscreen:  true,                        html:  'Hello  world'                });        } config object });
  • 21.
  • 22.
  • 24. toolbar back toolbar dataList click listCard detailCard CB.cards
  • 25. var  CB; Ext.application({        launch:  function()  { variable ref                CB  =  this;                CB.cards  =  Ext.create('Ext.Panel',  {                        fullscreen:  true,                        layout:  'card',                        items:  [{ how children lay out                                id:  'listCard',                                html:  'List' UI children                        },  {                                id:  'detailCard',                                html:  'Detail' id-based ref                        }]                });        } });
  • 26.
  • 28. Layouts card vbox fit hbox
  • 29. Child component patterns I var  list  =  new  Ext.List({        store:  store,        ... }); instantiate component var  panel  =  new  Ext.Panel({        items:  [list,  ...],        ... }); reference component by var
  • 30. Child component patterns II preferable in ST2 var  list  =  Ext.create('Ext.List',  {        store:  store,        ... }); var  panel  =  Ext.create('Ext.Panel',  {        items:  [list,  ...]        ... });
  • 31. Child component patterns III var  panel  =  Ext.create('Ext.Panel',  {        items:  [                {                        xtype:  'list',                        store:  store,                        ...                },  ... deferred creation*        ],        ... }); * a lightweight object until then
  • 33. The list card {        //  the  list  card        id:  'listCard', list should fill whole card        layout:  'fit',        items:  [{                //  main  top  toolbar docked top toolbar                xtype:  'toolbar',                docked:  'top',                title:  'Please  wait'                //  will  get  added  once  city  known        },  {                //  the  list  itself list*                //  gets  bound  to  the  store  once  city  known                id:  'dataList',                xtype:  'list'        }] } * list will be bound to a store later
  • 34. The detail card {        //  the  details  card        id:  'detailCard',        items:  [{                //  detail  page  also  has  a  toolbar                docked  :  'top',                xtype:  'toolbar',                title:  '' another docked toolbar*        },  {                //  textual  detail        }] } detail page to come later... * title will be dynamically set
  • 35. note: list already scrollable
  • 37. The YELP API... http://api.yelp.com/business_review_search ?ywsid=YELP_KEY &term=BUSINESS_TYPE free, rate limited &location=CITY business type, and city name
  • 38. ...returns a nested JSON array mmm, json
  • 39. Apigee API console ‘businesses’ array
  • 40. "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":  [...], some fields are        ...    },  ... useful for our app ]
  • 41. Create a data model give the ‘class’ a name Ext.define("Business",  {        extend:  "Ext.data.Model",        fields:  [ extending base model                {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"},        ] }); and with these named, typed fields
  • 42. <aside> Models can be associated with other models Fields can also have default values, conversion functions, and validation </aside>
  • 43. Create a model store create the store var  store  =  Ext.create('Ext.data.Store',  {        model:  "Business",        ... }); containing this type of model Think of a store as a ‘table’ of model instance ‘rows’
  • 44. Configure data source loads as soon as possible var  store  =  Ext.create('Ext.data.Store',  {        model:  'Business',        autoLoad:  true,        proxy:  { JSONP                //  call  Yelp  to  get  business  data                type:  'scripttag', source                url:  'http://api.yelp.com/business_review_search'  +                          '?ywsid='  +  YELP_KEY  +                          '&term='  +  escape(BUSINESS_TYPE)  +                          '&location='  +  escape(DEFAULT_CITY)                ,                reader:  {                        type:  'json',                        root:  'businesses' construct API URL                }        } }); read array from inside JSON
  • 45. Create constants please change this! <script>        YELP_KEY  =  'G3HueY_I5a8WZX-­‐_bAAAA';        DEFAULT_CITY  =  'San  Francisco';        BUSINESS_TYPE  =  'Bars'; </script>
  • 46. We can make the proxy URL dynamic, which would allow geolocation. But this requires an async callback sequence.
  • 47. Two-phase async sequence getCity:  function  (callback)  {        callback(DEFAULT_CITY); call when        //  this  could  now  be  a  geo  lookup  to        //  get  the  nearest  city UI ready }, use this in the URL getBusinesses:  function  (city,  callback)  {        Ext.define("Business",  {                ...        }); the data code         we just wrote        var  store  =  Ext.create('Ext.data.Store',  {                ...        }); } and this will need to fire the callback with store when it autoloads
  • 48. event var  store  =  Ext.create('Ext.data.Store',  { listeners        ...        listeners:  {                //  when  the  records  load,  fire  the  callback                load:  function  (store)  {                        callback(store); when loaded                }        } }); fire the callback with store
  • 51. our 2 async functions //  get  the  city CB.getCity(function  (city)  {        //  then  use  Yelp  to  get  the  businesses        CB.getBusinesses(city,  function  (store)  {                //  then  bind  data  to  list  and  show  it                CB.cards.query('#dataList')[0].setStore(store);        }); }); get dataList bind the store to it by its id
  • 52. :-( but we haz records!
  • 53. another component query CB.getCity(function  (city)  {        cards.query('#listCard  toolbar')[0]                .setTitle(city  +  '  '  +  BUSINESS_TYPE);        ... now title will always match city
  • 54. List items are templated {        id:  'dataList',        xtype:  'list',        store:  null,        itemTpl:  '{name}' } model fields in curly braces
  • 55. Spinner bound to store instantiate mask over body Ext.create('Ext.LoadMask',  Ext.getBody(),  {        store:  store,        msg:  '' }); will show when store is loading
  • 56.
  • 57. A more interesting template itemTpl:        '<img  class="photo"  src="{photo_url}"  width="40"  height="40"/>'  +        '{name}<br/>'  +        '<img  src="{rating_img_url_small}"/>&nbsp;'  +        '<small>{address1}</small>' HTML allowed
  • 58. Hack the style <style>        .photo  {                float:left;                margin:0  8px  16px  0;                border:1px  solid  #ccc;                -­‐webkit-­‐box-­‐shadow:  0  2px  4px  #777;        } </style>
  • 59. ...width="40"  height="40"  /> seems like a waste
  • 60. src.sencha.io <img  src="http://src.sencha.io/40/{photo_url}"          width="40"  height="40" /> 4 times smaller
  • 62. { when list items selection        id:  'dataList',        ... are selected        listeners:  {                selectionchange:  function  (selectionModel,  records)  {                        //  if  selection  made,  slide  to  detail  card                        if  (records[0])  {                                CB.cards.setActiveItem(1); also fires on detail card deselection                                CB.cards.getActiveItem().setData(                                        records[0].data                                ); ...to detail                        }                } apply record data... page template        } }
  • 63. A back button items:  [{ children of toolbars        //  detail  page  also  has  a  toolbar are implicitly        docked  :  'top',        xtype:  'toolbar', xtype: ‘button’        title:  '',        items:  [{                //  containing  a  back  button arrow style                //  that  slides  back  to  list  card                text:  'Back',                ui:  'back', back to list                listeners:  {                        tap:  function  ()  {                                CB.cards.setActiveItem(0); when tapped                        }                }        }],  ...
  • 64.
  • 66. style this card as regular HTML {        //  textual  detail        styleHtmlContent:  true,        cls:  'detail', CSS class for styling        tpl:  [                '<img  class="photo"  src="{photo_url}"  />',                '<h2>{name}</h2>', template for                '<div  class="info">',                        '{address1}<br/>', a whole panel                        '<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>'        ] }]
  • 67. :-(
  • 68. Remember this? setData does not cascade into child items! CB.cards.getActiveItem().setData(        records[0].data );
  • 69. Override setData set title on toolbar setData:  function  (data)  {        this.query('toolbar')[0].setTitle(data.name);        this.query('[cls="detail"]')[0].setData(data); }, apply data to template on inner panel
  • 71. A little styling .x-­‐html  h2  {        margin-­‐bottom:0; } .phone,  .link  {        clear:both; formatting        font-­‐weight:bold; the buttons        display:block;        text-­‐align:center;        margin-­‐top:8px; } temporary .detail  { fixes        -­‐webkit-­‐box-­‐orient:  vertical; } .detail  .photo  {        float:none; }
  • 72.
  • 73. One final tweak move from { inner panel...        //  textual  detail        cls:  'detail',        styleHtmlContent:  true,        ... {        //  the  details  card ...to outer card        id:  'detailCard',        styleHtmlContent:  true,
  • 75.
  • 76.
  • 77. Development sequence 1 App Architecture 5 List Event Handler 2 UI Structure 6 Detail Page 3 Data Modeling 7 Customize Theme 4 List Binding
  • 80. Packaging Add to home screen - Icon - Splash screen Hybrid app; PhoneGap / NimbleKit - Contacts API - Geolocation http://sencha.com/x/cy http://sencha.com/x/de
  • 83. O ine data Taking Yelp data o ine Taking images o ine - src.sencha.io to generate cross-origin B64 Detecting network connection changes http://sencha.com/x/df