← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 8011: local vn - Improved the performance in loading ICD form.

 

------------------------------------------------------------
revno: 8011
committer: Hieu <hieu.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2012-09-06 18:47:37 +0700
message:
  local vn - Improved the performance in loading ICD form.
added:
  local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/jquery.fixedheadertable.js
  local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/style/myTheme.css
modified:
  local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/DefaultLocalDataElementService.java
  local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementService.java
  local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementStore.java
  local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateLocalDataElementStore.java
  local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java
  local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/LoadICDFormAction.java
  local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/defaultICDForm.vm
  local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/form.js
  local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/select.vm


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/DefaultLocalDataElementService.java'
--- local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/DefaultLocalDataElementService.java	2012-05-10 16:18:43 +0000
+++ local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/DefaultLocalDataElementService.java	2012-09-06 11:47:37 +0000
@@ -28,6 +28,8 @@
 package org.hisp.dhis.dataelement;
 
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
 import org.hisp.dhis.attribute.Attribute;
 import org.hisp.dhis.dataset.DataSet;
@@ -71,4 +73,9 @@
     {
         return dataElementStore.get( dataSet, value );
     }
+
+    public Map<String, List<Integer>> get( DataSet dataSet, List<String> values )
+    {
+        return dataElementStore.get( dataSet, values );
+    }
 }

=== modified file 'local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementService.java'
--- local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementService.java	2012-05-10 16:18:43 +0000
+++ local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementService.java	2012-09-06 11:47:37 +0000
@@ -28,6 +28,8 @@
 package org.hisp.dhis.dataelement;
 
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
 import org.hisp.dhis.attribute.Attribute;
 import org.hisp.dhis.dataset.DataSet;
@@ -44,4 +46,6 @@
     int getDataElementCount( Integer dataElementId, Integer attributeId, String value );
     
     Collection<DataElement> getDataElements( DataSet dataSet, String value );
+    
+    Map<String, List<Integer>> get( DataSet dataSet, List<String> values );
 }

=== modified file 'local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementStore.java'
--- local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementStore.java	2012-05-10 16:18:43 +0000
+++ local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/LocalDataElementStore.java	2012-09-06 11:47:37 +0000
@@ -28,6 +28,8 @@
 package org.hisp.dhis.dataelement;
 
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
 import org.hisp.dhis.attribute.Attribute;
 import org.hisp.dhis.dataset.DataSet;
@@ -44,4 +46,6 @@
     int getDataElementCount( Integer dataElementId, Integer attributeId, String value );
     
     Collection<DataElement> get( DataSet dataSet, String value );
+
+    Map<String, List<Integer>> get( DataSet dataSet, List<String> values );
 }

=== modified file 'local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateLocalDataElementStore.java'
--- local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateLocalDataElementStore.java	2012-08-14 19:13:01 +0000
+++ local/vn/dhis-service-vn/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateLocalDataElementStore.java	2012-09-06 11:47:37 +0000
@@ -29,7 +29,9 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.hibernate.criterion.Projections;
 import org.hibernate.criterion.Restrictions;
@@ -84,12 +86,11 @@
         try
         {
             String sql = "select de.dataelementid, de.name, de.formname from dataelement de "
-                + "inner join datasetmembers dsm on de.dataelementid = dsm.dataelementid "
-                + "inner join dataelementattributevalues deav on deav.dataelementid = dsm.dataelementid "
-                + "inner join attributevalue av on av.attributevalueid = deav.attributevalueid "
-                + "inner join attribute att on att.attributeid = av.attributeid " + "where dsm.datasetid = "
-                + dataSet.getId() + " and av.value='" + value + "'";
-
+                + "join datasetmembers dsm on de.dataelementid = dsm.dataelementid "
+                + "join dataelementattributevalues deav on deav.dataelementid = dsm.dataelementid "
+                + "join attributevalue av on av.attributevalueid = deav.attributevalueid "
+                + "where dsm.datasetid = " + dataSet.getId() + " and av.value='" + value + "'";
+            
             SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
 
             while ( rowSet.next() )
@@ -105,4 +106,55 @@
             return new ArrayList<DataElement>();
         }
     }
+    
+    @Override
+    public Map<String, List<Integer>> get(DataSet dataSet, List<String> values)
+    {
+        StringBuffer sql = new StringBuffer();
+
+        int i = 0;
+        for ( String value : values )
+        {
+            i++;
+
+            if ( value != null && !value.trim().isEmpty() )
+            {
+                sql.append( "select av.value, de.dataelementid, de.name, de.formname from dataelement de " );
+                sql.append( "join datasetmembers dsm on de.dataelementid = dsm.dataelementid " );
+                sql.append( "join dataelementattributevalues deav on deav.dataelementid = dsm.dataelementid " );
+                sql.append( "join attributevalue av on av.attributevalueid = deav.attributevalueid " );
+                sql.append( "where dsm.datasetid = " + dataSet.getId() + " and av.value='" + value + "'" );
+                sql.append( i == values.size() ? " ORDER BY name" : " UNION " );
+            }
+        }
+
+        SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql.toString() );
+
+        sql = null;
+        String key = null;
+
+        Map<String, List<Integer>> map = new HashMap<String, List<Integer>>();
+
+        while ( rowSet.next() )
+        {
+            key = rowSet.getString( 1 );
+
+            if ( !map.containsKey( key ) )
+            {
+                List<Integer> ids = new ArrayList<Integer>();
+                ids.add( rowSet.getInt( 2 ) );
+
+                map.put( key, ids );
+            }
+            else
+            {
+                map.get( key ).add( rowSet.getInt( 2 ) );
+            }
+        }
+        
+        rowSet = null;
+        key = null;
+        
+        return map;
+    }
 }

=== modified file 'local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java'
--- local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java	2012-09-05 02:17:50 +0000
+++ local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java	2012-09-06 11:47:37 +0000
@@ -27,14 +27,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
 
 import org.hisp.dhis.dataelement.DataElement;
