Scarab commit: svn commit: r10798 - trunk/src: java/org/tigris/scarab/om webapp/WEB-INF/templates/layouts webapp/WEB-INF/templates/macros webapp/WEB-INF/templates/viewIssue

Hussayn Dabbous <[email protected]>
Newsgroups gmane.comp.java.scarab.cvs
Message-ID <[email protected]>
Author: dabbous
Date: 2009-07-14 13:37:03-0700
New Revision: 10798

Modified:
   trunk/src/java/org/tigris/scarab/om/Condition.java
   trunk/src/java/org/tigris/scarab/om/Issue.java
   trunk/src/webapp/WEB-INF/templates/layouts/Default.vm
   trunk/src/webapp/WEB-INF/templates/macros/GlobalMacros.vm
   trunk/src/webapp/WEB-INF/templates/viewIssue/ViewIssueTab1.vm

Log:
SCB2984: 
- added javascript generator for dynamic conditional required markup during issue editing.
- added #macro (drawRequiredMarkupAsNeeded $user $issue $attribute)
  this fixes another issue where conditionally required attributes where not marked as required
  even when the required condition was fulfilled. This macro internaly uses the former #showAsterisk()
  macro, which only worked for unconditionally required attributes.


Modified: trunk/src/java/org/tigris/scarab/om/Condition.java
Url: http://scarab.tigris.org/source/browse/scarab/trunk/src/java/org/tigris/scarab/om/Condition.java?view=diff&pathrev=10798&r1=10797&r2=10798
==============================================================================
--- trunk/src/java/org/tigris/scarab/om/Condition.java	(original)
+++ trunk/src/java/org/tigris/scarab/om/Condition.java	2009-07-14 13:37:03-0700
@@ -48,6 +48,8 @@
 
 import java.util.Map;
 import org.apache.torque.om.Persistent;
+import org.tigris.scarab.util.SimpleSkipFiltering;
+import org.tigris.scarab.util.SkipFiltering;
 
 /**
  * You should add additional methods to this class to meet the
@@ -120,4 +122,42 @@
         }
         return bEval;
     }
+
+    /**
+     * Create conditionchecker as javascript snippet.
+     * Can be used to check online if a specific condition is requied.
+     * Experimental...
+     * @param user
+     * @param issue
+     * @return
+     */
+    public SkipFiltering createConditionCheckerScript(RModuleAttribute rma, String setMarkerFunction, int indent) 
+    {
+        String indents = ""; for(int i=0; i< indent; i++) indents +=" ";
+        String result = "";
+        try {
+            if (this.getAttributeOption() != null) {
+                // Old-style condition (tied to any of the attribute-options
+                // being selected)
+                Attribute requiredAttribute = this.getAttributeOption().getAttribute();
+                Integer optionId = this.getOptionId();
+                result = indents+"if(attributeName == \""
+                       + requiredAttribute.getName()
+                       + "\")"
+                       + setMarkerFunction
+                       + "(\""
+                       + rma.getDisplayValue()
+                       + "\","
+                       + "displayValue==\"" + this.getAttributeOption().getName()
+                       + "\");\n";
+            } else 
+            {
+                // New-style condition (driven by an evaluated script)
+            }
+        } catch (Exception e) {
+            this.getLog().debug("evaluate: Failed to evaluate, will return empty String. ", e);
+        }
+        return new SimpleSkipFiltering(result);
+    }
+        
 }

Modified: trunk/src/java/org/tigris/scarab/om/Issue.java
Url: http://scarab.tigris.org/source/browse/scarab/trunk/src/java/org/tigris/scarab/om/Issue.java?view=diff&pathrev=10798&r1=10797&r2=10798
==============================================================================
--- trunk/src/java/org/tigris/scarab/om/Issue.java	(original)
+++ trunk/src/java/org/tigris/scarab/om/Issue.java	2009-07-14 13:37:03-0700
@@ -88,6 +88,8 @@
 import org.tigris.scarab.util.MutableBoolean;
 import org.tigris.scarab.util.ScarabConstants;
 import org.tigris.scarab.util.ScarabException;
+import org.tigris.scarab.util.SimpleSkipFiltering;
+import org.tigris.scarab.util.SkipFiltering;
 import org.tigris.scarab.util.word.SearchFactory;
 import org.tigris.scarab.workflow.WorkflowFactory;
 
@@ -4167,4 +4169,94 @@
         if(super.getLastTransId()==null)
             super.setLastTransId(createdTransId);
     }
