← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15520: Added category option start and end dates, blueprint category-start-end-dates

 

------------------------------------------------------------
revno: 15520
committer: jimgrace@xxxxxxxxx
branch nick: dhis2
timestamp: Mon 2014-06-02 11:29:13 -0400
message:
  Added category option start and end dates, blueprint category-start-end-dates
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.xml
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementCategoryOption.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/style/dhis-web-dataentry.css
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryOptionAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryOptionAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/addDataElementCategoryOptionForm.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/categoryOption.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryOptionForm.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 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java	2014-04-25 11:22:12 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java	2014-06-02 15:29:13 +0000
@@ -28,6 +28,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -59,6 +60,10 @@
 
     public static final String DEFAULT_NAME = "default";
 
+    private Date startDate;
+
+    private Date endDate;
+
     private Set<DataElementCategory> categories = new HashSet<DataElementCategory>();
 
     @Scanned
@@ -152,6 +157,30 @@
     }
 
     @JsonProperty
+    @JsonView( {DetailedView.class } )
+    public Date getStartDate()
+    {
+        return startDate;
+    }
+
+    public void setStartDate( Date startDate )
+    {
+        this.startDate = startDate;
+    }
+
+    @JsonProperty
+    @JsonView( {DetailedView.class } )
+    public Date getEndDate()
+    {
+        return endDate;
+    }
+
+    public void setEndDate( Date endDate )
+    {
+        this.endDate = endDate;
+    }
+
+    @JsonProperty
     @JsonSerialize(contentAs = BaseIdentifiableObject.class)
     @JsonView({ DetailedView.class })
     @JacksonXmlElementWrapper(localName = "categories", namespace = DxfNamespaces.DXF_2_0)

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.xml	2014-03-11 16:06:51 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.xml	2014-06-02 15:29:13 +0000
@@ -17,6 +17,10 @@
 
     <property name="name" column="name" not-null="true" unique="true" length="230" />
 
+    <property name="startDate" type="timestamp" />
+
+    <property name="endDate" type="timestamp" />
+
     <set name="categoryOptionCombos" table="categoryoptioncombos_categoryoptions" inverse="true">
       <cache usage="read-write" />
       <key column="categoryoptionid" foreign-key="fk_categoryoptioncombos_categoryoptions_categoryoptionid" />

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementCategoryOption.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementCategoryOption.vm	2013-02-22 14:58:47 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementCategoryOption.vm	2014-06-02 15:29:13 +0000
@@ -2,6 +2,8 @@
   {
     "id":  "${dataElementCategoryOption.id}" ,
     "name": "$!encoder.jsonEncode( ${dataElementCategoryOption.name} )",
+    "startDate": "$!format.formatDate( ${dataElementCategoryOption.startDate} )",
+    "endDate": "$!format.formatDate( ${dataElementCategoryOption.endDate} )",
 	"concept": "$!encoder.jsonEncode(${dataElementCategoryOption.concept.name})"
   }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml	2014-02-11 15:34:53 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml	2014-06-02 15:29:13 +0000
@@ -13,7 +13,7 @@
       <result name="success" type="velocity">/main.vm</result>
       <param name="page">/dhis-web-dataentry/select.vm</param>
       <param name="menu">/dhis-web-dataentry/menu.vm</param>
