## dhtmlXFolders Guide and Samples

### What is dhtmlxFolders

dhtmlxFolders can display various number of objects which have the same structure of data. Thus it can be used as a basis for file/image browsers, product catalogs or any kind of informational resources. Paging support allows displaying these objects one-by-one, portion by portion or all at once. The size of each object depends on visualization template. So this can be either icon with title under it or complete web page.

Using different visualization templates combined with different paging settings applied to the same data content, you can display items with different level of detalization. For example, you can switch from simple list of images to image thumbnails or full-size image view, or from list of products to product details pages, from list of documents titles to detailed list of documents and to document complete view at the end.

Built-in sorting and filtering capabilities make it easier to find necessary item among the others and provide ready-to-use file/image browser or internet product catalog/shop functionality. Such features as selection and drag-n-drop allow for easy and intuitive object reorganization. Besides, dhtmlxFolders provides the possibility of inline item editing.

### Main features

- Full control with JavaScript API
- XML/XSL or pure Javascript visualization
- Sorting
- Filtering
- Paging & dynamical loading
- Drag-and-drop

### Supported browsers

dhtmlxFolders developed using Javascript, including browsers built-n XML/XSLT/Xpath processors and CSS.
Guaranteed compatibility:
- IE 6 and above
- FireFox 2.x
- Safari 3.x
- Opera 9.x

### Working with dhtmlxFolders

#### Initialize dhtmlxFolders object on page

First of all you need to choose container for dhtmlxFolders object which will define width, height for it and its place on page. Most useful HTML object for these purposes is DIV element. It can be in any type of position - relative, absolute, static or fixed. But some css attributes are mandatory for it:

- width: in px or %
- height: in px or %
- overflow:hidden;

It also should have id attribute.
So here is a sample of valid dhtmlxFolder container:

    	<div id="folders_container" style="width:450px;height:450px;overflow:hidden;"></div>

Having container you now can create dhtmlxFolders object and put it there. This can be done with single script command:

    	myFolders = new dhtmlxFolders("folders_container");

Now, you have javascript object myFolders which has all functionality of dhtmlxFolders. You can define type of items you want to have in it and load data. We'll do this with short set of script commands:

    	myFolders.setItemType("type_name");
    	myFolders.setUserData("name","value")
    	myFolders.loadXML("/path/to/xml_source.xml","/path_to/itemtype_visualization/xsl_file.xsl");

setItemType method call is necessary if you want to use some of predefined types (read chapter "Define items type using built-in types") or switch from one type to another (read "Changing type dynamically" chapter).

setUserData method sets name/value pairs which then can be used in XSL as xsl variables. You can pass path to icons or some other values this way. If you use built-in or third party types you need to refer to the documentation to find out what variables should be set. Or look into xsl file to see what variables are used there. Userdata cab be set with script or in XML (using userdata tag).

loadXML method gets data provided in XML format from server and populates dhtmlxFolders object with items. As you can see it uses two arguments:

- XML file url. This can be either static XML file or any other programming file which responses data in valid XML format. (read "XML format" chapter to know what XML format is required by dhtmlxFolders)
- XSL file url. Each item type of "xml-xsl" kind has corresponding XSL used for formatting items. Built-in types has corresponding xsl files in codebase/types folder. All you need is to point dhtmlxFolders object there. For example "../codebase/types/ftable.xsl" . If you use your own XSL file, point dhtmlxFolders to this file (read "Define your own type" chapter to know how to create your own visualization files)

#### XML format

As far as dhtmlxFolders can display any kind of data which can be presented through HTML, XML can contain any data and its format can be of any kind. But… if you use built-in or third party types you have to follow XML format required by those types. In appendix you can find a summary table of available types and corresponding XML format.

You need to understand that xml structure should be defined based not only on exact necessities of the type (what information is shown by each item), but also on some additional purposes - like ordering by different property values (even if these properties are invisible), showing information out of dhtmlxFolders object (like showing additional information for selected item). Also XML structure can be defined taking into account the possible changing of type without reloading the data. For example when files list in file browser is shown as icons or as thumbnails.

Talking about XML we do not mean only static xml files. In most cases not static content is used. XML content can be created dynamically based on database data or file system (if you need to display real file system structure) using any server-side programming language. Common requirements for xml produced by server side language:

- Response content-type must be text/xml or application/xhtml+xml
- There shouldn't be any spaces or other content before xml declaration tag (same requirement is for static xml files).