-import org.hisp.dhis.dataelement.LocalDataElementService;
 import org.hisp.dhis.dataset.CompleteDataSetRegistration;
 import org.hisp.dhis.dataset.CompleteDataSetRegistrationService;
 import org.hisp.dhis.dataset.DataSet;
@@ -47,9 +43,7 @@
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodType;
-import org.hisp.dhis.reportsheet.AttributeValueGroupOrder;
-import org.hisp.dhis.reportsheet.AttributeValueGroupOrderService;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.hisp.dhis.util.SessionUtils;
 
 import com.opensymphony.xwork2.Action;
 
@@ -59,6 +53,8 @@
 public class GetDataValuesForDataSetAction
     implements Action
 {
+    protected static final String KEY_ICD_FORM_RESULT = "icdFormResults";
+
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
@@ -98,12 +94,6 @@
         this.organisationUnitService = organisationUnitService;
     }
 
-    @Autowired
-    private LocalDataElementService localDataElementService;
-
-    @Autowired
-    private AttributeValueGroupOrderService attributeValueGroupOrderService;
-
     // -------------------------------------------------------------------------
     // Input
     // -------------------------------------------------------------------------
@@ -182,12 +172,11 @@
         return storedBy;
     }
 
-    private List<String> values = new ArrayList<String>();
-
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
 
+    @SuppressWarnings( "unchecked" )
     public String execute()
     {
         OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( organisationUnitId );
@@ -198,35 +187,24 @@
         // Data values
         // ---------------------------------------------------------------------
 
-        AttributeValueGroupOrder group = attributeValueGroupOrderService.getAttributeValueGroupOrder( chapterId );
-
-        if ( group != null )
-        {
-            values = group.getAttributeValues();
-        }
-
-        if ( values != null && !values.isEmpty() )
-        {
-            Collection<DataElement> dataElements = new HashSet<DataElement>();
-
-            for ( String value : values )
-            {
-                dataElements.addAll( localDataElementService.getDataElements( dataSet, value ) );
-            }
-
-            dataValues = dataValueService.getDataValues( organisationUnit, period, dataElements );
+        Collection<DataElement> dataElements = null;
+
+        if ( chapterId != null && chapterId != -1 )
+        {
+            dataElements = (Collection<DataElement>) SessionUtils.getSessionVar( KEY_ICD_FORM_RESULT );
         }
         else
         {
-            dataValues = dataValueService.getDataValues( organisationUnit, period, dataSet.getDataElements() );
+            dataElements = dataSet.getDataElements();
         }
 
+        dataValues = dataValueService.getDataValues( organisationUnit, period, dataElements );
+
         // ---------------------------------------------------------------------
         // Min-max data elements
         // ---------------------------------------------------------------------
 
-        minMaxDataElements = minMaxDataElementService.getMinMaxDataElements( organisationUnit, dataSet
-            .getDataElements() );
+        minMaxDataElements = minMaxDataElementService.getMinMaxDataElements( organisationUnit, dataElements );
 
         // ---------------------------------------------------------------------
         // Data set completeness info
@@ -246,6 +224,8 @@
 
             locked = dataSetService.isLocked( dataSet, period, organisationUnit, null );
         }
+        
+        dataElements = null;
 
         return SUCCESS;
     }

=== modified file 'local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/LoadICDFormAction.java'
--- local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/LoadICDFormAction.java	2012-09-04 08:23:52 +0000
+++ local/vn/dhis-web-dataentry-hospital/src/main/java/org/hisp/dhis/de/action/LoadICDFormAction.java	2012-09-06 11:47:37 +0000
@@ -31,15 +31,18 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
 import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.dataelement.LocalDataElementService;
 import org.hisp.dhis.dataset.DataSet;
 import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.reportsheet.AttributeValueGroupOrder;
 import org.hisp.dhis.reportsheet.AttributeValueGroupOrderService;
+import org.hisp.dhis.util.SessionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import com.opensymphony.xwork2.Action;
@@ -51,11 +54,16 @@
 public class LoadICDFormAction
     implements Action
 {
+    protected static final String KEY_ICD_FORM_RESULT = "icdFormResults";
+
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
 
     @Autowired
+    private DataElementService dataElementService;
+
+    @Autowired
     private DataSetService dataSetService;
 
     @Autowired
@@ -95,6 +103,11 @@
 
     private List<String> values = new ArrayList<String>();
 
+    public List<String> getValues()
+    {
+        return values;
+    }
+
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -113,17 +126,28 @@
 
         Collections.sort( values );
 
+        Map<String, List<Integer>> orderedDiseaseDEIdentifiers = localDataElementService.get( dataSet, values );
+        
+        Collection<DataElement> dataElementList = new HashSet<DataElement>();
+
+        List<DataElement> dataElements = null;
+        
         for ( String value : values )
         {
-            if ( value != null && !value.trim().isEmpty() )
-            {
-                List<DataElement> dataElements = new ArrayList<DataElement>( localDataElementService.getDataElements(
-                    dataSet, value ) );
+            dataElements = new ArrayList<DataElement>( dataElementService.getDataElements( orderedDiseaseDEIdentifiers.get( value ) ) );
+            
+            dataElementList.addAll( dataElements );
 
-                orderedDiseaseDataElements.put( value, dataElements );
-            }
+            orderedDiseaseDataElements.put( value, dataElements );
         }
 
+        group = null;
+        dataSet = null;
+        dataElements = null;
+        orderedDiseaseDEIdentifiers = null;
+
+        SessionUtils.setSessionVar( KEY_ICD_FORM_RESULT, dataElementList );
+
         return DataSet.TYPE_DEFAULT;
     }
 