-      <param name="javascripts">../dhis-web-commons/ouwt/ouwt.js,javascript/form.js,javascript/entry.js,javascript/history.js</param>
+      <param name="javascripts">../dhis-web-commons/ouwt/ouwt.js,../dhis-web-commons/javascripts/ext/ext-all.js,javascript/form.js,javascript/entry.js,javascript/history.js</param>
       <param name="stylesheets">style/dhis-web-dataentry.css</param>
       <param name="manifest">../dhis-web-commons/cacheManifest.action</param>
     </action>

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js	2014-05-23 13:27:48 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js	2014-06-02 15:29:13 +0000
@@ -380,9 +380,6 @@
 
 function addEventListeners()
 {
-    var dataSetId = $( '#selectedDataSetId' ).val();
-	var formType = dhis2.de.dataSets[dataSetId].type;
-
     $( '.entryfield' ).each( function( i )
     {
         var id = $( this ).attr( 'id' );
@@ -692,6 +689,21 @@
     return split;
 }
 
+/**
+ * Creates an associative array with values of the current period.
+ */
+function currentPeriod()
+{
+    var period = {};
+    var part = ( $( '#selectedPeriodId' ).val() || "" ).split( ',' );
+
+    period.iso = part[0];
+    period.startDate = part[1];
+    period.endDate = part[2];
+
+    return period;
+}
+
 function refreshZebraStripes( $tbody )
 {
     $tbody.find( 'tr:not([colspan]):visible:even' ).find( 'td:first-child' ).removeClass( 'reg alt' ).addClass( 'alt' );
@@ -739,6 +751,9 @@
 // OrganisationUnit Selection
 // -----------------------------------------------------------------------------
 
+/**
+ * Callback for changes in organisation unit selections.
+ */
 function organisationUnitSelected( orgUnits, orgUnitNames, children )
 {
 	if ( dhis2.de.metaDataIsLoaded == false )
@@ -757,7 +772,7 @@
     $( '#selectedDataSetId' ).removeAttr( 'disabled' );
 
     var dataSetId = $( '#selectedDataSetId' ).val();
-    var periodId = $( '#selectedPeriodId' ).val();
+    var periodId = currentPeriod().iso;
 
     clearListById( 'selectedDataSetId' );
     addOptionById( 'selectedDataSetId', '-1', '[ ' + i18n_select_data_set + ' ]' );
@@ -849,6 +864,9 @@
     return dataSetList;
 }
 
+/**
+ * Gets list of data sets for selected organisation units.
+ */
 function getSortedDataSetListForOrgUnits( orgUnits )
 {
     var dataSetList = [];
@@ -886,16 +904,15 @@
 // DataSet Selection
 // -----------------------------------------------------------------------------
 
+/**
+ * Callback for changes in data set list.
+ */
 function dataSetSelected()
 {
-    $( '#selectedPeriodId' ).removeAttr( 'disabled' );
-    $( '#prevButton' ).removeAttr( 'disabled' );
-    $( '#nextButton' ).removeAttr( 'disabled' );
-
     var x = dhis2.de.currentDataSetId;
     
     var dataSetId = $( '#selectedDataSetId' ).val();
-    var periodId = $( '#selectedPeriodId' ).val();
+    var periodVal = $( '#selectedPeriodId' ).val();
 
     var previousDataSetValid = ( dhis2.de.currentDataSetId && dhis2.de.currentDataSetId != -1 );    
     var previousPeriodType = previousDataSetValid ? dhis2.de.dataSets[dhis2.de.currentDataSetId].periodType : null;
@@ -904,43 +921,25 @@
     
     if ( dataSetId && dataSetId != -1 )
     {
-	    var periodType = dhis2.de.dataSets[dataSetId].periodType;
-	    var allowFuturePeriods = dhis2.de.dataSets[dataSetId].allowFuturePeriods;
-      var periods = dhis2.period.generator.generateReversedPeriods(periodType, dhis2.de.currentPeriodOffset);
-
-      if( allowFuturePeriods == false )
-      {
-        periods = dhis2.period.generator.filterFuturePeriods(periods);
-      }
-
-        clearListById( 'selectedPeriodId' );
-        clearSectionFilters();
+        $( '#selectedPeriodId' ).removeAttr( 'disabled' );
+        $( '#prevButton' ).removeAttr( 'disabled' );
+        $( '#nextButton' ).removeAttr( 'disabled' );
+
+        var periodType = dhis2.de.dataSets[dataSetId].periodType;
+
+        if ( periodType != previousPeriodType )
+        {
+            displayPeriods();
+            clearSectionFilters();
+        }
 
         dhis2.de.currentCategories = dhis2.de.getCategories( dataSetId );
         
         dhis2.de.multiOrganisationUnit = !!$( '#selectedDataSetId :selected' ).data( 'multiorg' );
 
-        var attributeMarkup = dhis2.de.getAttributesMarkup();
-        $( '#attributeComboDiv' ).html( attributeMarkup );
-
-        if ( periods.length > 0 )
-        {
-        	addOptionById( 'selectedPeriodId', '-1', '[ ' + i18n_select_period + ' ]' );
-        }
-        else
-        {
-        	addOptionById( 'selectedPeriodId', '-1', i18n_no_periods_click_prev_year_button );
-        }
-        
-        $.safeEach( periods, function( idx, item )
-        {
-            addOptionById( 'selectedPeriodId', item.iso, item.name );
-        } );
-
         if ( dhis2.de.inputSelected() && previousPeriodType && previousPeriodType == periodType )
         {
-            showLoader();            
-            $( '#selectedPeriodId' ).val( periodId );
+            showLoader();
             loadForm();
         }
         else
@@ -950,24 +949,34 @@
     }
     else
     {
+        $( '#selectedPeriodId').val( "" );
+        $( '#selectedPeriodId' ).attr( 'disabled', 'disabled' );
+        $( '#prevButton' ).attr( 'disabled', 'disabled' );
+        $( '#nextButton' ).attr( 'disabled', 'disabled' );
+
         clearEntryForm();
         dhis2.de.clearAttributes();
     }
+
+    dhis2.de.updateOptionsStatus();
 }
 
 // -----------------------------------------------------------------------------
 // Period Selection
 // -----------------------------------------------------------------------------
 
+/**
+ * Callback for changes in period select list.
+ */
 function periodSelected()
 {
     var periodName = $( '#selectedPeriodId :selected' ).text();
-    var dataSetId = $( '#selectedDataSetId' ).val();
 
     $( '#currentPeriod' ).html( periodName );
 
-    var periodId = $( '#selectedPeriodId' ).val();
-	
+    var attributeMarkup = dhis2.de.getAttributesMarkup();
+    $( '#attributeComboDiv' ).html( attributeMarkup );
+
     if ( dhis2.de.inputSelected() )
     {    	
         showLoader();
@@ -981,24 +990,37 @@
             loadForm();
         }
     }
+    else
+    {
+        clearEntryForm();
+    }
 }
 
+/**
+ * Handles the onClick event for the next period button.
+ */
 function nextPeriodsSelected()
 {
     if ( dhis2.de.currentPeriodOffset < 0 ) // Cannot display future periods
     {
     	dhis2.de.currentPeriodOffset++;
-        displayPeriodsInternal();
+        displayPeriods();
     }
 }
 
+/**
+ * Handles the onClick event for the previous period button.
+ */
 function previousPeriodsSelected()
 {
 	dhis2.de.currentPeriodOffset--;
-    displayPeriodsInternal();
+    displayPeriods();
 }
 
-function displayPeriodsInternal()
+/**
+ * Generates the period select list options.
+ */
+function displayPeriods()
 {
     var dataSetId = $( '#selectedDataSetId' ).val();
     var periodType = dhis2.de.dataSets[dataSetId].periodType;
@@ -1014,16 +1036,17 @@
 
     if ( periods.length > 0 )
     {
-    	addOptionById( 'selectedPeriodId', '-1', '[ ' + i18n_select_period + ' ]' );
+    	addOptionById( 'selectedPeriodId', "", '[ ' + i18n_select_period + ' ]' );
     }
     else
     {
-    	addOptionById( 'selectedPeriodId', '-1', i18n_no_periods_click_prev_year_button );
+    	addOptionById( 'selectedPeriodId', "", i18n_no_periods_click_prev_year_button );
     }
     
     $.safeEach( periods, function( idx, item ) 
     {
-        addOptionById( 'selectedPeriodId', item.iso, item.name );
+        var periodInfo = item.iso + ',' + item.startDate + ',' + item.endDate;
+        addOptionById( 'selectedPeriodId', periodInfo, item.name );
     } );
 }
 
@@ -1032,8 +1055,8 @@
 //------------------------------------------------------------------------------
 
 /**
-* Returns an array of category objects for the given data set identifier. Categories 
-* are looked up using the category combo of the data set. Null is returned if 
+* Returns an array of category objects for the given data set identifier. Categories
+* are looked up using the category combo of the data set. Null is returned if
 * the given data set has the default category combo.
 */
 dhis2.de.getCategories = function( dataSetId )
@@ -1043,7 +1066,7 @@
 	if ( !dataSet || !dataSet.categoryCombo || dhis2.de.defaultCategoryCombo === dataSet.categoryCombo ) {
 		return null;
 	}
-	
+
 	var categoryCombo = dhis2.de.categoryCombos[dataSet.categoryCombo];
 	
 	var categories = [];
@@ -1117,6 +1140,34 @@
 };
 
 /**
+ * Updates the options status showing options selected if any.
+ */
+dhis2.de.updateOptionsStatus = function()
+{
+    var html = '';
+
+    if ( dhis2.de.currentCategories && dhis2.de.currentCategories.length != 0 )
+    {
+        var prefix = '(';
+        $.safeEach(dhis2.de.currentCategories, function (idx, category) {
+            var option = $('#category-' + category.id).val();
+
+            if (option && option != -1) {
+                var options = dhis2.de.categories[ category.id ].options;
+                var matching = $.grep(options, function (e) {
+                    return e.id == option;
+                });
+                html += prefix + matching[0].name;
+                prefix = ', ';
+            }
+        });
+        html += html.length == 0 ? '' : ')';
+    }
+
+    $( '#currentOptionsSelection').html( html );
+};
+
+/**
  * Returns a query param value for the currently selected category options where
  * each option is separated by the ; character.
  */
@@ -1140,14 +1191,28 @@
 }
 
 /**
+ * Tests to see if a category option is valid during a period.
+ */
+dhis2.de.optionValidWithinPeriod = function( option, period )
+{
+    return ( option.startDate == null || option.startDate <= period.endDate )
+        && ( option.endDate == null || option.endDate >= period.startDate )
+}
+
+/**
 * Returns markup for drop down boxes to be put in the selection box for the
 * given categories. The empty string is returned if no categories are given. 
 */
 dhis2.de.getAttributesMarkup = function()
 {
 	var html = '';
-	
-	if ( !dhis2.de.currentCategories || dhis2.de.currentCategories.length == 0 ) {
+
+    var period = currentPeriod();
+
+    var options = dhis2.de.getCurrentCategoryOptions();
+
+	if ( !dhis2.de.currentCategories || dhis2.de.currentCategories.length == 0
+		|| period.iso == "" ) {
 		return html;
 	}
 	
@@ -1156,9 +1221,12 @@
 		html += '<div class="selectionLabel">' + category.name + '</div>&nbsp;';
 		html += '<select id="category-' + category.id + '" class="selectionBoxSelect" onchange="dhis2.de.attributeSelected(\'' + category.id + '\')">';
 		html += '<option value="-1">[ ' + i18n_select_option + ' ]</option>';
-		
+
 		$.safeEach( category.options, function( idx, option ) {
-			html += '<option value="' + option.id + '">' + option.name + '</option>';
+			if ( dhis2.de.optionValidWithinPeriod( option, period ) ) {
+				var selected = Ext.Array.contains( options, option.id ) ? " selected" : "";
+				html += '<option value="' + option.id + '"' + selected + '>' + option.name + '</option>';
+			}
 		} );
 		
 		html += '</select>';
@@ -1191,6 +1259,12 @@
             loadForm();
         }
     }
+    else
+    {
+        clearEntryForm();
+    }
+
+    dhis2.de.updateOptionsStatus();
 };
 
 // -----------------------------------------------------------------------------
