The purpose of this tutorial is to show in step-by-step manner the easy way of building complex interface for AJAX based application with the help of DHTMLX library. This tutorial contains main stream - which describes the process of building Windows like file explorer and some includes (marked with orange border) which describes more complex functionality or provides more details about some things which don't relate to File Explorer development.
This tutorial is actual for dhtmlxSuite 2008 Rel.3 (initial release of dhtmlx 2.0). Further versions of dhtmlx components can contain some extra functionality which is not described here. Or some functionality can be used in some more convenient way.
Files related to this tutorial can be downloaded here: dhtmlx20_tutorial.zip
Any front end of AJAX based application is HTML page. So, let's create a simple HTML page:
<html> <head> <title>AJAX Application</title> </head> <body> </body> </html>
For further steps we'll use DHTMLX files concatenated with libCompiler, which is delivered within dhtmlxSuite and provides the possibility to unite all necessary components, functionality and appearance in single script file and single folder of necessary images.
If you do not have PHP on the server where you inflated dhtmlxSuite archive to, then you can just choose from the presets which already exists in the package (see directory “presets” in the root of the package). To get all available possibilities, just get preset “full”. If you have PHP and you do want to create your own set of components and functionality, then brows to libCompiler/index.html. There you'll see tree of available components with nested nodes representing available functionality and possible variants of skinning on the right side. You have two options from now:
I would choose the first option. Moreover, on stage of development I would use “full” preset keeping the possibility to decrease the file size for the final stage of development. Well, either way you go, you'll get two files (js and css) and a folder with images at the end. Files are: dhtmlx.js and dhtmlx.css, folder name is imgs. Put all where you need them (css and imgs should be put togather as you got them). I put in the codebase directory in the root folder of my future app. And added js and css files to the html I have:
<html> <head> <title>AJAX Application</title> <script src="codebase/dtmlx.js"></script> <link rel="STYLESHEET" type="text/css" href="codebase/dhtmlx.css"> </head> <body> </body> </html>
To prepare HTML page for full-screen dhtmlxLayout, you need to set some parameters of body tag. This can be actual just for initial release of DHTMLX 2.0 and can be not necessary for newer releases:
<body style="width:100%; height:100%; margin:0px; overflow:hidden;">
There are some predefined layout structures you can choose from. All of them are shown in dhtmlxLayout documentation. Their names start with number (reflects number of panels) followed by letter. For File Explorer we need quite simple one - “2U”. Left panel for navigation tree and right one for directory content. To start coding I would add onload event handler to body and place all necessary code in event handler. Also, we need to define global variables for all necessary objects (left side navigation tree, folders and grid for directory view, menu and toolbar for… for menu and toolbar ;). And layout itself of course.).
First we initialize full-screen layout.
<script> var myLayout, myTree, myGrid, myFolders, myMenu, myToolbar var gl_view_type = "icons"; //icons,dlist,tiles ... var gl_view_bg = ""; //which component is used for directory content view - grid or folders, empty from start function doOnLoad(){ myLayout = new dhtmlXLayoutObject(document.body, "2U", "dhx_blue"); } </script> <body onload="doOnLoad()" style="width:100%; height:100%; margin:0px; overflow:hidden;">
Besides full screen initialization there are some others:
(Nested layouts topic is described below)
Some words about skins. dhtmlx components has various predefined skins. Since version 2.0, when we provide the possibility to unite different components under the application interface, we also added some skins which can be applied to entire interface. Under dhtmlxLayout all dhtmlx components get unified skin set for the layout automatically (but we keep the possibility to set skin to each component also). These unified skins names start with “dhx_”:
dhx_black, dhx_light, dhx_lightblue.
So, using one of them as 3rd argument in dhtmlxLayout constructor you apply this skin on all dhtmlx components also.
If non of predefined layouts suites you absolutely, you can combine structures inserting one into another. For example:
myLayoutTop = new dhtmlXLayoutObject(document.body, "2U"); myLayoutIns = new dhtmlXLayoutObject(myLayoutTop.cells("a"), "2U");
This code creates 2U layout in the left panel of myLayoutTop layout. Thus you'll have 3 panels for further wok now:
function doOnLoad(){ myLayout = new dhtmlXLayoutObject(document.body, "2U", "dhx_black"); myLayout.cells("a").setWidth(250); }
There are two ways to apply to panel:
dhxLayout.cells("a")
dhxLayout.items[0]
Besides width you can define panel height
myLayout.cells("a").setHeight(250);
I'll leave header for the panel with folders tree and hide it for the panel with folder's content. Also, I'll change default header label (“a” for the panel in question) to “Folders”.
function doOnLoad(){ myLayout = new dhtmlXLayoutObject(document.body, "2U", "dhx_black"); myLayout.cells("a").setText("Folders"); myLayout.cells("b").hideHeader(); }
Current version of dhtmlxLayout (2.0 build 80829) provides the possibility to collapse/expand panel with mouse click through header only. Thus if you hide header for the panel user will not be able to collapse this panel.
I'll create top menu with items more or less similar to those you can see in your Windows Explorer. You'll be able to find ready to use fileExplorerMenu.xml file in the package of this tutorial files (see link in the introduction). Most items are dsabled there, cause they are not the goal of this tutorial. XML structure for dhtmlxMenu 2.0 can be found in dhtmlxMenu 2.0 documentation or in the doc article which describes XML structures of all dhtmlx components.
function doOnLoad(){ ... myMenu = myLayout.attachMenu(); myMenu.setImagePath("codebase/imgs/dhx_blue"); myMenu.loadXML("xml/fileExplorerMenu.xml"); }
Same as with the menu, toolbar items will be more or less similar to Windows File Explorer toolbar. You'll be able to find ready to use fileExplorerToolbar.xml file in the package of this tutorial files (see link in the introduction). XML structure for dhtmlxToolbar 2.0 can be found in dhtmlxToolbar 2.0 documentation or in the doc article which describes XML structures of all dhtmlx components.
function doOnLoad(){ ... myToolbar = myLayout.attachToolbar(); myToolbar.setIconPath("images/toolbar/"); myToolbar.loadXML("xml/fileExplorerToolbar.xml"); }
The difference in using setIconPath or setImagePath methods in dhtmlx components is the following: setIconPath defines the folder with graphical materials which are used in component but which are not parts of component - for example icons for buttons on toolbar, images in grid which represent some data. In most cases developer specifies the file names for these images (for example in XML) and these images are not delivered within components package (but can be in some cases).
On the other hand setImagePath defines the path to folder with images which are parts of component. For example parts of component skin or integral part of component functionality (like radiobutton or checkbox icons in grid, tree, menu or sorting arrow in grid, plus/minus signs in treegrid and tree). In all cases such images are delivered with components and located in codebase/imgs folder (or imgs folder inside preset directory for dhtmlx presets). So, setImagePath sets path to this imgs folder related to the page you use components on.
Most dhtmlx components can be attached to the dhtmlxLayout panel with single command. You did this with Menu and Toolbar. Same with the tree. After attaching the component you can work with it - configure, populate with data. In case of tree, we need to pass one value inside attachTree method (same we do for dhtmlxTree constructor when use it) - id of tree super-root element (id attribute of “tree” node in XML with tree structure). In most case “0” is ok.
function doOnLoad(){ ... myTree = myLayout.cells("a").attachTree("0"); myTree.setImagePath("codebase/imgs/"); myTree.setXMLAutoLoading("xml/directoryTree.php"); myTree.loadXML("xml/directoryTree.php"); }
directoryTree.php outputs directory structure in XML format required by dhtmlxTree. In our case it outputs one level at a time based on incoming directory (as directory structure can be quite big we use dynamical loading, loading just one level on request). If no directory came it ouputs starting directory (starting directory is specified in config.php included in tutorial files package. Find download link in Itroduction)
Again, we just add grid to dhtmlxLayout panel (in this case “b”) and then just work with grid - configuring and loading data. Tutorial of dhtmlxgrid basics is available here.
function showDList(dir){ //create grid in layout myGrid = myLayout.cells("b").attachGrid(); //configure grid with script myGrid.setImagePath("codebase/imgs/"); myGrid.setHeader("&nbsp;,Name,Size,Type,Modified"); myGrid.setColTypes("img,ro,ro,ro"); myGrid.setInitWidths("20,250,50,100,*"); myGrid.setColAlign("center,left,right,left"); //load directory contnet description in XML format myGrid.load("xml/directoryContent.php?dir="+dir) }
directoryContent.php outputs directory content (based on incoming directory) in dhtmlxGrid XML format with all necessary details for each item (file or directory):
dhtmlxFolders is used to display data items one by one based on incoming data and some visualization template. In our case, we'll use same datasource as we do for grid - directoryContent.php - and visualization templates (rendering functions) to display data items either as icons or as tiles (names are similar to Windows Explorer, so you can take a look there to see what should be the result).
Adding dhtmlxFolders to layout is as simple as in previous steps: just one command.
function showOtherViews(dir){ //create Folders in layout myFolders = myLayout.cells("b").attachFolders(); //confugure settings myFolders.enableSelection(true); myFolders.setItemTagName("row"); //change type of items depending on required if(gl_view_type=="icons"){ myFolders.setItemType("js_generic",rendFuncIcons); myFolders.setCSSBaseName("ficon"); }else if(gl_view_type=="tiles"){ myFolders.setItemType("js_generic",rendFuncTiles); myFolders.setCSSBaseName("ftiles"); } myFolders.loadXML("xml/directoryContent.php?dir="+dir); }
Attaching dhtmlxFolders to panel “b” removes grid from there (as we attach grid to panel “b” too) and visa versa. So, depending on currently selected view format (user can make a choice in toolbar) we should call either showDList or showOtherViews function to switch between view formats. And we should do this in two cases:
In both cases we should use event handlers - of tree (onSelect) and of toolbar (onClick) and menu (onRadioClick as we used radiobuttons in menu for this purposes). Here is the code where I define event handlers and call same function in which I decide if to call showDList or showOtherViews. As far as menu and toolbar items use same IDs for view related items, I'll use same event handler for both.
function showDirContent(dir){ if(gl_view_type=="dlist"){ showDList(dir); }else{ showOtherViews(dir); } } //this function we'll use for toolbar and menu event handlers function defineTypeAndLoad(id){ //set global variable value depending on user choice if(id=="view_dlist") gl_view_type="dlist"; else if(id=="view_icons") gl_view_type="icons"; else if(id=="view_tiles") gl_view_type="tiles"; //call function if(id.toString().indexOf("view")==0) showDirContent(myTree.getSelectedItemId()); } //tree event handler onSelect passes selected item ID as argument to the function. This is what we need in showDirContent, as I used directories as items IDs myTree.attachEvent("onSelect",showDirContent) myToolbar.attachEvent("onClick",defineTypeAndLoad); myMenu.attachEvent("onRadioClick",defineTypeAndLoad);
This tutorial demonstrated how easy you can create the interface of your web application based on dhtmlxLayout. To investigate the application code in details, please download it here: dhtmlx20_tutorial.zip. You may continue coding it, extending basic functionality which was described in this tutorial and implemented in the resulting application. Final application logic was not the goal of this article, but interface built here is a good start for creating full functional File Browser.