+    
+    /**
+     * Check if the given attribute is currently required.
+     * The required state can vary depending on conditions.
+     * @param attribute
+     * @param user
+     * @return
+     * @throws TorqueException
+     * @throws ScarabException
+     */
+    public boolean isRequiredAttributeFor(Attribute attribute, ScarabUser user) throws TorqueException, ScarabException
+    {
+        Module module         = this.getModule();
+        IssueType issueType   = this.getIssueType();
+        RModuleAttribute rma  = module.getRModuleAttribute(attribute, issueType);
+
+        boolean result = rma.getRequired();
+        if(result == false)
+        {
+            List<Condition> conditions = rma.getConditions();
+                
+            Iterator<Condition> iter = conditions.iterator();
+            while(iter.hasNext())
+            {
+                Condition condition = iter.next();
+                boolean eval = condition.evaluate(user, this);
+                result |= eval;
+            }
+        }
+        return result;
+    }
+    
+    
+    /**
+     * Create a javascript function, which can be used to check if the given
+     * attribute would become required if a specific attributeOption was set.
+     * @param attribute
+     * @return
+     * @throws TorqueException
+     * @throws ScarabException
+     */
+    public String createIssueChecker(RModuleAttribute rma, String setMarkerFunction, int indent) throws TorqueException, ScarabException
+    {
+        String result = "";
+        boolean isRequired = rma.getRequired();
+        if(!isRequired)
+        {
+            List<Condition> conditions = rma.getConditions();
+                
+            Iterator<Condition> iter = conditions.iterator();
+            while(iter.hasNext())
+            {
+                Condition condition = iter.next();
+                result += condition.createConditionCheckerScript(rma, setMarkerFunction, indent);
+            }
+        }
+        return result;
+    }
+
+    
+    public SkipFiltering createIssueChecker(String setMarkerFunction, int indent) throws TorqueException, ScarabException
+    {
+        String result = "";
+        List attributes = null;
+        Module module = getModule();
+        IssueType issueType = getIssueType();
+        attributes = issueType.getActiveAttributes(module);
+        Iterator<Attribute> iter = attributes.iterator();
+        while (iter.hasNext())
+        {
+            Attribute attribute = iter.next();
+            RModuleAttribute rma  = module.getRModuleAttribute(attribute, issueType);
+            result += createIssueChecker(rma, setMarkerFunction, indent);
+        }
+        
+        String prepend;
+        if(result.length() > 0)
+        {
+            prepend="\n";
+        }
+        else
+        {
+            prepend = "/* No conditional attributes found for this module/issueType */";
+        }
+        
+        return new SimpleSkipFiltering(prepend+result);
+    }     
+    
+    
+    
 }

Modified: trunk/src/webapp/WEB-INF/templates/layouts/Default.vm
Url: http://scarab.tigris.org/source/browse/scarab/trunk/src/webapp/WEB-INF/templates/layouts/Default.vm?view=diff&pathrev=10798&r1=10797&r2=10798
==============================================================================
--- trunk/src/webapp/WEB-INF/templates/layouts/Default.vm	(original)
+++ trunk/src/webapp/WEB-INF/templates/layouts/Default.vm	2009-07-14 13:37:03-0700
@@ -67,8 +67,102 @@
         #if ($autoresize)
           initialRows()
         #end
-        initializeTreeview()
+        initializeTreeview();
+        observer.subscribe(conditions_observer);
+
+        ## Add your own observers below
+        ##  An observer receives a data array containing the following
+        ##  informations:
+        ##
+        ##  data[0] = observerId
+        ##  data[1] = attributeName (as defined in RModuleIssueType)
+        ##  data[2] = key           (optionId)
+        ##  data[3  = value         (optionValueId)
+        ##  data[4] = display       (DisplayName)
+        ##
+             
+                
+      }
+
+     function getElementByIdCompatible (the_id) 
+     {
+         if (typeof the_id != 'string') 
+         {
+             return the_id;
+         }
+
+         if (typeof document.getElementById != 'undefined') 
+         {
+             return document.getElementById(the_id);
+         }
+         else if (typeof document.all != 'undefined') 
+         {
+             return document.all[the_id];
+         }
+         else if (typeof document.layers != 'undefined') 
+         {
+             return document.layers[the_id];
+         }
+         else
+         {
+             return null;
+         }
+      }      
+
+      // Helper array contains all RequiredMarkup elements
+      // which have already been visited form the current call of
+      // the conditions_observer. It is needed to correctly
+      // set the visibility of all visited markers.
+      
+      var visitedMarkers = {};
+      
+      /**
+      This function takes care about the "required attribute" markup.
+      It adjusts the markup dynamically while the user edits the issue.
+      */
+      function conditions_observer(data)
+      {
+        if(data[0] == "treeview")
+        {   
+            attributeName = data[1];
+            displayValue  = data[4];
+            
+            #if ($currentIssue)
+#set ($indent=12)
+$currentIssue.createIssueChecker("setMarkerValueIf", $indent)
+            #end
+            
+            visitedMarkers = {};
+
+        }
       }