@@ -1203,12 +1277,12 @@
 dhis2.de.inputSelected = function()
 {
     var dataSetId = $( '#selectedDataSetId' ).val();
-    var periodId = $( '#selectedPeriodId' ).val();
+    var periodId = currentPeriod().iso;
 
 	if (
 	    dhis2.de.currentOrganisationUnitId &&
 	    dataSetId && dataSetId != -1 &&
-	    periodId && periodId != -1 &&
+	    periodId && periodId != "" &&
 	    dhis2.de.categoriesSelected() ) {
 		return true;
 	}
@@ -1230,7 +1304,7 @@
 
 function getAndInsertDataValues()
 {
-    var periodId = $( '#selectedPeriodId' ).val();
+    var periodId = currentPeriod().iso;
     var dataSetId = $( '#selectedDataSetId' ).val();
 
     // Clear existing values and colors, grey disabled fields
@@ -1810,7 +1884,7 @@
 
 function viewHist( dataElementId, optionComboId )
 {
-    var periodId = $( '#selectedPeriodId' ).val();
+    var periodId = currentPeriod().iso;
 
 	if ( dataElementId && optionComboId && periodId && periodId != -1 )
 	{
@@ -2363,7 +2437,7 @@
     {
         var params = {
             'ds': $( '#selectedDataSetId' ).val(),
-            'pe': $( '#selectedPeriodId' ).val(),
+            'pe': currentPeriod().iso,
             'ou': getCurrentOrganisationUnit(),
             'multiOu': dhis2.de.multiOrganisationUnit
         };
@@ -2434,7 +2508,7 @@
             return true;
         }
     	
-    	return false;    	
+    	return false;
     }
 
     /**

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm	2014-02-25 05:51:59 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm	2014-06-02 15:29:13 +0000
@@ -69,7 +69,7 @@
 #foreach( $category in $categoryCombo.categories )
 "${category.uid}"#if( $velocityCount < $size2 ),#end
 #end
-] }#if( $velocityCount < $size1 ),#end
+] }#if( $velocityCount < $size1 ),#end
 #end
 },
 
@@ -80,8 +80,10 @@
 #set( $categoryOptions = $categoryOptionMap.get( $category.uid ) )
 #set( $size2 = $categoryOptions.size() )
 #foreach( $option in $categoryOptions )
-{"id":"${option.uid}","name":"$encoder.jsonEncode( ${option.displayName} )"}#if( $velocityCount < $size2 ),#end
+{"id":"${option.uid}","name":"$encoder.jsonEncode( ${option.displayName} )"
+#if( ${option.startDate} ),"startDate":"${option.startDate}"#end
+#if( ${option.endDate} ),"endDate":"${option.endDate}"#end}#if( $velocityCount < $size2 ),#end
 #end
-] }#if( $velocityCount < $size1 ),#end
+] }#if( $velocityCount < $size1 ),#end
 #end }
 } }

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm	2014-01-23 15:36:54 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm	2014-06-02 15:29:13 +0000
@@ -61,7 +61,8 @@
 
 <div id="currentSelection">
 	<span id="closeCurrentSelection"><img src="../images/hide.png" title="$i18n.getString( 'close' )" onclick="closeCurrentSelection()"></span>
-	<span id="currentOrganisationUnit">$i18n.getString( "no_organisationunit_selected" )</span> - <span id="currentPeriod">$i18n.getString( "no_period_selected" )</span/><br>
+	<span id="currentOrganisationUnit">$i18n.getString( "no_organisationunit_selected" )</span> - <span id="currentPeriod">$i18n.getString( "no_period_selected" )</span/>
+    <span id="currentOptionsSelection"></span><br>
 	<span id="currentDataElement">$i18n.getString( "no_dataelement_selected" )</span>
 </div>
 
@@ -81,13 +82,13 @@
 	<select id="selectedDataSetId" name="selectedDataSetId" class="selectionBoxSelect" onchange="dataSetSelected()" disabled="disabled"></select>
     <span id="loaderSpan" style="display:none"><img src='../images/ajax-loader-bar.gif'></span>
 </div>
-<div id="attributeComboDiv"></div>
 <div class="selectionBoxRow">
     <div class="selectionLabel">$i18n.getString( "period" )</div>
     <select id="selectedPeriodId" name="selectedPeriodId" style="width:225px" onchange="periodSelected()" disabled="disabled"></select>
     <input type="button" id="prevButton" style="width:85px" value="$i18n.getString( 'prev_year' )" title="$i18n.getString('earlier_periods')" onclick="previousPeriodsSelected()" disabled="disabled">
    	<input type="button" id="nextButton" style="width:85px" value="$i18n.getString( 'next_year' )" title="$i18n.getString('later_periods')" onclick="nextPeriodsSelected()" disabled="disabled">
 </div>
+<div id="attributeComboDiv"></div>
 <div id="filterDataSetSectionDiv" class="selectionBoxRow" style="display:none">
     <div class="selectionLabel">$i18n.getString( "filter_on_section" )</div>
     <select id="filterDataSetSection" name="filterDataSetSection" class="selectionBoxSelect" onchange="filterOnSection()"></select>

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/style/dhis-web-dataentry.css'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/style/dhis-web-dataentry.css	2014-04-25 11:10:13 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/style/dhis-web-dataentry.css	2014-06-02 15:29:13 +0000
@@ -4,7 +4,6 @@
   padding: 6px;
   background-color: #eee;
   border: 1px solid #bbb;
-  font-size: 14px;
   text-align: right;
   position: fixed;
   top: 55px;

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryOptionAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryOptionAction.java	2014-03-18 08:10:10 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryOptionAction.java	2014-06-02 15:29:13 +0000
@@ -29,10 +29,15 @@
  */
 
 import org.apache.commons.lang.StringUtils;
+import org.hisp.dhis.calendar.CalendarService;
+import org.hisp.dhis.calendar.DateUnit;
 import org.hisp.dhis.dataelement.DataElementCategoryOption;
 import org.hisp.dhis.dataelement.DataElementCategoryService;
 
 import com.opensymphony.xwork2.Action;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
 
 /**
  * @author Lars Helge Overland
@@ -51,6 +56,9 @@
         this.dataElementCategoryService = dataElementCategoryService;
     }
 
+    @Autowired
+    private CalendarService calendarService;
+
     // -------------------------------------------------------------------------
     // Input
     // -------------------------------------------------------------------------
@@ -69,6 +77,20 @@
         this.code = code;
     }
 
+    private String startDate;
+
+    public void setStartDate( String startDate )
+    {
+        this.startDate = startDate;
+    }
+
+    private String endDate;
+
+    public void setEndDate( String endDate )
+    {
+        this.endDate = endDate;
+    }
+
     // -------------------------------------------------------------------------
     // Output
     // -------------------------------------------------------------------------
@@ -87,10 +109,27 @@
     public String execute()
     {
         code = StringUtils.trimToNull( code );
-        
+
+        Date sDate = null;
+        Date eDate = null;
+
+        if ( startDate != null && startDate.trim().length() != 0 )
+        {
+            DateUnit isoStartDate = calendarService.getSystemCalendar().toIso( startDate );
+            sDate = isoStartDate.toJdkCalendar().getTime();
+        }
+
+        if ( endDate != null && endDate.trim().length() != 0 )
+        {
+            DateUnit isoEndDate = calendarService.getSystemCalendar().toIso( endDate );
+            eDate = isoEndDate.toJdkCalendar().getTime();
+        }
+
         dataElementCategoryOption = new DataElementCategoryOption( name );
         dataElementCategoryOption.setCode( code );
-        
+        dataElementCategoryOption.setStartDate( sDate );
+        dataElementCategoryOption.setEndDate( eDate );
+
         dataElementCategoryService.addDataElementCategoryOption( dataElementCategoryOption );
 
         return SUCCESS;

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryOptionAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryOptionAction.java	2014-03-18 08:10:10 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryOptionAction.java	2014-06-02 15:29:13 +0000
@@ -29,10 +29,15 @@
  */
 
 import org.apache.commons.lang.StringUtils;
+import org.hisp.dhis.calendar.CalendarService;
+import org.hisp.dhis.calendar.DateUnit;
 import org.hisp.dhis.dataelement.DataElementCategoryOption;
 import org.hisp.dhis.dataelement.DataElementCategoryService;
 
 import com.opensymphony.xwork2.Action;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
 
 /**
  * @author Chau Thu Tran
@@ -42,7 +47,7 @@
     implements Action
 {
     // -------------------------------------------------------------------------
-    // Dependency
+    // Dependencies
     // -------------------------------------------------------------------------
 
     private DataElementCategoryService dataElementCategoryService;
@@ -52,6 +57,9 @@
         this.dataElementCategoryService = dataElementCategoryService;
     }
 
+    @Autowired
+    private CalendarService calendarService;
+
     // -------------------------------------------------------------------------
     // Input
     // -------------------------------------------------------------------------
@@ -77,6 +85,31 @@
         this.code = code;
     }
 
+    private String startDate;
+
+    public void setStartDate( String startDate )
+    {
+        this.startDate = startDate;
+    }
+
+    private String endDate;
+
+    public void setEndDate( String endDate )
+    {
+        this.endDate = endDate;
+    }
+
+    // -------------------------------------------------------------------------
+    // Output
+    // -------------------------------------------------------------------------
+
+    private String message;
+
+    public String getMessage()
+    {
+        return message;
+    }
+
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -85,9 +118,26 @@
     {
         code = StringUtils.trimToNull( code );
         
+        Date sDate = null;
+        Date eDate = null;
+
+        if ( startDate != null && startDate.trim().length() != 0 )
+        {
+            DateUnit isoStartDate = calendarService.getSystemCalendar().toIso( startDate );
+            sDate = isoStartDate.toJdkCalendar().getTime();
+        }
+
+        if ( endDate != null && endDate.trim().length() != 0 )
+        {
+            DateUnit isoEndDate = calendarService.getSystemCalendar().toIso( endDate );
+            eDate = isoEndDate.toJdkCalendar().getTime();
+        }
+
         DataElementCategoryOption categoryOption = dataElementCategoryService.getDataElementCategoryOption( id );
         categoryOption.setName( name );
         categoryOption.setCode( code );
+        categoryOption.setStartDate( sDate );
+        categoryOption.setEndDate( eDate );
 
         dataElementCategoryService.updateDataElementCategoryOption( categoryOption );
 

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/addDataElementCategoryOptionForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/addDataElementCategoryOptionForm.vm	2014-02-12 16:09:47 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/addDataElementCategoryOptionForm.vm	2014-06-02 15:29:13 +0000
@@ -4,8 +4,14 @@
 		form.submit();
 	});
 
-		checkValueIsExist( "name", "validateDataElementCategoryOption.action" );	
-        checkValueIsExist( "code", "validateDataElementCategoryOption.action" ); 
+        dhis2.period.picker.createInstance('#startDate');
+        dhis2.period.picker.createInstance('#endDate');
+
+        $('#startDate').calendarsPicker('option', 'maxDate', dhis2.period.calendar.add(dhis2.period.calendar.today(), 100, 'y'));
+        $('#endDate').calendarsPicker('option', 'maxDate', dhis2.period.calendar.add(dhis2.period.calendar.today(), 100, 'y'));
+
+        checkValueIsExist( "name", "validateDataElementCategoryOption.action" );
+        checkValueIsExist( "code", "validateDataElementCategoryOption.action" );
 	});
 
     var i18n_specify_category_option_name = '$encoder.jsEscape( $i18n.getString( "specify_category_option_name" ) , "'")';
@@ -28,6 +34,22 @@
 	  <td><label>$i18n.getString( "code" )</td>
 	  <td colspan="3"><input type="text" id="code" name="code"/></td>
     </tr>
+      <tr>
+        <td>
+          <label for="startDate">$i18n.getString( 'start_date' )</label>
+        </td>
+        <td>
+          <input type="text" id="startDate" name="startDate" style="width:20em">
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <label for="endDate">$i18n.getString( 'end_date' )</label>
+        </td>
+        <td>
+          <input type="text" id="endDate" name="endDate" style="width:20em">
+        </td>
+      </tr>
 	<tr>
 	  <td></td>
 	  <td colspan="3">

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/categoryOption.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/categoryOption.vm	2014-02-14 13:17:54 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/categoryOption.vm	2014-06-02 15:29:13 +0000
@@ -15,9 +15,11 @@
 		jQuery.post( 'getDataElementCategoryOption.action', { id: context.id } ,
 			function ( json ) {
 			
-				setInnerHTML( 'nameField', json.dataElementCategoryOption.name );  
-				setInnerHTML( 'codeField', json.dataElementCategoryOption.code ); 
-				setInnerHTML( 'conceptField', json.dataElementCategoryOption.concept ); 				
+				setInnerHTML( 'nameField', json.dataElementCategoryOption.name );
+				setInnerHTML( 'codeField', json.dataElementCategoryOption.code );
+				setInnerHTML( 'startDateField', json.dataElementCategoryOption.startDate );
+				setInnerHTML( 'endDateField', json.dataElementCategoryOption.endDate );
+				setInnerHTML( 'conceptField', json.dataElementCategoryOption.concept );
 					  
 				showDetails();
 		});
@@ -85,7 +87,9 @@
         <a href="javascript:hideDetails()" title="$i18n.getString( 'hide_details' )"><img src="../images/hide.png" alt="$i18n.getString( 'hide_details' )"/></a>
       </div>
       <p><label>$i18n.getString( "name" ):</label><br/><span id="nameField"></span></p>
-        <p><label>$i18n.getString( "code" ):</label><br/><span id="codeField"></span></p>
+          <p><label>$i18n.getString( "code" ):</label><br/><span id="codeField"></span></p>
+          <p><label>$i18n.getString( "start_date" ):</label><br/><span id="startDateField"></span></p>
+          <p><label>$i18n.getString( "end_date" ):</label><br/><span id="endDateField"></span></p>
         <p><label>$i18n.getString( "concept" ):</label><br/><span id="conceptField"></span></p>
       </div>
 

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryOptionForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryOptionForm.vm	2014-02-12 16:09:47 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryOptionForm.vm	2014-06-02 15:29:13 +0000
@@ -3,10 +3,16 @@
 	    validation2( 'editDataElementCategoryOptionForm', function( form ){ form.submit()}, {
 			'beforeValidateHandler': function() { listValidator( 'memberValidator', 'categoryOptions' ); },
 			'rules': getValidationRules("dateElementCategoryOption")
-		}); 
+		});
+
+        dhis2.period.picker.createInstance('#startDate');
+        dhis2.period.picker.createInstance('#endDate');
+
+        $('#startDate').calendarsPicker('option', 'maxDate', dhis2.period.calendar.add(dhis2.period.calendar.today(), 100, 'y'));
+        $('#endDate').calendarsPicker('option', 'maxDate', dhis2.period.calendar.add(dhis2.period.calendar.today(), 100, 'y'));
 
         checkValueIsExist( "name", "validateDataElementCategoryOption.action", {id: $dataElementCategoryOption.id} );
-        checkValueIsExist( "code", "validateDataElementCategoryOption.action", {id: $dataElementCategoryOption.code} );
+//Error:        checkValueIsExist( "code", "validateDataElementCategoryOption.action", {id: $dataElementCategoryOption.code} );
 	});
 
     var i18n_confirm_delete = '$encoder.jsEscape( $i18n.getString( "confirm_delete_data_element_category_option" ) , "'")';
@@ -35,6 +41,22 @@
 	  <td colspan="3"><input type="text" id="code" name="code" style="width:25em" value="$!encoder.htmlEncode( $dataElementCategoryOption.code )" /></td>
     </tr>
     <tr>
+      <td>
+        <label for="startDate">$i18n.getString( 'start_date' )</label>
+      </td>
+      <td>
+        <input type="text" id="startDate" name="startDate" style="width:20em" value="$!format.formatDate( $!dataElementCategoryOption.startDate )">
+          </td>
+      </tr>
+      <tr>
+        <td>
+          <label for="endDate">$i18n.getString( 'end_date' )</label>
+        </td>
+      <td>
+          <input type="text" id="endDate" name="endDate" style="width:20em" value="$!format.formatDate( $!dataElementCategoryOption.endDate )">
+      </td>
+    </tr>
+    <tr>
       <td></td>
       <td colspan="3">
         <input type="submit" value="$i18n.getString( 'save' )" style="width:100px"/>