Using and Modifying the Project
This section explains how to modify the hFinder project for other applications. You see how to modify hFinder in the following ways:
Implement Windows Details view
Modify hFinder so that it resembles a Save As dialog
Create a directory picker dialog from the tree view
As mentioned earlier in this chapter, one of the goals of the hFinder application is to make it reusable for various other aspects of a content management system, and flexible enough to support multiple methods of viewing a directory's contents. The first way you'll modify hFinder is to see what an implementation of Windows Details view looks like.
Windows Details View
This section describes how to implement a new view in the hFinder application, a true-to-Windows Details view. Windows Details view is essentially nothing more than data organized in columns in a table. You can see this in Figure 9-12, which is a screenshot of Windows Details view.
Figure 9-12
As you can see from Figure 9-12 there isn't much to do to implement a Windows-style Details view. It's merely a restructuring of the data into tabular form, and the inclusion of some additional information about a file. To implement the Windows Details view, follow these steps:
Make the following modifications to hFinder.html:
</li>
</ul>
</li>
</ul>
</div>
<div id='hfinder-files'>
<table class='file-wdetails'>
<colgroup>
<col style='width: 16px;' />
<col />
<col style='width: 10%;' />
<col style='width: 20%;' />
<col style='width: 20%;' />
</colgroup>
<thead>
<tr>
<th></td>
<th>Name</th>
<th>Size</th>
<th>Type</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<tr id='dir-3645' class='file-directory' title='account'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>account</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:28 PM</td>
</tr>
<tr id='dir-31' class='file-directory' title='cp'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>cp</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:30 PM</td>
</tr>
<tr id='dir-3785' class='file-directory' title='daemons'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>daemons</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:33 PM</td>
</tr>
<tr id='dir-3677' class='file-directory' title='file'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>file</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:34 PM</td>
</tr>
<tr id='dir-26' class='file-directory' title='forum'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>forum</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:35 PM</td>
</tr>
<tr id='dir-3651' class='file-directory' title='home'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>home</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:37 PM</td>
</tr>
<tr id='dir-3681' class='file-directory' title='images'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>images</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:38 PM</td>
</tr>
<tr id='dir-3690' class='file-directory' title='js'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>js</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:39 PM</td>
</tr>
<tr id='dir-30' class='file-directory' title='listener'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>listener</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:40 PM</td>
</tr>
<tr id='dir-29' class='file-directory' title='logout'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>logout</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:41 PM</td>
</tr>
<tr id='dir-3682' class='file-directory' title='media'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>media</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:42 PM</td>
</tr>
<tr id='dir-3667' class='file-directory' title='network'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>network</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:44 PM</td>
</tr>
<tr id='dir-3735' class='file-directory' title='products'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>products</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:45 PM</td>
</tr>
<tr id='dir-28' class='file-directory' title='register'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='folder' />
</td>
<td class='file-name'>register</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:46 PM</td>
</tr>
<tr id='dir-3784' class='file-directory' title='search'>
<td>
<img src='images/16x16/MacOSXAqua_012.png' alt='search' />
</td>
<td class='file-name'>search</td>
<td class='file-size'></td>
<td class='file-type'>Directory</td>
<td class='file-last-modified'>11/26/2005 4:47 PM</td>
</tr>
<tr id='reg-112' class='file-registry-doc'
title='File Not Found'>
<td>
<img src='images/16x16/21.png' alt='text/html' />
</td>
<td class='file-name' id='freg-112'>404.html</td>
<td class='file-size'>900 Bytes</td>
<td class='file-type'>text/html</td>
<td class='file-last-modified'>11/26/2005 4:49 PM</td>
</tr>
<tr id='reg-1' class='file-registry-doc' title='Welcome'>
<td>
<img src='images/16x16/21.png' alt='text/html' />
</td>
<td class='file-name'>index.html</td>
<td class='file-size'>10 KB</td>
<td class='file-type'>text/html</td>
<td class='file-last-modified'>11/26/2005 4:50 PM</td>
</tr>
</tbody>
</table>
</div>
<div id='hfinder-contextmenu'>
<ul>
<li id='context-open' class='sep'>
<span style='font-weight: bold;'>Open</span>
</li>Save the modifications you made in a new file called hFinder.wDetails.html.
Make the following modifications to views.css:
div.file-highlight-on,
div.file-details.file-highlight-on {
background: url('images/stripes_darker.png');
padding: 4px;
}
div.file-highlight-off,
div.file-details.file-highlight-off {
background: transparent;
padding: 4px;
border: none;
}
table.file-wdetails {
font: 12px sans-serif;
width: 100%;
}
table.file-wdetails th {
text-align: left;
}Save views.css.
The modifications you made result in the output you see in Figure 9-13.
Figure 9-13
The CSS modifications you made were very simple: specify the font, make the <table> housing the file details take up all of the space available to it, and align the <th> fields to the left.
The next section discusses how to modify hFinder to make a Save As dialog.
Save As Dialog
To make a Save As dialog, the modifications are also relatively simple. To see how it's done, follow these steps:
Using the hFinder.list.html file on the source CD-ROM, make the following modifications:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-transitional.dtd">
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<meta http-equiv='content-language' content='en-us' />
<title>hFinder File Management Application</title>
<!-- compliance patch for microsoft browsers -->
<!--[if lt IE 7]>
<link rel='stylesheet'
type='text/css'
href='styles/hFinder.ie.css' />
<link rel='stylesheet'
type='text/css'
href='styles/tree.ie.css' />
<script type='text/javascript'
src='scripts/cssQuery/cssQuery-p.js'></script>
<script type='text/javascript'
src='scripts/png.js'></script>
<script src="/ie7/ie7-standard-p.js" type="text/javascript">
</script>
<![endif]-->
<link rel='stylesheet' type='text/css' href='styles/hFinder.css' />
</head>
<body id='hfinder-dialog'>
<div id='hfinder-toolbar'>
<table style='width: 100%; border-collapse: collapse;'>
<tbody>
<tr>
<td style='width: 35px;'>
<img src='images/back.png'
alt='Back'
title='Back'
class='hfinder-toolbar-control'
id='hfinder-back' />
</td>
<td style='width: 35px;'>
<img src='images/forward.png'
alt='Forward'
title='Forward'
class='hfinder-toolbar-control'
id='hfinder-forward' />
</td>
<td style='width: 35px;'>
<img src='images/refresh.png'
alt='Refresh'
title='Refresh'
class='hfinder-toolbar-control'
id='hfinder-refresh' />
</td>
<td style='width: 35px;'>
<img src='images/home.png'
alt='Home'
title='Home'
class='hfinder-toolbar-control'
id='hfinder-home' />
</td>
<td>
<div id='file-location'>
<div id='file-location-inner'>
<img src='images/drop-arrow.png'
id='file-location-arrow'
alt='arrow' />
<ul>
<li title='/'>
<span>Hard drive</span>
</li>
<!--
You may want to test what happens
when multiple directories are included
to do so, remove the comments around
the following <li> element
<li title='/account'>
<span>account</span>
</li>
-->
</ul>
</div>
</div>
</td>
<td style='width: 35px;'>
<img src='images/views.png'
alt='Change Views'
title='Change Views'
class='hfinder-toolbar-control'
id='hfinder-location-change-views' />
</td>
<td style='width: 35px;'>
<img src='images/directory.png'
alt='New Directory'
title='New Directory'
class='hfinder-toolbar-control'
id='hfinder-new-directory' />
</td>
<td style='width: 35px;'>
<img src='images/file.png'
alt='New File'
title='New File'
class='hfinder-toolbar-control'
id='hfinder-new-file' />
</td>
</tr>
</tbody>
</table>
</div>
<div id='hfinder-files'>
<div id='dir-3645'
class='file-list file-directory'
title='account'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>account</span>
</div>
</div>
</div>
<div id='dir-31'
class='file-list file-directory'
title='cp'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>cp</span>
</div>
</div>
</div>
<div id='dir-3785'
class='file-list file-directory'
title='daemons'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>daemons</span>
</div>
</div>
</div>
<div id='dir-3677'
class='file-list file-directory'
title='file'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>file</span>
</div>
</div>
</div>
<div id='dir-26'
class='file-list file-directory'
title='forum'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>forum</span>
</div>
</div>
</div>
<div id='dir-3651'
class='file-list file-directory'
title='home'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>home</span>
</div>
</div>
</div>
<div id='dir-3681'
class='file-list file-directory'
title='images'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>images</span>
</div>
</div>
</div>
<div id='dir-3690'
class='file-list file-directory'
title='js'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>js</span>
</div>
</div>
</div>
<div id='dir-30'
class='file-list file-directory'
title='listener'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>listener</span>
</div>
</div>
</div>
<div id='dir-29'
class='file-list file-directory'
title='logout'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>logout</span>
</div>
</div>
</div>
<div id='dir-3682'
class='file-list file-directory'
title='media'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>media</span>
</div>
</div>
</div>
<div id='dir-3667'
class='file-list file-directory'
title='network'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>network</span>
</div>
</div>
</div>
<div id='dir-3735'
class='file-list file-directory'
title='products'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>products</span>
</div>
</div>
</div>
<div id='dir-28'
class='file-list file-directory'
title='register'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='folder' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>register</span>
</div>
</div>
</div>
<div id='dir-3784'
class='file-list file-directory'
title='search'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/MacOSXAqua_012.png'
class='file-list-img'
alt='search' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name'>search</span>
</div>
</div>
</div>
<div id='reg-112'
class='file-list file-registry-doc'
title='File Not Found'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/21.png'
title='text/html'
alt='text/html'
class='file-list-img' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name' id='freg-112'>404.html</span>
</div>
</div>
</div>
<div id='reg-1'
class='file-list file-registry-doc'
title='Welcome'>
<div>
<div class='file-icon-wrapper'>
<img src='images/16x16/21.png'
alt='text/html'
title='text/html'
class='file-list-img' />
</div>
<div class='file-list-caption file-caption-wrapper'>
<span class='file-name' id='freg-1'>index.html</span>
</div>
</div>
</div>
</div>
<div id='hfinder-dialog-controls'>
<form action='javascript:void(0);' method='post'>
<table>
<colgroup>
<col />
<col style='width: 5%;' />
<col style='width: 5%;' />
</colgroup>
<tbody>
<tr>
<td><input type='text'
name='fname' value='' id='file-name' /></td>
<td><input type='submit'
name='save' value='Save' /></td>
<td><input type='submit'
name='cancel' value='Cancel' /></td>
</tr>
</tbody>
</table>
</form>
</div>
<div id='hfinder-contextmenu'>
<ul>
<li id='context-open' class='sep'>
<span style='font-weight: bold;'>Open</span>
</li>
<li id='context-control-panel'>
<span>Control Panel</span>
</li>
<li id='context-title-description' class='sep'>
<span>Modify Title and Description</span>
</li>
<li id='context-delete'>
<span>Delete</span>
</li>
<li id='context-rename' class='sep'>
<span>Rename</span>
</li>
<li id='context-properties'>
<span>Properties</span>
</li>
<li id='context-permissions'>
<span>Permissions</span>
</li>
</ul>
</div>Save the preceding modifications as hFinder.saveas.html.
Make the following modifications to hFinder.css:
div#hfinder-tree {
position: absolute;
top: 0;
bottom: 0;
left: 0;
margin: 73px 0 10px 10px;
width: 190px;
background: white;
overflow: auto;
border: 1px solid rgb(128, 128, 128);
z-index: 1;
}
div#hfinder-files {
margin: 73px 10px 10px 210px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: 1px solid rgb(128, 128, 128);
background: white url('../images/stripes.png');
z-index: 1;
overflow: auto;
}
body#hfinder-dialog div#hfinder-toolbar {
margin: 10px 10px 0 10px;
}
body#hfinder-dialog div#hfinder-files {
margin: 53px 10px 53px 10px;
}
div#hfinder-dialog-controls {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: 0 7px 0 7px;
}
div#hfinder-dialog-controls input#file-name {
background: white url('../images/stripes.png');
width: 98%;
}
div#hfinder-dialog-controls table {
width: 100%;
}
div#file-location {
height: 30px;
position: relative;
z-index: 2;
}
div#file-location-inner {
background: white url('../images/stripes.png');
height: 30px;
overflow: hidden;
border: 1px solid rgb(128, 128, 128);
font: 12px sans-serif;
position: absolute;
top: 0;
left: 0;
right: 0;
}
div#file-location ul {
list-style: none;
margin: 0;
padding: 0;
position: absolute;
bottom: 0;
left: 0;
}
div#file-location ul li {
height: 30px;
white-space: nowrap;
overflow: hidden;
background: url('../images/24x24/MacOSXAqua_012.png') no-repeat 10px center;
padding-left: 40px;
}
div#file-location ul li span {
line-height: 30px;
vertical-align: middle;
}
div#file-location ul li:first-child {
background: url('../images/24x24/MacOSXAqua_037.png') no-repeat 10px center;
}
img#file-location-arrow {
position: absolute;
top: 5px;
right: 5px;
}Save hFinder.css.
The result of the modifications is shown in Figure 9-14.
Figure 9-14
This series of modifications was quite a bit more complicated than implementing Windows-style Details view. In the Save As dialog you've removed the menus and the tree view, where the file location input was. A <div> and <ul> were added, which are intended to be the drop-down menu functionality that you find in a Save As dialog. This can be seen in Figure 9-15.
Figure 9-15
Figure 9-16 shows the same dialog with the drop-down dialog closed.
Figure 9-16
The drop-down navigation in hFinder is more simplified than that used by Windows. Because for this application there are not multiple drives to display, the drop-down navigation in hFinder is intended to show only the file path to the directory the user is currently viewing, and provide an easy method to jump to the other directories in that hierarchy.
When the user is browsing the file system, this box can be populated with the current file path. To the right of the drop-down navigation, a new icon for changing file views is added, and the Go icon was removed. Beneath the <div> element containing files and directories is a new form, which would be used to enter the new file name for the file you're saving.
In hFinder.css, you made some modifications to accommodate the Save As dialog. The first rule you applied takes advantage of the id name you applied to the <body> element. The addition of the id name to the <body> element allows you to override other style sheet rules via the cascade. In that first rule, you override the margin applied to the <div> with an hfinder-toolbar id name; its margin is reduced in response to removing the top menus File, View, Admin, and Help:
body#hfinder-dialog div#hfinder-toolbar {
margin: 10px 10px 0 10px;
}
As was the case in the previous rule, the margin for the <div> with an hfinder-files id name also needed a margin adjustment to facilitate the removal of the tree view and the menus from the top. The bottom margin also needed to be larger to make room for the new form at the bottom of the document:
body#hfinder-dialog div#hfinder-files {
margin: 53px 10px 53px 10px;
}
Because the <div> containing the files and directories is positioned absolutely, any element inserted after it must be positioned absolutely as well. The <div> housing the form at the bottom of the hFinder document (which provides controls for a user to enter a new file name to save a document) is positioned absolutely to the bottom of the viewport, and stretched from the left to the right border of the viewport. Then left and right margins are adjusted to line up the form with the <div> housing directories and files above it:
div#hfinder-dialog-controls {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: 0 7px 0 7px;
}
The <input /> element for new file names is given a width of 98% and a pinstripe background:
div#hfinder-dialog-controls input#file-name {
background: white url('../images/stripes.png');
width: 98%;
}
The <table> housing the <input /> for a new file name and the Save and Cancel buttons is then given a width of 100%:
div#hfinder-dialog-controls table {
width: 100%;
}
The <div> at the top of the document that houses the new drop-down navigation control is next to be styled. It receives an explicit height of 30 pixels; a relative position so that descendant elements positioned absolutely will position relative to it, and a position along the z-axis:
div#file-location {
height: 30px;
position: relative;
z-index: 2;
}
The following rule is for the <div> nested within the "file-location" <div> element. It has a file-location-inner id name. A nested <div> is required for purposes of layering. Because a position: relative; declaration has no effect when applied to a <td> element, a nested <div> element allows you to circumvent the need to apply position: relative; to the <td> element. Now armed with an element to position relative to, the nested file-location-inner <div> element is positioned absolutely, relative to its parent. It receives a pinstripe background and a height of 30 pixels. The overflow: hidden; declaration prevents descendant content that is larger than the boundaries of the file-location-inner <div> element from being seen, and plays a large role in developing a drop-down menu that displays only the last directory in the current file path. More on that when you get to the next rule. A 12-pixel, generic sans-serif font is specified. Finally, the <div> is stretched for the entire width of the element it is positioned relative to, its parent. Stretching the element lets it resize with the width of the window:
div#file-location-inner {
background: white url('../images/stripes.png');
height: 30px;
overflow: hidden;
border: 1px solid rgb(128, 128, 128);
font: 12px sans-serif;
position: absolute;
top: 0;
left: 0;
right: 0;
}
Within the drop-down navigation <div>, the current file path is housed in a <ul> element, which would be changed by a JavaScript to reflect the file path for whatever directory the user is currently viewing. As would be the case in a Windows Save As dialog, only the very last directory in the path is visible when the drop-down navigation is inactive. To make this work with CSS, the parent file-location-inner <div> element is given an explicit height of 30 pixels, and the overflow: hidden; declaration. When those properties are applied with those of the <ul> element and its children, the result is a drop-down navigation system in which only the last directory in the file path is visible. Ancestor directories in the current file path that exist in the markup are invisible to the user until the user accesses the drop-down navigation, which would be done by attaching a JavaScript onclick event to the file-location-inner <div>. On clicking the file-location-inner <div>, the <div>'s height is adjusted so that all of the directories in the path are visible, thereby giving the user a method to easily navigate to directories in the current file path:
div#file-location ul {
list-style: none;
margin: 0;
padding: 0;
position: absolute;
bottom: 0;
left: 0;
}
To hide the ancestor directories that exist in the markup but must be invisible until the drop-down navigation is accessed, the <ul> element is positioned absolutely to the left and bottom of the file-location-inner <div>. Then its children <li> elements are each given a height of 30 pixels, and some properties to ensure that height is always honored. Though most browsers honor an explicit height, Explorer does not always honor an explicit height if an element has more content than the height allows. The height is forced to be honored by the white-space: nowrap; and overflow: hidden; declarations. Now if a directory's name is too long to fit, it will be clipped at the width of the <li> element. Then each directory needs an icon; MacOSXAqua_012.png is the folder icon. It is positioned 10 pixels offset from the left of the <li> element and centered vertically. The padding-left: 40px; declaration prevents the text of the directory name from overlapping the icon. One essential element of a Save As dialog drop-down navigation is not accomplished with the CSS as it is written here, and that is indenting the directories in the path to show their relationship with one another. This is another aspect of the application that must be done with the JavaScript. In the completed application, the offset of the background image and the padding-left property would be adjusted in the JavaScript to indent each descendant directory a little further to the right:
div#file-location ul li {
height: 30px;
white-space: nowrap;
overflow: hidden;
background: url('../images/24x24/MacOSXAqua_012.png') no-repeat 10px center;
padding-left: 40px;
}
Next the text of the directory name must be adjusted so that it is centered vertically just as the icon was in the preceding rule. The text is centered vertically by adjusting the line-height of the <span> element to 30 pixels (same height as the parent <li> element), and then applying the vertical-align: middle; declaration. A nested <span> element is required here because the vertical-align property only applies to inline or <tr>, <th>, or <td> elements. Because the purpose of the vertical-align property is to align text vertically relative to a line's baseline (as applied to inline elements), the line-height must be first adjusted to match the height of the parent <li> element for the vertical-align property to provide the desired results:
div#file-location ul li span {
line-height: 30px;
vertical-align: middle;
}
The topmost directory is always the first in the list. This directory is special because it is the root directory. It receives a different icon than the other directories, and this is done via the :first-child pseudo-class. The image, MacOSXAqua_037.png, is a Mac hard drive icon:
div#file-location ul li:first-child {
background: url('../images/24x24/MacOSXAqua_037.png') no-repeat 10px center;
}
The last rule positions the arrow for the drop-down navigation. It places the arrow 5 pixels from the top and right of the file-location <div> element:
img#file-location-arrow {
position: absolute;
top: 5px;
right: 5px;
}
The last alternative implementation of hFinder is how to make a Choose a Directory dialog.
Choose a Directory Dialog
As you've seen throughout this project, hFinder is a complex application that can serve many different functions relating to file management. In fact, I could have spent the entire book on just hFinder alone. Although hFinder is by no means a complete application, you see what's required to handle the presentational aspects of such an application, and what's required to alter such an application to fit different purposes.
In the final alternative implementation of hFinder, you see what goes into creating a Choose a Directory dialog. This time you use the tree view, not the directory view. A Choose a Directory dialog, also known as a Browse for Folder dialog, looks like the one in Figure 9-17, which happens to be from the Windows version of iTunes.
Figure 9-17
To make a Choose a Directory dialog, follow these steps:
Make the following alterations to hFinder.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-transitional.dtd">
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'
id='hfinder-directory-dialog'>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<meta http-equiv='content-language' content='en-us' />
<title>hFinder File Management Application</title>
<link rel='stylesheet' type='text/css' href='styles/hFinder.css' />
</head>
<body>
<h4>Choose a Directory...</h4>
<div id='hfinder-tree'>
<ul class='file-tree'>
<li>
<div class='file-tree-directory file-tree-root'
id='tree-dir-1'>
<span>Hard drive</span>
</div>
<ul id='directory-1' class='file-tree-dir-list'>
<li>
<div class='file-tree-directory'
id='tree-dir-3645'>
<span>account</span>
</div>
<img src='images/right.png'
class='file-has-children'
id='tree-3645'
alt='+'
title='Click to expand.' />
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-31'>
<span>cp</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3785'>
<span>daemon</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3677'>
<span>file</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-26'>
<span>forum</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3651'>
<span>home</span>
</div>
<img src='images/right.png'
class='file-has-children'
id='tree-3651'
alt='+'
title='Click to expand.' />
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3681'>
<span>images</span>
</div>
<img src='images/right.png'
class='file-has-children'
id='tree-3681'
alt='+'
title='Click to expand.' />
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3690'>
<span>js</span>
</div>
<img src='images/right.png'
class='file-has-children'
id='tree-3690'
alt='+'
title='Click to expand.' />
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-30'>
<span>listener</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-29'>
<span>logout</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3682'>
<span>media</span>
</div>
<img src='images/right.png'
class='file-has-children'
id='tree-3682'
alt='+'
title='Click to expand.' />
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3667'>
<span>network</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3735'>
<span>products</span>
</div>
<img src='images/right.png'
class='file-has-children'
id='tree-3735'
alt='+'
title='Click to expand.' />
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-28'>
<span>register</span>
</div>
</li>
<li>
<div class='file-tree-directory'
id='tree-dir-3784'>
<span>search</span>
</div>
</li>
</ul>
</li>
</ul>
</div>
<div id='hfinder-dialog-controls'>
<form action='javascript:void(0);' method='post'>
<table>
<colgroup>
<col />
<col style='width: 5%;' />
<col style='width: 5%;' />
</colgroup>
<tbody>
<tr>
<td><input type='submit'
name='new_directory'
value='New Directory' /></td>
<td><input type='submit' name='ok' value='Ok' /></td>
<td><input type='submit'
name='cancel' value='Cancel' /></td>
</tr>
</tbody>
</table>
</form>
</div>
</body>
</html>Save the altered file as hFinder.chooseDirectory.html.
Using the version of hFinder.css you created to make a Save As dialog in the previous section, make the following modifications:
@import 'menus.css';
@import 'views.css';
@import 'tree.css';
@import 'popup.css';
body,
html {
width: 100%;
height: 100%;
min-width: 500px;
min-height: 300px;
}
body {
padding: 0;
margin: 0;
background: url('../images/brushed_metal.png');
-moz-user-select: none;
}
html#hfinder-directory-dialog,
html#hfinder-directory-dialog body {
min-width: 200px;
}
div#hfinder-toolbar {
position: absolute;
top: 0;
left: 0;
right: 0;
margin: 28px 10px 0 10px;
}
html#hfinder-directory-dialog h4 {
font: normal 12px sans-serif;
position: absolute;
margin: 0;
top: 15px;
left: 10px;
}
html#hfinder-directory-dialog div#hfinder-tree {
margin: 43px 10px 53px 10px;
right: 0;
width: auto;
}
div#hfinder-tree {
position: absolute;
top: 0;
bottom: 0;
left: 0;
margin: 73px 0 10px 10px;
width: 190px;
background: white;
overflow: auto;
border: 1px solid rgb(128, 128, 128);
z-index: 1;
}Save hFinder.css.
The result of the modifications is shown in Figure 9-18.
Figure 9-18
The modifications required to create a Choose a Directory dialog are few. In hFinder.html, you removed the menus, toolbar, popups, and directory view window, then added a button for the creation of a new directory, and OK and Cancel buttons. These controls are housed in a <div> named hfinder-dialog-controls, which was the same name used for the <div> element housing controls in the Save As dialog of the last section. The relevant CSS you applied for the Save As dialog for the hfinder-dialog-controls <div> is reused for the Choose a Directory dialog.
The CSS you applied to create the Choose a Directory dialog was only a few lines, and most of it was used to override, via the cascade, the default rules used for the original hFinder application. To facilitate this you added an id name to the <html> element, hfinder-directory-dialog. The first rule you added in hFinder.css overrides the default minimum width. The default minimum width was too large for a Choose a Directory dialog, which need not be very wide to be usable:
html#hfinder-directory-dialog,
html#hfinder-directory-dialog body {
min-width: 200px;
}
Then, in the markup you added a new <h4> element with the text "Choose a Directory…". This element is styled in hFinder.css with the following rule:
html#hfinder-directory-dialog h4 {
font: normal 12px sans-serif;
position: absolute;
margin: 0;
top: 15px;
left: 10px;
}
The <h4> element's font is set to remove the bold face, with the normal keyword, and then set to 12-pixel, generic sans-serif. The default margin is removed, and then the element is positioned absolutely 15 pixels from the top and 10 pixels from the left of the viewport.
The last rule added to hFinder.css overrides the margin and width for the hfinder-tree <div> and sets the right offset property to zero so that the hfinder-tree <div> is stretched for the whole width of the window:
html#hfinder-directory-dialog div#hfinder-tree {
margin: 43px 10px 53px 10px;
right: 0;
width: auto;
}
With the presentation of the hFinder set in place, it can now go on to become a much more complex application with the help of JavaScript, and a server-side language such as PHP, Java, Perl, and so on.
No comments:
Post a Comment