##### PHP Example of creation of correct header for XML producting routine:

    <?php
    if ( stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml") ) {
                      header("Content-type: application/xhtml+xml"); } else {
                      header("Content-type: text/xml");
    }
    echo("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
    ?>

#### Item Types

##### XML-XSL

There are 3 components of xml-xsl type :

- Javascript constructor (same for all, so you do not need to think about it a lot)
- XSL template. It defines visual appearance of the item. You can use built-in or create your own. XSL files for built-in types usually located in codebase/types
- CSS classes definition. By default css class name for top item element is created based on type name. using the following template: dhx_folders_[NAME OF TYPE IN UPPER CASE]_item. Thus if you use built-in type "ficon" and want to change something in CSS, you need to search for dhx_folders_FICON_item class in codeabse/dhtmlxfolders.css. If you create your own type (with name "mytype" for example), then define style through dhx_folders_MYTYPE_item class and sub classes

##### JSON

- Javascript constructor
- CSS class (see explanations above)

#### Define items type using built-in types

Although dhtmlxFolders contains some built-in types it is not possible to offer universal solution for all possible cases of dhtmlxFolders usage. Thus built-in types can be considered as basis for types you need for your development. They also provide basic functionality mostly demand for file browsers. You can find a list of built-in types in dhtmlxFolders Built-in Types.

So, to use any of this type, please make sure your XML contains all necessary tags and attributes required by type you are going to use. If it is, you can apply the type:

    	myFolders.setItemType("type_name");
    	myFolders.loadXML("/path/to/xml_source.xml","/path_to/itemtype_visualization/xsl_file.xsl");

In most cases xsl files for built-in types are in codebase/types folder inside dhtmlxFolders package. But you can put them in any place where they can be located by loadXML mathod.

#### Define your own type

##### XML-XSL

See Creation of item types for dhtmlxFolders

##### JSON

...

#### Changing type dynamically (keeping data)

To change type of dhtmlxFolders items which were already loaded and rendered with another type you need to call the following command:

    		myFolders.setItemType("type-name", "/path_to/itemtype_visualization/xsl_file.xsl");

Where first argument - new type name (for your own type try "xml_generic"), second - path to new type xsl file

#### Selection in dhtmlxFolders

Selection in dhtmlxFolders behave same way as in desktop applications:

1. Single click on item selects it
2. If you click on item when other item(s) selected:

1. Holding Shift key - selects all items starting from already selected to currently clicked
2. Holding Ctrl key - adds currently clicked item to selected items (if this item wasn't selected), removes currently clicked item from selected items (if item was already selected)

To select item with script call the following command:

    	selectItem(itemId,ctrl-key-state,shift-key-state);

#### Sorting

Items in dhtmlxFolders can be sorted using any of their parameter. To sort items you need to use sortItems method. The main thing you need to do is to define function for items comparison and pass it into that method (as first argument), second argument will be "asc" for ascending sort, "desc" for descending sort.

Items comparison function gets two abstract items as incoming arguments and returns:

- 0 if both items have identical compared values
- 1 if first item value is bigger (or should stay first higher in list)
- -1 if second item value is bigger (or should stay second higher in list)

For example XML representation of item in dhtmlxFolders is the following:

    <item name="[string]" id="[string]">
    	<size>[numeric value]</size>
    </item>

Comparison function to sort by name attribute will be the following:

    function sortByName(a,b){
    	var aName = a.data.dataObj.getAttribute("name");
    	var bName = b.data.dataObj.getAttribute("name");
    	if(aName>bName)
    		return 1;
    	else if(aName==bName)
    		return 0;
    	else
    		return -1;
    }

As you can see from example above, we get item XML node using itemObject.data.dataObj construction. Afterwards we can work with it as with XMLDOM node object.
To compare numeric value of size node we'll use the following comparison function:

    function sortBySize(a,b){
    	var aSize = parseInt(a.data.dataObj.getElementsByTagName("size")[0].firstChild.nodeValue);
    	var bSize = parseInt(b.data.dataObj.getElementsByTagName("size")[0].firstChild.nodeValue);
    	return aSize-bSize;
    }

Complete sorting command will be the following:

    myFolders.sortItems(sortByName,"asc");//to sort ascending by name
    myFolders.sortItems(sortBySize,"asc");//to sort ascending by size

#### Filtering

##### Apply filter

Use filterItems(...) method to filter dhtmlxFolder items by some mask.
Like with sorting, to create filter for dhtmlxFolders item you need to define function where you decide if item should be visible after filter applied or not. This function gets abstract item object as first incoming argument and mask as second argument. Function returns true if item should be visible, false if it shouldn't be.

For example XML representation of item in dhtmlxFolders is the following:

    <item name="[string]" id="[string]">
    	<size>[numeric value]</size>
    </item>

To filter items which name begins with some value, we define the following function:

    function filterByName(obj,mask){
    	var aName = obj.data.dataObj.getAttribute("name");
    	return (aName.toString().indexOf(mask)==0 || mask=="");
    }

Complete filtering command will be the following:

    	myFolders.filterItems(filterByName,"[mask value]");

##### Clear filters

To clear all applied filters use filterClear method:

    myFolders.filterClear();

##### Apply multiple filters

To apply filter keeping previous filters use third argument of filterItems method:

    	myFolders.filterItems(filterByName,"[mask value]");
    	myFolders.filterItems(filterBySize,"[mask value]",true);

This code will filter items by name and then (keeping results of first filtering) by size.

#### Paginal Output

By default all items loaded from server or created with script are shown at once. But to increasing loading speed and make perception better you can use paginal output (this is mostly usefull for product catalogs). With paginal output only limited number of items are visible. Other items can be viewed by switching to other page(s).

##### Turn on/off paginal output

To turn on paginal output use the following way:

    	myFolders.enablePaging(10,true);

Where first argument is number of items per page, second - allows dhtmlxFolders to request additional content from server when no items available to fill complete page (more details about dynamical loading see below).

To reset new number of items per page use enablePaging again - with new number items per page. Each time you change number of items per page, dhtmlxFolders switches to 1st page.

To turn paging off use:

    	myFolders.enablePaging(false);

##### Turn on ability to load additional items from server (dynamical loading)

Using second argument of enablePaging method you can allow (true) or deny (false) dhtmlxFolders to apply for additional content to server. In case it is allowed, dhtmxFolders will send request to server using same URL which was specified in loadXML method but with additional parameter: dhx_global_page - each time it has not enough items in collection to populate last page and untill this request returns 0 items. dhx_global_page parameter will increment its value by 1 with each next request starting from very first one (so, first automatic request will have dhx_global_page=2)

Important: if you are going to use paging with dynamical loading please make sure you included processing of dhx_global_page into your xml producing routine. Otherwise dhtmlxFolders will get same content endless times.

##### How to switch between pages (user interface)

First version of dhtmlxFolders doesn't provide ready to use interface objects for managing paging, but it does provide API methods for building it. Main method for it is: goToPage(pgNum). It provides the possibility to navigate through pages. If no page number passed, then it will return to the first page.
On each call, goToPage returns value, which means the following:

- 0 - there is no items in dhtmlxFolders object which can be displayed (this doesn't mean there is no items at all, but no items to show. Some items can be filtered out for example)
- 1 - page was completed without request for additional content
- 2 - dynamical request was sent to server, as page had no enough content and dynamical loading was on.
Same values are returned by enablePaging method.

Other methods which can be useful while working with paging:

- getCurrentPage - returns current page
- getNumberOfPages - returns number of pages

#### Drag-n-drop

dhtmlxFolders supports drag-n-drop in following ways:

- Drop before
- Drop next
- Drop in

To enable drag-n-drop you need to call the following command:

    	myFolders.enableDragAndDrop(true);

As far as drag-n-drop uses two images (included into dhtmlxFolders delivery package) to visualize before/next drop types, you also need to set path to codebase/imgs forlder:

    	myFolders.setImagePath("../../codebase/imgs/");

As far as Drag-n-drop in dhtmlxFolders has default actions for "before" and "next" drop types (move source item before/next target item), but no default action for "in" drop type, you'll need to define it on your own , or it will just do nothing. Action for any type of drag-n-drop can be reset using onBeforeDrop event handler. For example:

    	myFolders.attachEvent("onBeforeDrop",function(dropType,sID,tID){
    		//find type of target item (in this case - directory or file)
    		var tType = this.getItem(tID).data.dataObj.getAttribute("type");
    		//if type of drop is "in" and target item is directory - remove source item from folders
    		if(dropType=="in" && tType=="dir"){
    			this.deleteItem(sID);
    			//...and cancel default action
    			return false;
    		}else //else proceed wth default action
    			return true;
    	})

If this event handler returns false, then default action will be canceled. Thus it can be used to decide if drop should be allowed or not depending on drop type, source and target items.

#### Events

As with other dhtmlx components you can set event handlers on number of events using same method - attachEvent(…). List of available events can be found in API documentation. Nearly each event handler gets some parameters. This also described with list of available events.

Here is an example of how to set event handler to capture the moment item was clicked:

    	myFolders.attachEvent("onclick",function(id){
    		alert("Item ID is: "+id)
    	})

As you can see from example, item ID was passed to the event handler, so you can use it to get item object and all it's properties and values.

#### Delete Items with script

To delete items with script you can use deleteItem method with item ID passed into it. You also can pass array of IDs to delete more than one item at once.
You can use the following set of commands to delete selected item(s):

    	myFolders.deleteItem(myFolders.getSelectedId();

© DHTMLX LTD.