function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
JBallJBall 

Dependent Picklists in Flex

Has anyone successfully applied a bitmask for dependent picklists in Flex? I'm trying to port the dependent picklists example in the API documentation by tweaking the Bitset class as described below, and modifying the reporting loop to one that will work in Flex.  It's applying the bitmask, but the indexes aren't matching up correctly.

Code:
public class Bitset
{
 private var data:ByteArray;

 public function Bitset(data:String)
 {
  this.data = new ByteArray();
  this.data.writeUTFBytes(data);
 }
 
 public function testBit(n:int):Boolean
 {
  return (data[n>>3] & (0x80 >> n % 8)) != 0;
 }
 
 public function size():int
 {
  return data.length * 8;
 }
}//end class Bitset

 

Ron HessRon Hess
can you post a bit more code around how you get the dependent picklist values from the api call, and how you call this class?  I'd like to (try to) sort this out and put it into the test harness.

i'm also interested in how you went about displaying the dependent picklist in Flex.
thanks  
JBallJBall
Ron,

To get the picklist values, I'm using a describe SObjects call.  I've added a "Rejection Reason" field to the Lead object in my developer account, which is dependent upon the Status field.  The describe call returns the following result for "Rejection Reason"
Code:
      [Rejection_Reason__c] (com.salesforce.results::Field)#134
autoNumber = false
byteLength = 765
calculated = false
caseSensitive = false
controllerName = "Status"
createable = true
custom = true
defaultedOnCreate = false
dependentPicklist = true
digits = "0"
filterable = true
label = "Rejection Reason"
length = 255
name = "Rejection_Reason__c"
nameField = false
namePointing = false
nillable = true
picklistValues = (mx.collections::ArrayCollection)#135
filterFunction = (null)
length = 2
list = (mx.collections::ArrayList)#136
length = 2
source = (Array)#137
[0] (com.salesforce.results::PickListEntry)#138
active = true
defaultValue = false
label = "Erroneous Data"
validFor = "EAAA"
value = "Erroneous Data"
[1] (com.salesforce.results::PickListEntry)#139
active = true
defaultValue = false
label = "Signed with competitor"
validFor = "UAAA"
value = "Signed with competitor"
uid = "3E27917B-3AB1-B757-AE24-467AC9802617"
sort = (null)
source = (Array)#137
precision = "0"
referenceTo = (null)
restrictedPicklist = false
scale = "0"
soapType = "xsd:string"
sortable = true
type = "picklist"
unique = false
updateable = true
The Status picklist has not been modified.  The dependency is as follows:

Open-Not Contacted:
Working-Contacted: Signed With Competitor
Closed-Converted:
Closed-Not Converted: Erroneous Data
                                          Signed with competitor

To test dependency, I'm currently looping through the picklist entries so they each have the controller name, and converting the String validFor field to a Bitset validFor field (newItem.validFor = new Bitset(field.picklistValues[f].validFor);). I then use the following filter function to determine if a dependent should be displayed:
Code:
private function dependentPicklistFilter(item:Object):Boolean
{
//TODO:add checkbox dependencies
var ok:Boolean = false;
if(item.active)
ok = item.validFor.testBit(fieldMap[item.controller].controller.selectedIndex);
return ok;
}
Both the controlling and dependent picklists are ComboBoxes using the picklistValues ArrayCollections as their data providers.  On a change, the controller calls dependent.dataprovider.refresh() to cause the filter function to re-evaluate.  Rignt now, I'm not as interested in efficiency as I am functionality.

Thanks,
John
 

Ron HessRon Hess
Your Bitset class works, but i removed size() because it's not the size of the bitset that matters, but the size of the controling field that is important.

first i added your field and field dependancies to my lead object

then i added Bitset to the library
 your port works correctly.
Code:
package com.salesforce.objects
{
import flash.utils.ByteArray;

public dynamic class Bitset {
public var data:ByteArray;

public function Bitset(data:String) {
this.data = new ByteArray();
this.data.writeUTFBytes(data);
}

public function testBit(n:int):Boolean {
return ((data[n>>3] & (0x80 >> n % 8)) != 0);
}

}
}


then i used the test harness (salesforce.mxml) and replaced describeSObjects_CB with this code
(and changed the describe to call ["Lead"])

Code:
   private function describeSObjects_CB(result:Object):void
   {
    ta.text = 'describeSObjects_CB Result\n' + 
     ObjectUtil.toString(result[0].fields['Rejection_Reason__c']);
    
    var rejectPick:ArrayCollection = result[0].fields['Rejection_Reason__c'].picklistValues;

    var statusPick:ArrayCollection = result[0].fields['Status'].picklistValues;
    
  for ( var i:int=0; i< rejectPick.length; i++) { 
    
   var validFor:Bitset = new Bitset(rejectPick[i].validFor); 
  
   for ( var j:int=0; j < statusPick.length; j++) { 
    trace('Status :', statusPick[j].label, 
     ' and show:', rejectPick[i].label, validFor.testBit(j) );
   }
  }
   }

 


and here is my output on the console:
Code:
Status : Open - Not Contacted  and show: Signed With Competitor false
Status : Working - Contacted  and show: Signed With Competitor true
Status : Closed - Converted  and show: Signed With Competitor false
Status : Closed - Not Converted  and show: Signed With Competitor true
Status : Open - Not Contacted  and show: Erroneous Data false
Status : Working - Contacted  and show: Erroneous Data true
Status : Closed - Converted  and show: Erroneous Data false
Status : Closed - Not Converted  and show: Erroneous Data false

 

i didn't go back and use your loops, or create your filter function , but i think you can see how the bit set is indexed from this test code.  Let me know if you agree that this is working.

thanks again for your detailed code and problem description.
JBallJBall
Yep, that's it, thanks for your help!
JBallJBall
Ron,

I know I'm re-opening this thread rather late in the game, but I've only just had time to return to it.  It appears we prematurely accepted the results of the bitmask.  You'll notice Erroneous Data is true for a single controlling field value, but it's the wrong value!  It should be Closed - Not Converted that's the true value.  I'm getting the same results.

Status : Open - Not Contacted  and show: Signed With Competitor false
Status : Working - Contacted and show: Signed With Competitor true
Status : Closed - Converted and show: Signed With Competitor false
Status : Closed - Not Converted and show: Signed With Competitor true
Status : Open - Not Contacted and show: Erroneous Data false
Status : Working - Contacted and show: Erroneous Data true
Status : Closed - Converted and show: Erroneous Data false
Status : Closed - Not Converted and show: Erroneous Data false

Ron HessRon Hess
I just checked in a fix, basicaly the string needs to be decoded from base 64 before creating the bitset data
    Code:
public function Bitset(data:String)        {
            // the string that comes over the wire is base 64
            // need to move it back to binary data       
            this.data = Base64.decode(data); 
        }

JBallJBall
Thanks Ron,

I don't know how long it would have taken me before I'd thought of that!