=== modified file 'local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/defaultICDForm.vm'
--- local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/defaultICDForm.vm	2012-09-05 02:17:50 +0000
+++ local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/defaultICDForm.vm	2012-09-06 11:47:37 +0000
@@ -1,6 +1,22 @@
+<link href="style/myTheme.css" rel="stylesheet" media="screen" />
+
+<style>
+
+	#filterSpan
+	{
+		width:25em;
+		font-style: oblique;
+		color: #A9A9A9
+	}
+
+	.fancyTable tbody#list input
+	{
+		width: 5em; text-align: right
+	}
+</style>
+
 <script type="text/javascript">
 	jQuery(document).ready( function() {
-		setTableStyles();
 
 		var filterSpan = jQuery( "#filterSpan" );
 		filterSpan.val( i18n_filter_disease_or_icd_code );
@@ -18,9 +34,9 @@
 #set( $tabIndex = 1 )
 #set( $hasAccess = $auth.hasAccess( "dhis-web-dataentry-hospital", "saveValue" ) )
 
-<table class="listTable" id="listTable" cellspacing="0">
+<table class="fancyTable" id="listTable" cellspacing="0">
 	<thead>
-	<tr><td><span><input type="text" id="filterSpan" style="width:25em" onkeyup="filterValues( this.value, 1 );"/></span></td>
+	<tr><th><span><input type="text" id="filterSpan" onkeyup="filterValues( this.value, 1 );"/></span></th>
 		<th>$i18n.getString( "icd_element_1" )</th>
 		<th>$i18n.getString( "icd_element_2" )</th>
 		<th>$i18n.getString( "icd_element_3" )</th>
@@ -37,7 +53,7 @@
 	</thead>
 
 	<tbody id="list">
-	#foreach( $key in $!orderedDiseaseDataElements.keySet() )
+	#foreach( $key in $!values )
 	<tr>
 		<td>${encoder.htmlEncode( $key )}</td>
 		#foreach( $dataElement in $!orderedDiseaseDataElements.get( $key ) )

=== modified file 'local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/form.js'
--- local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/form.js	2012-09-05 02:17:50 +0000
+++ local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/form.js	2012-09-06 11:47:37 +0000
@@ -569,17 +569,13 @@
 
 	var chapterId = getFieldValue( 'chapterId' );
 	var	url = ( chapterId && chapterId != -1 ? 'loadICDForm.action' : 'loadForm.action' );
-	
-	if ( chapterId )
-	{
-	}
 
 	$( '#contentDiv' ).load( url,
 	{
 		dataSetId : dataSetId,
 		chapterId: chapterId,
-		value: value
-	}, 
+		value: (value == undefined ? "" : value)
+	},
 	function ( responseText, textStatus, req )
 	{
 		if ( textStatus == "error" ) {

=== added file 'local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/jquery.fixedheadertable.js'
--- local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/jquery.fixedheadertable.js	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/javascript/jquery.fixedheadertable.js	2012-09-06 11:47:37 +0000
@@ -0,0 +1,705 @@
+/*!
+ * jquery.fixedHeaderTable. The jQuery fixedHeaderTable plugin
+ *
+ * Copyright (c) 2011 Mark Malek
+ * http://fixedheadertable.com
+ *
+ * Licensed under MIT
+ * http://www.opensource.org/licenses/mit-license.php
+ * 
+ * http://docs.jquery.com/Plugins/Authoring
+ * jQuery authoring guidelines
+ *
+ * Launch  : October 2009
+ * Version : 1.3
+ * Released: May 9th, 2011
+ *
+ * 
+ * all CSS sizing (width,height) is done in pixels (px)
+ */
+
+(function ($) {
+
+    $.fn.fixedHeaderTable = function (method) {
+
+        // plugin's default options
+        var defaults = {
+            
+            width:          '100%',
+            height:         '100%',
+            themeClass:     'fht-default',
+            borderCollapse:  true,
+            fixedColumns:    0, // fixed first columns
+            fixedColumn:     false, // For backward-compatibility
+            sortable:        false,
+            autoShow:        true, // hide table after its created
+            footer:          false, // show footer
+            cloneHeadToFoot: false, // clone head and use as footer
+            autoResize:      false, // resize table if its parent wrapper changes size
+            create:          null // callback after plugin completes
+        };
+
+        var settings = {};
+
+        // public methods
+        var methods = {
+            init: function (options) {
+                settings = $.extend({}, defaults, options);
+
+                // iterate through all the DOM elements we are attaching the plugin to
+                return this.each(function () {
+                    var $self = $(this), // reference the jQuery version of the current DOM element
+                    self = this; // reference to the actual DOM element
+                    
+                    if (helpers._isTable($self)) {
+                        methods.setup.apply(this, Array.prototype.slice.call(arguments, 1));
+                        $.isFunction(settings.create) && settings.create.call(this);
+                    } else {
+			$.error('Invalid table mark-up');
+		    }
+                });
+            },
+	    
+	    /*
+	     * Setup table structure for fixed headers and optional footer
+	     */
+            setup: function (options) {
+                var $self  = $(this),
+                self   = this,
+                $thead = $self.find('thead'),
+                $tfoot = $self.find('tfoot'),
+                $tbody = $self.find('tbody'),
+                $wrapper,
+                $divHead,
+                $divFoot,
+                $divBody,
+                $fixedHeadRow,
+                $temp,
+                tfootHeight = 0;
+                
+                settings.originalTable = $(this).clone();
+                settings.includePadding = helpers._isPaddingIncludedWithWidth();
+                settings.scrollbarOffset = helpers._getScrollbarWidth();
+		settings.themeClassName = settings.themeClass;
+		
+		if (settings.width.search('%') > -1) {
+		    var widthMinusScrollbar = $self.parent().width() - settings.scrollbarOffset;
+		} else {
+		    var widthMinusScrollbar = settings.width - settings.scrollbarOffset;				
+		}
+		
+                $self.css({
+	            width: widthMinusScrollbar
+	        });
+	        
+
+                if (!$self.closest('.fht-table-wrapper').length) {
+                    $self.addClass('fht-table');
+                    $self.wrap('<div class="fht-table-wrapper"></div>');
+                }
+
+                $wrapper = $self.closest('.fht-table-wrapper');
+                
+                if(settings.fixedColumn == true && settings.fixedColumns <= 0) {
+                	settings.fixedColumns = 1;
+                }
+                
+                if (settings.fixedColumns > 0 && $wrapper.find('.fht-fixed-column').length == 0) {
+                    $self.wrap('<div class="fht-fixed-body"></div>');
+                    
+                    var $fixedColumns = $('<div class="fht-fixed-column"></div>').prependTo($wrapper),
+                    $fixedBody	 = $wrapper.find('.fht-fixed-body');
+                }
+                
+                $wrapper.css({
+	            width: settings.width,
+	            height: settings.height
+	        })
+	            .addClass(settings.themeClassName);
+
+                if (!$self.hasClass('fht-table-init')) {
+                    
+                    $self.wrap('<div class="fht-tbody"></div>');
+                    
+                }
+		$divBody = $self.closest('.fht-tbody');
+		
+                var tableProps = helpers._getTableProps($self);
+                
+                helpers._setupClone($divBody, tableProps.tbody);
+
+                if (!$self.hasClass('fht-table-init')) {
+                    if (settings.fixedColumns > 0) {
+                	$divHead = $('<div class="fht-thead"><table class="fht-table"></table></div>').prependTo($fixedBody);
+                    } else {
+                	$divHead = $('<div class="fht-thead"><table class="fht-table"></table></div>').prependTo($wrapper);
+                    }
+                    
+                    $divHead.find('table.fht-table').addClass(settings.originalTable.attr('class'));
+                    $thead.clone().appendTo($divHead.find('table'));
+                } else {
+                    $divHead = $wrapper.find('div.fht-thead');
+                }
+
+                helpers._setupClone($divHead, tableProps.thead);
+                
+                $self.css({
+                    'margin-top': -$divHead.outerHeight(true)
+                });
+                
+                /*
+                 * Check for footer
+                 * Setup footer if present
+                 */
+                if (settings.footer == true) {
+
+                    helpers._setupTableFooter($self, self, tableProps);
+                    
+                    if (!$tfoot.length) {
+                	$tfoot = $wrapper.find('div.fht-tfoot table');
+                    }
+                    
+                    tfootHeight = $tfoot.outerHeight(true);
+                }
+
+                var tbodyHeight = $wrapper.height() - $thead.outerHeight(true) - tfootHeight - tableProps.border;
+                
+                $divBody.css({
+	            'height': tbodyHeight
+	        });
+                
+                $self.addClass('fht-table-init');
+                
+                if (typeof(settings.altClass) !== 'undefined') {
+                    methods.altRows.apply(self);
+                }
+                
+                if (settings.fixedColumns > 0) {
+                    helpers._setupFixedColumn($self, self, tableProps);
+                }
+                
+                if (!settings.autoShow) {
+                    $wrapper.hide();
+                }
+                
+                helpers._bindScroll($divBody, tableProps);
+                
+                return self;
+            },
+            
+            /*
+             * Resize the table
+             * Incomplete - not implemented yet
+             */
+            resize: function(options) {
+            	var $self = $(this),
+            	self  = this;
+            	return self;
+            },
+            
+            /*
+             * Add CSS class to alternating rows
+             */
+            altRows: function(arg1) {
+            	var $self       = $(this),
+            	self            = this,
+            	altClass        = (typeof(arg1) !== 'undefined') ? arg1 : settings.altClass;
+            	
+            	$self.closest('.fht-table-wrapper')
+            	    .find('tbody tr:odd:not(:hidden)')
+            	    .addClass(altClass);
+            },
+            
+            /*
+             * Show a hidden fixedHeaderTable table
+             */
+            show: function(arg1, arg2, arg3) {
+                var $self		= $(this),
+                self  		= this,
+                $wrapper 	= $self.closest('.fht-table-wrapper');
+
+		// User provided show duration without a specific effect
+                if (typeof(arg1) !== 'undefined' && typeof(arg1) === 'number') {
+                    
+                    $wrapper.show(arg1, function() {
+                	$.isFunction(arg2) && arg2.call(this);
+                    });
+
+                    return self;
+                    
+                } else if (typeof(arg1) !== 'undefined' && typeof(arg1) === 'string'
+                	    && typeof(arg2) !== 'undefined' && typeof(arg2) === 'number') {
+		    // User provided show duration with an effect
+		    
+                    $wrapper.show(arg1, arg2, function() {
+                	$.isFunction(arg3) && arg3.call(this);
+                    });
+                    
+                    return self;
+                    
+                }
+                
+            	$self.closest('.fht-table-wrapper')
+                    .show();
+                $.isFunction(arg1) && arg1.call(this);
+                
+                return self;
+            },
+            
+            /*
+             * Hide a fixedHeaderTable table
+             */
+            hide: function(arg1, arg2, arg3) {
+                var $self 		= $(this),
+                self		= this,
+                $wrapper 	= $self.closest('.fht-table-wrapper');
+                
+                // User provided show duration without a specific effect
+                if (typeof(arg1) !== 'undefined' && typeof(arg1) === 'number') {
+                    $wrapper.hide(arg1, function() {
+                	$.isFunction(arg3) && arg3.call(this);
+                    });
+                    
+                    return self;
+                } else if (typeof(arg1) !== 'undefined' && typeof(arg1) === 'string'
+                	    && typeof(arg2) !== 'undefined' && typeof(arg2) === 'number') {
+
+                    $wrapper.hide(arg1, arg2, function() {
+                	$.isFunction(arg3) && arg3.call(this);
+                    });
+                    
+                    return self;
+                }
+                
+                $self.closest('.fht-table-wrapper')
+                    .hide();
+                
+                $.isFunction(arg3) && arg3.call(this);
+                
+                
+                
+                return self;
+            },
+            
+            /*
+             * Destory fixedHeaderTable and return table to original state
+             */
+            destroy: function() {
+                var $self    = $(this),
+                self     = this,
+                $wrapper = $self.closest('.fht-table-wrapper');
+                
+                $self.insertBefore($wrapper)
+                    .removeAttr('style')
+                    .append($wrapper.find('tfoot'))
+                    .removeClass('fht-table fht-table-init')
+                    .find('.fht-cell')
+                    .remove();
+                
+                $wrapper.remove();
+                
+                return self;
+            }
+
+        }
+
+        // private methods
+        var helpers = {
+
+	    /*
+	     * return boolean
+	     * True if a thead and tbody exist.
+	     */
+            _isTable: function($obj) {
+                var $self = $obj,
+                hasTable = $self.is('table'),
+                hasThead = $self.find('thead').length > 0,
+                hasTbody = $self.find('tbody').length > 0;
+
+                if (hasTable && hasThead && hasTbody) {
+                    return true;
+                }
+                
+                return false;
+
+            },
+            
+            /*
+             * return void
+             * bind scroll event
+             */
+            _bindScroll: function($obj, tableProps) {
+            	var $self = $obj,
+            	$wrapper = $self.closest('.fht-table-wrapper'),
+            	$thead = $self.siblings('.fht-thead'),
+            	$tfoot = $self.siblings('.fht-tfoot');
+            	
+            	$self.bind('scroll', function() {
+            	    if (settings.fixedColumns > 0) {
+            	        var $fixedColumns = $wrapper.find('.fht-fixed-column');
+            	        
+            	        $fixedColumns.find('.fht-tbody table')
+            	            .css({
+            	                'margin-top': -$self.scrollTop()
+            	            });
+            	    }
+            	    
+            	    $thead.find('table')
+            		.css({
+            		    'margin-left': -this.scrollLeft
+            		});
+            	    
+            	    if (settings.footer || settings.cloneHeadToFoot) {
+            		$tfoot.find('table')
+	            	    .css({
+	            		'margin-left': -this.scrollLeft
+	            	    });
+            	    }
+            	});
+            },
+            
+            /*
+             * return void
+             */
+            _fixHeightWithCss: function ($obj, tableProps) {
+            	if (settings.includePadding) {
+	            $obj.css({
+	            	'height': $obj.height() + tableProps.border
+	            });
+            	} else {
+            	    $obj.css({
+            		'height': $obj.parent().height() + tableProps.border
+            	    });
+            	}
+            },
+            
+            /*
+             * return void
+             */
+            _fixWidthWithCss: function($obj, tableProps, width) {
+            	if (settings.includePadding) {
+            	    $obj.each(function(index) {
+			$(this).css({
+            		    'width': width == undefined ? $(this).width() + tableProps.border : width + tableProps.border
+			});
+            	    }); 
+            	} else {
+            	    $obj.each(function(index) {
+			$(this).css({
+            		    'width': width == undefined ? $(this).parent().width() + tableProps.border : width + tableProps.border
+			});
+            	    });
+            	}
+
+            },
+            
+            /*
+             * return void
+             */
+	    _setupFixedColumn: function ($obj, obj, tableProps) {
+		var $self		= $obj,
+		self			= obj,
+		$wrapper		= $self.closest('.fht-table-wrapper'),
+		$fixedBody		= $wrapper.find('.fht-fixed-body'),
+		$fixedColumn		= $wrapper.find('.fht-fixed-column'),
+		$thead			= $('<div class="fht-thead"><table class="fht-table"><thead><tr></tr></thead></table></div>'),
+		$tbody			= $('<div class="fht-tbody"><table class="fht-table"><tbody></tbody></table></div>'),
+		$tfoot			= $('<div class="fht-tfoot"><table class="fht-table"><tfoot><tr></tr></tfoot></table></div>'),
+		$firstThChildren,//	= $fixedBody.find('.fht-thead thead tr > *:first-child'),
+		$firstTdChildren,
+		fixedColumnWidth,//	= $firstThChild.outerWidth(true) + tableProps.border,
+		fixedBodyWidth		= $wrapper.width(),
+		fixedBodyHeight		= $fixedBody.find('.fht-tbody').height() - settings.scrollbarOffset,
+		$newRow;
+
+		$thead.find('table.fht-table').addClass(settings.originalTable.attr('class'));
+		$tbody.find('table.fht-table').addClass(settings.originalTable.attr('class'));
+		$tfoot.find('table.fht-table').addClass(settings.originalTable.attr('class'));
+		
+		$firstThChildren = $fixedBody.find('.fht-thead thead tr > *:lt(' + settings.fixedColumns + ')');
+		fixedColumnWidth = settings.fixedColumns * tableProps.border;
+		$firstThChildren.each(function(index) {
+		    fixedColumnWidth += $(this).outerWidth(true);
+		});
+
+		// Fix cell heights
+		helpers._fixHeightWithCss($firstThChildren, tableProps);
+		helpers._fixWidthWithCss($firstThChildren, tableProps);
+
+		var tdWidths = [];
+		$firstThChildren.each(function(index) {
+		    tdWidths.push($(this).width());
+		});
+
+		firstTdChildrenSelector = 'tbody tr > *:not(:nth-child(n+' + (settings.fixedColumns + 1) + '))';
+		$firstTdChildren = $fixedBody.find(firstTdChildrenSelector)
+		    .each(function(index) {
+			helpers._fixHeightWithCss($(this), tableProps);
+			helpers._fixWidthWithCss($(this), tableProps, tdWidths[index % settings.fixedColumns] );
+		    });
+
+		// clone header
+		$thead.appendTo($fixedColumn)
+		    .find('tr')
+		    .append($firstThChildren.clone());
+		
+		$tbody.appendTo($fixedColumn)
+		    .css({
+			'margin-top': -1,
+			'height': fixedBodyHeight + tableProps.border
+		    });
+
+		var $newRow;
+		$firstTdChildren.each(function(index) {
+		    if (index % settings.fixedColumns == 0) {
+			$newRow = $('<tr></tr>').appendTo($tbody.find('tbody'));
+			
+			if (settings.altClass && $(this).parent().hasClass(settings.altClass)) {
+			    $newRow.addClass(settings.altClass);
+			} 
+		    }
+		    
+		    $(this).clone()
+			.appendTo($newRow);
+		});
+		
+		// set width of fixed column wrapper
+		$fixedColumn.css({
+		    'height': 0,
+		    'width': fixedColumnWidth
+		})
+
+
+		// bind mousewheel events
+		var maxTop = $fixedColumn.find('.fht-tbody .fht-table').height() - $fixedColumn.find('.fht-tbody').height();
+		$fixedColumn.find('.fht-table').bind('mousewheel', function(event, delta, deltaX, deltaY) {
+		    if (deltaY == 0) return;
+		    var top = parseInt($(this).css('marginTop'), 10) + (deltaY > 0 ? 120 : -120);
+		    if (top > 0) top = 0;
+		    if (top < -maxTop) top = -maxTop;
+		    $(this).css('marginTop', top);
+		    $fixedBody.find('.fht-tbody').scrollTop(-top).scroll();
+		    return false;
+		});
+
+		
+		// set width of body table wrapper
+		$fixedBody.css({
+		    'width': fixedBodyWidth
+		});
+		
+		// setup clone footer with fixed column
+		if (settings.footer == true || settings.cloneHeadToFoot == true) {
+		    var $firstTdFootChild = $fixedBody.find('.fht-tfoot tr > *:lt(' + settings.fixedColumns + ')');
+		    
+		    helpers._fixHeightWithCss($firstTdFootChild, tableProps);
+		    $tfoot.appendTo($fixedColumn)
+			.find('tr')
+			.append($firstTdFootChild.clone());
+		    // Set (view width) of $tfoot div to width of table (this accounts for footers with a colspan)
+		    footwidth = $tfoot.find('table').innerWidth();
+		    $tfoot.css({
+			'top': settings.scrollbarOffset,
+			'width': footwidth
+		    });
+		}
+	    },
+            
+            /*
+             * return void
+             */
+            _setupTableFooter: function ($obj, obj, tableProps) {
+            	
+            	var $self 		= $obj,
+            	self  		= obj,
+            	$wrapper 	= $self.closest('.fht-table-wrapper'),
+            	$tfoot		= $self.find('tfoot'),
+            	$divFoot	= $wrapper.find('div.fht-tfoot');
+            	
+            	if (!$divFoot.length) {
+            	    if (settings.fixedColumns > 0) {
+            		$divFoot = $('<div class="fht-tfoot"><table class="fht-table"></table></div>').appendTo($wrapper.find('.fht-fixed-body'));
+            	    } else {
+            		$divFoot = $('<div class="fht-tfoot"><table class="fht-table"></table></div>').appendTo($wrapper);
+            	    }
+            	}
+            	$divFoot.find('table.fht-table').addClass(settings.originalTable.attr('class'));
+
+            	switch (true) {
+            	case !$tfoot.length && settings.cloneHeadToFoot == true && settings.footer == true:
+            	    
+            	    var $divHead = $wrapper.find('div.fht-thead');
+            	    
+            	    $divFoot.empty();
+            	    $divHead.find('table')
+            		.clone()
+            		.appendTo($divFoot);
+            	    
+            	    break;
+            	case $tfoot.length && settings.cloneHeadToFoot == false && settings.footer == true:
+            	    
+            	    $divFoot.find('table')
+            		.append($tfoot)
+	                .css({
+	                    'margin-top': -tableProps.border
+	                });
+            	    
+            	    helpers._setupClone($divFoot, tableProps.tfoot);
+            	    
+            	    break;
+            	}
+            	
+            },
+            
+            /*
+             * return object
+             * Widths of each thead cell and tbody cell for the first rows.
+             * Used in fixing widths for the fixed header and optional footer.
+             */
+            _getTableProps: function($obj) {
+                var tableProp = {
+                    thead: {},
+                    tbody: {},
+                    tfoot: {},
+                    border: 0
+                },
+                borderCollapse = 1;
+                
+                if (settings.borderCollapse == true) {
+                    borderCollapse = 2;
+                }
+		
+		tableProp.border = ($obj.find('th:first-child').outerWidth() - $obj.find('th:first-child').innerWidth()) / borderCollapse;
+		
+                $obj.find('thead tr:first-child > *').each(function(index) {
+                    tableProp.thead[index] = $(this).width() + tableProp.border;
+                });
+                
+                $obj.find('tfoot tr:first-child > *').each(function(index) {
+                    tableProp.tfoot[index] = $(this).width() + tableProp.border;
+                });
+                
+                $obj.find('tbody tr:first-child > *').each(function(index) {
+                    tableProp.tbody[index] = $(this).width() + tableProp.border;
+                });
+
+                return tableProp;
+            },
+            
+            /*
+             * return void
+             * Fix widths of each cell in the first row of obj.
+             */
+            _setupClone: function($obj, cellArray) {
+                var $self    = $obj,
+                selector = ($self.find('thead').length) ?
+                    'thead tr:first-child > *' : 
+                    ($self.find('tfoot').length) ?
+                    'tfoot tr:first-child > *' :
+                    'tbody tr:first-child > *',
+                $cell;
+                
+                $self.find(selector).each(function(index) {
+                    $cell = ($(this).find('div.fht-cell').length) ? $(this).find('div.fht-cell') : $('<div class="fht-cell"></div>').appendTo($(this));
+		    
+                    $cell.css({
+                        'width': parseInt(cellArray[index])
+                    });
+                    
+                    /*
+                     * Fixed Header and Footer should extend the full width
+                     * to align with the scrollbar of the body 
+                     */
+                    if (!$(this).closest('.fht-tbody').length && $(this).is(':last-child') && !$(this).closest('.fht-fixed-column').length) {
+                    	var padding = (($(this).innerWidth() - $(this).width()) / 2) + settings.scrollbarOffset;
+                    	$(this).css({
+                    	    'padding-right': padding + 'px'
+                    	});
+                    }
+                });
+            },
+            
+            /*
+             * return boolean
+             * Determine how the browser calculates fixed widths with padding for tables
+             * true if width = padding + width
+             * false if width = width
+             */
+            _isPaddingIncludedWithWidth: function() {
+            	var $obj 			= $('<table class="fht-table"><tr><td style="padding: 10px; font-size: 10px;">test</td></tr></table>'),
+            	defaultHeight,
+            	newHeight;
+            	
+            	$obj.addClass(settings.originalTable.attr('class'));
+            	$obj.appendTo('body');
+            	
+            	defaultHeight = $obj.find('td').height();
+            	
+            	$obj.find('td')
+            	    .css('height', $obj.find('tr').height());
+            	
+            	newHeight = $obj.find('td').height();
+            	$obj.remove();
+
+            	if (defaultHeight != newHeight) {
+            	    return true;
+            	} else {
+            	    return false;
+            	}
+            	
+            },
+            
+            /*
+             * return int
+             * get the width of the browsers scroll bar
+             */
+            _getScrollbarWidth: function() {
+            	var scrollbarWidth = 0;
+            	
+            	if (!scrollbarWidth) {
+		    if ($.browser.msie) {
+			var $textarea1 = $('<textarea cols="10" rows="2"></textarea>')
+			    .css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body'),
+			$textarea2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>')
+			    .css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body');
+			scrollbarWidth = $textarea1.width() - $textarea2.width() + 2; // + 2 for border offset
+			$textarea1.add($textarea2).remove();
+		    } else {
+			var $div = $('<div />')
+			    .css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: -1000 })
+			    .prependTo('body').append('<div />').find('div')
+			    .css({ width: '100%', height: 200 });
+			scrollbarWidth = 100 - $div.width();
+			$div.parent().remove();
+		    }
+		}
+		
+		return scrollbarWidth;
+            }
+
+        }
+
+
+        // if a method as the given argument exists
+        if (methods[method]) {
+
+            // call the respective method
+            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+
+            // if an object is given as method OR nothing is given as argument
+        } else if (typeof method === 'object' || !method) {
+
+            // call the initialization method
+            return methods.init.apply(this, arguments);
+
+            // otherwise
+        } else {
+
+            // trigger an error
+            $.error('Method "' +  method + '" does not exist in fixedHeaderTable plugin!');
+
+        }
+
+    };
+
+})(jQuery);

=== modified file 'local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/select.vm'
--- local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/select.vm	2012-09-05 02:17:50 +0000
+++ local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/select.vm	2012-09-06 11:47:37 +0000
@@ -1,3 +1,4 @@
+<!--script type="text/javascript" src="javascript/jquery.fixedheadertable.js"></script-->
 <script type="text/javascript">
 	jQuery(document).ready( function() {
 		jQuery.get( '../dhis-web-spreadsheet-reporting/getAttributeValueGroupOrders.action',
@@ -56,18 +57,6 @@
 		<td><select id='chapterId' name='chapterId' style="width:370px" onchange="loadFormByChapter( this.value );"></select></td>
 	</tr>
 
-	<!--tr id='attributeTR' style='display:none;'>
-		<td>
-			<label class='bold' for="attributeId">$i18n.getString( "disease" )</label>
-		</td>
-		<td>
-			<select id='value' name='value' style='display:none;' ></select>
-			<input type="text" id="valueInput" style="width:210px" name="valueInput" />
-			<button type='button' id='valueButton' class='small-button' >&nbsp;</button>
-			<input type="button" id="showReportButton" value="$i18n.getString( 'show_icd_report' )" style="display:none;width:120px" onclick="showICDReport();"/>
-		</td>
-	</tr-->
-
 </table>
 </div>
 

=== added file 'local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/style/myTheme.css'
--- local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/style/myTheme.css	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-dataentry-hospital/src/main/webapp/dhis-web-dataentry-hospital/style/myTheme.css	2012-09-06 11:47:37 +0000
@@ -0,0 +1,239 @@
+.divider {
+	margin-top: 40px;
+	}
+	
+.button {
+	/* appearance */
+	background-color: #3f3f3f;
+	background-image: -moz-linear-gradient(
+		top,
+		rgba(255,255,255,0.0) 0%,
+		rgba(255,255,255,0.1) 50%);
+	
+	background-image: -webkit-gradient(
+		linear, left top, left bottom,
+		color-stop(100%,rgba(255,255,255,0.0)),
+		color-stop(50%,rgba(255,255,255,0.1)));
+	border: 1px solid #000000;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	border-radius: 5px;
+	-webkit-box-shadow: 0 1px 0 rgba(139,139,139,1) inset, 0 1px 0 rgba(88,88,88,1);
+	-moz-box-shadow: 0 1px 0 rgba(139,139,139,1) inset, 0 1px 0 rgba(88,88,88,1);
+	box-shadow: 0 1px 0 rgba(139,139,139,1) inset, 0 1px 0 rgba(88,88,88,1);
+	cursor: pointer;
+	
+	/* position */
+	display: inline-block;
+	margin: 10px;
+	
+	/* size */
+	padding: 0 10px;
+	
+	/* text */
+	color: #eaeaea;
+	font-size: 12px;
+	line-height: 30px;
+	text-decoration: none;
+	white-space: nowrap;
+	}
+.button:hover {
+	/* appearance */
+	background-color: #6495ed;
+	-webkit-box-shadow: 0 0 3px #6495ed;
+	-moz-box-shadow: 0 0 3px #6495ed;
+	box-shadow: 0 0 3px #6495ed;
+	}
+
+.myTableWrapper {
+	width: 800px;
+	height: 500px;
+	}
+
+.height250 {
+        height: 250px;
+        overflow-x: auto;
+        overflow-y: auto;
+}
+
+.height400 {
+        height: 400px;
+        overflow-x: auto;
+        overflow-y: auto;
+}
+
+.fancyTable td, .fancyTable th {
+	/* appearance */
+	border: 1px solid #778899;
+	
+	/* size */
+	padding: 5px;
+	}
+
+.fancyTable {
+	/* text */
+	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+	}
+
+.fancyTable tbody tr td {
+	/* appearance */
+	background-color: #eef2f9;
+	background-image: -moz-linear-gradient(
+		top,
+		rgba(255,255,255,0.4) 0%,
+		rgba(255,255,255,0.2) 50%,
+		rgba(255,255,255,0.1) 51%,
+		rgba(255,255,255,0.0) 100%);
+	
+	background-image: -webkit-gradient(
+		linear, left top, left bottom,
+		color-stop(0%,rgba(255,255,255,0.4)),
+		color-stop(50%,rgba(255,255,255,0.2)),
+		color-stop(51%,rgba(255,255,255,0.1)),
+		color-stop(100%,rgba(255,255,255,0.0)));
+		
+	/* text */
+	color: #262c31;
+	font-size: 11px;
+	}
+
+.fancyTable tbody tr.odd td {
+	/* appearance */
+	background-color: #d6e0ef;
+	background-image: -moz-linear-gradient(
+		top,
+		rgba(255,255,255,0.4) 0%,
+		rgba(255,255,255,0.2) 50%,
+		rgba(255,255,255,0.1) 51%,
+		rgba(255,255,255,0.0) 100%);
+	
+	background-image: -webkit-gradient(
+		linear, left top, left bottom,
+		color-stop(0%,rgba(255,255,255,0.4)),
+		color-stop(50%,rgba(255,255,255,0.2)),
+		color-stop(51%,rgba(255,255,255,0.1)),
+		color-stop(100%,rgba(255,255,255,0.0)));
+	}
+
+.fancyTable thead tr th,
+.fancyTable thead tr td,
+.fancyTable tfoot tr th, 
+.fancyTable tfoot tr td {
+	/* appearance */
+	background-color: #8ca9cf;
+	background-image: -moz-linear-gradient(
+		top,
+		rgba(255,255,255,0.4) 0%,
+		rgba(255,255,255,0.2) 50%,
+		rgba(255,255,255,0.1) 51%,
+		rgba(255,255,255,0.0) 100%);
+	
+	background-image: -webkit-gradient(
+		linear, left top, left bottom,
+		color-stop(0%,rgba(255,255,255,0.4)),
+		color-stop(50%,rgba(255,255,255,0.2)),
+		color-stop(51%,rgba(255,255,255,0.1)),
+		color-stop(100%,rgba(255,255,255,0.0)));
+		
+	/* text */
+	color: #121517;
+	font-size: 12px;
+	font-weight: bold;
+	text-shadow: 0 1px 1px #e8ebee;
+	}
+	
+
+/* Fancy Dark Table */	
+.fancyDarkTable .numeric {
+	/* text */
+	text-align: right;
+	}
+
+.fancyDarkTable td, .fancyDarkTable th {
+	border: 1px solid #000000;
+	padding: 5px;
+}
+
+.fancyDarkTable thead tr th {
+	padding: 10px 5px 10px 5px;
+	}
+
+.fancyDarkTable {
+	/*border-collapse: separate;*/
+	
+	/* text */
+	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+	}
+
+.fancyDarkTable tbody tr td {
+	/* appearance */
+	background-color: #48535e;
+	background-image: -moz-linear-gradient(
+		top,
+		rgba(255,255,255,0.0) 0%,
+		rgba(255,255,255,0.02) 100%);
+	
+	background-image: -webkit-gradient(
+		linear, left top, left bottom,
+		color-stop(0%,rgba(255,255,255,0.0)),
+		color-stop(100%,rgba(255,255,255,0.02)));
+	border-bottom-color: #22272e;
+	border-top-color: #708090;
+	border-right-color: #000;
+	border-left-color: #3c454f;
+
+	/* size */
+	padding: 10px 5px 30px 5px;
+
+	/* text */
+	color: #FFFFFF;
+	font-size: 11px;
+	font-weight: bold;
+	text-shadow: 0 -1px 1px #000000;
+	}
+
+.fancyDarkTable tbody tr.odd td {
+	/* appearance */
+	background-color: #3c454f;
+	background-image: -moz-linear-gradient(
+		top,
+		rgba(255,255,255,0.0) 0%,
+		rgba(255,255,255,0.02) 100%);
+	
+	background-image: -webkit-gradient(
+		linear, left top, left bottom,
+		color-stop(0%,rgba(255,255,255,0.0)),
+		color-stop(100%,rgba(255,255,255,0.02)));
+	border-right-color: #000;
+	}
+
+.fancyDarkTable thead tr th,
+.fancyDarkTable tfoot tr td {
+	/* appearance */
+	background-color: #0b0d10;
+	background-image: -moz-linear-gradient(
+		top,
+		rgba(255,255,255,0.4) 0%,
+		rgba(255,255,255,0.2) 50%,
+		rgba(255,255,255,0.1) 51%,
+		rgba(255,255,255,0.0) 100%);
+	
+	background-image: -webkit-gradient(
+		linear, left top, left bottom,
+		color-stop(0%,rgba(255,255,255,0.4)),
+		color-stop(50%,rgba(255,255,255,0.2)),
+		color-stop(51%,rgba(255,255,255,0.1)),
+		color-stop(100%,rgba(255,255,255,0.0)));
+		
+	/* text */
+	color: #ffffff;
+	font-size: 12px;
+	font-weight: bold;
+	text-shadow: 0 -1px 1px #000;
+	}
+	
+.fancyDarkTable .fht-head {
+	-webkit-box-shadow: 0 5px 10px #000;
+	z-index: 1;
+	position: relative;
+	}
\ No newline at end of file