← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 4722: Made it possible to add category options to existing categories. New categoryoptioncombos will be...

 

Merge authors:
  Lars Helge Øverland (larshelge)
------------------------------------------------------------
revno: 4722 [merge]
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2011-09-27 19:12:04 +0200
message:
  Made it possible to add category options to existing categories. New categoryoptioncombos will be added for category combos which includes the actual category.
added:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOption.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryOptionAction.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryComboServiceTest.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/javascript/category.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryForm.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/DataElementCategoryService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java	2011-09-26 17:37:55 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java	2011-09-27 15:51:10 +0000
@@ -310,6 +310,23 @@
     void generateOptionCombos( DataElementCategoryCombo categoryCombo );
 
     /**
+     * Invokes updateOptionCombos( DataElementCategoryCombo ) for all category
+     * combos which the given category is a part of.
+     * 
+     * @param category the DataElementCategory.
+     */
+    void updateOptionCombos( DataElementCategory category );
+    
+    /**
+     * Generates the complete set of category option combos for the given
+     * category combo and compares it to the set of persisted category option
+     * combos. Those which are not matched are persisted.
+     *  
+     * @param categoryCombo the DataElementCategoryCombo.
+     */
+    void updateOptionCombos( DataElementCategoryCombo categoryCombo );
+    
+    /**
      * Populates all transient properties on each Operand in the given collection.
      * 
      * @param operands the collection of Operands.

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java	2011-09-26 17:37:55 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java	2011-09-27 15:51:10 +0000
@@ -469,12 +469,41 @@
         
         for ( DataElementCategoryOptionCombo optionCombo : categoryCombo.getOptionCombos() )
         {
+            categoryCombo.getOptionCombos().add( optionCombo );
             addDataElementCategoryOptionCombo( optionCombo );
         }
         
         updateDataElementCategoryCombo( categoryCombo );
     }
     
+    public void updateOptionCombos( DataElementCategory category )
+    {
+        for ( DataElementCategoryCombo categoryCombo : getAllDataElementCategoryCombos() )
+        {
+            if ( categoryCombo.getCategories().contains( category ) )
+            {
+                updateOptionCombos( categoryCombo );
+            }
+        }
+    }
+    
+    public void updateOptionCombos( DataElementCategoryCombo categoryCombo )
+    {
+        List<DataElementCategoryOptionCombo> generatedOptionCombos = categoryCombo.generateOptionCombosList();
+        Set<DataElementCategoryOptionCombo> persistedOptionCombos = categoryCombo.getOptionCombos();
+        
+        for ( DataElementCategoryOptionCombo optionCombo : generatedOptionCombos )
+        {
+            if ( !persistedOptionCombos.contains( optionCombo ) )
+            {
+                categoryCombo.getOptionCombos().add( optionCombo );
+                addDataElementCategoryOptionCombo( optionCombo );
+            }
+        }
+
+        updateDataElementCategoryCombo( categoryCombo );
+    }
+    
     public int getDataElementCategoryCount()
     {
         return dataElementCategoryStore.getCount();

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryComboServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryComboServiceTest.java	2011-09-26 15:17:15 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryComboServiceTest.java	2011-09-27 15:51:10 +0000
@@ -53,6 +53,7 @@
     private DataElementCategoryOption categoryOptionD;
     private DataElementCategoryOption categoryOptionE;
     private DataElementCategoryOption categoryOptionF;
+    private DataElementCategoryOption categoryOptionG;
     
     private DataElementCategory categoryA;
     private DataElementCategory categoryB;
@@ -81,6 +82,7 @@
         categoryOptionD = new DataElementCategoryOption( "OptionD" );
         categoryOptionE = new DataElementCategoryOption( "OptionE" );
         categoryOptionF = new DataElementCategoryOption( "OptionF" );
+        categoryOptionG = new DataElementCategoryOption( "OptionG" );
         
         categoryService.addDataElementCategoryOption( categoryOptionA );
         categoryService.addDataElementCategoryOption( categoryOptionB );
@@ -88,6 +90,7 @@
         categoryService.addDataElementCategoryOption( categoryOptionD );
         categoryService.addDataElementCategoryOption( categoryOptionE );
         categoryService.addDataElementCategoryOption( categoryOptionF );
+        categoryService.addDataElementCategoryOption( categoryOptionG );
         
         categoryA = new DataElementCategory( "CategoryA" );
         categoryB = new DataElementCategory( "CategoryB" );
@@ -199,6 +202,86 @@
         
         assertEquals( 8, optionCombos.size() );
         
+        assertOptionCombos( optionCombos );
+    }
+    
+    @Test
+    public void testUpdateCategoryOptionCombosA()
+    {
+        categoryComboA = new DataElementCategoryCombo( "CategoryComboA", categories );
+        categoryService.addDataElementCategoryCombo( categoryComboA );
+        
+        categoryService.generateOptionCombos( categoryComboA );
+        
+        assertNotNull( categoryComboA.getOptionCombos() );
+        assertEquals( 8, categoryComboA.getOptionCombos().size() );
+        assertOptionCombos( categoryComboA.getOptionCombos() );
+        
+        categoryC.getCategoryOptions().add( categoryOptionG );
+        categoryOptionG.setCategory( categoryC );
+        categoryService.updateDataElementCategory( categoryC );
+        
+        categoryService.updateOptionCombos( categoryComboA );
+        
+        assertNotNull( categoryComboA.getOptionCombos() );
+        assertEquals( 12, categoryComboA.getOptionCombos().size() );
+        assertOptionCombos( categoryComboA.getOptionCombos() );
+        
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionC, categoryOptionG ) ) );
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionD, categoryOptionG ) ) );
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionC, categoryOptionG ) ) );
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionD, categoryOptionG ) ) );
+    }
+
+    @Test
+    public void testUpdateCategoryOptionCombosB()
+    {
+        categoryComboA = new DataElementCategoryCombo( "CategoryComboA", categories );
+        categoryService.addDataElementCategoryCombo( categoryComboA );
+        
+        categoryService.generateOptionCombos( categoryComboA );
+        
+        assertNotNull( categoryComboA.getOptionCombos() );
+        assertEquals( 8, categoryComboA.getOptionCombos().size() );
+        assertOptionCombos( categoryComboA.getOptionCombos() );
+
+        categoryService.updateOptionCombos( categoryComboA );
+
+        assertNotNull( categoryComboA.getOptionCombos() );
+        assertEquals( 8, categoryComboA.getOptionCombos().size() );
+        assertOptionCombos( categoryComboA.getOptionCombos() );
+    }
+
+    @Test
+    public void testUpdateCategoryOptionCombosC()
+    {
+        categoryComboA = new DataElementCategoryCombo( "CategoryComboA", categories );
+        categoryService.addDataElementCategoryCombo( categoryComboA );
+        
+        categoryService.generateOptionCombos( categoryComboA );
+        
+        assertNotNull( categoryComboA.getOptionCombos() );
+        assertEquals( 8, categoryComboA.getOptionCombos().size() );
+        assertOptionCombos( categoryComboA.getOptionCombos() );
+        
+        categoryC.getCategoryOptions().add( categoryOptionG );
+        categoryOptionG.setCategory( categoryC );
+        categoryService.updateDataElementCategory( categoryC );
+        
+        categoryService.updateOptionCombos( categoryC );
+        
+        assertNotNull( categoryComboA.getOptionCombos() );
+        assertEquals( 12, categoryComboA.getOptionCombos().size() );
+        assertOptionCombos( categoryComboA.getOptionCombos() );
+        
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionC, categoryOptionG ) ) );
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionD, categoryOptionG ) ) );
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionC, categoryOptionG ) ) );
+        assertTrue( categoryComboA.getOptionCombos().contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionD, categoryOptionG ) ) );
+    }
+  
+    private void assertOptionCombos( Set<DataElementCategoryOptionCombo> optionCombos )
+    {
         assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionC, categoryOptionE ) ) );
         assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionC, categoryOptionF ) ) );
         assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionD, categoryOptionE ) ) );

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOption.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOption.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOption.vm	2011-09-27 17:05:48 +0000
@@ -0,0 +1,6 @@
+{ "dataElementCategoryOption":
+  {
+    "id": "$!{dataElementCategoryOption.id}",
+    "name": "$encoder.jsonEncode( $!{dataElementCategoryOption.name} )"
+  }
+}
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryAction.java	2010-09-04 07:26:32 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryAction.java	2011-09-27 15:11:53 +0000
@@ -108,5 +108,4 @@
 
         return SUCCESS;
     }
-
 }

=== added 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	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/AddDataElementCategoryOptionAction.java	2011-09-27 17:05:48 +0000
@@ -0,0 +1,100 @@
+package org.hisp.dhis.dd.action.category;
+
+/*
+ * Copyright (c) 2004-2010, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.hisp.dhis.dataelement.DataElementCategory;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class AddDataElementCategoryOptionAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private DataElementCategoryService dataElementCategoryService;
+
+    public void setDataElementCategoryService( DataElementCategoryService dataElementCategoryService )
+    {
+        this.dataElementCategoryService = dataElementCategoryService;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private Integer categoryId;
+    
+    public void setCategoryId( Integer categoryId )
+    {
+        this.categoryId = categoryId;
+    }
+
+    private String name;
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    // -------------------------------------------------------------------------
+    // Output
+    // -------------------------------------------------------------------------
+
+    private DataElementCategoryOption dataElementCategoryOption;
+
+    public DataElementCategoryOption getDataElementCategoryOption()
+    {
+        return dataElementCategoryOption;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+    {
+        DataElementCategory category = dataElementCategoryService.getDataElementCategory( categoryId );
+        
+        dataElementCategoryOption = new DataElementCategoryOption( name );
+        dataElementCategoryOption.setCategory( category );
+        category.getCategoryOptions().add( dataElementCategoryOption );
+        
+        dataElementCategoryService.addDataElementCategoryOption( dataElementCategoryOption );
+        dataElementCategoryService.updateDataElementCategory( category );
+        dataElementCategoryService.updateOptionCombos( category );
+        
+        return SUCCESS;
+    }
+}

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryAction.java	2011-09-27 10:12:47 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/category/UpdateDataElementCategoryAction.java	2011-09-27 15:11:53 +0000
@@ -32,6 +32,7 @@
 
 import org.hisp.dhis.concept.ConceptService;
 import org.hisp.dhis.dataelement.DataElementCategory;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
 import org.hisp.dhis.dataelement.DataElementCategoryService;
 
 import com.opensymphony.xwork2.Action;
@@ -107,14 +108,15 @@
         // CategoryOptions can only be sorted on update
         // ---------------------------------------------------------------------
 
-        dataElementCategory.getCategoryOptions().clear();
-
+        List<DataElementCategoryOption> options = new ArrayList<DataElementCategoryOption>();
+        
         for ( String id : categoryOptions )
         {
-            dataElementCategory.getCategoryOptions().add(
-                dataElementCategoryService.getDataElementCategoryOption( Integer.parseInt( id ) ) );
+            options.add( dataElementCategoryService.getDataElementCategoryOption( Integer.parseInt( id ) ) );
         }
 
+        dataElementCategory.setCategoryOptions( options );
+        
         dataElementCategoryService.updateDataElementCategory( dataElementCategory );
 
         return SUCCESS;

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/META-INF/dhis/beans.xml	2011-09-27 10:12:47 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/META-INF/dhis/beans.xml	2011-09-27 15:52:56 +0000
@@ -600,6 +600,13 @@
     </property>
   </bean>
 
+  <bean id="org.hisp.dhis.dd.action.category.AddDataElementCategoryOptionAction" class="org.hisp.dhis.dd.action.category.AddDataElementCategoryOptionAction"
+    scope="prototype">
+    <property name="dataElementCategoryService">
+      <ref bean="org.hisp.dhis.dataelement.DataElementCategoryService" />
+    </property>
+  </bean>
+
   <bean id="org.hisp.dhis.dd.action.category.UpdateDataElementCategoryOptionAction" class="org.hisp.dhis.dd.action.category.UpdateDataElementCategoryOptionAction"
     scope="prototype">
     <property name="dataElementCategoryService">
@@ -670,11 +677,6 @@
     <property name="indicatorService" ref="org.hisp.dhis.indicator.IndicatorService" />
   </bean>
 
-  <!-- Other -->
-
-  <bean id="org.hisp.dhis.dd.action.NoAction" class="org.hisp.dhis.dd.action.NoAction" />
-
-
   <!-- Validate CategoryOption -->
 
   <bean id="org.hisp.dhis.dd.action.category.ValidateDataElementCategoryOptionAction" class="org.hisp.dhis.dd.action.category.ValidateDataElementCategoryOptionAction"
@@ -684,7 +686,7 @@
     </property>
   </bean>
 
-  <!-- Concept Name -->
+  <!-- Concept -->
 
   <bean id="org.hisp.dhis.dd.action.concept.AddConceptAction" class="org.hisp.dhis.dd.action.concept.AddConceptAction"
     scope="prototype">
@@ -716,4 +718,8 @@
     <property name="conceptService" ref="org.hisp.dhis.concept.ConceptService" />
   </bean>
 
+  <!-- Other -->
+
+  <bean id="org.hisp.dhis.dd.action.NoAction" class="org.hisp.dhis.dd.action.NoAction" />
+
 </beans>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties	2011-09-08 15:28:20 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties	2011-09-27 17:05:48 +0000
@@ -343,7 +343,7 @@
 concept_management								= Concept management
 concept											= Concept
 selected_name									= Selected name
-update_category_option							= Update Category Option
+update_category_option							= Update category option
 move_selected                                   = Move selected
 number_value_type								= Number type
 int												= Integer

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/struts.xml	2011-09-27 12:16:53 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/struts.xml	2011-09-27 17:05:48 +0000
@@ -620,6 +620,13 @@
       <param name="requiredAuthorities">F_DATAELEMENT_DELETE</param>
     </action>
 
+    <action name="addDataElementCategoryOption" class="org.hisp.dhis.dd.action.category.AddDataElementCategoryOptionAction">
+      <result name="success" type="velocity-json">
+        /dhis-web-commons/ajax/jsonCategoryOption.vm
+      </result>
+      <param name="requiredAuthorities">F_DATAELEMENT_ADD</param>
+    </action>
+
     <action name="updateDataElementCategoryOption" class="org.hisp.dhis.dd.action.category.UpdateDataElementCategoryOptionAction">
       <result name="success" type="velocity-json">
         /dhis-web-commons/ajax/jsonResponseSuccess.vm

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/javascript/category.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/javascript/category.js	2011-09-27 13:25:44 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/javascript/category.js	2011-09-27 17:05:48 +0000
@@ -3,25 +3,26 @@
 {
 	removeItem( categoryId, categoryName, i18n_confirm_delete, 'removeDataElementCategory.action' );
 }
-	
+
 function addCategoryOption()
 {
-	var value = getFieldValue( 'categoryOptionName' );
-	if( value.length == 0 ) 
+	var value = $( '#categoryOptionName' ).val();
+	
+	if ( value.length == 0 ) 
 	{
 		markInvalid( 'categoryOptionName', i18n_specify_category_option_name );
-	} 
+	}
 	else if ( listContainsById( 'categoryOptionNames', value ) ) 
 	{
 		markInvalid( 'categoryOptionName', i18n_category_option_name_already_exists );
-	} 
+	}
 	else 
 	{
 		jQuery.postJSON( 'validateDataElementCategoryOption.action', { name:value }, function( json ) 
 		{
 			if ( json.response == 'success' )
 			{					
-				addOption( 'categoryOptionNames', value, value );
+				addOptionById( 'categoryOptionNames', value, value );
 				setFieldValue( 'categoryOptionName', '' );
 			}
 			else
@@ -32,40 +33,62 @@
 	}
 }
 
+function addCategoryOptionToExistingCategory()
+{
+	var name = $( '#categoryOptionName' ).val();
+	var id = $( '#id' ).val();
+	
+	if ( name.length == 0 ) 
+	{
+		markInvalid( 'categoryOptionName', i18n_specify_category_option_name );
+	}
+	else if ( listContainsById( 'categoryOptions', name, true ) )
+	{
+		markInvalid( 'categoryOptionName', i18n_category_option_name_already_exists );
+	}
+	else
+	{
+		jQuery.postJSON( 'validateDataElementCategoryOption.action', { name:name, id:id }, function( json )
+		{
+			if ( json.response == 'success' )
+			{
+				saveCategoryOption( id, name );
+			}
+			else
+			{
+				markInvalid( 'categoryOptionName', i18n_category_option_name_already_exists );
+			}
+		} );
+	}	
+}
+
 function updateCategoryOption()
 {
-	try
-	{
-		var name = getFieldValue( 'categoryOptionName' );
-		var id = getFieldValue( 'categoryOptions' );
-		
-		if ( name.length == 0 )
-		{
-			markInvalid( 'categoryOptionName', i18n_specify_category_option_name );
-		}		
-		else if ( listContainsById( 'categoryOptions', name, true ) )
-		{
-			markInvalid( 'categoryOptionName', i18n_category_option_name_already_exists );
-		}
-		else
-		{
-			jQuery.postJSON( 'validateDataElementCategoryOption.action', { name:name, id:id }, function( json )
-			{
-				if( json.response == 'success' )
-				{
-					updateCategoryOptionName();
-				}
-				else
-				{
-					markInvalid( 'categoryOptionName', i18n_category_option_name_already_exists );
-				}
-			} );
-		}
-	}
-	catch ( e )
+	var name = $( '#categoryOptionName' ).val();
+	var id = $( '#categoryOptions :selected' ).val;
+	
+	if ( name.length == 0 )
 	{
 		markInvalid( 'categoryOptionName', i18n_specify_category_option_name );
 	}
+	else if ( listContainsById( 'categoryOptions', name, true ) )
+	{
+		markInvalid( 'categoryOptionName', i18n_category_option_name_already_exists );
+	}
+	else
+	{
+		jQuery.postJSON( 'validateDataElementCategoryOption.action', { name:name, id:id }, function( json )
+		{
+			if ( json.response == 'success' )
+			{
+				updateCategoryOptionName();
+			}
+			else
+			{
+				markInvalid( 'categoryOptionName', i18n_category_option_name_already_exists );
+			}
+		} );
+	}
 }
 
 function getSelectedCategoryOption()
@@ -81,7 +104,18 @@
 	
 	var url = 'updateDataElementCategoryOption.action?id=' + id + '&name=' + name;
 	
-	$.postUTF8( url, {}, function() {
+	$.postUTF8( url, {}, function() 
+	{
 		$( '#categoryOptions :selected' ).text( name );
 	} );
 }
+
+function saveCategoryOption( id, name )
+{
+	var url = 'addDataElementCategoryOption.action';
+	
+	$.postJSON( url, { categoryId:id, name:name }, function( json )
+	{
+		addOptionById( 'categoryOptions', json.dataElementCategoryOption.id, name );
+	} );
+}

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryForm.vm	2011-09-27 12:16:53 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/multidimensional/updateDataElementCategoryForm.vm	2011-09-27 16:31:45 +0000
@@ -57,7 +57,8 @@
 	 <tr>
       <td></td>
       <td colspan="3">
-      	<input type="button" value="$i18n.getString( 'update_category_option' )" onclick="updateCategoryOption();" style="width:200px"/>
+      	<input type="button" value="$i18n.getString( 'add_category_option' )" onclick="addCategoryOptionToExistingCategory();" style="width:150px"/>
+      	<input type="button" value="$i18n.getString( 'update_category_option' )" onclick="updateCategoryOption();" style="width:150px"/>
       </td>
     </tr>
     <tr>