Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Web Development

1802 Articles
article-image-ext-js-4-working-grid-component
Packt
11 Jan 2012
10 min read
Save for later

Ext JS 4: Working with the Grid Component

Packt
11 Jan 2012
10 min read
(For more resources on JavaScript, see here.) Grid panel The grid panel is one of the most-used components when developing an application Ext JS 4 provides some great improvements related to this component. The Ext JS 4 Grid panel renders a different HTML than Ext JS 3 Grid did. Sencha calls this new feature Intelligent Rendering. Ext JS 3 used to create the whole structure, supporting all the features. But, what if someone just wanted to display a simple grid? All the other features not being rendered would just be wasted, because no one was using that structure. Ext JS 4 now renders only the features the grid uses, minimizing and boosting the performance. Before we examine the grid's new features and enhancements, let's take a look how to implement a simple grid in Ext JS 4: Ext.create('Ext.grid.Panel', { store: Ext.create('Ext.data.ArrayStore', { fields: [ {name: 'book'}, {name: 'author'} ], data: [['Ext JS 4: First Look','Loiane Groner']] }), columns: [ { text : 'Book', flex : 1, sortable : false, dataIndex: 'book' },{ text : 'Author', width : 100, sortable : true, dataIndex: 'author' }], height: 80, width: 300, title: 'Simple Grid', renderTo: Ext.getBody() }); As you can see in the preceding code, the two main parts of the grid are the store and the columns declarations. Note, as well, names of both store and model fields always have to match with the column's dataIndex (if you want to display the column in the grid). So far, nothing has changed. The way we used to declare a simple grid in Ext JS 3 is the same way we do for Ext JS 4. However, there are some changes related to plugins and the new features property. We are going to take a closer look at that in this section. Let's dive into the changes! Columns Ext JS 4 organizes all the column classes into a single package—the Ext.grid.column package. We will explain how to use each column type with an example. But first, we need to declare a Model and a Store to represent and load the data: Ext.define('Book', { extend: 'Ext.data.Model', fields: [ {name: 'book'}, {name: 'topic', type: 'string'}, {name: 'version', type: 'string'}, {name: 'released', type: 'boolean'}, {name: 'releasedDate', type: 'date'}, {name: 'value', type: 'number'} ] }); var store = Ext.create('Ext.data.ArrayStore', { model: 'Book', data: [ ['Ext JS 4: First Look','Ext JS','4',false,null,0], ['Learning Ext JS 3.2','Ext JS','3.2',tr ue,'2010/10/01',40.49], ['Ext JS 3.0 Cookbook','Ext JS','3',true,'2009/10/01',44.99], ['Learning Ext JS','Ext JS','2.x',true,'2008/11/01',35.99], ] }); Now, we need to declare a grid: Ext.create('Ext.grid.Panel', { store: store, width: 550, title: 'Ext JS Books', renderTo: 'grid-example', selModel: Ext.create('Ext.selection.CheckboxModel'), //1 columns: [ Ext.create('Ext.grid.RowNumberer'), //2 { text: 'Book',//3 flex: 1, dataIndex: 'book' },{ text: 'Category', //4 xtype:'templatecolumn', width: 100, tpl: '{topic} {version}' },{ text: 'Already Released?', //5 xtype: 'booleancolumn', width: 100, dataIndex: 'released', trueText: 'Yes', falseText: 'No' },{ text: 'Released Date', //6 xtype:'datecolumn', width: 100, dataIndex: 'releasedDate', format:'m-Y' },{ text: 'Price', //7 xtype:'numbercolumn', width: 80, dataIndex: 'value', renderer: Ext.util.Format.usMoney },{ xtype:'actioncolumn', //8 width:50, items: [{ icon: 'images/edit.png', tooltip: 'Edit', handler: function(grid, rowIndex, colIndex) { var rec = grid.getStore().getAt(rowIndex); Ext.MessageBox.alert('Edit',rec.get('book')); } },{ icon: 'images/delete.gif', tooltip: 'Delete', handler: function(grid, rowIndex, colIndex) { var rec = grid.getStore().getAt(rowIndex); Ext.MessageBox.alert('Delete',rec.get('book')); } }] }] }); The preceding code outputs the following grid: The first column is declared as selModel, which, in this example, is going to render a checkbox, so we can select some rows from the grid. To add this column into a grid, simply declare the selModel (also known as sm in Ext JS 3) as CheckBox selection model, as highlighted in the code (comment 1 in the code). The second column that we declared is the RowNumberer column. This column adds a row number automatically into the grid. In the third column (with text:'Book'), we did not specify a column type; this means the column will display the data itself as a string. In the fourth column, we declared a column with xtype as templatecolumn. This column will display the data from the store, specified by an XTemplate, as declared in the tpl property. In this example, we are saying we want to display the topic (name of the technology) and its version. The fifth column is declared as booleancolumn. This column displays a true or false value. But, if we do not want to display true or false in the grid, we can specify the values that we want to get displayed. In this example, we displayed the value as Yes (for true values) and No (for false values), as we declared in the trueText and falseText. The sixth column we declared as datecolumn, which is used to display dates. We can also declare a date format we want to be displayed. In this example, we want to display only the month and the year. The format follows the same rules for PHP date formats. The seventh column we declared as numbercolumn. This column is used to display numbers, such as a quantitative number, money, and so on. If we want to display the number in a particular format, we can use one of the Ext JS renderers to create a customized one. And the last column we declared is the actioncolumn. In this column, we can display icons that are going to execute an action, such as delete or edit. We declare the icons we want to display in the items property. topic: {name}{rows.length} Book topic: {name}{rows.length} Books Feature support In Ext JS 3, when we wanted to add a new functionality to a grid, we used to create a plugin or extend the GridPanel class. There was no default way to do it. Ext JS 4 introduces the Ext.grid.feature.Feature class that contains common methods and properties to create a plugin. Inside the Ext.grid.feature packages, we will find seven classes: AbstractSummary, Chunking, Feature, Grouping, GroupingSummary, RowBody, and Summary. A feature is very simple to use—we need to add the feature inside the feature declaration in the grid: features: [{ groupHeaderTpl: 'Publisher: {name}', ftype: 'groupingsummary' }] Let's take a look at how to use some of these native grid features. Ext.grid.feature.Grouping Grouping rows in Ext JS 4 has changed. Now, Grouping is a feature and can be applied to a grid through the features property. The following code displays a grid grouped by book topic: Ext.define('Book', { extend: 'Ext.data.Model', fields: ['name', 'topic'] }); var Books = Ext.create('Ext.data.Store', { model: 'Book', groupField: 'topic', data: [{ name: 'Learning Ext JS', topic: 'Ext JS' },{ name: 'Learning Ext JS 3.2', topic: 'Ext JS' },{ name: 'Ext JS 3.0 Cookbook', topic: 'Ext JS' },{ name: 'Expert PHP 5 Tools', topic: 'PHP' },{ name: 'NetBeans IDE 7 Cookbook', topic: 'Java' },{ name: 'iReport 3.7', topic: 'Java' },{ name: 'Python Multimedia', topic: 'Python' },{ name: 'NHibernate 3.0 Cookbook', topic: '.NET' },{ name: 'ASP.NET MVC 2 Cookbook', topic: '.NET' }] }); Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 400, title: 'Books', features: [Ext.create('Ext.grid.feature.Grouping',{ groupHeaderTpl: 'topic: {name} ({rows.length} Book{[values.rows.length > 1 ? "s" : ""]})' })], columns: [{ text: 'Name', flex: 1, dataIndex: 'name' },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] }); In the groupHeaderTpl attribute, we declared a template to be displayed in the grouping row. We are going to display one of the following customized strings, depending on the number of books belonging to the topic: The string comprises of the topic name ({name}) and the count of the book for the topic ({rows.length}). In Ext JS 3, we still had to declare a grouping field in the store; but, instead of a Grouping feature, we used to declare GroupingView, as follows: view: new Ext.grid.GroupingView({ forceFit:true, groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Books" : "Book"]})' }) If we execute the grouping grid, we will get the following output:   Ext.grid.feature.GroupingSummary The GroupingSummary feature also groups rows with a field in common, but it also adds a summary row at the bottom of each group. Let's change the preceding example to use the GroupingSummary feature: Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 400, title: 'Books', features: [{ groupHeaderTpl: 'Topic: {name}', ftype: 'groupingsummary' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name', summaryType: 'count', summaryRenderer: function(value){ return Ext.String.format('{0} book{1}', value, value !== 1 ? 's' : ''); } },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] }); We highlighted two pieces in the preceding code. The first line is the feature declaration: in the previous example (Grouping) we created the feature using the Ext.create declaration. But if we do not want to explicitly create the feature every time we declare, we can use the ftype property, which is groupingsummary in this example. The groupingsummary that we added to the grid's name column is in the second line of highlighted code. We declared a summaryType property and set its value as count. Declaring the summaryType as count means we want to display the number of books in that particular topic/category; it is going to count how many records we have for a particular category in the grid. It is very similar to the count of the PL/SQL language. Other summary types we can declare are: sum, min, max, average (these are self-explanatory). In this example, we want to customize the text that will be displayed in the summary, so we are going to use the summaryRenderer function. We need to pass a value argument to it, and the value is the count of the name column. Then, we are going to return a customized string that is going to display the count (token {0}) and the string book or books, depending on the count (if it is more than 1 we add s at the end of the string book). Ext.String.format is a function that allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each token must be unique and must increment in the format {0}, {1}, and so on. The preceding code will output the following grid: Ext.grid.feature.Summary The GroupingSummary feature adds a row at the bottom of each grouping. The Summary feature adds a row at the bottom of the grid to display summary information. The property configuration is very similar to that for GroupingSummary, because both classes are subclasses of AbstractSummary (a class that provides common properties and methods for summary features). Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 300, title: 'Books', features: [{ ftype: 'summary' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name', summaryType: 'count', summaryRenderer: function(value){ return Ext.String.format('{0} book{1}', value, value !== 1 ? 's' : ''); } },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] }); The only difference from the GroupingSummary feature is the feature declaration itself. The summayType and summaryRenderer properties work in a similar way. The preceding code will output the following grid: Ext.grid.feature.RowBody The rowbody feature adds a new tr->td->div in the bottom of the row that we can use to display additional information. Here is how to use it: Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 300, title: 'Books', features: [{ ftype: 'rowbody', getAdditionalData: function(data, idx, record, orig) { return { rowBody: Ext.String.format( '->topic: {0}', data.topic) }; } }, { ftype: 'rowwrap' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name' }] });  In the preceding code, we are not only displaying the name of the book; we are using the rowbody to display the topic of the book as well. The first step is to declare the rowbody feature. One very important thing to be noted is that rowbody will be initially hidden, unless you override the getAdditionalData method. If we execute the preceding code, we will get the following output:
Read more
  • 0
  • 0
  • 6783

article-image-article-building-location-aware-web-applications-mongodb-php
Packt
06 Jan 2012
14 min read
Save for later

Building Location-aware Web Applications with MongoDB and PHP

Packt
06 Jan 2012
14 min read
(For more resources on PHP and MongoDB, see here.) A geolocation primer The term geolocation refers to the act of locating the geographic position of a person, a place, or any place of interest. The geographic position of the object is determined mainly by the latitude and longitude of the object, sometimes its height from sea level is also taken into account. In this section, we are going to learn about different techniques that location- based applications use to determine a user's location. You may skip this section if you are already familiar with them, or if you just cannot wait to get started coding! Methods to determine location There are several ways to locate the geographic position of a computing device. Let's briefly learn about the most effective ones among them: Global Positioning System (GPS ): Nowadays, tech savvy people carry GPS-enabled smartphones in their pockets. Devices like these act as GPS receivers; they constantly exchange information with GPS satellites orbiting the Earth and calculate their geographic position. This process is known as trilateration . This is perhaps the most accurate way to determine location, as of today. Cellphone tracking: Each cellphone has a Cell ID assigned to it that uniquely identifies it in a particular cellular network. In a process known as cellular triangulation , three base stations (cellphone towers) are used to correctly identify the latitude and longitude of the cellphone identified by the Cell ID. This method is more accurate in urban areas, where there are more cellphone towers close to each other, than in rural areas. IP address: Internet service providers are given blocks of IP addresses based on a country/city/region. When a user visits a website, the website could take a look at his IP address and consult an database that stores location data against IP addresses (it might be either an internal database or provided by a third-party service) to get the location of the user. Accuracy of this approach depends on the accuracy of the database itself. Also, if the user is behind a proxy server, the application will see the IP address of the proxy server, which could be located in a different region than the user. Wi-Fi MAC address tracking: A Wi-Fi access point has a MAC (Media Access Control) address assigned to it, which is globally unique. Some location-based services use this to identify the location of the Wi-Fi router, and therefore, the location of users on that Wi-Fi LAN. In principle, it works in the same way IP address-based geolocation does. Google has an API that gives location information (latitude, longitude, and so on) when provided with a MAC address. If you are curious to learn more about how geolocation works, How Stuff Works has a comprehensive article on it available at http://electronics.howstuffworks.com/ everyday-tech/location-tracking.htm. Detecting the location of a web page visitor When building a location-aware web application, the first part of the problem to be solved is to get the location of the user visiting the web page. We have covered geolocation techniques in the previous section, now it is time to see them in action. The W3C Geolocation API We are going to use the W3C Geolocation API for locating the visitors to our web page. The W3C Geolocation API provides a high-level interface for web developers to implement geolocation features in an application. The API takes care of detecting the location using one or more methods (GPS, Cell ID, IP address). The developers do not have to worry about what is going on under the hood; they only need to focus on the geographic information returned by the API! You can read the whole specification online at http://www.w3.org/TR/ geolocation-API/. Browsers that support geolocation The following table lists the browsers that support the W3C Geolocation API: Browser Version Google Chrome 5.0+ Mozilla Firefox 3.5+ Internet Explorer 9.0+ Safari 5.0+ Opera 10.6+ iPhone 3.1+ Android 2.0+ Blackberry 6.0+ Make sure you use one of these browsers when you try the practical examples in this article. Time for action – detecting location with W3C API In this section, we are going to build a web page that detects the location of a visitor using the Geolocation API. The API will detect the latitude and longitude of the user who loads the page in his browser. We are going use that information on a map, rendered dynamically using the Google Maps API: Fire up your text editor and create a new HTML file named location.html. Put the following code in it: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xml_lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link rel="stylesheet" href="styles.css"/> <style type="text/css" media="screen"> div#map { width:450px; height: 400px; } </style> <title>Locating your position</title> </head> <body> <div id="contentarea"> <div id="innercontentarea"> <h2>Locating your position</h2> <div id="map"></div> </div> </div> <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"> </script> <script type="text/javascript" src="geolocation.js"> </script> </body> </html> Create another file named geolocation.js and put the following JavaScript code in it: var mapContainer = document.getElementById('map');var map;function init() { //Google map settings (zoom level, map type etc.) var mapOptions = {zoom: 16, disableDefaultUI: true, mapTypeId: google.maps.MapTypeId.ROADMAP}; //map will be drawn inside the mapContainer map = new google.maps.Map(mapContainer, mapOptions); detectLocation();}function detectLocation(){ var options = { enableHighAccuracy: true, maximumAge: 1000, timeout: 30000}; //check if the browser supports geolocation if (window.navigator.geolocation) { //get current position window.navigator.geolocation.getCurrentPosition( drawLocationOnMap, handleGeoloacteError, options); } else { alert("Sorry, your browser doesn't seem to support geolocation :-("); }}//callback function of getCurrentPosition(), pinpoints location//on Google mapfunction drawLocationOnMap(position) { //get latitude/longitude from Position object var lat = position.coords.latitude; var lon = position.coords.longitude; var msg = "You are here: Latitude "+lat+", Longitude "+lon; //mark current location on Google map var pos = new google.maps.LatLng(lat, lon); var infoBox = new google.maps.InfoWindow({map: map, position:pos, content: msg}); map.setCenter(pos); return;}function handleGeoloacteError() { alert("Sorry, couldn't get your geolocation :-(");}window.onload = init; Load the location.html page in your browser. When the browser asks for permission to allow the page to access your location, click Yes/OK/Allow:   (Move the mouse over the image to enlarge.)   Once you allow the page to access your location, it renders a map that shows your current location on it, along with the geographic coordinates: What just happened? We built a web page and added JavaScript code that detects the latitude and longitude of the user who loads the page in his browser. The API needs the user's permission to get his geographic information. So when the page loads, it prompts the user to specify whether or not he will allow the page to get his location. If the user agrees, the JavaScript code executes and gets his geographic coordinates using the W3C Geolocation API. Then it renders a small map using the Google Maps API, and highlights the user's location on the map. The Geolocation object The Geolocation object implements the W3C Geolocation API. The JavaScript engine uses this object to obtain geographic information of the computer or phone on which the browser is running. Geolocation is a property of the Browser object (window.navigator), accessed as window.navigator.geolocation. In our example, we detect if the browser has geolocation capabilities by accessing this object, and notify the user if the browser fails the test: //check if the browser supports geolocationif (window.navigator.geolocation) { window.navigator.geolocation.getCurrentPosition( drawLocationOnMap, handleGeoloacteError, options);} else { alert("Sorry, your browser doesn't seem to support geolocation.");} The getCurrentPosition() method The location information is obtained invoking the getCurrentPosition() method on the Geolocation object.   getCurrentPostition(callbackOnSuccess, [callbackOnFailure, options])   The argument callbackOnSuccess is a reference to a callback function. It is executed when the getCurrentPosition() method successfully determines the geolocation. This is a mandatory argument. callbackOnFailure is an optional argument, a callback function for handling failure to get the geolocation. options represents the PositionOptions object, which specifies optional configuration parameters to the method. The PositionOptions object has the following properties: enableHighAccuracy : Tells the API to try its best to get the exact current position. It is set to false by default. When set to true, the API response tends to be slower. maximumAge : If API responses are cached, this setting specifies that the API will not use the cached responses older than maximumAge milliseconds. timeout : The timeout value in milliseconds to receive the API response. In our example, we used the drawLocationOnMap() method as a callbackOnSuccess function , which draws a map and pinpoints the location on it (we will walkthrough it shortly). The handleGeoloacteError() method notifies the user of any error while getting the position: window.navigator.geolocation.getCurrentPosition( drawLocationOnMap, handleGeoloacteError, options); Drawing the map using the Google Maps APTI The Google Maps APTIis a popular JavaScript API for drawing maps on a web page. This API has methods to highlight objects on the rendered map. We can access the API methods by adding the following script tag in the web page (as we did in the location.html file): <script type="text/javascript"src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> If you are on a GPS-enabled device, set the sensor parameter to true, as follows: When the script is loaded, we can initiate the map drawing by instantinating the google. maps.Map object . The Map object takes a DOM object as its first parameter; the map will be rendered inside this DOM. It also takes an optional JSON object that specifies configurations for the map (zoom level, map type, and so on): var mapContainer = document.getElementById('map');var mapOptions = {zoom: 16, disableDefaultUI: true, mapTypeId: google.maps.MapTypeId.ROADMAP};map = new google.maps.Map(mapContainer, mapOptions); Now, let's focus on the drawLocationOnMap() function in the geolocation.js file, which is the callback function of the getCurrentPosition() method . As we know, this method gets called when the W3C API successfully locates the position; it receives a Position object as its argument. This object holds all the geolocation data returned by the API. The Position object holds a reference to the Coordinates object (accessed by the property coords). The Coordinates object contains geographical coordinates such as latitude, longitude, altitude, and so on of the location: function drawLocationOnMap(position) { var lat = position.coords.latitude; var lon = position.coords.longitude; var msg = "You are here: Latitude "+lat+", Longitude "+lon; ……………………………………………………………………………………………………………………………………………………………} After we get the latitude and longitude values of the coordinate, we set it as the center of the map. We also display an information box with a message saying, You are here on the map! function drawLocationOnMap(position) { var lat = position.coords.latitude; var lon = position.coords.longitude; var msg = "You are here: Latitude "+lat+", Longitude "+lon; var pos = new google.maps.LatLng(lat, lon); var infoBox = new google.maps.InfoWindow({map: map, position:pos, content: msg}); map.setCenter(pos); return;} Get to know Google Maps API We are going to use the Google Maps API in the upcoming examples as well. You might consider familiarizing yourself with it by reading some of its online documentation at http://code.google.com/apis/maps/ documentation/javascript/basics.html. Geospatial indexing We can now turn our attention to the main topic of this article—geospatial indexing . A geospatial index is a special kind of index, designed specifically with location queries in mind, so you can perform queries like "Give me the closest n objects to my location". Geospatial indexing essentially turns your collection into a two-dimensional map. Each point of interest on that map (each document in the collection) is assigned a special value named geohash. Geohashing divides the coordinate system into hierarchical buckets of grids; the whole map gets divided into smaller quadrants. When you look for objects nearest to a point (x,y) on the map, MongoDB calculates the geohash of (x,y) and returns the points with the same geohash. I am not going to delve into much detail here on how it works, but if you are interested, I recommend you read MongoDB in Flatland (found at http://www.snailinaturtleneck.com/blog/2011/06/08/mongo-in-flatland/), an elaborate yet simple demonstration of how geospatial indexing works in MongoDB. Indexes are generally applied on fields to make field lookups faster. Time for action – creating geospatial indexes Let's see how we can build the geospatial index on a MongoDB collection: Launch the mongo interactive shell. Switch to a new database namespace called geolocation: $ ./mongodb/bin/mongoMongoDB shell version: 1.8.1connecting to: test> use geolocationswitched to db geolocation> Insert a few documents in a collection named ?map. Each document must contain an embedded document with two fields, latitude and longitude: > db.map.insert({coordinate: {latitude:23.2342987, longitude:90.20348}})> db.map.insert({coordinate: {latitude:23.3459835, longitude:90.92348}})> db.map.insert({coordinate: {latitude:23.6743521, longitude:90.30458}}) Create the geospatial index for the map collection by issuing the following command: >db.map.ensureIndex({coordinate: '2d'}) Enter the next command to check if the index was created: > db.system.indexes.find(){ "name" : "_id_", "ns" : "geolocation.map", "key" : { "_id" : 1 }, "v" : 0 }{ "_id" : ObjectId("4e46af48ffd7d5fd0a4d1e41"), "ns" : "geolocation.map", "key" : { "coordinate" : "2d" }, "name" : " coordinate _" } What just happened? We created a MongoDB collection named geocollection in a database named map. We manually inserted documents into the collection, each document contains some random latitude and longitude values in an embedded document named coordinate: > db.map.findOne(){ "_id" : ObjectId("4e46ae9bffd7d5fd0a4d1e3e"), "coordinate" : { "latitude" : 23.2342987, "longitude" : 90.20348 }} After that, we built the geospatial index on the latitude/longitude pairs by calling the ensureIndex() method on the collection: db.map.ensureIndex({coordinate: "2d"}) Next, we invoked the system.indexes.find() method that lists the indexes in the database. The index we created should be in that list: > db.system.indexes.find(){ "name" : "_id_", "ns" : "geolocation.map", "key" : { "_id" : 1 }, "v" : 0 }{ "_id" : ObjectId("4e46af48ffd7d5fd0a4d1e41"), "ns" : "geolocation.map", "key" : { "coordinate" : "2d" }, "name" : " coordinate _" } Geospatial indexing – Important things to know There are a few of things you must know about geospatial indexing: There can be only one geospatial index for a MongoDB collection. You cannot have more than one geospatial index for a collection. The index must be created for an embeded documendt or an array field of the document. If you build the index for an array field, the first two elements of the array will be considered as the (x,y) coordinate: >db.map.insert({coordinate: [23.3459835, 90.92348]})>db.map.ensureIndex({coordinate: "2d"}) Ordering is important when you are storing coordinates. If you store them in the order (y,x) rather than (x,y), you will have to query the collection with (y,x). Use arrays to store coordinates When storing coordinates in a geospatially indexed field, arrays are preferable to embedded objects. This is because an array preserves the order of items in it. No matter what programming language you are using to interact with MongoDB, this comes in very handy when you do queries.
Read more
  • 0
  • 0
  • 1777

article-image-qooxdoo-working-layouts
Packt
27 Dec 2011
16 min read
Save for later

qooxdoo: Working with Layouts

Packt
27 Dec 2011
16 min read
(For more resources on this topic, see here.) qooxdoo uses the generic terminology of the graphical user interface. So, it is very easy to understand the concepts involved in it.. The basic building block in qooxdoo is termed a widget. Each widget (GUI component) is a subclass of the Widget class. A widget also acts as a container to hold more widgets. Wherever possible, grouping of the widgets to form a reusable component or custom widget is a good idea. This allows you to maintain consistency across your application and also helps you to build the application quicker than the normal time. It also increases maintainability, as you need to fix the defect at only one place. qooxdoo provides a set of containers too, to carry widgets, and provides public methods to manage. Let's start with the framework's class hierarchy: Base classes for widgets qooxdoo framework abstracts the common functionalities required by all the widgets into a few base classes, so that it can be reused by any class through object inheritance. Let's start with these base classes. qx.core.Object Object is the base class for all other qooxdoo classes either directly or indirectly. The qx.core.Object class has the implementation for most of the functionalities, such as, object management, logging, event handling, object-oriented features, and so on. A class can extend the qx.core.Object class to get all the functionalities defined in the this class. When you want to add any functionality to your class, just inherit the Object class and add the extra functionalities in the subclass. The major functionalities of the Object class are explained in the sections that follow. Object management   The Object class provides the following methods for object management, such as, creation, destruction, and so on: base(): This method calls base class method dispose(): This method disposes or destroys the object isDisposed(): This method returns a true value if the object is disposed toString(): This method returns the object in string format toHashCode(): This method returns hash code of the object Event handling The Object class provides the following methods for event creation, event firing, event listener, and so on: addListener(): This method adds the listener on the event target and returns the ID of the listener addListenerOnce(): This method adds the listener and listens only to the first occurrence of the event dispatchEvent(): This method dispatches the event fireDataEvent(): This method fires the data event fireEvent(): This method fires the event removeListener(): This method removes the listener removeListenerById(): This method removes the listener by its ID, given by addListener() Logging The Object class provides the following methods to log the message at different levels: warn(): Logs the message at warning level info(): Logs the message at information level error(): Logs the message at error level debug(): Logs the message at the debugging level trace(): Logs the message at the tracing level Also, the Object class provides the methods for setters and getters for properties, and so on. qx.core.LayoutItem LayoutItem is the super most class in the hierarchy. You can place only the layout items in the layout manager. LayoutItem is an abstract class. The LayoutItem class mainly provides properties, such as, height, width, margins, shrinking, growing, and many more, for the item to be drawn on the screen. It also provides a set of public methods to alter these properties. Check the API documentation for a full set of class information. qx.core.Widget Next in the class hierarchy is the Widget class, which is the base class for all the GUI components. Widget is the super class for all the individual GUI components, such as, button, text field, combobox, container, and so on, as shown in the class hierarchy diagram. There are different kinds of widgets, such as, containers, menus, toolbars, form items, and so on; each kind of widgets are defined in different namespaces. We will see all the different namespaces or packages, one-by-one, in this article. A widget consists of at least three HTML elements. The container element, which is added to the parent widget, has two child elements—the decoration and the content element. The decoration element decorates the widget. It has a lower z-index and contains markup to render the widget's background and border styles, using an implementation of the qx.ui.decoration.IDecorator interface. The content element is positioned inside the container element, with the padding, and contains the real widget element. Widget properties Common widget properties include:   Visibility: This property controls the visibility of the widget. The possible values for this property are: visible: Makes the widget visible on screen. hidden: Hides the widget, but widget space will be occupied in the parent widget's layout. This is similar to the CSS style visibility:hidden. exclude: Hides the widget and removes from the parent widget's layout, but the widget is still a child of its parent's widget. This is similar to the CSS style display:none. The methods to modify this property are show(), hide(), and exclude(). The methods to check the status are isVisible(), isHidden(), and isExcluded(). Tooltip: This property displays the tooltip when the cursor is pointing at the widget. This tooltip information consists of toolTipText and toolTipIcon. The different methods available to alter this property are: setToolTip()/getToolTip(): Sets or returns the qx.ui.tooltip.ToolTip instance. The default value is null. setToolTipIcon()/getToolTipIcon(): Sets or returns the URL for the icon. The default value is null. setToolTipText()/getToolTipText(): Sets or returns the string text. It also supports the HTML markup. Default value is null. Text color: The textColor property sets the frontend text color of the widget. The possible values for this property are any color or null. Padding: This property is a shorthand group property for paddingTop, paddingRight, paddingBottom and paddingLeft of the widget. The available methods are setPadding() and resetPadding(), which sets values for top, right, bottom, and left padding, consecutively. If any values are missing, the opposite side values will be taken for that side. Also, set/get methods for each padding side are also available. Tab index: This property controls the traversal of widgets on the Tab key press. Possible values for this property are any integer or null. The traversal order is from lower value to higher value. By default, tab index for the widgets is set in the order in which they are added to the container. If you want to provide a custom traversal order, set the tab index accordingly. The available methods are setTabIndex() and getTabIndex(). These methods, respectively set and return the integer value (0 to 32000) or null. Font: The Font property defines the font for the widget. The possible value is either a font name defined in the theme, or an instance of qx.bom.Font, or null. The available methods are: setFont(): Sets the font getFont(): Retrieves the font initFont(): Initializes the font resetFont(): Resets the font Enabled: This property enables or disables the widget for user input. Possible values are true or false (Boolean value). The default value is true. The widget invokes all the input events only if it is in the enabled state. In the disabled state, the widget will be grayed out and no user input is allowed. The only events invoked in the disabled state are mouseOver and mouseOut. In the disabled state, tab index and widget focus are ignored. The tab traversal focus will go to the next enabled widget. setEnabled()/getEnabled() are the methods to set or get a Boolean value, respectively. Selectable: This property says whether the widget contents are selectable. When a widget contains text data and the property is true, native browser selection can be used to select the contents. Possible values are true or false. The default value is false. setSelectable(), getSelectable(), initSelectable(), resetSelectable(), and toggleSelectable() are the methods available to modify the Selectable property. Appearance: This property controls style of the element and identifies the theme for the widget. Possible values are any string defined in the theme; the default value is widget. setAppearence(), getAppearence(), initAppearence(), and resetAppearence() are the methods to alter the appearance. Cursor: This property specifies which type of cursor to display on mouse over the widget. The possible values are any valid CSS2 cursor name defined by W3C (any string) and null. The default value is null. Some of the W3C-defined cursor names are default, wait, text, help, pointer, crosshair, move, n-resize, ne-resize, e-resize, se-resize, s-resize, sw-resize, w-resize, and nw-resize. setCursor(), getCursor(), resetCursor(), and initCursor() are the methods available to alter the cursor property. qx.application The starting point for a qooxdoo application is to write a custom application class by inheriting one of the qooxdoo application classes in the qx.application namespace or package. Similar to the main method in Java, the qooxdoo application also starts from the main method in the custom application class. qooxdoo supports three different kinds of applications: Standalone: Uses the application root to build full-blown, standalone qooxdoo applications. Inline: Uses the page root to build traditional web page-based applications, which are embedded into isles in the classic HTML page. Native: This class is for applications that do not involve qooxdoo's GUI toolkit. Typically, they only make use of the IO (AJAX) and BOM functionality (for example, to manipulate the existing DOM). Whenever a user creates an application with the Python script, a custom application class gets generated with a default main method. Let's see the custom application class generated for our Team Twitter application. After generation, the main function code is edited to add functionality to communicate to the RPC server and say "hello" to the qooxdoo world. The following code is the content of the Application.js class file with an RPC call to communicate with the server: /** * This is the main application class of your custom application "teamtwitter" */ qx.Class.define("teamtwitter.Application", { extend : qx.application.Standalone, members : { /** * This method contains the initial application code and gets called during startup of the application * @lint ignoreDeprecated(alert) */ main : function() { // Call super class this.base(arguments); // Enable logging in debug variant if (qx.core.Variant.isSet("qx.debug", "on")) { // support native logging capabilities, e.g. Firebug for Firefox qx.log.appender.Native; // support additional cross-browser console. Press F7 to toggle visibility qx.log.appender.Console; } /* Below is your actual application code... */ // Create a button var button1 = new qx.ui.form.Button("First Button", "teamtwitter/test.png"); // Document is the application root var doc = this.getRoot(); // Add button to document at fixed coordinates doc.add(button1, {left: 100, top: 50}); // Add an event listener button1.addListener("execute", function(e) { var rpc = new qx.io.remote.Rpc(); rpc.setCrossDomain( false ); rpc.setTimeout(1000); var host = window.location.host; var proto = window.location.protocol; var webURL = proto + "//" + host + "/teamtwitter/.qxrpc"; rpc.setUrl(webURL); rpc.setServiceName("qooxdoo.test"); rpc.callAsync(function(result, ex, id){ if (ex == null) { alert(result); } else { alert("Async(" + id + ") exception: " + ex); } }, "echo", "Hello to qooxdoo World!"); }); } } }); We've had an overview of the class hierarchy of the qooxdoo framework and got to know the base classes for the widgets. Now, we have an idea of the core functionalities available for the widgets, the core properties of the widgets, and the methods to manage those properties. We've received more information on the application in the qooxdoo framework. Now, it is time to learn about the containers. Containers A container is a kind of widget. It holds multiple widgets and exposes public methods to manage their child widgets. One can configure a layout manager for the container to position all the child widgets in the container. qooxdoo provides different containers for different purposes. Let's check different containers provided by the qooxdoo framework and understand the purpose of each container. Once you understand the purpose of each container, you can select the right container when you design your application. Scroll Whenever the content widget size (width and height) is larger than the container size (width and height), the Scroll container provides vertical, or horizontal, or both scroll bars automatically. You have to set the Scroll container's size carefully to make it work properly. The Scroll container is used most commonly if the application screen size is large. The Scroll container has a fixed layout and it can hold a single child. So, there is no need to configure the layout for this container. The following code snippet demonstrates how to use the Scroll container: // create scroll containervar scroll = new qx.ui.container.Scroll().set({width: 300,height: 200});// adding a widget with larger widget and height of the scrollscroll.add(new qx.ui.core.Widget().set({width: 600,minWidth: 600,height: 400,minHeight: 400})); // add to the root widget.this.getRoot().add(scroll); The GUI look for the preceding code is as follows: Stack The Stack container puts a widget on top of an old widget. This container displays only the topmost widget. The Stack container is used if there are set of tasks to be carried out in a flow. An application user can work on each user interface one-by-one in order. The following code snippet demonstrates how to use the Stack container: // create stack containervar stack = new qx.ui.container.Stack();// add some childrenstack.add(new qx.ui.core.Widget().set({backgroundColor: "red"}));stack.add(new qx.ui.core.Widget().set({backgroundColor: "green"}));stack.add(new qx.ui.core.Widget().set({backgroundColor: "blue"}));this.getRoot().add(stack); The GUI look for the preceding code is as follows: Resizer Resizer is a container that gives flexibility for resizing at runtime. This container should be used only if you want to allow the application user to dynamically resize the container. The following code snippet demonstrates how to use the Resizer container: var resizer = new qx.ui.container.Resizer().set({marginTop : 50,marginLeft : 50,width: 200,height: 100});resizer.setLayout(new qx.ui.layout.HBox());var label = new qx.ui.basic.Label("Resize me <br>I'm resizable");label.setRich(true);resizer.add(label);this.getRoot().add(resizer); The GUI look for the preceding code is as follows: Composite This is a generic container. If you do not want any of the specific features, such as, resize on runtime, stack, scroll, and so on, but just want a container, you can use this container. This is one of the mostly used containers. The following code snippet demonstrates the Composite container usage. A horizontal layout is configured to the Composite container. A label and a text field are added to the container. The horizontal layout manager places them horizontally: // create the compositevar composite = new qx.ui.container.Composite()// configure a layout.composite.setLayout(new qx.ui.layout.HBox());// add some child widgetscomposite.add(new qx.ui.basic.Label("Enter Text: "));composite.add(new qx.ui.form.TextField());// add to the root widget.this.getRoot().add(composite); The GUI look for the preceding code is as follows: Window Window is a container that has all features, such as, minimize, maximize, restore, and close. The icons for these operations will appear on the top-right corner. Different themes can be set to get the look and feel of a native window within a browser. This window is best used when an application requires Multiple Document Interface (MDI) or Single Document Interface (SDI). The following code snippet demonstrates a window creation and display: var win = new qx.ui.window.Window("First Window");win.setWidth(300);win.setHeight(200);// neglecting minimize buttonwin.setShowMinimize(false);this.getRoot().add(win, {left:20, top:20});win.open(); The GUI look for the preceding code is as follows: TabView The TabView container allows you to display multiple tabs, but only one tab is active at a time. The TabView container simplifies the GUI by avoiding the expansive content spreading to multiple pages, with a scroll. Instead, the TabView container provides the tab title buttons to navigate to other tabs. You can group the related fields into each tab and try to avoid the scroll by keeping the most-used tab as the first tab and making it active. Application users can move to other tabs, if required. TabView is the best example for the stack container usage. It stacks all pages one over the other and displays one page at a time. Each page will have a button at the top, in a button bar, to allow switching the page. Tabview allows positioning the button bar on top, bottom, left, or right. TabView also allows adding pages dynamically; a scroll appears when the page buttons exceed the size. The following code snippet demonstrates the usage of TabView: var tabView = new qx.ui.tabview.TabView();// create a pagevar page1 = new qx.ui.tabview.Page("Layout", "icon/16/apps/utilitiesterminal.png");// add page to tabviewtabView.add(page1);var page2 = new qx.ui.tabview.Page("Notes", "icon/16/apps/utilitiesnotes.png");page2.setLayout(new qx.ui.layout.VBox());page2.add(new qx.ui.basic.Label("Notes..."));tabView.add(page2);var page3 = new qx.ui.tabview.Page("Calculator", "icon/16/apps/utilities-calculator.png");tabView.add(page3);this.getRoot().add(tabView, {edge : 0}); The GUI look for the preceding code is as follows: GroupBox GroupBox groups a set of form widgets and shows an effective visualization with the use of a legend, which supports text and icons to describe the group. As with the container, you can configure any layout manager and allow adding a number of form widgets to the GroupBox. Additionally, it is possible to use checkboxes or radio buttons within the legend. This allows you to provide group functionalities such as selecting or unselecting all the options in the group. This feature is most important for complex forms with multiple choices. The following code snippet demonstrates the usage of GroupBox: // group boxvar grpBox = new qx.ui.groupbox.GroupBox("I am a box");this.getRoot().add(grpBox, {left: 20, top: 70});// radio group boxvar rGrpBox = new qx.ui.groupbox.RadioGroupBox("I am a box");rGrpBox.setLayout(new qx.ui.layout.VBox(4));rGrpBox.add(new qx.ui.form.RadioButton("Option1"));rGrpBox.add(new qx.ui.form.RadioButton("Option2"));this.getRoot().add(rGrpBox, {left: 160, top: 70});// check group boxvar cGrpBox = new qx.ui.groupbox.CheckGroupBox("I am a box");this.getRoot().add(cGrpBox, {left: 300, top: 70}); The GUI look for the preceding code is as follows: We got to know the different containers available in the qooxdoo framework. Each container provides a particular functionality. Based on the information displayed on the GUI, you should choose the right container to have better usability of the application. Containers are the outer-most widgets in the GUI. Once you decide on the containers for your user interface, the next thing to do is to configure the layout manager for the container. Layout manager places the child widgets in the container, on the basis of the configured layout manager's policies. Now, it's time to learn how to place and arrange widgets inside the container, that is, how to lay out the container.
Read more
  • 0
  • 0
  • 5334

Packt
20 Dec 2011
8 min read
Save for later

Ajax:Basic Utilities

Packt
20 Dec 2011
8 min read
Validating a form using Ajax The main idea of Ajax is to get data from the server in real time without reloading the whole page. In this task we will build a simple form with validation using Ajax. Getting ready As a JavaScript library is used in this task, we will choose jQuery. We will download (if we haven't done it already) and include it in our page. We need to prepare some dummy PHP code to retrieve the validation results. In this example, let's name it inputValidation.php. We are just checking for the existence of a param variable. If this variable is introduced in the GET request, we confirm the validation and send an OK status back to the page: ?php $result = array(); if(isset($_GET["param"])){ $result["status"] = "OK"; $result["message"] = "Input is valid!"; } else { $result["status"] = "ERROR"; $result["message"] = "Input IS NOT valid!"; } echo json_encode($result); ?> How to do it... Let`s start with basic HTML structure. We will define a form with three input boxes and one text area. Of course, it is placed in : <body> <h1>Validating form using Ajax</h1> <form class="simpleValidation"> <div class="fieldRow"> <label>Title *</label> <input type="text" id="title" name="title" class="required" /> </div> <div class="fieldRow"> <label>Url</label> <input type="text" id="url" name="url" value="http://" /> </div> <div class="fieldRow"> <label>Labels</label> <input type="text" id="labels" name="labels" /> </div> <div class="fieldRow"> <label>Text *</label> <textarea id="textarea" class="required"></textarea> </div> <div class="fieldRow"> <input type="submit" id="formSubmitter" value="Submit" disabled="disabled" /> </div> </form> </body> <style> For visual confirmation of the valid input, we will define CSS styles: label{ width:70px; float:left; } form{ width:320px; } input, textarea{ width:200px; border:1px solid black; float:right; padding:5px; } input[type=submit] { cursor:pointer; background-color:green; color:#FFF; } input[disabled=disabled], input[disabled] { background-color:#d1d1d1; } fieldRow { margin:10px 10px; overflow:hidden; } failed { border: 1px solid red; } </style> Now, it is time to include jQuery and its functionality: <script src="js/jquery-1.4.4.js"></script> <script> var ajaxValidation = function(object){ var $this = $(object); var param= $this.attr('name'); var value = $this.val(); $.get("ajax/inputValidation.php", {'param':param, 'value':value }, function(data) { if(data.status=="OK") validateRequiredInputs(); else $this.addClass('failed'); },"json"); } var validateRequiredInputs = function (){ var numberOfMissingInputs = 0; $('.required').each(function(index){ var $item = $(this); var itemValue = $item.val(); if(itemValue.length) { $item.removeClass('failed'); } else { $item.addClass('failed'); numberOfMissingInputs++; } }); var $submitButton = $('#formSubmitter'); if(numberOfMissingInputs > 0){ $submitButton.attr("disabled", true); } else { $submitButton.removeAttr('disabled'); } } </script> We will also initialize the document ready function: <script> $(document).ready(function(){ var timerId = 0; $('.required').keyup(function() { clearTimeout (timerId); timerId = setTimeout(function(){ ajaxValidation($(this)); }, 200); }); }); </script> When everything is ready, our result is as follows: How it works... We created a simple form with three input boxes and one text area. Objects with class required are automatically validated after the keyup event and calling the ajaxValidation function. Our keyup functionality also includes theTimeoutfunction to prevent unnecessary calls if the user is still writing. The validation is based on two steps: Validation of the actual input box: We are passing the inserted text to the ajax/inputValidation.php via Ajax. If the response from the server is not OK we will mark this input box as failed. If the response is OK, we proceed to the second step. Checking the other required fields in our form. When there is no failed input box left in the form, we will enable the submit button. There's more... Validation in this example is really basic. We were just checking if the response status from the server is OK. We will probably never meet a validation of the required field like we have here. In this case,it's better to use the length property directly on the client side instead of bothering the server with a lot of requests,simply to check if the required field is empty or filled. This task was just a demonstration of the basic Validationmethod. It would be nice to extend it with regular expressions on the server-side to directly check whether the URL form or the title already exist in our database, and let the user know what the problem is and how he/she can fix it. Creating an autosuggest control This recipe will show us how to create an autosuggest control. This functionality is very useful when we need to search within huge amounts of data. The basic functionality is to display the list of suggested data based on text in the input box. Getting ready We can start with the dummy PHP page which will serve as a data source. When we call this script with GET method and variable string, this script will return the list of records (names) which include the selected string: <?php $string = $_GET["string"]; $arr = array( "Adam", "Eva", "Milan", "Rajesh", "Roshan", // ... "Michael", "Romeo" ); function filter($var){ global $string; if(!empty($string)) return strstr($var,$string); } $filteredArray = array_filter($arr, "filter"); $result = ""; foreach ($filteredArray as $key => $value){ $row = "<li>".str_replace($string, "<strong>".$string."</strong>", $value)."</li>"; $result .= $row; } echo $result; ?> How to do it... As always, we will start with HTML. We will define the form with one input box and an unsorted list datalistPlaceHolder: <h1>Dynamic Dropdown</h1> <form class="simpleValidation"> <div class="fieldRow"> <label>Skype name:</label> <div class="ajaxDropdownPlaceHolder"> <input type="text" id="name" name="name" class="ajaxDropdown" autocomplete="OFF" /> <ul class="datalistPlaceHolder"></ul> </div> </div> </form> When the HTML is ready, we will play with CSS: <style> label { width:80px; float:left; padding:4px; } form{ width:320px; } input, textarea{ width:200px; border:1px solid black; border-radius: 5px; float:right; padding:5px; } input[type=submit] { cursor:pointer; background-color:green; color:#FFF; } input[disabled=disabled] { background-color:#d1d1d1; } fieldRow { margin:10px 10px; overflow:hidden; } validationFailed { border: 1px solid red; } validationPassed { border: 1px solid green; } .datalistPlaceHolder { width:200px; border:1px solid black; border-radius: 5px; float:right; padding:5px; display:none; } ul.datalistPlaceHolder li { list-style: none; cursor:pointer; padding:4px; } ul.datalistPlaceHolder li:hover { color:#FFF; background-color:#000; } </style> Now the real fun begins. We will include jQuery library and define our keyup events: <script src="js/jquery-1.4.4.js"></script> <script> var timerId; var ajaxDropdownInit = function(){ $('.ajaxDropdown').keyup(function() { var string = $(this).val(); clearTimeout (timerId); timerId = setTimeout(function(){ $.get("ajax/dropDownList.php", {'string':string}, function(data) { if(data) $('.datalistPlaceHolder').show().html(data); else $('.datalistPlaceHolder').hide(); }); }, 500 ); }); } </script> When everything is set, we will call the ajaxDropdownInit function within the document ready function: <script> $(document).ready(function(){ ajaxDropdownInit(); }); </script> Our autosuggest control is ready. The following screenshot shows the output: How it works... The autosuggest control in this recipe is based on the input box and the list of items in datalistPlaceHolder. After each keyup event of the input box,datalistPlaceHolder will load the list of items from ajax/dropDownList.php via the Ajax function defined in ajaxDropdownInit. A good feature of this recipe is thetimerID variable that,when used with thesetTimeout method, will allow us to send the request on the server only when we stop typing (in our case it is 500 milliseconds). It may not look so important, but it will save a lot of resources. We do not want to wait for the response of "M" typed in the input box, when we have already typed in "Milan". Instead of 5 requests (150 milliseconds each), we have just one. Multiply it, for example, with 10,000 users per day and the effect is huge. There's more... We always need to remember that the response from the server is in the JSON format. [{ 'id':'1', 'contactName':'Milan' },...,{ 'id':'99', 'contactName':'Milan (office)' }] Using JSON objects in JavaScript is not always useful from the performance point of view. Let's imagine we have 5000 contacts in one JSON file. It may take a while to build HTML from 5000 objects but, if we build a JSON object, the code will be as follows: [{ "status": "100", "responseMessage": "Everything is ok! :)", "data": "<li><h2><ahref=\"#1\">Milan</h2></li> <li><h2><ahref=\"#2\">Milan2</h2></li> <li><h2><ahref=\"#3\">Milan3</h2></li>" }] It may take a while to build HTML from 5000 objects but, if we build a JSON object, the code will be as follows: <?php echo "STEP 1"; // Same for 2 and 3 ?>   In this case, we will have the complete data in HTML and there is no need to create any logic to create a simple list of items.
Read more
  • 0
  • 0
  • 1570

article-image-ajax-basic-utilities
Packt
20 Dec 2011
8 min read
Save for later

Ajax: Basic Utilities

Packt
20 Dec 2011
8 min read
(For more resources on PHP Ajax, see here.) Validating a form using Ajax The main idea of Ajax is to get data from the server in real time without reloading the whole page. In this task we will build a simple form with validation using Ajax. Getting ready As a JavaScript library is used in this task, we will choose jQuery. We will download (if we haven't done it already) and include it in our page. We need to prepare some dummy PHP code to retrieve the validation results. In this example, let's name it inputValidation.php. We are just checking for the existence of a param variable. If this variable is introduced in the GET request, we confirm the validation and send an OK status back to the page: <?php $result = array(); if(isset($_GET["param"])){ $result["status"] = "OK"; $result["message"] = "Input is valid!"; } else { $result["status"] = "ERROR"; $result["message"] = "Input IS NOT valid!"; } echo json_encode($result); ?> How to do it... Let`s start with basic HTML structure. We will define a form with three input boxes and one text area. Of course, it is placed in : <body> <h1>Validating form using Ajax</h1> <form class="simpleValidation"> <div class="fieldRow"> <label>Title *</label> <input type="text" id="title" name="title" class="required" /> </div> <div class="fieldRow"> <label>Url</label> <input type="text" id="url" name="url" value="http://" /> </div> <div class="fieldRow"> <label>Labels</label> <input type="text" id="labels" name="labels" /> </div> <div class="fieldRow"> <label>Text *</label> <textarea id="textarea" class="required"></textarea> </div> <div class="fieldRow"> <input type="submit" id="formSubmitter" value="Submit" disabled= "disabled" /> </div> </form> </body> <style> For visual confirmation of the valid input, we will define CSS styles: label{ width:70px; float:left; } form{ width:320px; } input, textarea{ width:200px; border:1px solid black; float:right; padding:5px; } input[type=submit] { cursor:pointer; background-color:green; color:#FFF; } input[disabled=disabled], input[disabled] { background-color:#d1d1d1; } fieldRow { margin:10px 10px; overflow:hidden; } failed { border: 1px solid red; } </style> Now, it is time to include jQuery and its functionality: <script src="js/jquery-1.4.4.js"></script> <script> var ajaxValidation = function(object){ var $this = $(object); var param= $this.attr('name'); var value = $this.val(); $.get("ajax/inputValidation.php", {'param':param, 'value':value }, function(data) { if(data.status=="OK") validateRequiredInputs(); else $this.addClass('failed'); },"json"); } var validateRequiredInputs = function (){ var numberOfMissingInputs = 0; $('.required').each(function(index){ var $item = $(this); var itemValue = $item.val(); if(itemValue.length) { $item.removeClass('failed'); } else { $item.addClass('failed'); numberOfMissingInputs++; } }); var $submitButton = $('#formSubmitter'); if(numberOfMissingInputs > 0){ $submitButton.attr("disabled", true); } else { $submitButton.removeAttr('disabled'); } } </script> We will also initialize the document ready function: <script> $(document).ready(function(){ var timerId = 0; $('.required').keyup(function() { clearTimeout (timerId); timerId = setTimeout(function(){ ajaxValidation($(this)); }, 200); }); }); </script> When everything is ready, our result is as follows: How it works... We created a simple form with three input boxes and one text area. Objects with class required are automatically validated after the keyup event and calling the ajaxValidation function. Our keyup functionality also includes theTimeoutfunction to prevent unnecessary calls if the user is still writing. The validation is based on two steps: Validation of the actual input box: We are passing the inserted text to the ajax/inputValidation.php via Ajax. If the response from the server is not OK we will mark this input box as failed. If the response is OK, we proceed to the second step. Checking the other required fields in our form. When there is no failed input box left in the form, we will enable the submit button. There's more... Validation in this example is really basic. We were just checking if the response status from the server is OK. We will probably never meet a validation of the required field like we have here. In this case,it's better to use the length property directly on the client side instead of bothering the server with a lot of requests,simply to check if the required field is empty or filled. This task was just a demonstration of the basic Validationmethod. It would be nice to extend it with regular expressions on the server-side to directly check whether the URL form or the title already exist in our database, and let the user know what the problem is and how he/she can fix it. Creating an autosuggest control This recipe will show us how to create an autosuggest control. This functionality is very useful when we need to search within huge amounts of data. The basic functionality is to display the list of suggested data based on text in the input box. Getting ready We can start with the dummy PHP page which will serve as a data source. When we call this script with GET method and variable string, this script will return the list of records (names) which include the selected string: <?php $string = $_GET["string"]; $arr = array( "Adam", "Eva", "Milan", "Rajesh", "Roshan", // ... "Michael", "Romeo" ); function filter($var){ global $string; if(!empty($string)) return strstr($var,$string); } $filteredArray = array_filter($arr, "filter"); $result = ""; foreach ($filteredArray as $key => $value){ $row = "<li>".str_replace($string, "<strong>".$string."</strong>", $value)."</li>"; $result .= $row; } echo $result; ?> How to do it... As always, we will start with HTML. We will define the form with one input box and an unsorted list datalistPlaceHolder: <h1>Dynamic Dropdown</h1> <form class="simpleValidation"> <div class="fieldRow"> <label>Skype name:</label> <div class="ajaxDropdownPlaceHolder"> <input type="text" id="name" name="name" class="ajaxDropdown" autocomplete="OFF" /> <ul class="datalistPlaceHolder"></ul> </div> </div> </form> When the HTML is ready, we will play with CSS: <style> label { width:80px; float:left; padding:4px; } form{ width:320px; } input, textarea{ width:200px; border:1px solid black; border-radius: 5px; float:right; padding:5px; } input[type=submit] { cursor:pointer; background-color:green; color:#FFF; } input[disabled=disabled] { background-color:#d1d1d1; } fieldRow { margin:10px 10px; overflow:hidden; } validationFailed { border: 1px solid red; } validationPassed { border: 1px solid green; } .datalistPlaceHolder { width:200px; border:1px solid black; border-radius: 5px; float:right; padding:5px; display:none; } ul.datalistPlaceHolder li { list-style: none; cursor:pointer; padding:4px; } ul.datalistPlaceHolder li:hover { color:#FFF; background-color:#000; } </style>   Now the real fun begins. We will include jQuery library and define our keyup events: <script src="js/jquery-1.4.4.js"></script> <script> var timerId; var ajaxDropdownInit = function(){ $('.ajaxDropdown').keyup(function() { var string = $(this).val(); clearTimeout (timerId); timerId = setTimeout(function(){ $.get("ajax/dropDownList.php", {'string':string}, function(data) { if(data) $('.datalistPlaceHolder').show().html(data); else $('.datalistPlaceHolder').hide(); }); }, 500 ); }); } </script> When everything is set, we will call the ajaxDropdownInit function within the document ready function: <script>$(document).ready(function(){ajaxDropdownInit();});</script>  Our autosuggest control is ready. The following screenshot shows the output: How it works... The autosuggest control in this recipe is based on the input box and the list of items in datalistPlaceHolder. After each keyup event of the input box,datalistPlaceHolder will load the list of items from ajax/dropDownList.php via the Ajax function defined in ajaxDropdownInit. A good feature of this recipe is thetimerID variable that,when used with thesetTimeout method, will allow us to send the request on the server only when we stop typing (in our case it is 500 milliseconds). It may not look so important, but it will save a lot of resources. We do not want to wait for the response of "M" typed in the input box, when we have already typed in "Milan". Instead of 5 requests (150 milliseconds each), we have just one. Multiply it, for example, with 10,000 users per day and the effect is huge. There's more... We always need to remember that the response from the server is in the JSON format. [{ 'id':'1', 'contactName':'Milan' },...,{ 'id':'99', 'contactName':'Milan (office)' }] Using JSON objects in JavaScript is not always useful from the performance point of view. Let's imagine we have 5000 contacts in one JSON file. It may take a while to build HTML from 5000 objects but, if we build a JSON object, the code will be as follows: [{ "status": "100", "responseMessage": "Everything is ok! :)", "data": "<li><h2><ahref="#1">Milan</h2></li> <li><h2><ahref="#2">Milan2</h2></li> <li><h2><ahref="#3">Milan3</h2></li>" }] It may take a while to build HTML from 5000 objects but, if we build a JSON object, the code will be as follows: <?php echo "STEP 1"; // Same for 2 and 3 ?> In this case, we will have the complete data in HTML and there is no need to create any logic to create a simple list of items.
Read more
  • 0
  • 0
  • 1950

article-image-setting-online-shopping-cart-drupal-and-ubercart
Packt
19 Dec 2011
7 min read
Save for later

Setting up an online shopping cart with Drupal and Ubercart

Packt
19 Dec 2011
7 min read
(For more resources on Drupal, see here.) Setting up the e-commerce system Ubercart has existed since Drupal 6 so those users who have used Ubercart with Drupal 6 will have some experience setting up and configuring this module for Drupal 7. In this section we'll install and set up the basic Ubercart configuration. Goal Set up the system that will allow visitors to purchase take-out from the website. Additional modules needed Ubercart, Token, Views, CTools, Entity, Token, Rules (http://drupal.org/project/ubercart). Configuring Ubercart In order to utilize an e-commerce solution within a website, you must either build a solution from scratch or use a ready-made solution. Because building a professional e-commerce solution from scratch would take an entire book and weeks or months to build, we are fortunate to have Ubercart, which is a professional quality e-commerce solution tailor-made for Drupal. To begin using Ubercart: Download and install the module from its project page. The current stable release for Drupal 7 is 7.x-3.0-rc3. To use Ubercart, you will also need to install some dependency modules in order to get the best functionality and performance from Ubercart. These dependencies are listed on the Ubercart Website: Token, Views, Rules, CTools, Entity API, Entity Token and Token. Go ahead and install and enable the dependency modules and Ubercart. Once installed, we will begin by enabling the following Ubercart modules: All of the modules in the Ubercart—Core section including Cart, Order, Product, and Store. Then enable the following Core (Optional) modules: Catalog, File downloads, Payment, Product Attributes, Reports, Roles, and Taxes. Then in the Extra section enable the following: Product Kit and Stock. For our Payment method and module enable the Credit card, PayPal, and Test Gateway modules. We will not be shipping any items so we do not need to enable shipping modules at this point. There are a variety of other modules that can be optionally enabled. We will explore some of these in future topics. If you are planning to use the PayPal Express Checkout payment method with Ubercart you should make sure you have enabled the CURL PHP extension for use in your PHP configuration. To do this you can ask your hosting company to enable the CURL extension in your php.ini file. Otherwise if you have access to the php.ini file you can open the file and uncomment the CURL extension to enable it. Then save your php.ini file and restart the Web server. When you check your PHP info via the Drupal status report you should see the following section showing you that the PHP CURL extension is enabled.     Now, you should see the following Ubercart modules that you have enabled on your main modules configuration page:   Ubercart installs a new menu item called Store next to the menu item called Dashboard in the Administer menu bar, which includes the options shown in the following screenshot:   The first thing you'll notice is a warning message telling you that one or more problems exist with your Drupal install. Click on the Status report link. On the Status report page you'll see a warning telling you to enable credit card encryption. In order to use Ubercart for payment processing for your online store transactions you first need to set up an encryption location for your credit card data.   To do this click on the credit card security settings link. That will load the Credit card settings screen. Under Basic Settings, for now let's enable the Test Gateway. Later we'll discuss integrating PayPal but for testing purposes we can use the Test Gateway configuration.   Click on the Security Settings tab. Here we need to set up our card number encryption settings. We can first create a folder outside of our document root (outside of our Drupal directory) but on our web server to hold our encrypted data. We'll create a folder at the root level of our MAMP install called "keys". Go ahead and do this then type in /Applications/MAMP/keys in your Card number encryption key file path field. Also make sure the folder allows for write permissions.   Now click on the PayPal Website Payments Pro tab and disable the gateway for use. Click on the Test Gateway tab and leave this enabled for use. Click on Credit card settings and leave the defaults selected. Under Customer messages you can specify any custom messages you want to show the user if their credit card fails during the transaction process. Click Save configuration. When you save your configuration you should get the following success message: Credit card encryption key file generated. Card data will now be encrypted. The configuration options have been saved. Now, we have successfully set up our payment processing with the Test gateway enabled. We're ready to start using Ubercart. To begin using Ubercart, we will need to: Edit the Configuration settings, which are shown in the following screenshot: Clicking on the Store link allows you to configure several options that control how information on the site is displayed, as well as specify some basic contact information for the site To edit the settings for a section, click on the tab for that section. On the Store settings page, we simply need to update the Store name, Store owner, e-mail address, phone and fax numbers for the store. You can also enter store address information. If your store is not located in the United States, you will also need to modify the Currency Format settings. If you are shipping items you may need to tweak the Weight and Length formats. You can also specify a store help page where you'll provide help information. You can simply create a new page in Drupal and alias it, and then type the alias in here. Once you finish entering your Store settings click the Save configuration button Configuring Ubercart user permissions You should also create a role for store administration, by clicking on User management and then Roles. We will call our role Store Administrator. Click Add role to finish building the role. After the role has been added, click the edit permissions link for the role to define the permissions for the new role. Ubercart includes several sections of permissions including: Catalog Credit Card File Downloads Store Payment Product Product attributes Product kit Order Taxes Since this is an administrative role you may just want to give this staff person all permissions for an admin level role on the site. Go ahead and check off the permissions you need to grant and then save your role's permissions.If your site has employees, you may also want to create a separate role (or several roles) that do not give full control over the store for your employees. For example, you may not want an employee to be able to create or delete products, but you would like them to be able to take new orders. Ubercart provided blocks The Ubercart module ships with a core block that you can enable to make it easier for visitors to your site to see what they have ordered and to check out. Go to your blocks administrative page and you can enable the Shopping cart block to show in one of your block regions. I'll put it in the Sidebar second region. These are the basic configuration options which need to be done after you enable the block. Click on the configure link and then you can title your block, select whether to display the shopping cart icon, make the cart block collapsible, add cart help text ,and more. I'll leave the defaults selected for now. You should see a block admin screen similar to the following:  
Read more
  • 0
  • 0
  • 4606
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-wordpress-customizing-content-display
Packt
14 Dec 2011
8 min read
Save for later

WordPress: Customizing Content Display

Packt
14 Dec 2011
8 min read
(For more resources on WordPress, see here.) At its most basic, a simple implementation of the loop could work like this: <?php if (have_posts()) : while (have_posts()) : the_post(); ?><?php the_title(); ?><?php the_content(); ?><?php endwhile; else: ?><p>Sorry, no posts matched your criteria.'</p><?php endif; ?> In the real world, however, the WordPress loop is rarely that simple. This is one of those concepts best explained by referring to a real world example, so open up the index.php file of your system's TwentyEleven theme. Look for the following lines of code: <?php if ( have_posts() ) : ?><?php twentyeleven_content_nav( 'nav-above' ); ?><?php /* Start the Loop */ ?><?php while ( have_posts() ) : the_post(); ?><?php get_template_part( 'content', get_post_format()); ?><?php endwhile; ?><?php twentyeleven_content_nav( 'nav-below' ); ?><?php else : ?><article id="post-0" class="post no-results not-found"><header class="entry-header"><h1 class="entry-title"><?php _e( 'Nothing Found','twentyeleven' ); ?></h1></header><!-- .entry-header --><div class="entry-content">3<p><?php _e( 'Apologies, but no results were foundfor the requested archive. Perhaps searching will helpfind a related post.', 'twentyeleven' ); ?></p><?php get_search_form(); ?></div><!-- .entry-content --></article><!-- #post-0 --><?php endif; ?> Most of the extra stuff seen in the loop from TwentyEleven is there to add in additional page elements, including content navigation; there's also some code to control what happens if there are no posts to display. The nature of the WordPress loops means that theme authors can add in what they want to display and thereby customize and control the output of their site. As you would expect, the WordPress Codex includes an extensive discussion of the WordPress loop. Visit http://codex.wordpress.org/The_Loop. Accessing posts within the WordPress loop In this recipe, we look at how to create a custom template that includes your own implementation of the WordPress loop. Getting ready All you need to execute this recipe is your favorite code editor and access to the WordPress files on your server. You will also need a theme template file, which we will use to hold our modified WordPress loop. How to do it Let's assume you have created a custom template. Inside of that template you will want to include the WordPress loop. Follow these steps to add the loop, along with a little customization: Access the active theme files on your WordPress installation. Find a template file and open it for editing. If you're not sure which one to use, try the index.php file. Add to the file the following line of code, which will start the loop: <?php if ( have_posts() ) : while ( have_posts() ) : the_post();?> Next, let's display the post title, wrapped in an h2 tag: <h2><?php the_title() ?></h2> Let's also add a link to all posts by this author. Add this code immediately below the previous line: <?php the_author_posts_link() ?> For the post content, let's wrap it in a div for easy styling: <div class="thecontent"><?php the_content(); ?></div> Next, let's terminate the loop and add some code to display a message if there were no posts to display: <?php endwhile; else: ?><p>Oops! There are no posts to display.</p> Finally, let's put a complete stop to the loop by ending the if statement that began the code in step number 3, above: <?php endif; ?> Save the file. That's all there is to it. Your code should look like this: ?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?><h2><?php the_title() ?></h2><?php the_author_posts_link() ?><div class="thecontent"><?php the_content(); ?></div><?php endwhile; else: ?><p>Oops! There are no posts to display.</p><?php endif; ?> How it works... This basic piece of code first checks if there are posts in your site. If the answer is yes, the loop will repeat until every post title and their contents are displayed on the page. The post title is displayed using the_title(). The author's name and link are added with the_ author_posts_link() function. The content is displayed with the_content() function and styled by the div named thecontent. Finally, if there are no posts to display, the code will display the message Oops! There are no posts to display. There's more... In the preceding code you saw the use of two template tags: the_author_posts_link and the_content. These are just two examples of the many template tags available in WordPress. The tags make your life easier by reducing an entire function to just a short phrase. You can find a full list of the template tags at: http://codex.wordpress.org/ Template_Tags. The template tags can be broken down into a number of categories: General tags: The tags in this category cover general page elements common to most templates Author tags: Tags related to author information Bookmark tags: The tag to list bookmarks Category tags: Category, tag, and item description-related Comment tags: Tags covering the comment elements Link tags: Tags for links and permalinks Post tags: Tags for posts, excerpts, titles, and attachments Post Thumbnail tags: Tags that relate to the post thumbnails Navigation Menu tags: Tags for the nav menu and menu tree Retrieving posts from a specific category There are times when you might wish to display only those posts that belong to a specific category, for example, perhaps you want to show only the featured posts. With a small modification to the WordPress loop, it's easy to grab only those posts you want to display. In this recipe we introduce query_posts(),which can be used to control which posts are displayed by the loop. Getting ready To execute this recipe, you will need a code editor and access to the WordPress files on your server. You will also need a theme template file, which we will use to hold our modified WordPress loop. To keep this recipe short and to the point, we use the loop we created in the preceding recipe. How to do it... Let's create a situation where the loop shows only those posts assigned to the Featured category. To do this, you will need to work through two different processes. First, you need to find the category ID number of the Featured category. To do this, follow these steps: Log in to the Dashboard of your WordPress site. Click on the Posts menu. Click on the Categories option. Click on the category named Featured. Look at the address bar of your browser and you will notice that part of the string looks something like this:&tag_ID=9. On the site where we are working, the Featured category has the ID of 9. Category IDs vary from site to site. The ID used in this recipe may not be the same as the ID for your site! Next, we need to add a query to our loop that will extract only those posts that belong to the Featured category, that is, to those posts that belong to the category with the ID of 9. Follow these steps: Open the file that contains the loop. We'll use the same file we created in the preceding recipe. Find the loop: <?php if ( have_posts() ) : while ( have_posts() ) :the_post(); ?><h2><?php the_title() ?></h2><?php the_author_posts_link() ?><div class="thecontent"><?php the_content(); ?></div><?php endwhile; else: ?><p>Oops! There are no posts to display.</p><?php endif; ?> Add the following line of code immediately above the loop: <?php query_posts($query_string.'&cat=9'); ?> Save the file. That's all there is to it. If you visit your site, you will now see that the page displays only the posts that belong to the category with the ID of 9. How it works... The query_posts() function modifies the default loop. When used with the cat parameter, it allows you to specify one or more categories that you want to use as filters for the posts. For example: query_posts(&query_string.'&cat=5');: Get posts from the category with ID 5 only query_posts(&query_string.'&cat=5,6,9');: Get posts from the category with IDs 5, 6, and 9 query_posts(&query_string.'&cat=-3');: Get posts from all categories, except those from the category with ID 3 For more information, visit the WordPRess Codex page on query posts: http://codex.wordpress.org/Function_Reference/query_posts
Read more
  • 0
  • 0
  • 5152

article-image-creating-basic-vaadin-project
Packt
13 Dec 2011
10 min read
Save for later

Creating a Basic Vaadin Project

Packt
13 Dec 2011
10 min read
  (For more resources on this topic, see here.)   Understanding Vaadin In order to understand Vaadin, we should first understand what is its goal regarding the development of web applications. Vaadin's philosophy Classical HTML over HTTP application frameworks are coupled to the inherent request/response nature of the HTTP protocol. This simple process translates as follows: The client makes a request to access an URL. The code located on the server parses request parameters (optional). The server writes the response stream accordingly. The response is sent to the client. All major frameworks (and most minor ones, by the way) do not question this model: Struts, Spring MVC, Ruby on Rails, and others, completely adhere to this approach and are built upon this request/response way of looking at things. It is no mystery that HTML/HTTP application developers tend to comprehend applications through a page-flow filter. On the contrary, traditional client-server application developers think in components and data binding because it is the most natural way for them to design applications (for example, a select-box of countries or a name text field). A few recent web frameworks, such as JSF, tried to cross the bridge between components and page-flow, with limited success. The developer handles components, but they are displayed on a page, not a window, and he/she still has to manage the flow from one page to another. The Play Framework (http://www.playframework.org/) takes a radical stance on the page-flow subject, stating that the Servlet API is a useless abstraction on the request/response model and sticks even more to it. Vaadin's philosophy is two-fold: It lets developers design applications through components and data bindings It isolates developers as much as possible from the request/response model in order to think in screens and not in windows This philosophy lets developers design their applications the way it was before the web revolution. In fact, fat client developers can learn Vaadin in a few hours and start creating applications in no time. The downside is that developers, who learned their craft with the thin client and have no prior experience of fat client development, will have a hard time understanding Vaadin as they are inclined to think in page-flow. However, they will be more productive in the long run. Vaadin's architecture In order to achieve its goal, Vaadin uses an original architecture. The first fact of interest is that it is comprised of both a server and a client side. The client side manages thin rendering and user interactions in the browser The server side handles events coming from the client and sends changes made to the user interface to the client Communication between both tiers is done over the HTTP protocol. We will have a look at each of these tiers.   Client server communication Messages in Vaadin use three layers: HTTP, JSON, and UIDL. The former two are completely un-related to the Vaadin framework and are supported by independent third parties; UIDL is internal. HTTP protocol Using the HTTP protocol with Vaadin has the following two main advantages: There is no need to install anything on the client, as browsers handle HTTP (and HTTPS for that matter) natively. Firewalls that let pass the HTTP traffic (a likely occurrence) will let Vaadin applications function normally. JSON message format Vaadin messages between the client and the server use JavaScript Objects Notation (JSON). JSON is an alternative to XML that has the following several differences: First of all, the JSON syntax is lighter than the XML syntax. XML has both a start and an end tag, whereas JSON has a tag coupled with starting brace and ending brace. For example, the following two code snippets convey the same information, but the first requires 78 characters and the second only 63. For a more in depth comparison of JSON and XML, refer to the following URL: http://json.org/xml.html <person> <firstName>John</firstName> <lastName>Doe</lastName> </person> {"person" { {"firstName": "John"}, {"lastName": "Doe"} } The difference varies from message to message, but on an average, it is about 40%. It is a real asset only for big messages, and if you add server GZIP compression, size difference starts to disappear. The reduced size is no disadvantage though. Finally, XML designers go to great length to differentiate between child tags and attributes, the former being more readable to humans and the latter to machines. JSON messages design is much simpler as JSON has no attributes. UIDL "schema" The last stack that is added to JSON and HTTP is the User Interface Definition Language (UIDL). UIDL describes complex user interfaces with JSON syntax. The good news about these technologies is that Vaadin developers won't be exposed to them. The client part The client tier is a very important tier in web applications as it is the one with which the end user directly interacts. In this endeavor, Vaadin uses the excellent Google Web Toolkit (GWT) framework. In the GWT development, there are the following mandatory steps: The code is developed in Java. Then, the GWT compiler transforms the Java code in JavaScript. Finally, the generated JavaScript is bundled with the default HTML and CSS files, which can be modified as a web application. Although novel and unique, this approach provides interesting key features that catch the interest of end users, developers, and system administrators alike: Disconnected capability, in conjunction with HTML 5 client-side data stores Displaying applications on small form factors, such as those of handheld devices Development only with the Java language Excellent scalability, as most of the code is executed on the client side, thus freeing the server side from additional computation On the other hand, there is no such thing as a free lunch! There are definitely disadvantages in using GWT, such as the following: The whole coding/compilation/deployment process adds a degree of complexity to the standard Java web application development. Although a Google GWT plugin is available for Eclipse and NetBeans, IDEs do not provide standard GWT development support. Using GWT development mode directly or through one such plugin is really necessary, because without it, developing is much slower and debugging almost impossible. For more information about GWT dev mode, please refer to the following URL: http://code.google.com/intl/en/webtoolkit/doc/latest/DevGuideCompilingAndDebugging.html There is a consensus in the community that GWT has a higher learning curve than most classic web application frameworks; although the same can be said for others, such as JSF. If the custom JavaScript is necessary, then you have to bind it in Java with the help of a stack named JavaScript Native Interface (JSNI), which is both counter-intuitive and complex. With pure GWT, developers have to write the server-side code themselves (if there is any). Finally, if ever everything is done on the client side, it poses a great security risk. Even with obfuscated code, the business logic is still completely open for inspection from hackers. Vaadin uses GWT features extensively and tries to downplay its disadvantages as much as possible. This is all possible because of the Vaadin server part. The server part Vaadin's server-side code plays a crucial role in the framework. The biggest difference in Vaadin compared to GWT is that developers do not code the client side, but instead code the server side that generates the former. In particular, in GWT applications, the browser loads static resources (the HTML and associated JavaScript), whereas in Vaadin, the browser accesses the servlet that serves those same resources from a JAR (or the WEB-INF folder). The good thing is that it completely shields the developer from the client-code, so he/she cannot make unwanted changes. It may be also seen as a disadvantage, as it makes the developer unable to change the generated JavaScript before deployment. It is possible to add custom JavaScript, although it is rarely necessary. In Vaadin, you code only the server part! There are two important tradeoffs that Vaadin makes in order achieve this: As opposed to GWT, the user interface related code runs on the server, meaning Vaadin applications are not as scalable as pure GWT ones. This should not be a problem in most applications, but if you need to, you should probably leave Vaadin for some less intensive part of the application; stick to GWT or change an entirely new technology. While Vaadin applications are not as scalable as applications architecture around a pure JavaScript frontend and a SOA backend, a study found that a single Amazon EC2 instance could handle more than 10,000 concurrent users per minute, which is much more than your average application. The complete results can be found at the following URL: http://vaadin.com/blog/-/blogs/vaadin-scalabilitystudy-quicktickets Second, each user interaction creates an event from the browser to the server. This can lead to changes in the user interface's model in memory and in turn, propagate modifications to the JavaScript UI on the client. The consequence is that Vaadin applications simply cannot run while being disconnected from the server! If your requirements include the offline mode, then forget Vaadin. Terminal and adapter As in any low-coupled architecture, not all Vaadin framework server classes converse with the client side. In fact, this is the responsibility of one simple interface: com.vaadin.terminal.Terminal. In turn, this interface is used by a part of the framework aptly named as the Terminal Adapter, for it is designed around the Gang of Four Adapter (http://www.vincehuston.org/dp/adapter.html) pattern. This design allows for the client and server code to be completely independent of each other, so that one can be changed without changing the other. Another benefit of the Terminal Adapter is that you could have, for example, other implementations for things such as Swing applications. Yet, the only terminal implementation provided by the current Vaadin implementation is the web browser, namely com.vaadin.terminal.gwt.server.WebBrowser. However, this does not mean that it will always be the case in the future. If you are interested, then browse the Vaadin add-ons directory regularly to check for other implementations, or as an alternative, create your own! Client server synchronization The biggest challenge when representing the same model on two heterogeneous tiers is synchronization between each tier. An update on one tier should be reflected on the other or at least fail gracefully if this synchronization is not possible (an unlikely occurrence considering the modern day infrastructure). Vaadin's answer to this problem is a synchronization key generated by the server and passed on to the client on each request. The next request should send it back to the server or else the latter will restart the current session's application. This may be the cause of the infamous and sometimes frustrating "Out of Sync" error, so keep that in mind.  
Read more
  • 0
  • 0
  • 3062

article-image-wordpress-3-designing-your-blog
Packt
12 Dec 2011
19 min read
Save for later

WordPress 3: Designing your Blog

Packt
12 Dec 2011
19 min read
(For more resources on WordPress, see here.) Blog design principles Blogs tend to have a fairly simple, minimalist layout and design. This has always been one of their key characteristics. Blogs are all about frequently updated content, so the main purpose of their design is to present that content as efficiently and conveniently as possible. The vast majority of blogs present their most recent content on the page that visitors arrive at; hence, the front page contains the latest posts. There's no home page with a verbose welcome message and a long navigation menu to click through to the important stuff. The visitor gets straight into the meat of the blog. By default, this is the structure that WordPress provides. It is possible to set a static page as your blog's front page, but, in the vast majority of cases, I wouldn't recommend it. So when considering the architecture of a blog, unlike other types of website, we don't have to worry too much about a complex navigation structure. There is a convention that we can follow. Yes, we may want to add some extra static pages, but probably only a few of these. What we are most concerned with in blog design is not a complicated navigation structure and how all the pages link together, but how the actual blog page should look and feel. This can be broken down into four key components, which we will examine, one by one: Layout Color Typography Usability and accessibility Layout Good design is all about making something easy for people to use. Designers achieve this by employing standards and conventions. For example, cars have a standard design: four wheels, a chassis, a steering wheel, gas pedal, brake, gear shift, and so on. Car designers have stuck to this convention for many years. First, because it works well and second, because it enables us to drive any car we choose. When you sit down in any standard road car, you know how it works. You turn the key in the ignition, select a gear, hit the gas, and off you go. It's certainly not beyond the ken of car designers to come up with new ways for getting a car in motion (a joystick maybe, or a hand-operated brake) but this would make it more difficult for people to drive. Cars work reasonably safely and efficiently because we are all familiar with these conventions. The layout of blog pages also tends to follow certain conventions. As with cars, this helps people to use blogs efficiently. They know how they work, because they're familiar with the conventions. Most blogs have a header and a footer with the main content arranged into columns. This columnar layout works very well for the type of chronological content presented in blogs. Because of these conventions, the decisions about our blog layout are fairly simple. It's basically a case of deciding where we want to place all our page elements and content within this standard columnar layout. The set of page elements we have to choose from is also based on fairly well entrenched blogging conventions. The list of things we may want on our page includes: Header Posts Comments Static content (for example, the About page) Links to static pages (simple navigation) RSS feeds Search Categories Archives Blogroll Widgets and plugins Footer If we look at this list in more detail, we can see that these page elements can be grouped in a sensible way. For example: Group 1 Header Links to static pages Group 2 Posts Comments Static content Group 3 RSS Feeds Search Categories Group 4 Archives Blogroll Widgets and plugins Group 5 Footer This isn't the only possible grouping scheme we might come up with. For example, we may place the items in Groups 3 and 4 into a single larger group, or we may have widgets and plugins in a group on their own. From this grouping, we can see that the type of items in Group 2 are likely to be the main content on our page, with Groups 3 and 4 being placed in sidebars . Sidebars are areas on the page where we place ancillary content. Having considered the elements we want on the page and how they might be grouped, we can think about possible layouts. Within the conventional columnar structure of blogs there are quite a few possible layout variations. We'll look at four of the most common. The first is a three-column layout. Here, we have two sidebars, one on either side of the main content. Using this type of layout, we would probably place the items in Groups 3 and 4 in the sidebars and Group 2 in the main content area. A variation on the three-column layout is to have the two sidebars next to each other on one side of the page (usually the right), as shown in the following diagram. This is a popular layout for blogs, not just for aesthetics, but because the search engine spiders encounter the post column first as that content is at the top of the template. Using two sidebars is useful if you anticipate having a lot of ancillary content on your blog. The list of page elements given earlier is really the bare minimum you would want on your page. However, if you decide to use lots of widgets or have a long blogroll, it's a good idea to spread them across two sidebars. This means that more of your content can be placed above the fold. The concept of above the fold in web design applies to content in a web page which is visible without having to scroll down, that is, the stuff in the top part of the page. It's a good idea to place the most important content above the fold so that readers can see it immediately. This is particularly true if you plan to monetize your blog by displaying adverts. Adverts that appear above the fold get the most exposure, and therefore, generate the most revenue Another popular layout amongst bloggers has just two columns. In this layout, we would place the items in Groups 3 and 4 together in the one sidebar. It doesn't really matter which side of the page the sidebar is placed, but it seems more common to have it on the right. Studies have shown that a web user's eyes are most often focused on the top-left region of a web page, when they first open any page. So it makes sense to place your main content there, with your sidebar on the right. Also, remember that the search engine spiders will find the leftmost content first. You want them to find your main content quickly, which is a good reason for placing your sidebar on the right, out of their way. An important benefit of a two-column layout is that it allows more room for your main content area. This may be important, if you intend to use a lot of video or images within your blog posts. The extra room allows you to display this visual content bigger. Many blogs place some of their ancillary content just above the footer, below the main content. This also has the advantage of leaving more space for the main content, as with the two-column layout. The following diagram shows this type of layout. Here, the content just above the footer isn't strictly speaking a sidebar, but I've labeled it this way because it's the terminology most often applied to this type of ancillary content. Wireframing The layout diagrams we've just seen are referred to as wireframes by web designers. They give a simple overview of where the elements of a page should be placed. It would be a good idea for you to create your own wireframe for your blog design. This can be done using most graphic software packages or something like Microsoft Visio , or a simple pen and paper does the job equally well! Color This is the next design principle we need to consider. It may be that you already have a corporate color scheme based on your company logo, stationery, or existing website. In this case, you'll probably want to continue that theme through your blog design. Even if you already have your corporate color scheme, this section may still be useful in case you decide to change your blog colors in the future. The subject of color in design is a large one. Design students spend a great deal of time learning about the psychology and science of colors and techniques for achieving the best color schemes. Obviously, we don't have enough space to go into that kind of detail, but I will try to give you a few pointers. The first thing to think about is the psychology of color, in particular, color associations. This is the idea that different colors evoke different feelings and emotions in the eye of the beholder. To a certain extent this can be rather subjective and it can also depend on cultural influences, but there are some generalities that can be applied. For example, red is often perceived as being exciting, passionate, or dramatic. Yellow is an active and highly visible color, which is why it is used in warning signs. It is also associated with energy and happiness. Blue is sometimes thought of as being cold. It can also be a calming color and may sometimes be seen as corporate or conservative. White, for many people, gives the idea of cleanliness, purity, and perfection. Black can be seen as strong, elegant, and chic. Obviously, these color associations can vary from person to person, so designers don't rely on them solely in their color decisions, but they are certainly worth bearing in mind. There are more practical considerations regarding color that are probably more relevant than color psychology. For example, we all know that some color combinations don't work well together. There is a great deal of design theory aimed at devising good color combinations, but unless you're a professional designer, it's not really worth going into. Probably the best method for working out good color combinations is trial and error. If you're trying to figure out a background color and text color for your blog, simply test a few out. You could use a graphics package such as Photoshop or Microsoft Paint , or one of the many online color tools such as, http://colorschemedesigner.com/ or Adobe's Kuler at http://kuler.adobe.com. When choosing background and text colors you need to think about contrast. For example, yellow text on a white background can be very difficult to read. Some people also find light text on a black background a strain on their eyes. It's also important not to use too many colors in your design. Try to limit your palette to a maximum of three or four. Sometimes you may only need two colors to make an attractive design. One method for devising color combinations is to look for examples all around you, particularly in nature. Maybe look at a photograph of a landscape and pick out color combinations you like. Also consider the work of professional designers. Think about websites and blogs you like, and examine the color schemes they have used. You will also find good examples in offline design—pick up a book and see how colors have been used in the cover design. If you would like to base your blog's color scheme on your company logo, you could use lighter and darker versions of one color from the logo. Use the most vivid color in the logo for emphasis or headings. Web color theory At this point, it's worth looking at the technical theory behind colors on the Web. Web browsers use the Hexadecimal RGB color system to render colors in web pages. This is because computer monitors use an RGB color model, which means every pixel is colored using a combination of red, green, and blue light (hence RGB). There are 256 different levels of red light, 256 different levels of green light, and 256 different levels of blue light. These can be combined to create 16,277,216 different colors, which are all available for your web browser. The hexadecimal system gives us a way of counting from 0 to 255 using numbers and letters, which covers all 256 levels of RGB light. In the hexadecimal scale, 0 is 00 and 255 is FF. A six-character hexadecimal color code specifies the levels of red, green and blue, which form a particular color. For example, the color white combines red, green, and blue at their highest possible levels, that is 255. Remember that in hexadecimal 255 is FF, so the color code for white is FFFFFF (Red: FF, Green: FF, and Blue: FF). The color code for black is 000000 as the levels of red, green, and blue are set to their lowest, or 00 (in hexadecimal). The code for red is FF0000, blue is 0000FF, and yellow is FFFF00, and so on. We can use six-character Hexadecimal RGB codes to define all of the 16,277,216 web colors. So how do we know the hexadecimal code for a particular color? Well, there are many tools available that define the Hexadecimal RGB codes for the colors you choose. Some are standalone applications for PC or Mac, and others are online. Take a look at https://www.webpagefx.com/web-design/color-picker/ or do a quick search in Google on color picker . For more information on web colors , read the article at http://en.wikipedia.org/wiki/Web_colors. Typography Another important consideration for your blog design is the fonts you use. Your choice of font will have a big impact on the readability of your blog. It's important to bear in mind that although there are literally thousands of fonts to choose from, only a small number of them are practical for web design. This is because a web browser can only display fonts that are already installed on the user's computer. If you choose an obscure font for your blog, the chances are that most users won't have it installed on their computer. If this is the case the web browser will automatically select a substitute font. This may be smaller or far less readable than the font you had in mind. It's always safest to stick to the fonts that are commonly used in web design, which are known as web safe fonts. These include the following: Arial Verdana Times New Roman Georgia There are two types of font, serif and sans-serif. Serif fonts have little flourishes at the end of the strokes whereas sans-serif fonts don't have this extra decoration. Arial and Verdana are sans-serif fonts, whereas Times New Roman and Georgia are serif fonts. As you'll see later in the article, when we look at CSS, fonts are usually specified in groups or families. They are listed in the order of the designer's preference. For example, a designer may specify font-family:"Georgia, Times New Roman, serif". This means when the browser renders the page it will first look for the Georgia font; if it isn't installed, it will look for the Times New Roman font and if that isn't installed, it will look for the computer's default serif font. This method gives the designer more control over the font choices the browser will make. The size of your font is also an important factor. Generally speaking, the bigger it is, the easier it is to read. Computer displays are getting bigger and bigger but the default screen resolutions are tending to get smaller. In other words, the individual pixels on users' screens are getting smaller. This is a good reason for web designers to choose larger font sizes. This trend can be seen on many Web 2.0 sites, which tend to use large and clear fonts as part of their design, for example http://www.37signals.com. But be careful not to go too big as this can make your design look messy and a little childish. Remember that you're not limited to using just one font in your blog design. For example, you may decide to use a different font for your headings. This can be an effective design feature but don't go crazy by using too many fonts, as this will make your design look messy. Probably two, or at most three, fonts on a page are plenty. Font replacement Font replacement refers to a relatively new group of technologies that are pushing the envelope of web typography. In theory, they allow designers to use any font in their web page designs. In practice, things are a little more complicated. Issues around browser compatibility and font licensing make font replacement technologies a bit of a minefield for anyone who is new to web design. It's true that, thanks to font replacement technologies, professional designers are no longer constrained by the notion of web safe fonts. But, if you are a web design novice, I recommend you stick to web safe fonts until your skills improve and you are ready to learn a whole new technology. A full discussion on font replacement is way beyond the scope of this article; I mention it only to give you a better overview of the current state of web typography. But if you are interested in knowing more, three popular font replacement technologies are Cufón (http://cufon.shoqolate.com), Font Squirrel (http://www.fontsquirrel.com), and Google Fonts API (http://code.google.com/apis/webfonts/). There is also something known as @font-face, which is part of CSS3, the latest specification of CSS. Again, it offers the tantalizing possibility of giving designers free rein in their choice of fonts. Sadly, @font-face is also hindered by browser compatibility and font licensing issues. The Font Squirrel technology, mentioned previously, resolves these issues to a certain extent, so this is something to be aware of as your web design skills develop. But for the time being, I recommend you concentrate on the basics of web typography and don't worry about @font-face until you feel ready. Usability and accessibility This is another very important area to consider when designing your blog. Many people, who live with various disabilities, use a range of 'assistive' software to access the Web. For example, people with visual impairments use screen readers, which translate the text in a web browser into audible speech. There are also people who are unable to use a mouse, and instead rely on their keyboard to access web pages. It's the responsibility of web designers to ensure that their websites are accessible for these different methods of browsing. There's no sense in alienating this group of web surfers just because your blog is inaccessible to them. There are also many other circumstances when your blog might be accessed by means other than a standard web browser, for example, via mobile phones, PDAs, or tablets. Again, a good designer will ensure that these modes of browsing are catered for. The web design industry has been well aware of these accessibility issues for many years and has come up with guidelines and technologies to help conscientious designers build websites that are standards compliant . These web standards help ensure best practice and maximize accessibility and usability. Luckily, WordPress takes care of a lot of the accessibility issues simply by the way it's been developed and built. The code behind WordPress is valid XHTML and CSS, which means that it complies with web standards and is easily accessible. It's important, then, that you don't break the system by allowing bad practice to creep in. Some of the things to bear in mind relate to a couple of design principles we've already discussed, for example, using a color scheme and font size that makes your text easy to read. Other issues include keeping the number of navigation links on your page to a minimum—a whole load of useless links can be annoying for people who have to tab through them to get to your main content. You should also ensure that any third-party plugins you install are standards-compliant and don't throw up any accessibility problems. The same is true if you decide to use a ready-made theme for your blog design. Just make sure it's accessible and satisfies web standards. For more background reading on web standards, you could take a look at http://www.alistapart.com or the World Wide Web Consortium (W3C) website at http://www.w3.org. Implementing your blog design We've now considered the principles involved in designing our blog. The next thing to decide is how we actually carry out the design work. There are three main options available, each of which involves varying degrees of work. However, they all require knowledge of the design principles we just covered. The first approach is probably the easiest; it simply involves finding a readymade theme and installing it in WordPress. By working through the earlier design principles, you should have an idea of what you want your blog to look like and then you simply need to find a theme that matches your vision as closely as possible. A good place to start looking is the official WordPress Free Themes Directory at http://wordpress.org/extend/themes/. You'll also find many more theme resources by running a search through Google. There are hundreds of very attractive WordPress themes available for free and many others which you can pay for. However, if you adopt this approach to your blog design, you won't have a unique or original blog. The chances are the theme you choose will also be seen on many other blogs. At the other end of the scale, in terms of workload, is designing your own theme from scratch. This is a fairly complicated and technical process, and is well beyond the scope of this article. In fact, it's a subject that requires its own book. If you intend to build your own theme, I recommend WordPress 2.8 Theme Design by Tessa Blakeley Silver ISBN 978-1-849510-08-0 published by Packt Publishing. The third approach is to modify a readymade theme. You could do this with any theme you choose, even the default Twenty Ten theme that ships with WordPress. However, if you edit a fully developed theme, you spend a lot of time unpicking someone else's design work and you may still be left with elements that are not completely your own. A better method is to start with a theme framework, which has been specially designed to be a blank canvas for your own design. Over the last few years many WordPress theme frameworks have appeared, some free, some paid-for. Two of the most popular paid-for theme frameworks are Thesis (http://diythemes.com/) and Genesis (http://www.studiopress.com/themes/genesis), while popular free frameworks include Hybrid (http://themehybrid.com/), Carrington (http://carringtontheme.com/), and Thematic (see below).
Read more
  • 0
  • 0
  • 2647

article-image-configuring-your-moodle-course
Packt
12 Dec 2011
7 min read
Save for later

Configuring your Moodle Course

Packt
12 Dec 2011
7 min read
(For more resources on Moodle, see here.) From curriculum to courses: What counts as a Moodle course Let's start this section with me describing the course I'm going to be converting to Moodle as we work together through this book. The course is called "Backyard Ballistics" and it's a science course that forms part of an applied physics qualification. The course is all about the art of firing weird objects through the air with chemicals and equipment that you will find in your average domestic kitchen and garden shed.   There are certain aspects of this course that I can't convert to Moodle. I want my students to get an appreciation of energy and dynamics by "doing" (kinesthetic learning) the science using everyday items you'll find around your house. But there is a good deal of support material, handouts, diagrams, and quizzes, that currently I try and distribute electronically using a "shared drive" on the college server. However, my students can never find the materials I tell them to go and look for. At least, that's their excuse. But I've got to admit that after a few years of use our shared drive is starting to look a bit of a mess. But where do I put these resources in Moodle? The answer is that you put them into a Moodle course. And here is a screenshot of just a fragment of a Moodle course: (Move the mouse over the image to enlarge.) I've divided my course into six topics: Getting Things Flying ‹ Lighter Than Air: Hydrogen Filled Balloons Fire Kites ‹ Basic Rocketry: The Match Rocket ‹ The World Famous Tennis Ball Mortar! ‹ Backyard Ballistics: End of Course Project The reason why I've chosen to convert Backyard Ballistics into topics is partly because that's how I teach it and partly because I am happy for the students to "dip into" the resources and activities I have converted to Moodle. Before we look at how we can get a course and start adding content to it we really need to understand what Moodle considers to be a course and how Moodle organizes them. What is a Moodle course You can clearly see now that, at its most basic, a Moodle course is a placeholder for resources and activities. Obviously it's much more than this, as you'll be learning as you work through this book. One obvious advantage Moodle has over a shared drive is that links to resources and activities can be interspersed with text and graphics to make the experience more visually appealing and engaging, and the resources I upload easy to find (I don't accept any excuses these days). How Moodle organizes its courses Let's take a quick look at how you can organize courses in Moodle. To help organize courses, Moodle has the idea of categories and subcategories: Remember that you'll only find resources and activities in a Moodle course. Categories and subcategories are only there to help you organize and manage the organization of courses. So how does that work in practice? For example, I work in the Physics department, part of the Faculty of Science. My Backyard Ballistics course supports the Applied Physics qualification. Here's how we've got our categories and subcategories arranged: I'm sure you could think of examples for your subject area. You could have a category called English that contained two subcategories, Literature and Language. Within literature you could have short courses on particular aspects of the set text you are teaching. You could have a category 20th Century History containing subcategories for Britain, Germany, France, Italy, and USA. Each country subcategory can contain further subcategories called Politics, Society, and so on. Because this is such a key issue when you first start using Moodle, let's spend a little time investigating the more common approaches taken when converting face-to-face teaching to Moodle. Breaking up is hard to do How you break up a face-to-face, traditionally taught course, depends on the age group and the subject area you are working in, so let's study some examples. Often younger children will have the same teacher for all of their subjects. Schools in this situation usually categorize Moodle courses based on year groups, and within the year group each teacher will have their own subcategory in which they are free to create and delete courses as they wish: Each teacher having their own Moodle course means it is much easier for the children to find the resources that have been uploaded and activities created for them. As the children get older you can start running different Moodle courses for different subjects depending on that child's age and ability. Now I could have a category for each year group, and within them categories for each subject area: Instead of a mathematics teacher having just one course they may instead have a course in Year 9, two in Year 10 and another one in Year 12. As the subject areas begin to broaden and the amount of material you need to get through increases, you might need to think about having Moodle courses for particular subject areas, especially those areas that students tend to struggle with. As students become older, things tend to become easier, because qualifications examined by external examination bodies will have their own syllabus. Read the syllabus carefully and you will often be able to see immediately how to break the subject down into Moodle courses. Mathematics, for example, naturally falls into categories, namely: ‹ Number ‹ Algebra Geometry (shape, space, and measure) ‹ Data handling and statistics Within each category there is then a natural divide between subject areas. See whether you can spot a similar pattern in your subject area. For students who are older still (that is, college or university age), subjects are most often taught in units anyway. A short 10-week unit, for example, is an ideal candidate for a Moodle course. To close this section, I will leave you with just a few more thoughts. One is that Moodle courses can also be created to develop a student's key skills. Examples of key skills could be: Communication ‹ Application of number ‹ Information and communication technology ‹ Problem solving ‹ Collaboration Another is that Moodle courses are not set in stone; once they are created they can be changed as you require. You will also see later in this book that responsibility for different aspects of your Moodle course can be delegated down to your students, enabling you all to work together developing your page. Have a go hero – developing key skills Try identifying courses that support developing one of the key skills. If key skills are a priority in your school or college, then no doubt you will have lots of skills-based teaching materials already to hand that you can convert into Moodle courses. If in doubt, hold a meeting In this section we've been investigating how we could break up traditionally taught, face-to- face courses and identifying what might be converted into Moodle courses. You can do this along traditional lines, or you can approach the problem by looking at key skills or learning styles. It is an extremely complicated issue and will undoubtedly involve discussions with your department colleagues. I strongly suggest you hold a Moodle meeting to discuss which courses are going to be created, initially. Use the opportunity to discuss who is going to teach them, and what categories they are going to ft into. Plan as much as you can before you start doing anything in Moodle. Remember to involve your Moodle administrator in those meetings, especially if they are the one responsible for creating your categories and courses. Now that we know what Moodle categories and courses we're going to need, we can focus on creating and running those courses. Let's get started: Setting up the course The remainder of the book will focus on just one course. If you're putting your whole department into Moodle then you'll have lots of courses to work through. That's why it's so useful to assign other teaching staff to course creation, and let them share the work. We'll show you how to do that too.
Read more
  • 0
  • 0
  • 2215
article-image-iphone-customizing-our-icon-navigation-bar-and-tab-bar
Packt
09 Dec 2011
7 min read
Save for later

iPhone: Customizing our Icon, Navigation Bar, and Tab Bar

Packt
09 Dec 2011
7 min read
  (For more resources on iPhone, see here.) The application icon and essential interaction elements such as the Navigation Bar and Tab Bar are crucial for the success of our work. The user will be tapping the icon every time they go to use our app, and interact with our navigation elements throughout their entire experience in our application. If we want success, we must focus on making these components attractive and functional. Attention to detail and the presentation of these pieces will be key, and we'll need to produce our best work if we want to stand out in a sea of apps. Designing an application icon and preparing it for the user home screen It's often said that a book shouldn't be judged by its cover, but the harsh reality of mobile development is that an app is often judged by its icon. This rounded rectangle will appear on the home screen of every user, and it's important that we create something that is attractive and also a good indication as to what the user should expect after downloading our application. In this recipe, we'll create a strategy for successful app icon design. Getting ready Adobe Photoshop will be our primary tool in the design of our app icon. It may also be helpful to grab some paper and a pencil so that we can sketch out any concepts we may have before we begin working on our computer. How to do it... The application icon is a primary component of any work. Appearing in the App Store, on a user's home screen, in Spotlight searches, and more, it's an important part of our job. Let's take a look at several steps that will be useful in the creation of our app icon: We should start by with either a rough sketch or Photoshop mockup of our intended design. We should create this mock up at several sizes to help represent the different resolutions at which our icon will be viewed. After we've developed an idea that we believe is going to scale well, its time to sit down in Photoshop or Illustrator and begin work on our icon. At this point, we need to determine what size canvas we want to design our icon on. Apple requires that our icon be available at a variety of sizes, with a 512 by 512 pixel square currently being the largest required format, but we should be prepared in case this requirement changes in the future and design our icon accordingly. There are two different ways we can go about making our icon "future proof". We can go about designing the icon in a vector format using an application like Adobe Illustrator. Vector drawings will always be the best way to ensure that our icon will scale to any size, but they can be a bit more difficult to create. If we're more comfortable using a raster image manipulation program like Photoshop, it's best to create our icon at a resolution well above what we'll ever need for the App Store, starting with a canvas of 4096 by 4096 pixels square or greater. Such a large raster size will give us a piece of art that will print comfortably on sizes as large as 13 inches when printed at 300 DPI, while also easily scaling down to whatever size we need for the App Store. Once we've decided which format we're most comfortable with, its time to go about creating our icon. Once we've completed our icon, it is time to prepare it for inclusion into our application. This icon should then be named apple-touch-icon.png and placed inside of our application bundle. iOS will then automatically add the glare effect to the top half of the icon, as seen throughout the interface. The Info.plist is a file that allows us to customize a bunch of different application attributes. We'll learn how to use it to remove the icon gloss effect in an upcoming recipe titled Removing the app icon's gloss effect. After finishing our icon, we may also want to run a small focus group, much like we would in order to gain feedback on our user interface design.We can quickly set up a simple website with a form asking for opinions on our design or even email an image of the icon to friends and family in order to facilitate feedback. When looking to gather opinion on our icon, we want to better understand a user's first impression of our icon. For a good portion of purchase decisions, the icon may be the only bit of insight into our app that the user has before tapping the buy button. We want to make sure that on first impression, the typical user associates our icon with quality, simplicity, and value. If our icon looks amateur, users probably won't consider our application for purchase. How it works... Icon design is tough, primarily because we're required to design a small square that represents our application's purpose, quality, and value. It's truly a challenge to design something that works well at 512 pixels and 27 pixels. Let's take a look at how the steps above work together to create a good icon. Resolution flexibility is arguably the difficult part of icon design, as our work needs to look great at 512 pixels by 512 pixels and at 27 by 27 pixels. Small details that look great at a high resolution can really make an icon indecipherable when scaled down to the lowest resolution required: In the above screenshot, we can quickly see how an icon becomes less legible as it decreases in size. It's necessary to provide the icon to Apple in several different sizes, which can vary depending upon the iOS device we're developing our application for and the current operating system requirements from Apple. These file sizes have varied significantly throughout the life of iOS, so we should verify the current requirements in the iOS Development Center before their creation. Sebastiaan De With keeps an excellent Photoshop file for iOS icon design, complete with resolution requirements, which he updates every time Apple changes the icon requirements. We can find the file here at http://blog.cocoia.com/2010/iphone-4-icon-psd-file/ and it should reference it while designing a new icon. When building our icon, we should really take time to think about what our icon should look like and what users will think when they first set eyes on it in the App Store. This set process works because it systematically creates a piece of work that will be optimized for the various needs of iOS. There's more... It may take a bit of practice to get a firm grasp on what makes a great or poor icon. Here are a few helpful ideas, just in case we're struggling to develop an icon that we're happy with. Dropping the text We should always refrain from including a great deal of text in our app icon. Text tends to become illegible when scaled down to small resolutions such as 27 x 27, so it is often best to keep text out of our icon. If we absolutely must include text in our icon, we should use short words that are large in size and in a bold typeface. Great gradients From an art design perspective, we'll probably be including an artistic gradient in our icon to offer the illusion of brushed metal or progressive lighting. But choosing a strong color palate for a gradient can be difficult. Dezigner Folio has created a large library of fresh, modern gradients that they've offered up for free use in any project. For the entire library, feel free to visit their website at http://www.dezinerfolio.com/2007/05/03/ultimate-web-20-gradients-v30-release. If all else fails.... If we're having a rough time with icon design and all else fails, we can always hire a freelance artist or design firm to help out with the production of our application icon. A quick search of Google can help us find a multitude of artists who have become specialists in the field of icon design. Finding a talented designer can actually be quite affordable, with many freelance artists charging a hundred dollars or less for a high quality icon. As icons can be produced in Photoshop, local graphic designers or students can help out at affordable rates as well.  
Read more
  • 0
  • 0
  • 2514

article-image-building-your-first-liferay-site
Packt
09 Dec 2011
10 min read
Save for later

Building your First Liferay Site

Packt
09 Dec 2011
10 min read
(For more resources on Liferay, see here.) Designing the site—Painting the full picture Whenever we get the requirements of the portal, we should first ask ourselves, how would the portal look when it goes live? This one small question will open a door to a lot of other questions and a lot of information which will be required to implement the portal. You should always think of the end state of the portal and then start painting the complete picture of the portal. This approach is known as Beginning with the end! Now, as we have just discussed the approach we should take while starting the site design, let's understand what all information we can retrieve or get when we ask this question to ourselves. We will discuss about four main components of the Liferay Portal design. Users No matter what the size of the portal is—small, medium, or large—it will always be designed for the users. Users are in the centre of any portal application. Let's think of a very common portal . Just imagine that you have to implement this portal. You are sitting in your nice comfy rocking chair and thinking of the users of this portal. What all questions would you ask yourself (or the client, if he/she is with you) about the users of this portal? Who will be using this portal? Will all the users of this portal have same privileges? Or some of the users will have more privileges than the others? Can we collect the users into any specific group? Are these users organized in any kind of hierarchy? Can the users leave or join this portal at a will? and so on. Let's discuss about the answers of the preceding questions and the information we can retrieve from the answers. If we want to provide an answer to the first question in only one word, then it can be—Users. It is quite obvious that the portal will be used by the users. However, if we go into the detail of this question we can get an answer like—all the employees of CNN, users from all over the world, John Walter who will be responsible for administration of the entire portal, and so on. So answer to this question will give us the information about all the players associated with the portal. If all the users of the portal have the same privileges, then it's pretty obvious that every user will be able to perform the same function in the portal. However, this may not be the case with our portal, http://www.cnn.com. Here, we have end users who will come to the portal and will access the information; we can also have a group of internal users who can create the content. Similarly, there can be a group who can approve the content and other group can publish the content; there can also be users who are responsible for user management and one or more users who are responsible for portal management. So this kind of question will give us the information about different roles and permissions associated with each role in our portal. It will also give us the information that which user should be associated with what kind of role. This information is very useful when we are working on the security piece of the portal. If the answer of the third question is Yes then we can either create a user group in our portal or group the users into a specific role. This question will give us the information about user grouping in the portal. Now, answer to the last two questions will be discussed in more detail in this article. However, these questions will help us to determine if we should use an organization or community or mix of both in our portal. Every Liferay portal must have at least one organization or community. Once we get the information about the users in our portal, we should think of the content next. Content No portal can exist without any kind of content. The content can be a static HTML, a static article, a video, an audio, podcast, document, image, and so on. To make the portal more effective, we have to manage the content properly. We will continue with our example of : What kind of questions can we ask to ourselves or to the client about the content? What are the types of the content we will use in the portal? Where are we going to store the content? To Liferay database or some other external database? Do we have to create the content from scratch? Do we need to migrate existing content to Liferay? And a few more… I am sure you must be visiting many portals every day. Can you think of the possible answers to the preceding questions? Also, think of the information which can be retrieved from those answers. The answer to the first question can be—document, images, web content, video, podcast, and so on. This answer will give us an idea about the content types which need to be implemented in the portal. Some of the contents like web content and documents can be available out of the box in Liferay; while other content types like video and podcast may not be available out of the box. This information will enable us to determine the types of content and effort required to create the new content. The second question is a bit tricky. By default, Liferay stores the content into database. However, if the client wants we can store the content in some shared location as well. For example, storing documents into file system. Also, it requires high availability. You can refer to wiki about this on . An answer to this question will give us information like if we need to add any additional hardware or not, if we should do any specific configuration to meet the requirements, and so on. Answers to third and fourth questions will be mainly used for the effort estimation purpose. If a portal like site is using a huge amount of content and all of the content has to be built from scratch then it may take a good amount of time. If the content is already available, we need to consider the effort of migrating and organizing the content. We can also think of other questions like requirement of workflow, type of the flow, if staging is required for the content or not, and so on. All of the preceding questions will give us a good picture about the content to be created or used in our portal. Once we are thorough with this section, it becomes easy to appoint someone to do content management design for your portal. Applications We have discussed about the user and the content of the portal. However, what about the applications which will be hosted on the portal? We cannot imagine a portal without any application nowadays. A portal can contain different applications like forum, wiki, blog, document viewer, video player, and so on. Let's get a list of questions which you should ask yourself while designing the portal: What are the different applications required for this portal? Do we have any application available out of the box in Liferay? Do we need to modify/extend any existing application available in Liferay? Do we have to create any new application for the portal? If yes, what is the complexity of this application? Liferay ships with more than 60 applications pre-bundled known as portlets. These applications are very commonly used in many of the portals. When we ask the preceding questions to ourselves, we get the following information: Number of applications required in the portal How many applications are available out of the box? If we have more applications available OOTB (out of the box) then it can reduce the development time Scope of the project. Do we need any integration with external system or not? Kind of applications we have to develop from scratch Once we go through the preceding set of questions, it becomes very easy to get a picture of the applications required in our portal. It will also provide us information about the efforts required to implement the portal. So, if you are managing a portal development project, you should definitely have this information ready before starting the project. Security Security is one of the most important aspects of any portal. When we think about security of any portal, we must consider access to the content and the applications on the portal. You must have come across many of the portals so far. Some of the portals allow you to create your account freely; some of the portals require an authorization before creating the account while some other portals don't allow creating an account at all. Also, there are some portals which display the same information to all the users while other portals display certain information to members only. To put this in a nutshell, each of the portal has its own security policy and it operates based on that policy only. Once we have discussed/thought about users, content, and application in portal design, we should consider the security aspect of the portal. Now, let's think of some of the questions which we should normally ask to ourselves/client while considering security aspect of the portal. Can everyone freely create an account with the portal? Do we need to migrate the users from an existing user base like LDAP? Can everyone access the same information or we need to display certain information to portal members only? Can all the members of the portal access all the applications with the same privileges or certain users have more privileges over other members? And so on… When we get answers to the preceding questions, we get following information about the portal security: If everyone can create an account with the portal, then in that case we need to provide the create account functionality to the users. Also, we don't need to do any authorization on account creation. If the answer to the first question is NO, then we need to either provide some kind of authorization on account creation or we need to remove the account creation facility completely If we have to migrate the users from an existing user base, then we have to think about the migration and integration. Liferay provides integration with LDAP. If the user base is not present, then we will end up creating all the accounts manually or provide users an ability to create their accounts If all the users (including non-logged in users) can access the same information then we will keep all the information on public pages but if we want certain information to be accessed by members only, then we might consider putting that information on the pages which can be accessed only after logging in If all the members of the portal can access the same information with same privileges then we will not need any special role in the portal. However, if a certain group or a set of users have more privileges over the other—like only content creators can create content—then we will have to create a role and provide the required permission to the role When we think of the security of the portal, we are thinking about users and their access, applications and access to those applications, and other security-related aspects of the portal. It is very important to think about the security before implementing the portal to prevent unauthorized and unauthenticated access to the portal and applications within the portal.
Read more
  • 0
  • 0
  • 2837

article-image-iphone-user-interface-starting-stopping-and-multitasking-applications
Packt
09 Dec 2011
16 min read
Save for later

iPhone User Interface: Starting, Stopping, and Multitasking Applications

Packt
09 Dec 2011
16 min read
  (For more resources on iPhone, see here.)   Starting the application with a proper Default.png When an application loads for the first time, the user is presented with a variable duration of loading time. This period can change depending on the device processor or RAM, memory requirements of the application, current free memory available on the device, and any number of other variables. Ideally, the user will only be required to sit through this period for a brief moment. However, this duration can last up to several seconds in length if we're loading an image intensive app on an older device. Apple has designed a loading screen method that is required by each app, through the inclusion of a PNG file in our app bundle. In this recipe, we'll discuss two interface strategies for this loading period. Getting ready For this recipe, we should have a computer with Photoshop or another image creation tool. We should also have knowledge of the devices and orientation types that our application will support. How to do it... Loading times are an inherent problem with all types of software, regardless of platform. As hardware has increased in speed, these times have diminished, but they haven't become non-existent. Apple created a simple design fix for this problem, offering up a quick and easy way to load an image during the loading period. Here are quick, simple steps in order to create an image that will display during the loading period: We should start by designing up an art image measuring either 320 x 480 pixels or 320 x 460 pixels (or the equivalent Retina display double resolution size), containing the art piece which we would like the user to see during the loading screen. Next, we should then save and name that file Default.png. Finally, we should include that image in the resource bundle of our application project in XCode. If we're creating a web application, we can also include the image in our HTML code so that the image is displayed when the user launches the web app. To do this, we should name our file startup.png and place the following code in our HTML header: <link rel="apple-touch-startup-image" href="/startup.png"> iOS is designed to search the bundle for a PNG with this name, and then display it on load if it's available. Once we finish these steps, we have accomplished everything we need to do to have the image load on startup. When it comes to design styles and technique on what we should include on the image, there are two different strategies that we can take: The right way Apple's documentation on the Default.png is fairly clear. According to their design documents, this image should serve as a clean visual of what the application would look like with no pre-populated data. In essence, this provides the perception that the application has already loaded, but the user is just waiting for the data to populate. It's a subtle way to trick the user into thinking our app loads quicker than it actually does. This trick works because it typically takes the brain about 2-4 seconds to see an image on screen, process the layout of what is before them, and then make a decision. Because the loading process for an application is relatively short, typically under three seconds, presenting an overlay of the interface as the Default.png loading image allows the brain to use this time to process what is about to be presented on screen. Phone - © 2007-2011 Apple Inc. As shown above, Phone, Messages, and Photos all load preview images with their Default.png displays, which offer the perception that the application loads very quickly. By preparing the user for the app during the Default.png load image period, the user will subconsciously perceive that our application loads faster than it actually does. The wrong, but possibly preferable way While we're supposed to use the loading image to prepare the user for our app, we may want this time to serve another purpose, such as a way to advertise our development team or Twitter account. It's an important and powerful moment for application branding, so we should feel free to use this moment as a way to build brand equity through use of a logo and appropriate styling. There is no set rule that says we can't use the Default.png as an advertisement of sorts, and many applications succeed using this strategy. We'll need to include a Default.png in the application package, to give our app something to display before loading has concluded. Depending on our application type and loading period, we should be able to include a screen that fits into one of these two methods with ease. How it works... Apple has designed iOS so that it is easy to present a loading screen to the user—we only need to create a PNG image, name it Default, and include it inside of our application bundle. The operating system will do the rest for us. Because this predetermined method works so well, we can instead focus on optimizing the image to best fit into our application. It's important to remember that the Default image is the first thing that the user will ever see in our app, and we should take considerable care in the creation of the art. Attention to detail with such seemingly minute application attributes is what sets outstanding applications apart. For some situations, creating an image that looks like similar to the first screen after launch will be ideal; as it will offer the perception that our application loads quicker than it actually does. This will increase user appreciation and enjoyment of our app. In other situations, it may be desirable to go with this splash screen approach instead of the prescribed approach of faking application load. For applications where loading takes a considerable period of time, usually anything over four seconds, it is difficult to use the load to ease users into our app like Apple does with Mail, Messages, or Phone. The pause becomes so long that the user instead believes that the application has broken. So in such situations, these banner loading Default.png images may provide a better alternative, offering up a way for the user to know that they have indeed loaded the correct application, but that it will still be several seconds before they're able to interact with the initial view. Regardless of what method we choose, it will be necessary to include a Default.png in with the project. With a bit of work and consideration, we can create something that will win the hearts of our user base. There's more... Now that we've learned more about different styles of Default images, we can put a bit of extra effort into going the extra mile with the image as well. Here are a few tips on how to produce a great Default.png. We can retina optimize our Default.png too Like any other art piece, we can include a Retina display specific graphic inside our application. By adding the standard @2x modifier to the end of the image, iOS will know to pull this image instead when running a higher resolution device. As the Default.png is the first image presented to the user, we should take extra effort to show that we're dedicated to a full retina optimized experience. Prepare for multiple orientations On the iPhone, we're limited to only one Default.png orientation requirement, as applications tend to be optimized for one orientation and we can create the Default image to account for the prominent orientation. However, on the iPad, each application should be designed for optimal use in either orientation. This requires us to create two Default images, one for the app launching in portrait and another for if the app launches in landscape. Apple has created an easy system for the simple creation of such different images. We only need to create the images and add a simple –Portrait or –Landscape modifier (for example, Default-Portrait.png) in order to launch the appropriate view.   Planning our application UI for a first impression In the real world, we spend a good deal of time preparing for first impressions. We tuck our shirts in, spend time making sure our hair looks perfect, and iron our shirts so that they're wrinkle free. We do this because it's a common understanding that others will greatly have their feelings toward us determined on the basis of how we look or talk during our first meeting. If we don't impress them off the bat, they'll never be willing to warm up to us. Mobile application development falls under the same sense of unspoken understanding. If our application isn't easy to manage or understand in the first 30 seconds, users will have no qualms over closing our work and deleting it off their device. Are the colors attractive? Is information easy to access? Do they seem to know what the correct next step is? These are all important questions that the user will subconsciously answer during their first several minutes inside our work. In this recipe, we'll discuss a couple of design decisions that we can make, in order to impress our users early. Getting ready Little is needed for this recipe. Ideally, the implementation of this recipe will take place throughout the course of development, as we fine tune along the way. How to do it... The Default.png image is the first visual that every user will see when they check out our app, but it isn't necessarily the first visual that their brain will take a good deal of time processing. That honor will fall on our actual application, once loaded in full glory for all eyes to behold. It's a somewhat magical moment, as our work is first presented to the audience. Like the opening line of a play, first chapter of a book, the front door to a house, the first few minutes of a game, this is an important moment in the user's determination of what they think about our app. So how do we present our application with its best foot forward? Here are a couple of simple tips, to help users quickly feel at home inside of our application: Use simple, clean In-App icons to help signify key features: When selecting icons to fall inside of Tab Bar cells or Navigation buttons, it's important to ensure that our icon use falls in line with expectations found in other applications. The magnifying glass represents search, a star presumes favorites or top performers, three dots represent that the tab contains multiple options, and a square with a pencil infers that the button composes a new email. Start by giving users a push in the right direction: Feel free to offer up a friendly push to the user from the get go. If we make the first step clear, the subsequent steps may become a bit more obvious, as shown in the following screenshot from Grades by Tapity: Grades - © Tapity Hold back sound, flashy animation, or bright colors until the user has had the chance to settle in. Offer content early, if only a little taste of what is to come. How it works... Creating an intuitive application interface from the first second a user opens our app is an art, which requires that we shape our app carefully overtime. As we add new features, create new art, or conceive new ways to present data on screen, we should always be thinking about what a new user will think upon first presentation of our app. For Step 1, Apple routinely updates the Mobile Human Interface Guidelines , https://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html, with suggestions on how to use icons that come built into the iOS SDK . These guidelines account for a limited quantity of icons and uses, which makes it a bit difficult to gain a good grasp of how we should truly utilize such pieces in our app. While it would be impossible to create an exhaustive list of general shapes and their associated meaning on iOS, the best we can do is make ourselves familiar with as many apps as we possibly can in order to best understand how others have paved the road of user expectations. In Step 2, we took a look at Grades by Jeremy Olsen. The application allows users to manage test scores and class grades, with an exceptional level of open-ended opportunity. No matter how complex or simple a class's grade scale may be, the application handles the data with ease. The application makes such scalability easy for the user by using a simple contextual clue on initial launch. By offering direction on how to start tracking information for a class, the user is essentially given a tutorial without even realizing that they're being taught. There is no confusion as to what the first step is, and the user can jump right in and start keeping track of their grades. For Step three, if we are in the mood, or feel as if it's necessary to make our application stand out through a good deal of noise, eccentric color, or excessive animation, that's perfectly fine. Each application has a different art strategy and depending on our target audience, these elements may very much make sense in our work. However, we should be hesitant to use such vivid visuals or loud sounds during the user's introduction to our app. While the user may be in our target audience and enjoy our app otherwise, such sudden extreme sense stimulation may be off-putting. Instead, we should slowly walk our users into the application and give them a chance to prepare for any noise or bright lights that we may throw their way. This way, the user is expecting whatever we decide to present. For example, if we offer loud noises right after the initial launch and our user is sitting in a quiet auditorium, the successive embarrassing situation may turn the user away from our application, just because we presented them with an unexpected bout of displeasure. By working the user into our loud, colorful, flashy application, we'll be less likely to scare away potential long-term users in the first five minute of using our app. With regards to Step 3, if our application is a content heavy application, such as a social network or application that features extensive listings of local sport scores, we may be inclined to encourage users to sign up for our service before we offer the meat and potatoes of our app. Most designers are confident that their content is so valuable, users will jump through whatever hoops necessary in order to gain access. However, the typical user is an impatient soul, unlikely to fill out forms in order to gain access to an app's walled garden. Instead they'll download our app, see the frictional barrier in front of the content, and decide that they're not that interested. By offering a quick glimpse, we hold some hope in convincing the user that our content is worth going through the sign up process. Service applications such as Instagram and Twitter do a great job at this, offering a handful of images or text entries before asking the user to sign up. These quick entries give an example of the wealth of content laying behind the apparent barrier of a sign up form. Through these quick previews, the user can gain an idea as to whether they'll enjoy the service or not. By using a preview method such as this, users are able to gauge interest before the sign up, saving everyone's valuable time. Finally, we know that every iOS device user is familiar with Apple's bundled applications, as they are the only applications that come pre-installed and as such, are the only applications that every user is likely to have used. We should look here for inspiration, as Apple offers a good deal of guidance with their work. When placing an icon on our Tab Bar, ask yourself if every user will instantly know the tabs function based on the imagery. If we have doubts, there is probably a better alternative icon. In many respects, this recipe isn't so much a one-time action like many others found throughout this book. Instead, it's a design philosophy which we will fine tune as we create more applications for the iPhone or iPad. There's more... Tutorials and help menus were a somewhat taboo topic during the early days of the App Store, with Apple holding a hard stance that apps requiring such a menu were too complex for the mobile platform. Times are changing a bit, with Apple themselves offering help menus in complex apps like Garageband or iMovie. Here's a tip on how to best offer support inside of our app. Lend a helping hand While most early apps were capable of success without a help menu, many new apps have become much more complex and require such a way to teach the user about app features. If we want to provide help for our users, we have two choices. One thing we could do is create a specific help view; we could do something like provide a table of topics that the user can tap upon in order to learn more about. This allows us to dive in-depth into a variety of topics, with as much detail as we feel is required. We could also provide a tutorial through on screen overlays, where tapping a help button presents short tips on screen with insight into different app features. This method works well because we can directly point at an interface element and tell the user what its purpose is. However, because we're overlaying such information on top of the interface, we must be brief when using this choice. Our app may be simple and self-explanatory enough, that we won't need one of these two methods in order to provide a help menu. However, if we think that we need to lend a hand, either of these two routes would work well.  
Read more
  • 0
  • 0
  • 2116
article-image-interface-designing-games-ios
Packt
09 Dec 2011
9 min read
Save for later

Interface Designing for Games in iOS

Packt
09 Dec 2011
9 min read
  (For more resources on iPhone, see here.) Users have few expectations as to what a typical mobile application should feel like, there is often an expectation with regards to what a game should play like. Mobile gaming platforms have been popular since the Game Boy's rise to popularity in the early 90s, and users have an idea as to what games work well when on the go, and iOS games are expected to match or exceed these preconceived notions of what is possible. However, it isn't necessarily easy to produce a game on iOS, as the device presents one of the first touch screen mobile gaming experiences. There isn't much precedent as to what game genres and control styles work well. This can be beneficial for innovation, but can also lead to a great deal of heartache for any designer.   Planning your game around touch Unlike traditional mobile gaming platforms, we won't have physical buttons and a set interface blueprint to serve as a guide for our game. Mobile platforms such as the Game Boy or PlayStation Portable have a physical control pad and buttons that lend the user to an inherent understanding of the game on screen. The user can quickly pick up and play a game, because they know that there is a finite set of buttons that can control game mechanics. We're in a bit of a more difficult-to-manage scenario with iOS, as there is no control pad or face button to commonly dictate interaction on screen when in a game. Since we're on a touch screen device, we can create any interaction mechanic that we'd like, no matter how unorthodox the interface may be. This offers up an extraordinary opportunity for new gameplay experiences; however it does make our design work a bit more difficult to construct. In this recipe, we'll discuss how touch screens drastically alter the design and playability of our game. Designing a game around touch is never an easy task. Controls are difficult to implement, screen size is often limited, and we'll need to innovate on top of standard game play mechanics to provide a fun experience. While the operating system is only a few years old, there has been a significant evolution in gaming on the platform. Early games, such as Super Monkey Ball by Sega, were often ports of previous console games by big name publishers. Apple's affordable developer program allowed independent developers to step in and experiment on the platform, pushing forward intuitive new experiences like Doodle Jump, Mr. AahH!!, and Zen Bound. In recent years, the market has matured so that both traditional franchises and independent creative ventures can succeed. Getting ready To work on this recipe, it would be useful to have an iOS device along with a traditional gaming console in order to contrast the difference in mechanics between the two machines. How to do it... Depending on the type of game we plan on developing, there are a variety of strategies for success on the iPhone or iPad. However there are a few key attributes that will make any iOS game enjoyable: Remember that users will be using the iPhone or iPad as both a screen and a controller. Don't punish users for accidental interactions with the screen. Keep in mind that these are mobile devices. While a good portion of our interface will vary greatly depending upon the type of game we're looking to create, these three rules are universal and will benefit any iPhone or iPad game. With these guidelines in mind, we can move on and begin to draft up our controls and heads up display. How it works... The low level of entry and unique touch controls have helped iOS evolve into a platform where designers can reach outside of their comfort zone in an effort to release an innovative game on the platform. In step one, it's important to understand that traditionally, users and designers are trained toward expecting games to have an external controller that is used for manipulation of the game world. The screen is a separate device; either a television or portable LCD screen serves as a way to project the game. However on iOS, the screen and controller are one. Regardless as to whether users interact with our game through buttons on screen or by using a device hardware feature such as the accelerometer, it is a guarantee that the iPhone or iPad will be held in a hand while our game is being played. We should always keep this in mind when designing both our game and interface, as the user will need to comfortably hold the device while playing. If we use traditional controls through a software joystick or buttons, we should place these elements on screen in a manner that allows for the iPhone or iPad to be held comfortably while playing. Depending upon our game and orientation, we may find that specific parts of the play area are perfect for the placement of such controls while in other scenarios, we may want to give the user the ability to customize the placement of buttons to their preference. If we expect the user to tilt or shake the controller to interact with our game, we should take this into consideration as well. While it may sound somewhat clichéd, the game and its controls are one and the same. There is no separation and any design that assumes that we can quickly implement controls without taking this fact into consideration is destined to fail. Not being given a set control pad or buttons gives us the flexibility to be creative, but poor design can quickly confuse or frustrate users. In the next screenshot, we can see that Flight Control developer Firemint has used small exclamation point markers to offer up a hint as to where inbound aircraft will soon appear. This offers a quick heads up to the user who may have had their hands in a poor position. Flight Control - © 2009 Firemint Pty Inc. We expand upon this new type of game control with these new devices in step two in the previous section. Because the game controller and device screen are so intertwined, it's very likely that the user will come into accidental contact with the screen at some point. It's just too difficult to eliminate unintended taps, as the finger is an imprecise pointing device. We can assume that the user will make unintentional contact with the screen, and so we should do our best to design a play mechanic and interface that will not punish users for their mistake. For example, if we're building a racing game, it would be silly to place the pause button near the button used for acceleration, as misplaced fingers could often pause the game and frustrate users. How we go about verifying this in our application can vary based on the type of game we're looking to design, but we should be mindful to keep this philosophy salient in our work. The limited ability to include a help menu in our application will encourage users to pick up app controls through point and tap experimentation. If the user experiences frustration in their first few minutes of using the app, they'll be likely to give up on using our app. Finally in step three, we should focus on creating an interface that is mobile. While we're designing with a device that is nearly as powerful as home gaming consoles, we must keep in mind that our users will be using their iPhone or iPad when on the run. They may be playing our game on a train, or in the car, or when walking between classes, so it's important to remember that this is a slightly different game platform than what we've ever developed for before. Because users will be playing our app when on the go and users will be less likely to sit down and play our game for extended periods of time, we should prepare our gameplay and interface around this probability. Big buttons and forgiving controls are the best way to go about designing for a mobile interface. Larger targets on screen will make it easier for the user to perform an intended action, even when walking or riding around. If we'd like to take mobile usability a bit further, we could also implement modifiable controls into our app as well. Giving the user the ability to calibrate settings will enable our game to play well, regardless as to the situation they're currently in. In the next screenshot, we can see how Doodle Jump allows users to adjust the game's controls: Doodle Jump - © 2011 Lima Sky, LLC It's also important to note that we should design our interface for the rapid entry and exit that is common of iPhone users. People will be playing our game on buses, while waiting in line at a store, and in other scenarios where their time spent inside of the app may be no longer than one to two minutes. This will affect game play drastically, so it's important to test such game scenarios while we build our app. Because our first iOS game may be our first touch screen based game, or our first game in general, we should be cautious and conservative with our interface and game play mechanics. That's not to say that the creation of any game is easy; however these are significant pitfalls that could plague our work if we're not careful. There's more... While rare, there is the possibility that our iPhone can be used as a controller for a device other than itself. Using the iPhone as a controller…for the iPad Thanks to the Bluetooth integration that Apple has included in new iPhone, iPod touch, and iPad devices, it is possible to use our iPhone as a controller for iPad games, so long as the developer has produced games for both platforms and supports the feature. It isn't necessarily easy to design and develop a game that includes such a feature, but it is by no means impossible. If we're working on an expansive game, it is definitely possible to create an immersive experience where the iPhone is used to control action on the iPad.  
Read more
  • 0
  • 0
  • 2829

article-image-article-html5-working-with-images-and-videos
Packt
02 Dec 2011
19 min read
Save for later

HTML5: Working with Images and Videos

Packt
02 Dec 2011
19 min read
(For more resources on this topic, see here.) Introduction This article focuses on yet another very exciting topic of the HTML5 canvas, images and videos. Along with providing basic functionality for positioning, sizing, and cropping images and videos, the HTML5 canvas API also allows us to access and modify the color and transparency of each pixel for both mediums. Let's get started! Drawing an image Let's jump right in by drawing a simple image. In this recipe, we'll learn how to load an image and draw it somewhere on the canvas. How to do it... Follow these steps to draw an image in the center of the canvas: Define the canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object, set the onload property to a function that draws the image, and then set the source of the image:     var imageObj = new Image();    imageObj.onload = function(){        var destX = canvas.width / 2 - this.width / 2;        var destY = canvas.height / 2 - this.height / 2;                context.drawImage(this, destX, destY);    };    imageObj.src = "jet_300x214.jpg";}; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... To draw an image, we first need to create an image object using new Image(). Notice that we've set the onload property of the image object before defining the source of the image. It's good practice to define what we want to do with the image when it loads before setting its source. Theoretically, if we were to define the source of the image before we define the onload property; the image could possibly load before the definition is complete (although, it's very unlikely). The key method in this recipe is the drawImage() method: context.drawImage(imageObj,destX,destY); Where imageObj is the image object, and destX and destY is where we want to position the image. There's more... In addition to defining an image position with destX and destY, we can also add two additional parameters, destWidth and destHeight to define the size of our image: context.drawImage(imageObj,destX,destY,destWidth,destHeight); For the most part, it's a good idea to stay away from resizing an image with the drawImage() method, simply because the quality of the scaled image will be noticeably reduced, similar to the result when we resize an image with the width and height properties of an HTML image element. If image quality is something you're concerned about (why on earth wouldn't you be?), it's usually best to work with thumbnail images alongside bigger images if you're creating an application that needs scaled images. If, on the other hand, your application dynamically shrinks and expands images, using the drawImage() method with destWidth and destHeight to scale images is a perfectly acceptable approach. Cropping an image In this recipe, we'll crop out a section of an image and then draw the result onto the canvas. How to do it... Follow these steps to crop out a section of an image and draw the result onto the canvas. Define the canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object, set the onload property to a function that crops the image, and then set the source of the image:     var imageObj = new Image();    imageObj.onload = function(){    // source rectangular area        var sourceX = 550;        var sourceY = 300;        var sourceWidth = 300;        var sourceHeight = 214;            // destination image size and position        var destWidth = sourceWidth;        var destHeight = sourceHeight;        var destX = canvas.width / 2 - destWidth / 2;        var destY = canvas.height / 2 - destHeight / 2;                context.drawImage(this, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);    };    imageObj.src = "jet_1000x714.jpg";}; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... In the last recipe, we discussed two different ways that we can use the drawImage() method to draw images on the canvas. In the first case, we can pass an image object and a position to simply draw an image at the given position. In the second case, we can pass an image object, a position, and a size to draw an image at the given position with the given size. Additionally, we can also add six more parameters to the drawImage() method if we wanted to crop an image: Context.drawImage(imageObj,sourceX,sourceY,sourceWidth, sourceHight, sourceHeight,sourceHeight, destX, destY, destWidth, destHeight); Take a look at the following diagram: As you can see, sourceX and sourceY refer to the top-left corner of the cropped region in the source image. sourceWidth and sourceHeight refer to the width and height of the cropped image from the source. destX and destY refer to the position of the cropped image on the canvas, and destWidth and destHeight refer to the width and height of the resulting cropped image. If you don't intend to scale a cropped image, then destWidth equals sourceWidth and destHeight equals sourceHeight. Copying and pasting sections of the canvas In this recipe, we'll cover yet another interesting usage of the drawImage() method—copying sections of the canvas. First, we'll draw a spade in the center of the canvas, then we'll copy the right side of the spade and then paste it to the left, and then we'll copy the left side of the spade and then paste it to the right. How to do it... Follow these steps to draw a spade in the center of the canvas and then copy-and-paste sections of the shape back onto the canvas: Define the canvas context: window.onload = function(){    // drawing canvas and context    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Draw a spade in the center of the canvas using the drawSpade() function:     // draw spade    var spadeX = canvas.width / 2;    var spadeY = 20;    var spadeWidth = 140;    var spadeHeight = 200;        // draw spade in center of canvas    drawSpade(context, spadeX, spadeY, spadeWidth, spadeHeight); Copy the right half of the spade and then paste it on the canvas to the left of the spade using the drawImage() method:     context.drawImage(    canvas,             spadeX,         // source x    spadeY,         // source y    spadeWidth / 2,     // source width    spadeHeight,       // source height    spadeX - spadeWidth,  // dest x    spadeY,         // dest y    spadeWidth / 2,     // dest width    spadeHeight        // dest height  ); Copy the left half of the spade and then paste it on the canvas to the right of the spade using the drawImage() method:     context.drawImage(    canvas,     spadeX - spadeWidth / 2,  // source x       spadeY,           // source y    spadeWidth / 2,       // source width    spadeHeight,         // source height    spadeX + spadeWidth / 2,   // dest x    spadeY,           // dest y    spadeWidth / 2,       // dest width    spadeHeight          // dest height  );}; Embed the canvas inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... To copy a section of the canvas, we can pass the canvas object to the drawImage() method instead of an image object: Context.drawImage(canvas,sourceX,sourceY,sourceWidth, sourceHight, sourceHeight,sourceHeight, destX, destY, destWidth, destHeight); As we'll see in the next recipe, not only can we copy sections of an image or a canvas with drawImage(), we can also copy sections of HTML5 video. Working with video Although the HTML5 canvas API doesn't provide a direct method for drawing videos on the canvas like it does for images, we can certainly work with videos by capturing frames from a hidden video tag and then copying them onto the canvas with a loop. Getting ready... Before we get started, let's talk about the supported HTML5 video formats for each browser. At the time of writing, the video format war continues to rage on, in which all of the major browsers—Chrome, Firefox, Opera, Safari, and IE—continue to drop and add support for different video formats. To make things worse, each time a major browser adds or drops support for a particular video format, developers have to once again re-formulate the minimal set of video formats that's required for their applications to work across all browsers. At the time of writing, the three major video formats are Ogg Theora, H.264, and WebM. For the video recipes in this article, we'll be using a combination of Ogg Theora and H.264. When working with video, it's strongly advised that you do a search online to see what the current status is for video support as it is a subject to change at any moment. There's more! Once you've decided which video formats to support, you'll probably need a video format converter to convert the video file that you have on hand to other video formats. One great option for converting video formats is the Miro Video Converter, which supports video format conversions for just about any video format including Ogg Theora, H.264, or WebM formats. Miro Video Converter is probably the most common video converter available at the time of writing, although you can certainly use any other video format converter of your liking. You can download Miro Video Converter from: http://www.mirovideoconverter.com/. How to do it... Follow these steps to draw a video onto the canvas: Create a cross-browser method that requests an animation frame: window.requestAnimFrame = (function(callback){    return window.requestAnimationFrame ||    window.webkitRequestAnimationFrame ||    window.mozRequestAnimationFrame ||    window.oRequestAnimationFrame ||    window.msRequestAnimationFrame ||    function(callback){        window.setTimeout(callback, 1000 / 60);    };})(); Define the drawFrame() function which copies the current video frame, pastes it onto the canvas using the drawImage() method, and then requests a new animation frame to draw the next frame: function drawFrame(context, video){    context.drawImage(video, 0, 0);    requestAnimFrame(function(){        drawFrame(context, video);    });} Define the canvas context, get the video tag, and draw the first video frame: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d");    var video = document.getElementById("myVideo");    drawFrame(context, video);}; Embed the canvas and the video tag inside the body of the HTML document: <video id="myVideo" autoplay="true" loop="true" style="display:none;">    <source src="BigBuckBunny_640x360.ogv" type="video/ogg"/><source src="BigBuckBunny_640x360.mp4" type="video/mp4"/></video><canvas id="myCanvas" width="600" height="360" style="border:1px solid black;"></canvas> How it works... To draw a video on an HTML5 canvas, we first need to embed a hidden video tag in the HTML document. In this recipe, and in future video recipes, I've used the Ogg Theora and H.264 (mp4) video formats. Next, when the page loads, we can use our cross-browser requestAnimFrame() method to capture the video frames as fast as the browser will allow and then draw them onto the canvas. Getting image data Now that we know how to draw images and videos, let's try accessing the image data to see what kind of properties we can play with. WARNING: This recipe must run on a web server due to security constraints with the getImageData() method. Getting ready... Before we get started working with image data, it's important that we cover canvas security and the RGBA color space. So why is canvas security important with respect to accessing image data? Simply put, in order to access image data, we need to use the getImateData() method of the canvas context which will throw a SECURITY_ERR exception if we try accessing image data from an image residing on a non-web server file system, or if we try accessing image data from an image on a different domain. In other words, if you're going to try out these demos for yourself, they won't work if your files reside on your local file system. You'll need to run the rest of the recipes in this article on a web server.Next, since pixel manipulation is all about altering the RGB values of pixels, we should probably cover the RGB color model and the RGBA color space while we're at it. RGB represents the red, green, and blue components of a pixel's color. Each component is an integer between 0 and 255, where 0 represents no color and 255 represents full color. RGB values are often times represented as follows: rgb(red,green,blue) Here are some common color values represented with the RGB color model: rgb(0,0,0) = blackrgb(255,255,255) = whitergb(255,0,0) = redrgb(0,255,0) = greenrgb(0,0,255) = bluergb(255,255,0) = yellowrgb(255,0,255) = magentargb(0,255,255) = cyan In addition to RGB, pixels can also have an alpha channel which refers to its opacity. An alpha channel of 0 is a fully transparent pixel, and an alpha channel of 255 is a fully opaque pixel. RGBA color space simply refers to the RGB color model (RGB) plus the alpha channel (A). Be careful not to confuse the alpha channel range of HTML5 canvas pixels, which are integers 0 to 255, and the alpha channel range of CSS colors, which are decimals 0.0 to 1.0. How to do it... Follow these steps to write out the image data properties of an image: Define a canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object, set the onload property to a function which draws the image:     var imageObj = new Image();    imageObj.onload = function(){        var sourceWidth = this.width;        var sourceHeight = this.height;        var destX = canvas.width / 2 - sourceWidth / 2;        var destY = canvas.height / 2 - sourceHeight / 2;        var sourceX = destX;        var sourceY = destY;            // draw image on canvas        context.drawImage(this, destX, destY); Get the image data, write out its properties, and then set the source of the image object outside of the onload definition:     // get image data from the rectangular area     // iof the canvas containing the image        var imageData = context.getImageData(sourceX, sourceY, sourceWidth, sourceHeight);        var data = imageData.data;        // write out the image data properties        var str = "width=" + imageData.width + ", height=" + imageData.height + ", data length=" + data.length;        context.font = "12pt Calibri";        context.fillText(str, 4, 14);    };    imageObj.src = "jet_300x214.jpg";}; Embed the canvas tag into the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... The idea behind this recipe is to draw an image, get its image data, and then write out the image data properties to the screen. As you can see from the preceding code, we can get the image data using the getImageData() method of the canvas context: context.getImageData(sourceX,sourceY,sourceWidth,sourceHeight); Notice that the getImageData() method only works with the canvas context and not the image object itself. As a result, in order to get image data, we must first draw an image onto the canvas and then use getImageData() method of the canvas context. The ImageData object contains three properties: width, height, and data. As you can see from the screenshot in the beginning of this recipe, our ImageData object contains a width property of 300, a height property of 214, and a data property which is an array of pixel information, which in this case has a length of 256,800 elements. The key to the ImageData object, in all honesty, is the data property. The data property contains the RGBA information for each pixel in our image. Since our image is made up of 300 * 214 = 64,200 pixels, the length of this array is 4 * 64,200 = 256,800 elements. Introduction to pixel manipulation: inverting image colors Now that we know how to access image data, including the RGBA for every pixel in an image or video, our next step is to explore the possibilities of pixel manipulation. In this recipe, we'll invert the colors of an image by inverting the color of each pixel. WARNING: This recipe must be run on a web server due to security constraints with the getImageData() method. How to do it... Follow these steps to invert the colors of an image: Define the canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object and set the onload property to a function that draws the image and gets the image data:     var imageObj = new Image();    imageObj.onload = function(){        var sourceWidth = this.width;        var sourceHeight = this.height;        var sourceX = canvas.width / 2 - sourceWidth / 2;        var sourceY = canvas.height / 2 - sourceHeight / 2;        var destX = sourceX;        var destY = sourceY;                context.drawImage(this, destX, destY);                var imageData = context.getImageData(sourceX, sourceY, sourceWidth, sourceHeight);        var data = imageData.data; Loop through all of the pixels in the image and invert the colors:         for (var i = 0; i < data.length; i += 4) {            data[i] = 255 - data[i]; // red            data[i + 1] = 255 - data[i + 1]; // green            data[i + 2] = 255 - data[i + 2]; // blue            // i+3 is alpha (the fourth element)        } Overwrite the original image with the manipulated image, and then set the source of the image outside of the onload definition:         // overwrite original image with        // new image data        context.putImageData(imageData, destX, destY);    };    imageObj.src = "jet_300x214.jpg";}; Embed the canvas tag into the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... To invert the color of an image using HTML5 canvas, we can simply loop through all of the pixels in an image and then invert each pixel using a color inverting algorithm. Don't worry it's easier than it sounds. To invert a pixel's color, we can invert each of its RGB components by subtracting each value from 255 as follows: data[i  ] = 255 - data[i  ]; // reddata[i+1] = 255 - data[i+1]; // greendata[i+2] = 255 - data[i+2]; // blue Once the pixels have been updated, we can redraw the image using the putImageData() method of the canvas context: context.putImageData(imageData, destX, destY);  This method basically allows us to draw an image using image data instead of a source image with the drawImage() method.
Read more
  • 0
  • 0
  • 1939
Modal Close icon
Modal Close icon