DevExtreme Angular - Built-in Layouts
In most cases, you do not have to define layouts yourself. The framework comes with a set of predefined layouts. You can find them in the DevExtreme zip archive or in the folder where you have installed DevExtreme, which is C:\Program Files (x86)\DevExpress 17.2\DevExtreme\Sources\Lib\layouts by default. A folder with layouts is added to the project template as well. So you don't have to add them manually.
As you can see in the layouts folder, each layout is represented by a set of three files.
- .html
Includes HTML layout templates for different devices. - .css
Includes CSS rules specific for different devices. - .js
Contains a layout controller that shows a view using the layout template that is appropriate for the device on which the application is running.
Before using predefined layouts, find out which content placeholders and command containers are available in their device-specific versions. This information will be required when defining views and mapping the commands that are added to these views.
Below you will find details about each of the predefined layouts. In addition, you will learn how to use layout sets to specify which layouts should be used in your application and when.
Navbar Layout
The Navbar layout is available for all platforms supported by the framework. This layout is characterized by the presence of a navigation control on a view. The navigation control is global navigation that provides access to the root views of the application.
iOS
Links:
<link rel="dx-template" type="text/html" href="layouts/NavBar/NavbarLayout.html" /> <script type="text/javascript" src="layouts/NavBar/NavbarLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/NavBar/NavbarLayout.css" />
Android
Links:
<link rel="dx-template" type="text/html" href="layouts/NavBar/NavbarLayout.html" /> <script type="text/javascript" src="layouts/NavBar/NavbarLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/NavBar/NavbarLayout.css" />
Windows Phone
Links:
<link rel="dx-template" type="text/html" href="layouts/NavBar/NavbarLayout.html" /> <script type="text/javascript" src="layouts/NavBar/NavbarLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/NavBar/NavbarLayout.css" /> <link rel="stylesheet" type="text/css" href="layouts/Pivot/PivotLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Pivot/PivotLayout.html"/> <script type="text/javascript" src="layouts/Pivot/PivotLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html"/> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script>
Generic
Links:
<link rel="dx-template" type="text/html" href="layouts/NavBar/NavbarLayout.html" /> <script type="text/javascript" src="layouts/NavBar/NavbarLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/NavBar/NavbarLayout.css" />
Pivot Layout
The Pivot layout is available for Windows Phone 8 applications. This layout is characterized by the presence of a pivot control on a view. The pivot control is a global navigation that provides access to the root views of the application.
Links:
<link rel="dx-template" type="text/html" href="layouts/Pivot/PivotLayout.html" /> <script type="text/javascript" src="layouts/Pivot/PivotLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Pivot/PivotLayout.css" />
SlideOut Layout
The SlideOut layout is available for all the platforms supported by the framework. This layout is characterized by its slide-out menu that is hidden behind the main screen. This menu can be revealed by a click on the top left corner menu icon. The slide-out menu represents a global navigation that provides access to the root views of the application.
iOS
Links:
<link rel="dx-template" type="text/html" href="layouts/SlideOut/SlideOutLayout.html" /> <script type="text/javascript" src="layouts/SlideOut/SlideOutLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/SlideOut/SlideOutLayout.css" />
Android
Links:
<link rel="dx-template" type="text/html" href="layouts/SlideOut/SlideOutLayout.html" /> <script type="text/javascript" src="layouts/SlideOut/SlideOutLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/SlideOut/SlideOutLayout.css" />
Windows Phone 8
Links:
<link rel="dx-template" type="text/html" href="layouts/SlideOut/SlideOutLayout.html" /> <script type="text/javascript" src="layouts/SlideOut/SlideOutLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/SlideOut/SlideOutLayout.css" />
Generic
Links:
<link rel="dx-template" type="text/html" href="layouts/SlideOut/SlideOutLayout.html" /> <script type="text/javascript" src="layouts/SlideOut/SlideOutLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/SlideOut/SlideOutLayout.css" />
Split Layout
The Split layout is designed for Windows, iOS and Android tablet applications to effectively organize space on a screen. In this layout, there are two panes - a "master" pane and a "detail" pane. A "master" pane usually presents a list of items. A "detail" pane presents detail information on the item selected in the "master" pane. The type of the layout controller and the layout markup to be used for each pane are determined in a root Split layout controller. The IOSSplitLayoutController that is used in iOS apps applies the Simple layout for both panes. The AndroidSplitLayoutController that is used in Android apps and Win8SplitLayoutController that is used in Windows apps apply the Empty layout for both panes.
When defining views, specify the pane in which a view will be displayed in the Split layout by using the pane option of the corresponding dxView markup component. In addition, denote the layout placeholder in which the view will be displayed within the pane. The Simple and Empty layouts that are used in split layout panes provide the 'content' placeholder. So, put the view's markup within this placeholder. For details on how to do this, refer to the Insert View into Layout topic.
iOS
Links:
<link rel="dx-template" type="text/html" href="layouts/Split/SplitLayout.html" /> <script type="text/javascript" src="layouts/Split/SplitLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Split/SplitLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html" /> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" />
Android
Links:
<link rel="dx-template" type="text/html" href="layouts/Split/SplitLayout.html" /> <script type="text/javascript" src="layouts/Split/SplitLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Split/SplitLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Empty/EmptyLayout.html" /> <script type="text/javascript" src="layouts/Empty/EmptyLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Empty/EmptyLayout.css" />
Windows Phone
Links:
<link rel="dx-template" type="text/html" href="layouts/Split/SplitLayout.html" /> <script type="text/javascript" src="layouts/Split/SplitLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Split/SplitLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Empty/EmptyLayout.html" /> <script type="text/javascript" src="layouts/Empty/EmptyLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Empty/EmptyLayout.css" />
Customize Split Layout
You can replace layouts used in panes with other ones. For this purpose, you will have to specify a custom layout set where you will create the IOSSplitLayoutController, AndroidSplitLayoutController or/and Win8SplitLayoutController controller(s) passing an object with a specified panesConfig field as a parameter.
window.MyApp = {}; $(function() { MyApp.app = new DevExpress.framework.html.HtmlApplication({ layoutSet:[ { platform: 'android', controller: new IOSSplitLayoutController() }, { platform: 'ios', controller: new IOSSplitLayoutController({paneConfig: { content: { controller: new DX.framework.html.NavBarController(), selector: ".master-pane" }, detail: { controller: new DX.framework.html.SimpleLayoutController(), selector: ".detail-pane" } }) }, { platform: 'win8', phone: false, controller: new Win8SplitLayoutController() } ], namespace: MyApp }); });
Show Blank View in a Detail Pane
Views shown in a "detail" pane may be accompanied by commands. After executing these commands, navigation to a view may be required. For instance, a particular view should be shown instead of the detail view of the object that has just been removed via a "Delete" command. In phone applications, the "Delete" command executed in a detail view usually returns to a list view (a previous view). In a tablet application, a list view remains displayed in the "master" pane when performing manipulations in the "detail" pane. Thus, it is recommended that you navigate to a blank view in the "detail" pane in such scenarios. The "Blank" view is available within the application project template that comes with DevExtreme. You can use this view as is.
handleDelete: function() { //If an object is removed if(viewInfo.canBack) { AppNamespace.app.back(); } else { AppNamespace.app.navigate("Blank", { target: "current" }); } // },
Save the State of Slitted Views
When refreshing an application page in a browser, the application is recreated and the views that were displayed before the refresh should be displayed again. If you are going to run a Split layout application in a browser, implement the saving and restoring of the application's state. For this purpose, add the Split layout's controller to the state sources collection of the application's state manager. To do this, access the state manager using the stateManager field of the HtmlApplication object and call the addStateSource(stateSource) method passing the Split layout controller as a parameter.
window.MyApp = window.MyApp || {}; $(function() { MyApp.app = new DevExpress.framework.html.HtmlApplication({ namespace: MyApp, layoutSet: DevExpress.framework.html.layoutSets['split'], //... }); MyApp.app.stateManager.addStateSource(DevExpress.framework.html.layoutSets["split"].controller); //... });
The Split layout controller can be treated as a state source because it has the methods that are required by the state manager to save/restore/remove the application state.
To save the state of the Split layout application when the application page is refreshed, call the saveState method of the HtmlApplication object on the window's unload event.
$(window).unload(function() { MyApp.app.saveState(); });
The saveState method will call the saveState method of the application's state manager. The latter will send a request to save the state to all the registered state sources, and to the Split layout controller in particular.
The saved state will be automatically restored by the framework when recreating the application.
Simple Layout
The Simple layout is available for all the platforms supported by the framework. This layout is characterized by the absence of a navigation control on the view. Thus, it is normally used for the views that are invoked to present specific data, perform particular actions and return back to the previous view or pass to the next context view.
iOS
Links:
<link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html" /> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" />
Android
Links:
<link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html" /> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" />
Windows Phone 8
Links:
<link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html" /> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" />
Generic
Links:
<link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html" /> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" />
Popup Layout
The Popup Layout is available for all the platforms supported by the framework. This layout is used to show modal views in a popup window.
The Popup Layout uses the Popup widget to display a view in a popup window. The content of the popup window is managed by a specified layout controller. By default, the SimpleLayoutController is used for the popup window. This means that when defining a modal view, find out which content placeholders and command containers are available in the Simple Layout.
Links:
<link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html" /> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Popup/PopupLayout.html" /> <script type="text/javascript" src="layouts/Popup/PopupLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Popup/PopupLayout.css" />
Customize Popup Layout Content
You can replace the layout that is used in the popup window with another one. For this purpose, you will have to specify a custom layout set where you will create the PopupLayoutController controller passing an object with a specified childController field as a parameter.
Empty Layout
The Empty layout includes a single 'content' content placeholder on any platform.
Links:
<link rel="dx-template" type="text/html" href="layouts/Empty/EmptyLayout.html" /> <script type="text/javascript" src="layouts/Empty/EmptyLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Empty/EmptyLayout.css" />
Desktop Layout
The Desktop layout is available for the 'generic' platform only. This platform is set when the application is running in a desktop, or the current platform is not known to the framework. You can also set the 'generic' platform manually to make the application look like a web site.
The Desktop layout is characterized by the presence of a navigation control on a view. The navigation control is a global navigation that provides access to the root views of the application. In addition, there is a toolbar on the view, which you can use to add custom actions.
Links:
<link rel="dx-template" type="text/html" href="layouts/Desktop/DesktopLayout.html" /> <script type="text/javascript" src="layouts/Desktop/DesktopLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Desktop/DesktopLayout.css" />
Default Command Mapping
Built-in layouts come with default command mapping. This means that if you use particular identifiers for your commands, these commands are automatically added to the command containers of the predefined layouts. The following table details a command location on a toolbar representing a command container according default command mapping.
Command Container | Before | Center | After | Menu |
---|---|---|---|---|
ios-header-toolbar | "back" "cancel" |
"edit" "save" "create" |
||
ios-view-footer | "delete" | |||
android-header-toolbar | "back" | "edit" "save" "create" |
"cancel" "delete" |
|
android-footer-toolbar | "edit" "save" |
"create" | "delete" | |
android-simple-toolbar | "back" "save" |
"create" | "edit" "cancel" "delete" |
|
generic-header-toolbar | "back" "cancel" |
"edit" "save" "create" |
||
generic-view-footer | "delete" | |||
win8-appbar | "create" | "edit" "cancel" "save" "delete" |
||
win8-toolbar | "previousPage" | |||
win8-phone-appbar | "create" "edit" "cancel" "save" |
"delete" |
Customize Layout CSS
Layout CSS includes classes from the DevExtreme themes. You can customize the classes for any of the DevExtreme themes using the DevExtreme Theme Builder.
For details, refer to the Theme Builder article.
Ready-to-Use Layout Sets
In non-basic applications, different layouts can be used for different views. For example, Android apps have a navbar on root views only. So to implement such an application, you will have to use a Navbar layout for root views and a Simple layout for child views. To save you time, the framework comes with ready-to-use layout sets.
navbar
Different layout sets are used for different platforms.- iOS
All views are displayed in the Navbar layout. - Android
Root views are displayed in the Navbar layout. Other views are displayed in the Simple layout. - Windows Phone 8
Root views are displayed in the Pivot layout. Other views are displayed in the Simple layout. - generic
All views are displayed in the Navbar layout.
- iOS
slideOut
All views are displayed in the Slideout layout on all platforms.split
Designed to be used on Windows Phone, iOS and Android tablet devices.- Windows Phone
Root views are displayed in the Navbar layout. Other views are displayed in the Split layout. - iOS and Android
All views are displayed in the Split layout. It is recommended, that the first navigated view in an application includes global navigation. For this purpose, implement a 'navigation' view with a widget(s) that will allow you to navigate to the application's root views.
- Windows Phone
simple
All views are displayed in the Simple layout on all platforms.
These layout sets are available from the DevExpress.framework.html.layoutSets object. To get a particular layout set, use one of the following approaches.
DevExpress.framework.html.layoutSets['navbar']
DevExpress.framework.html.layoutSets.navbar
To specify the layout set that you are going to use in your application, use the layoutSet configuration option of your HtmlApplication object.
window.MyApp = {}; $(function() { MyApp.app = new DevExpress.framework.html.HtmlApplication({ namespace: MyApp, layoutSet: DevExpress.framework.html.layoutSets['navbar'], //... }); });
Ensure that the layouts that are demanded by the specified layout set are linked in the application page.
<!-- Layouts --> <script type="text/javascript" src="layouts/NavBar/NavbarLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/NavBar/NavbarLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/NavBar/NavbarLayout.html"/> <script type="text/javascript" src="layouts/Pivot/PivotLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Pivot/PivotLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Pivot/PivotLayout.html"/> <script type="text/javascript" src="layouts/Simple/SimpleLayout.js"></script> <link rel="stylesheet" type="text/css" href="layouts/Simple/SimpleLayout.css" /> <link rel="dx-template" type="text/html" href="layouts/Simple/SimpleLayout.html"/>
Global Navigation Items
All the predefined layout sets, except for Simple, utilize the layouts that include a widget that implements global navigation. This widget provides access to the main views of the application - the root views. To specify which views must be accessible from global navigation, use the navigation configuration option of the HtmlApplication object.
window.MyApp = {}; $(function() { MyApp.app = new DevExpress.framework.html.HtmlApplication({ namespace: MyApp, layoutSet: DevExpress.framework.html.layoutSets['navbar'], navigation: [ { title: "Home", onExecute: "#home", icon: "home" }, { title: "About", onExecute: "#about", icon: "info" } ], //... }); });
When navigating to a view, the target URI is compared with the URI provided by the onExecute option of each global navigation command. If there is a command whose URI coincides with the navigated URI, the corresponding item of the widget that implements global navigation (navbar item, slide-out menu item or pivot item) is selected automatically.
There can be scenarios, when you have to select a certain navigation item manually in code. For instance, there is a navigation item with the view1 URI. When navigating to the view1 using the view1/1 URI, this navigation item will not be selected, because its URI does not coincide with the navigated URI. To select it, do the following.
Set the id option for the required navigation commands.
JavaScriptnavigation: [ { id: "view1" title: "View1", onExecute: "#view1" }, { id: "view2" title: "View2", onExecute: "#view2" } ],
Set the currentNavigationItemId field to the corresponding command id within the required ViewModels.
JavaScriptMyApp.view1 = function (params) { var viewModel = { currentNavigationItemId = "view1" }; return viewModel; };
Custom Layout Sets
If the predefined layout sets do not address your task at hand, introduce a custom layout set.
A custom layout set is an array of objects that define which layout controller should be used and when. Here is an example.
window.MyApp = {}; $(function() { MyApp.app = new DevExpress.framework.html.HtmlApplication({ layoutSet:[ { platform: 'android', controller: new MyAndroidLayoutController() }, { platform: 'ios', controller: new MyiOSLayoutController() } ], namespace: MyApp }); });
The object defining a layout within a layout set should expose the following fields.
- controller
Specifies an instance of a layout controller. - root
Indicates whether or not the view to which the application navigates must be a root view (the view that is available from global navigation). - customResolveRequired
Indicates whether or not the specified layout controller must be excluded when choosing the most appropriate controller for a view. When you set this field to true, it is implied that you will set it for views manually in a custom context. For this purpose, use the resolveLayoutController event (read below). - modal
Indicates whether or not the specified layout controller must be used to manage a modal view display. - Any field of the device object.
Specifies in which device the layout can be used.
In very specific cases, when the fields listed above do not allow you to define a context for using a layout, handle the application's resolveLayoutController event. The viewInfo field of the object passed as the event handler's parameter provides you access to information on the currently displayed view. Set the layout controller that should be used for this view using the layoutController field of the object passed as the parameter.
window.AppNamespace = {}; $(function () { AppNamespace.myController = new myLayoutController({ layoutTemplateName: "myLayout" }); AppNamespace.app = new DevExpress.framework.html.HtmlApplication( { namespace: AppNamespace, layoutSet: [ { platform: 'android', controller: new MyAndroidLayoutController() }, { platform: 'ios', controller: new MyiOSLayoutController() }, { customResolveRequired: true, controller: AppNamespace.myController } ], //... } ); AppNamespace.app.router.register(":view/:name", { view: "home", name: '' }); AppNamespace.app.on("resolveLayoutController", function(args) { var viewName = args.viewInfo.viewName; if(viewName === "about") { args.layoutController = AppNamespace.myController; } }); AppNamespace.app.navigate(); });
You can assign a combination of several predefined layout sets to the application's layoutSet option. In this instance, handle the application's resolveLayoutController event to specify the contexts in which the layout controllers from the combined layout sets must be applied.
function findController(name, controllers) { var result = $.grep(controllers, function (item, index) { return item.controller.name == name; }); return result.length ? result[0].controller : null; } window.AppNamespace = {}; $(function() { var layoutSet = []; layoutSet.push.apply(layoutSet, DevExpress.framework.html.layoutSets["navbar"]); layoutSet.push.apply(layoutSet, DevExpress.framework.html.layoutSets["empty"]); AppNamespace.app = new DevExpress.framework.html.HtmlApplication({ namespace: AppNamespace, layoutSet: layoutSet, //... }); AppNamespace.app.router.register(":view/:id", { view: "home", id: undefined }); AppNamespace.app.on("resolveLayoutController", function (args) { if (args.viewInfo.viewName == 'home') { args.layoutController = findController('empty', args.availableLayoutControllers); } }); AppNamespace.app.navigate(); });
As you can see in the code above, you can use the application's collection of available controllers when deciding which layout controller to use for the currently displayed view. This collection includes objects from the application's layout set. But not all the objects - just the ones that can be used for the current device (its platform and type). To access this collection, use the availableLayoutControllers field of the object passed as the resolveLayoutController event handler parameter. To find the required controller within the availableLayoutControllers collection, use the layout controller's name field.
If you have technical questions, please create a support ticket in the DevExpress Support Center.