When developing applications that will run on mobile devices, you should keep in mind that their screens are small and that they have no real keyboard. The good news is that Wijmo was designed to run really well on mobile devices, so if you develop a Wijmo application for the desktop, it will run just fine on mobile devices. You will get the touch support, inertial scrolling, zooming, and all the features that make mobile devices so popular and easy to use. But the small screen size may affect your application’s usability. Consider for example this simple application:
<body>
<div>
<div id="theGrid"></div>
</div>
</body>
window.onload = function () {
// create the grid
var grid = new wijmo.grid.FlexGrid('#theGrid', {
autoGenerateColumns: false,
headersVisibility: wijmo.grid.HeadersVisibility.Column,
columns: [
{ header: "Company Name", binding: "CompanyName", width: "20*" },
{ header: "Contact Name", binding: "ContactName", width: "15*" },
{ header: "Contact Title", binding: "ContactTitle", width: "20*" },
{ header: "Address", binding: "Address", width: "20*" },
{ header: "City", binding: "City", width: "10*" },
{ header: "Country", binding: "Country", width: "15*" }
],
});
// get some data
wijmo.httpRequest('http://…/Customers?$format=json', {
success: function (xhr) {
var response = JSON.parse(xhr.responseText);
grid.itemsSource = response.value;
}
});
}
This application will run just fine. It will show a grid with several columns that you can scroll, sort on, edit, etc. Because the columns use the “star-sizing” feature, the grid will even adapt to different layouts as you resize the browser or flip your mobile device between portrait and landscape. The images below show the effect of star-sizing: notice how the columns resize proportionally as the screen size changes: As you can see, all columns remain visible when the grid is resized. But the content may be truncated and hard to read. You could address this by disabling the star-sizing, but then some important fields might be rendered off-screen and users would have to scroll horizontally to see their content. That would be functional, but not very user-friendly. A simple way to address this would be to handle the window’s “resize” event, compute the grid’s width, and change the columns collection depending on screen size. For example, you could design a special “summary” column that shows all the essential information for an item in a single cell, and show or hide that column depending on the grid’s current width. Here is some code that does that: First, we add our new “summary” column to the grid:
// create the grid
var grid = new wijmo.grid.FlexGrid('#theGrid', {
autoGenerateColumns: false,
headersVisibility: wijmo.grid.HeadersVisibility.Column,
columns: [
{ header: "Company", allowDragging: false, visible: false, width: "*" },
{ header: "Company Name", binding: "CompanyName", width: "20*" },
{ header: "Contact Name", binding: "ContactName", width: "15*" },
{ header: "Contact Title", binding: "ContactTitle", width: "20*" },
{ header: "Address", binding: "Address", width: "20*" },
{ header: "City", binding: "City", width: "10*" },
{ header: "Country", binding: "Country", width: "15*" }
],
});
The summary column starts invisible, and we set its “allowDragging” property to false to ensure it will always be the first column on the grid. Next, we make the grid responsive by adding a handler to the window’s “resize” event:
// store default row height
var rowHeight = grid.rows.defaultSize;
// make the grid responsive
grid.addEventListener(window, 'resize', updateLayout);
function updateLayout () {
// show/hide colummns
var phone = grid.hostElement.offsetWidth < 600,
cols = grid.columns;
for (var i = 0; i < cols.length; i++) {
grid.columns[i].visible = (i == 0 ? phone : !phone);
}
// make rows taller on phone layout
grid.rows.defaultSize = phone ? rowHeight * 3 : rowHeight;
}
This code does two things:
- It changes the visibility of the columns based on the control’s current width (anything narrower than 600 pixels is assumed to be a phone), and
- It changes the default row height to accommodate the detail cells, which are taller than regular cells.
Finally, we use the grid’s “formatItem” event to provide the content for the “summary” column:
// show company summary on phone layout
grid.formatItem.addHandler(function (s, e) {
if (e.panel == grid.cells && e.col == 0) {
var html = wijmo.format(
'<div class="item-header">{CompanyName}</div>' +
'<div class="item-detail">{ContactName}, {ContactTitle}</div>' +
'<div>{Address}, {City}, {Country}</div>',
grid.rows[e.row].dataItem);
e.cell.innerHTML = html;
}
});
The “formatItem” event can be used to add any content to any grid cell. In this case, we use Wijmo’s “format” method to create an HTML string containing a summary of the company’s information, all in a single cell. The code adds class identifiers to the elements in the detail cells so they can be styled. This is done with the following CSS rules:
/* format detail cells */
.item-header {
font-weight: bold;
font-size: 150%;
}
.item-detail {
margin-left: 12px;
}
When you run this updated version of the app on a mobile device, the grid will automatically switch between the original and summary views when you flip the device between portrait and landscape modes: When the screen becomes narrower, the grid automatically switches to summary view, where users can see all the information about each item in a single cell. No horizontal scrolling is required, and the application becomes really similar to typical native apps. Users can scroll the list with swiping gestures, and they will get the great inertial scrolling they expect. You can see this application live, and experiment with it here: http://jsfiddle.net/Wijmo5/rz7h0cLg/ This is a good example of the flexibility provided by the FlexGrid’s object model. Turning a regular grid into a responsive one took about 20 lines of code, and the solution is very flexible. It not only changes the layout of the columns, but also the default row height and the overall appearance of the grid.