-
13 Mar 2011 4:54 AM #1
Creating an Icon Grid with ST
Creating an Icon Grid with ST
Hello,
Firstly, allow me to introduce myself. I am a web developer from the UK, and am currently trying to learn Sencha Touch for some future projects and my own interest. I have been experimenting with other mobile web application frameworks such as jQuery Mobile and jQTouch, but feel that Sencha Touch is the way to go, simply because of its extensive library and functionality.
In order to learn Sencha Touch to an acceptable level, I have decided that I'm going to try and create something similar to the Facebook Mobile Application (not for release obviously, just for my own learning). While I have found the Kitchen Sink demos and tutorials very useful, I have hit a bit of a hurdle with creating a 'dashboard' style Panel in Sencha Touch.
My question, in short, is how would I go about creating a simple 3x3 icon grid which can act as a dashboard for my application? Here's a shot of the Facebook sample that I'm trying to replicate:

As far as I can tell, it would be possible to create this using a combination of vbox and hbox components, but I don't fully understand how to create complex layouts in Sencha Touch just yet. Ideally, I would like the generated dashboard to be extensible, so would be looking to define the items for the dashboard in an array, something similar to:
Any help with creating something along these lines would certainly be most gratefully received indeed.Code:var dashboardItems = [ { title: 'News Feed', icon: '../icons/dashboard/newsfeed.png', handler: function() { alert('blah'); } }, { title: 'Profile', icon: '../icons/dashboard/profile.png', handler: function() { alert('blah2'); } }, { title: 'Friends', icon: '../icons/dashboard/friends.png', handler: function() { alert('blah3'); } } ];
Thanks,
Ben.
-
13 Mar 2011 6:13 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 34,121
- Vote Rating
- 453
You can do it with a mix of HBox and VBox layouts.
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
13 Mar 2011 7:10 AM #3
Could also use a DataView with a store to read the array data and an XTemplate in the tpl property to do the layout, using the new CSS3 display properties for display: table, display: table-row, and display: table-cell. When you are building the page from data objects, I find the templates to be a better approach.
-
13 Mar 2011 9:42 AM #4
Thanks for your help, guys. I have come up with a solution that requires some polishing. As soon as I'm pleased with it, I'll post same here. Effectively, I wrote a new class in JS which produces a grid of icons.
Thanks,
Ben.
-
7 Apr 2011 6:50 PM #5
Would love if you could share how you accomplished this fully. I am trying to do the same.
-
10 Apr 2011 5:21 AM #6
Sorry for the delayed reaction to your message, dchall - I've been snowed under with work this end and haven't had a chance to check the Forums here for a while.
Well, here's a screenshot of what I managed to achieve:
Screen-shot-2011-04-10-at-14.21.png
Essentially, the GridView can be generated by passing in an array of objects. So, for the example above, I pass in the following array of dock items:
And then, here's the method which actually outputs the dashboard:Code:var dashboardCfg = { defaultCls: 'dashboardButton', cols: 3, rows: 3, title: 'Dashboard', cells: [ { id: 'profile', label: 'Profile', icon: 'assets/icons/dashboard/profile.png' }, { id: 'friends', label: 'Friends', icon: 'assets/icons/dashboard/friends.png' }, { id: 'networks', label: 'Networks', icon: 'assets/icons/dashboard/networks.png' }, { id: 'search', label: 'Search', icon: 'assets/icons/dashboard/search.png' }, { id: 'messages', label: 'Messages', icon: 'assets/icons/dashboard/messages.png' }, { id: 'requests', label: 'Requests', icon: 'assets/icons/dashboard/requests.png' }, { id: 'map', label: 'Map', icon: 'assets/icons/dashboard/map.png' }, { id: 'lock', label: 'Lock', icon: 'assets/icons/dashboard/lock.png' }, { id: 'settings', label: 'Settings', icon: 'assets/icons/dashboard/settings.png' }, { id: 'about', label: 'About', icon: 'assets/icons/dashboard/about.png' } ], tpl: '<img src="{icon}" title="{label}" width="48" height="48" /><span>{label}</span>' };
And finally, you call the code as follows:Code:// This is a custom method for making a dashboard: var GridView = function(args) { var totalItems = args.cells.length; var maxBtnsPerPane = args.cols * args.rows; var noPanes = Math.ceil(totalItems / maxBtnsPerPane); var panes = []; var cellIndex = 0; var showIndicator; // Create the panes: for(var i = 0; i < noPanes; i++) { panes[i] = new Ext.Panel({ title: 'Dashboard' + (i + 1), layout: { type: 'vbox', align: 'stretch' }, pack: 'center', defaults: { flex: 1 } }); var thisCount = i + maxBtnsPerPane; // Loop through how many rows we need: for(var rowCount = 0; rowCount < args.rows; rowCount++) { var thisRow = new Ext.Panel({ layout: { type: 'hbox', align: 'stretch', pack: 'center' }, id: 'row' + (rowCount + 1), defaults: { flex: 1 } }); // Now we need to add the cells: for(var colCount = 0; colCount < args.cols; colCount++) { var cellLabel, handlerFunc; (cellIndex > (totalItems - 1)) ? cellLabel = '' : cellLabel = args.cells[cellIndex].label; if(cellIndex < totalItems) { var thisCell = new Ext.Panel({ title: args.cells[cellIndex].label, cls: 'dashboardButton', layout: { type: 'vbox', align: 'center', pack: 'center' }, id: args.cells[cellIndex].id, items: [{ html: args.tpl.replace(/\{(\w+)\}/g, function(match, key) { return args.cells[cellIndex][key]; }) }], listeners: { tap: { element: 'el', fn: function() { rootPanel.setActiveItem(screens[this.id], { type: 'slide' } ); } } } }); } else var thisCell = new Ext.Panel({ title: '' }) thisRow.add(thisCell); cellIndex++; } panes[i].add(thisRow); } } (noPanes == 1) ? showIndicator = false : showIndicator = true; var gridview = new Ext.Carousel({ title: args.title, items: panes, indicator: showIndicator }); return gridview; };
The returned object (i.e. 'dashboard') can then be docked to your panel using the standard Sencha Touch methods.Code:var dashboard = new GridView(dashboardCfg);
Thanks, and hope that helps!
Ben.
-
4 Jul 2011 2:38 AM #7
Confused while integration....
Confused while integration....
That looks very cool, but i run into several errors while doing this:
"The returned object (i.e. 'dashboard') can then be docked to your panel using the standard Sencha Touch methods."
My example application looks like that:
Tha dashboard should be the starting respectively the content of the startup container.Code:new Ext.Application({ name: 'MobileSbf', tabletStartupScreen: 'tablet_startup.png', phoneStartupScreen: 'phone_startup.png', icon: 'icon.png', glossOnIcon: false, useLoadMask: true, launch: function(){ var dashboardCfg = { defaultCls: 'dashboardButton', cols: 3, rows: 3, title: 'Dashboard', cells: [ { id: 'profile', label: 'Profile', icon: 'assets/icons/dashboard/profile.png' }, { id: 'friends', label: 'Friends', icon: 'assets/icons/dashboard/friends.png' }, { id: 'networks', label: 'Networks', icon: 'assets/icons/dashboard/networks.png' }, { id: 'search', label: 'Search', icon: 'assets/icons/dashboard/search.png' }, { id: 'messages', label: 'Messages', icon: 'assets/icons/dashboard/messages.png' }, { id: 'requests', label: 'Requests', icon: 'assets/icons/dashboard/requests.png' }, { id: 'map', label: 'Map', icon: 'assets/icons/dashboard/map.png' }, { id: 'lock', label: 'Lock', icon: 'assets/icons/dashboard/lock.png' }, { id: 'settings', label: 'Settings', icon: 'assets/icons/dashboard/settings.png' }, { id: 'about', label: 'About', icon: 'assets/icons/dashboard/about.png' } ], tpl: '<img src="{icon}" title="{label}" width="48" height="48" /><span>{label}</span>' }; // This is a custom method for making a dashboard: var GridView = function(args) { var totalItems = args.cells.length; var maxBtnsPerPane = args.cols * args.rows; var noPanes = Math.ceil(totalItems / maxBtnsPerPane); var panes = []; var cellIndex = 0; var showIndicator; // Create the panes: for(var i = 0; i < noPanes; i++) { panes[i] = new Ext.Panel({ title: 'Dashboard' + (i + 1), layout: { type: 'vbox', align: 'stretch' }, pack: 'center', defaults: { flex: 1 } }); var thisCount = i + maxBtnsPerPane; // Loop through how many rows we need: for(var rowCount = 0; rowCount < args.rows; rowCount++) { var thisRow = new Ext.Panel({ layout: { type: 'hbox', align: 'stretch', pack: 'center' }, id: 'row' + (rowCount + 1), defaults: { flex: 1 } }); // Now we need to add the cells: for(var colCount = 0; colCount < args.cols; colCount++) { var cellLabel, handlerFunc; (cellIndex > (totalItems - 1)) ? cellLabel = '' : cellLabel = args.cells[cellIndex].label; if(cellIndex < totalItems) { var thisCell = new Ext.Panel({ title: args.cells[cellIndex].label, cls: 'dashboardButton', layout: { type: 'vbox', align: 'center', pack: 'center' }, id: args.cells[cellIndex].id, items: [{ html: args.tpl.replace(/\{(\w+)\}/g, function(match, key) { return args.cells[cellIndex][key]; }) }], listeners: { tap: { element: 'el', fn: function() { rootPanel.setActiveItem(screens[this.id], { type: 'slide' } ); } } } }); } else var thisCell = new Ext.Panel({ title: '' }) thisRow.add(thisCell); cellIndex++; } panes[i].add(thisRow); } } (noPanes == 1) ? showIndicator = false : showIndicator = true; var gridview = new Ext.Carousel({ title: args.title, items: panes, indicator: showIndicator }); return gridview; }; var dashboard = new GridView(dashboardCfg); MobileSbf.views.startUpToolbar = new Ext.Toolbar({ id: 'startUpToolbar', title: 'Mobile SBF', items: [ { xtype: 'spacer' }, { id: 'infoButton', text: 'Info', ui: 'action', handler: function () { MobileSbf.views.viewport.setActiveItem('infoContainer', { type: 'fade', direction: 'right' }); } } ] }); MobileSbf.views.infoToolbar = new Ext.Toolbar({ id: 'infoToolbar', title: 'Infos', items: [ { id: 'backButton', text: 'Home', ui: 'back', handler: function () { MobileSbf.views.viewport.setActiveItem('startUpContainer', { type: 'fade', direction: 'right' }); } }, { xtype: 'spacer' } ] }); MobileSbf.views.infoContainer = new Ext.Panel({ id: 'infoContainer', layout: 'fit', html: 'ProfeOfConcept', dockedItems: [MobileSbf.views.infoToolbar] }); MobileSbf.views.startUpContainer = new Ext.Panel({ id: 'startUpContainer', layout: 'fit', html: '', dockedItems:[ MobileSbf.views.startUpToolbar ] }); MobileSbf.views.viewport = new Ext.Panel({ fullscreen: 'true', layout: 'card', cardAnimation: 'slide', items: [ MobileSbf.views.startUpContainer, MobileSbf.views.infoContainer ] }); } });
I tried a lot arround the namespaces an adding it as items to the container an so on.
Now I'm a bit confused, because it doesn't work for me.
-
19 Jul 2011 1:58 AM #8
Just add the below mentioned code after the code provided by BenMajor:
It will run smoothly. Reps addedCode:Ext.setup({ onReady: function() { var list = new Ext.Panel ({ fullscreen: true, layout: 'fit', scroll: 'vertical', items: [dashboard], }) } });
-
20 Jul 2011 1:00 AM #9
Thanks for this hint.... i tried to use it as a dockeditem instead a item.
I got it with:
Code:MobileSbf.views.startUpContainer = new Ext.Panel({ id: 'startUpContainer', fullscreen: true, scroll: 'vertical', layout: 'fit', dockedItems:[ MobileSbf.views.startUpToolbar ], items:[ dashboard ] });
-
27 Jul 2011 12:10 AM #10
Hi,
I would like to use your code to create a menu like in the facebook app, but your code give a strange result in my app.
Indeed all my icons are superimposed and I don't understand why I have this result.
If I use your code with a carousel at the end of your function, nothing is displayed, if I remplace it by a Panel, I have this result.
My code :Code:var gridview = new Ext.Panel({ title: args.title, items: panes, indicator: showIndicator });
Code:Ext.ns('App.View'); var dashboard = new GridView({ defaultCls: 'dashboardButton', cols: 3, rows: 3, title: 'Menu', cells: [ { id: 's', label: '0', icon: '/images/dir.png' }, { id: 'c', label: '1', icon: '/images/dir.png' }, { id: 'd', label: '2', icon: '/images/dir.png' }, { id: 'e', label: '3', icon: '/images/dir.png' }, { id: 'r', label: '4', icon: '/images/dir.png' }, { id: 't', label: '5', icon: '/images/dir.png' }, { id: 'y', label: '6', icon: '/images/dir.png' }, { id: 'u', label: '7', icon: '/images/dir.png' }, { id: 'i', label: '8', icon: '/images/dir.png' } ], tpl: '<img src="{icon}" title="{label}" width="48" height="48" /><span>{label}</span>' }); App.View.Menu360 = Ext.extend(Ext.Panel, { initComponent: function() { var config = { title: 'Menu 360', iconCls: 'info', scroll: 'vertical', fullscreen: true, defaults:{ scroll: false }, dockedItems: [{ xtype: 'toolbar', dock: 'top', items: [ { xtype: 'button', name: 'btBackDetailsClient', id: 'btBackDetailsClient', ui: 'back', text: 'Retour', iconMask: true, dock: 'left', stretch: false, align: 'left', handler: this.onBackAction }] }], items: [dashboard] }; Ext.apply(this, config); App.View.Menu360.superclass.initComponent.call(this); } }); Ext.reg('App.View.Menu360', App.View.Menu360);
Similar Threads
-
Creating new icon cls
By miroperez in forum Sencha Touch 1.x: DiscussionReplies: 14Last Post: 6 Jul 2012, 12:48 PM -
Tool tip for '-' icon as 'collapsible' and '+' icon 'expandable' in a grid
By awanish in forum Ext 3.x: Help & DiscussionReplies: 1Last Post: 23 Sep 2010, 3:44 AM -
Creating grid as generic...
By bhaskar1605 in forum Ext 2.x: Help & DiscussionReplies: 4Last Post: 20 Dec 2008, 7:28 AM -
Creating a Grid 'on the fly'
By TheLlama in forum Ext 2.x: Help & DiscussionReplies: 3Last Post: 4 Jun 2008, 4:25 PM -
Creating a Menu When a Titlebar Icon is Pressed
By mconnors1234 in forum Ext 2.x: Help & DiscussionReplies: 2Last Post: 10 Jan 2008, 6:15 AM


Reply With Quote