+
+      /**
+        This helper function actually makes the requiredMarkup
+        visible or hides it depending on the condition.
+        Note: Currently only OR conditions are supported here!!!
+      */      
+      function setMarkerValueIf(condAttName, isRequired)
+      {
+          cid = "conditional:"+condAttName;
+          element = getElementByIdCompatible(cid);
+          if (element != null)
+          {
+              if(isRequired)
+              {
+                visitedMarkers[condAttName] = "visible";
+              }
+              else
+              {
+                if (visitedMarkers[condAttName]==null)              
+                {
+                   visitedMarkers[condAttName] = "hidden";
+                }
+              }
+              element.style.visibility = visitedMarkers[condAttName];              
+            }
+      }      
+      
     </script>
 
   </head>

Modified: trunk/src/webapp/WEB-INF/templates/macros/GlobalMacros.vm
Url: http://scarab.tigris.org/source/browse/scarab/trunk/src/webapp/WEB-INF/templates/macros/GlobalMacros.vm?view=diff&pathrev=10798&r1=10797&r2=10798
==============================================================================
--- trunk/src/webapp/WEB-INF/templates/macros/GlobalMacros.vm	(original)
+++ trunk/src/webapp/WEB-INF/templates/macros/GlobalMacros.vm	2009-07-14 13:37:03-0700
@@ -802,6 +802,39 @@
 <small>(</small><b class="asterisk">*</b> <small>$l10n.RequiredFields)</small>
 #end
 
+
+## ==============================================================================
+## [HD]Create a marker for required fields.
+## For conditioned fields the required attribute may vary dynamically.
+## Hence this method needs a way to determine the actual state.
+## Note: This method creates invisible markup when the rma is not required.
+## And it creates css ids along with the element. This will later be used
+## from javascript in order to dynamically enable/disable the "requiredMarker"
+## when the user selects options which cause an attribute to become required
+## ==============================================================================
+#macro (drawRequiredMarkupAsNeeded $user $issue $attribute)
+
+  ## Here we take care about the conditionally required attribute 
+  ## AND the static required attributes:
+
+  #set ($rma        = $module.getRModuleAttribute($attribute, $issue.IssueType) )
+  #set ($isRequired = $rma.Required )
+  #if ($isRequired)
+    #showAsterisk() ## unconditionally required.
+  #elseif ($rma.Conditions.size() > 0)
+  #set ($isRequired = $issue.isRequiredAttributeFor($attribute, $user))
+  #set ($visibility = "hidden")
+  #if  ($isRequired)
+    #set ($visibility = "visible")
+  #end
+    <b class="asterisk" id="conditional:${rma.DisplayValue}" style="visibility:$visibility;">*</b>
+  #else
+    ## atribute is neither required nor has it conditional attributres. Nothing TODO
+#end
+#end
+
+
+
 #macro (showAsterisk)
 <b class="asterisk">*</b>
 #end
@@ -1073,11 +1106,10 @@
           #if ($index > 1)
             #set ($displayValue = $attVal.RModuleAttribute.DisplayValue.substring($index))
             #set ($appendToNextLine = [$attVal, $att, $field, $displayValue])
-          #else
+          #else
+          
           <tr>
-            <th> #if ($attVal.isRequired()) #showAsterisk() #end 
-                 $attVal.RModuleAttribute.DisplayValue
-            </th>
+              <th> #drawRequiredMarkupAsNeeded($user $issue $att)$attVal.RModuleAttribute.DisplayValue</th>
             <td>
           #if ($attVal.Attribute.isOptionAttribute())
            #if ($templ)
@@ -1109,14 +1141,14 @@
               #attrValueErrorMsg ($attVal $field)
 
                 #if ($appendToNextLine != "")
