multi-dimensional visibility gird

Is there a way to set up a visibility grid based on a combination two or three other dropdown values?

Example:

dropdown 1 is a dropdown with of values A, B,C

dropdown 2 is a dropdown with of values 1, 2, 3, <blank>


Dropdown 3 should display a subset of options  dependent on dropdown 1 AND dropdown 2

dropdown1=A & dropdown2=1 -> dropdown 3 values i, ii

dropdown1=A & dropdown2=2 -> dropdown 3 values i, ii, iii

dropdown1=B & dropdown2=1 -> dropdown 3 values i

dropdown1=B & dropdown2= <blank> -> dropdown 3 values i, iii, iv

and so on...

thanks,
FrancescaS

  • I had to do something similar in the past and ended up using a custom SetOptions dependency to accomplish it.

  • Brett Zufelt,

    I am having some trouble....

    I keep getting an error: FATAL[2019-1-23 15:17:57]: Uncaught TypeError: expression.match is not a function

    I defined the Expression following some of the expressions that are in the core sugar (like ForecastSalesStageExpression which restricts the dropdown based on parameters passed) 

    I see the expression at the bottom of the list when I run the "Rebuild Sugar Logic Functions"

    (restrictSalesGoalsDropdown) RestrictSalesGoalsDropdownExpression

    custom/include/Expressions/Expression/Enum/RestrictSalesGoalsDropdownExpression.php

    <?php
    require_once 'include/Expressions/Expression/Enum/EnumExpression.php';
    class RestrictSalesGoalsDropdownExpression extends EnumExpression
    {
        /**
         * Returns the entire enumeration bare.
         */

        public function evaluate()
        {
            $GLOBALS['log']->fatal('RestrictSalesGoalsDropdownExpression');
            $params = $this->getParameters();
            $keysToRemove = array();
              $array = array_keys($GLOBALS['app_list_strings']['opp_transaction_type_dd']);
              $goal_type = $params[0]->evaluate();
              $sales_group = $params[1]->evaluate();
              $sales_sub_group = $params[2]->evaluate();
              if($goal_type == 'Quarterly Sales Target'){
                $keysToRemove = array("B2B","B2C","B2E") ;
              }elseif($goal_type == 'Quarterly Forecasting Sales Quota'){
                $keysToRemove = array("B2E") ;
              }elseif($goal_type == 'Annual Sales Quota'){
                switch ($sales_group){
                  case "Academic":
                    switch ($sales_sub_group){
                      case "Key Accounts":
                        $keysToRemove = array("B2C");
                        break;
                      case "Oubound":
                        $keysToRemove = array("B2C");
                        break;
                      case "Inside Sales":
                        $keysToRemove = array("B2B", "B2C");
                        break;
                    }
                  break;
                  case "Commercial":
                    switch ($sales_sub_group){
                      case "AE":
                        $keysToRemove = array("B2C", "B2E");
                        break;
                      case "Enterprise":
                        $keysToRemove = array("B2B", "B2C");
                        break;
                      case "Inside Sales":
                        $keysToRemove = array("B2B", "B2E");
                        break;
                      case "Sales Group":
                        $keysToRemove = array("B2B", "B2C", "B2E");
                        break;
                    }
                  break;
                  case "IBD":
                    switch ($sales_sub_group){
                      case "AE":
                        $keysToRemove = array();
                        break;
                      case "Sales Group":
                        $keysToRemove = array("B2B", "B2C", "B2E");
                        break;
                    }
                  break;
                }
              }
            $list = rtrim(implode(',', array_diff($array, $keysToRemove)), ',');
            return $list;
        }



        /**
         * Returns the JS Equivalent of the evaluate function.
         */

        public static function getJSEvaluate()
        {
            return <<<JS
            var array = [],
                keysToRemove = [],
                params = this.getParameters(),
                array = _.keys(App.lang.getAppListStrings('opp_transaction_type_dd')),
                goal_type = params[0].evaluate(),
                sales_group = params[1].evaluate(),
                sales_sub_group = params[2].evaluate();
            if(goal_type == 'Quarterly Sales Target'){
              keysToRemove = ["B2B","B2C","B2E"] ;
            }else if(goal_type == 'Quarterly Forecasting Sales Quota'){
              keysToRemove = ["B2E"] ;
            }else if(goal_type == 'Annual Sales Quota'){
              switch (sales_group){
                case "Academic":
                  switch (sales_sub_group){
                    case "Key Accounts":
                      keysToRemove = ["B2C"];
                      break;
                    case "Oubound":
                      keysToRemove = ["B2C"];
                      break;
                    case "Inside Sales":
                      keysToRemove = ["B2B", "B2C"];
                      break;
                  }
                break;
                 case "Commercial":
                   switch (sales_sub_group){
                    case "AE":
                      keysToRemove = ["B2C", "B2E"];
                      break;
                    case "Enterprise":
                      keysToRemove = ["B2B", "B2C"];
                      break;
                    case "Inside Sales":
                      keysToRemove = ["B2B", "B2E"];
                      break;
                    case "Sales Group":
                      keysToRemove = ["B2B", "B2C", "B2E"];
                      break;
                  }
                break;
                case "IBD":
                  switch (sales_sub_group){
                    case "AE":
                      keysToRemove = array();
                      break;
                    case "Sales Group":
                      keysToRemove = ["B2B", "B2C", "B2E"];
                      break;
                  }
                break;
              }
            }
            return _.difference(array, keysToRemove);
    JS;
        }

        public static function getParamCount()
        {
            return 3;
        }

        static function getParameterTypes() {
          return array(AbstractExpression::$ENUM_TYPE, AbstractExpression::$ENUM_TYPE, AbstractExpression::$ENUM_TYPE);
        }

        /**
         * Returns the operation name that this Expression could be called by.
         */

        public static function getOperationName()
        {
            return array("restrictSalesGoalsDropdown");
        }
        /**
         * Returns the String representation of this Expression.
         */

        public function toString()
        {
        }

    I defined the Dependency

    custom/Extension/modules/sgoal_SalesGoals/Ext/Dependencies/deps.ext.php

    $dependencies['sgoal_SalesGoals']['setoptions_order_origin'] = array(
       'hooks' => array("edit","save"),
       'trigger' => true,
       'triggerFields' => array('goal_type', 'sales_entity_type', 'sales_group'),
       'onload' => true,
       'actions' => array(
          array(
            'name' => 'SetOptions',
            'params' => array(
               'target' => 'order_origin',
               'keys' => 'createList(restrictSalesGoalsDropdown($goal_type, $sales_entity_type, $sales_group))',               
               'labels' => 'createList(restrictSalesGoalsDropdown($goal_type, $sales_entity_type, $sales_group))',
            ),
          ),
        ),
    );

    Where am I going wrong? Clearly I'm not understanding this fully.

    Interestingly the dependency is not showing in 

    cache/modules/sgoal_SalesGoals/clients/base/dependency.php

    but is showing in 

    custom/modules/sgoal_SalesGoals/Ext/Dependencies/deps.ext.php

    thanks,
    FrancescaS

  • Nothing obvious stands out to me on why it isn't working. It could be your use of the _.difference underscore function. If I recall correctly, I tried using an underscore function in a custom sugar logic function in the past and I kept on getting weird behavior or errors. I finally removed the underscore method and just used some standard javascript functions and the problem went away.

    My only other suggestion would be to strip the functions back to very basic behavior and slowly add the code back in pieces at a time to try and narrow down the line of code causing the problem.

  • Brett Zufelt,

    I will try your suggestions, thank you.

    Should the dependency be in cache/modules/sgoal_SalesGoals/clients/base/dependency.php

    because it's not.

    That would suggest a problem with the dependency definition rather than an issue with the formula.

    thanks,
    FrancescaS

  • I don't believe the dependency needs to be in the cache folder. I looked at some of my custom dependencies that I know are working and they only show up in the custom/modules/<module>/Ext/Dependencies/deps.ext.php file and not in the cache directory.

    I don't feel the most knowledgeable in this area though, so hopefully someone else will chime in with additional guidance.

  • Thank you, that helps a lot, it means I need to focus elsewhere.

  • André Lopes, sorry to bother you, can you see anything obvious in my code that would cause it not to work?

    thanks,

    FrancescaS

  • I'm afraid you had overcomplicated the solution Francesca Shiekh .

    You better implement it through SetOption dependency, find bellow a working scenario:

    $dependencies['Cases']['case_status_xpto'] = array(

       'hooks' => array("view", "edit"),

       'trigger' => '

    and(

       not(equal($id, "")), isUserInList(createList("SIMM_GER", "SIMM_SUP")), equal($status, "Ag. Postagem"),

       or(

          equal($acc_tipo_cliente_c, "Cliente VIP"),

          and(equal($acc_tipo_cliente_c, "Cliente Final"), equal($extravio_transporte_c, false))

       )

    )

    ',

       'triggerFields' => array('status', 'acc_tipo_cliente_c', 'extravio_transporte_c'),

       'onload' => true,

       'actions' => array(

          array(

             'name' => 'SetOptions',

             'params' => array(

                'target' => 'status',

                'keys' => 'getDropdownKeySet("case_status_AgPostagemCliente_mgnt")',

                'labels' => 'getDropdownValueSet("case_status_AgPostagemCliente_mgnt")'

             ),

          ),

       ),

    );

    Regards

    André Lopes
    Lampada Global
    Skype: andre.lampada
  • Thank you André Lopes, I have a profound hatred for sugar logic formulas, but I'll give it a try.