+                  #set ($AttributeIsRequired = $issue.isRequiredAttributeFor($appendToNextLine.get(1), $user))
                   #set ($visibility="hidden")
-                  #if ($appendToNextLine.get(0).isRequired())
+                  #if ($AttributeIsRequired)  
                     #set ($visibility="block")
                   #end
                 
                   <span id="$appendToNextLine.get(3)" style="visibility:$visibility;">
-                  #if ($appendToNextLine.get(0).isRequired()) #showAsterisk() #end
-                  $appendToNextLine.get(3)
+                  #drawRequiredMarkupAsNeeded($user $issue $appendToNextLine.get(1))$appendToNextLine.get(3)
                   &nbsp;
                   #if ($appendToNextLine.get(0).Attribute.isOptionAttribute())
                     #if ($templ)

Modified: trunk/src/webapp/WEB-INF/templates/viewIssue/ViewIssueTab1.vm
Url: http://scarab.tigris.org/source/browse/scarab/trunk/src/webapp/WEB-INF/templates/viewIssue/ViewIssueTab1.vm?view=diff&pathrev=10798&r1=10797&r2=10798
==============================================================================
--- trunk/src/webapp/WEB-INF/templates/viewIssue/ViewIssueTab1.vm	(original)
+++ trunk/src/webapp/WEB-INF/templates/viewIssue/ViewIssueTab1.vm	2009-07-14 13:37:03-0700
@@ -110,10 +110,10 @@
                   #set ($appendToNextLine = [$rma, $displayValue,  $fieldExtraHeader, $att, $attVal, $field, $fieldSize, $fieldHint, $attrInput])
                 #else
                   <tr>
-                    <th style="white-space:nowrap;"> 
-                      #if ($rma.getRequired() || ( $field.equals("OptionId") && $rma.isRequiredIf($attVal.getOptionId()))) #showAsterisk()#end$rma.DisplayValue
+                    <th> 
+                      <span style="white-space:nowrap;">#drawRequiredMarkupAsNeeded($user $currentIssue $att)$rma.DisplayValue</span>
                       #if($fieldExtraHeader)
-                      <pre>$fieldExtraHeader</pre>
+                        <pre>$fieldExtraHeader</pre>
                       #end
                     </th>
                     <td>
@@ -135,7 +135,8 @@
                         #set ($visibility="visible")
                       #end
                       <span id="$appendToNextLine.get(1)" style="visibility:$visibility;">
-                        #if ($appendToNextLine.get(0).getRequired() || ($appendToNextLine.get(5).equals("OptionId") && $appendToNextLine.get(0).isRequiredIf($appendToNextLine.get(4).getOptionId) ) )#showAsterisk()#end $appendToNextLine.get(1)
+                        #set ($isReasonRequired = $appendToNextLine.get(0).getRequired() || ($appendToNextLine.get(5).equals("OptionId") && $appendToNextLine.get(0).isRequiredIf($appendToNextLine.get(4).getOptionId) ))
+                        #drawRequiredMarkupAsNeeded($user $currentIssue $appendToNextLine.get(3))$appendToNextLine.get(1)
                         #if($appendToNextLine.get(2))
                         <pre>$appendToNextLine.get(2)</pre>
                         #end
@@ -251,12 +252,16 @@
   #if ($isEditAttributes)
     #set ($attCommentGroup = $intake.Attachment.setKey("attCommentKey$currentIssue.QueryKey"))
     #if ($reasonIsVisible)
-      #set ($reasonIsRequired = $module.isIssueReasonRequired() )    
+      #set ($reasonIsRequired = $module.isIssueReasonRequired() )
+      #set ($visibility="hidden")
+      #if  ($reasonIsRequired)
+        #set ($visibility="visible")
+      #end    
       <h4>$l10n.SaveChanges#if($reasonIsRequired) #asterisk()#end</h4>
       <div class="axial">
         <table cellpadding="3" cellspacing="2" border="0" width="100%">
           <tr>
-              <th nowrap="nowrap">#if($reasonIsRequired)#showAsterisk()#end$l10n.ReasonSavedAs</th>
+              <th nowrap="nowrap"> #if($reasonIsRequired) #showAsterisk()#end$l10n.ReasonSavedAs</th>
               <td>
                   <input type="radio" name="saveReasonAs" value="history" checked="checked"> $l10n.History</input>
                   #if ($canAddComment)

------------------------------------------------------
http://scarab.tigris.org/ds/viewMessage.do?dsForumId=3577&dsMessageId=2371329
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.