Results 1 to 7 of 7

Thread: Quick and Easy Tristate Checkbox in a cCjGridColumn

  1. #1
    Join Date
    Feb 2009
    Location
    Birmingham, UK
    Posts
    977

    Default Quick and Easy Tristate Checkbox in a cCjGridColumn

    Just because I was bored and wanted a tristate checkbox in a cCjGridColumn without needing to resort to using an icon...

    Code:
    Class cMyCjGridColumn is a cCJGridColumn
        
        Procedure Construct_Object
            Forward Send Construct_Object
    
    
            {Visibility=Private}
            Property Boolean Private_pbTristateCheckbox     False
            {Category=Behavior}
            Property String psCheckboxIndeterminate         "2"
                    
        End_Procedure
    
    
        {MethodType=Property InitialValue=False}
        {Category=Appearance }
        Procedure Set pbTristateCheckbox Boolean bValue
            Set pbCheckbox to True
            Set Private_pbTristateCheckbox to True
        End_Procedure 
        
        Function pbTristateCheckbox Returns Boolean
            Function_Return (Private_pbTristateCheckbox(Self))
        End_Function
    
    
        Function ValueToTristate String sValue Returns Integer
            If (sValue=psCheckboxTrue(Self)) Begin
                Function_Return 1
            End
            If (sValue=psCheckboxIndeterminate(Self)) Begin
                Function_Return 2
            End
            Function_Return 0
        End_Function
        
        Function TristateToValue Integer iValue Returns String
            If (iValue=1) Begin
                Function_Return (psCheckboxTrue(Self))        
            End
            If (iValue=2) Begin
                Function_Return (psCheckboxIndeterminate(Self))      
            End
            Function_Return (psCheckboxFalse(Self))
        End_Function
    
    
        Procedure DrawCell Handle hoRow Handle hoItem Handle hoMetrics Integer iRow String sValue
            Boolean bTristate
            Integer iValue
            
            Forward Send DrawCell hoRow hoItem hoMetrics iRow sValue
            Get pbTristateCheckbox to bTristate
            If (bTristate) Begin
                Get ValueToTristate sValue to iValue
                Set ComTristateCheckbox of hoItem to True
                Set ComCheckboxState of hoItem to iValue 
            End  
        End_Procedure
    
    
    End_Class
    ..and then implementing this is as easy as:

    Code:
    Object oCjGrid is a cCJGrid
        Set Size to 200 300
        Set Location to 0 0
        Set peAnchors to anAll
    
         Object oCol_Text is a cMyCjGridColumn
            Set piWidth to 100
            Set psCaption to "Description"
        End_Object
    
    
        Object oCol_Tristate_Checkbox is a cMyCjGridColumn
            Set piWidth to 100
            Set psCaption to "Grant"
            Set pbTristateCheckbox to True
            Set psCheckboxTrue to "Y"
            Set psCheckboxFalse to "N"
            Set psCheckboxIndeterminate to ""
        End_Object
            
        Procedure LoadData
            tDataSourceRow[] TheData
                
            Move "True"          to TheData[0].sValue[0]
            Move "Y"             to TheData[0].sValue[1]
            Move "False"         to TheData[1].sValue[0]
            Move "N"             to TheData[1].sValue[1]
            Move "Indeterminate" to TheData[2].sValue[0]
            Move ""              to TheData[2].sValue[1]
            Move "False"         to TheData[3].sValue[0]
            Move "N"             to TheData[3].sValue[1]
            Move "Indeterminate" to TheData[4].sValue[0]
            Move ""              to TheData[4].sValue[1]
            Move "True"          to TheData[5].sValue[0]
            Move "Y"             to TheData[5].sValue[1]
            Move "True"          to TheData[6].sValue[0]
            Move "Y"             to TheData[6].sValue[1]
              
            Send InitializeData TheData
            Send MoveToFirstRow
        End_Procedure
        
        Procedure Activating
            Forward Send Activating
            Send LoadData
        End_Procedure
    End_Object

    Don't know if this will be of any use to anyone ... but hey, just in case.
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	tristate.jpg 
Views:	143 
Size:	66.8 KB 
ID:	10369  
    Last edited by Peter Bragg; 18-Oct-2016 at 09:01 AM. Reason: added image
    "My wife thinks I over-analyse our marriage, which, to be frank completely contradicts the findings of my report." - @MooseAllain

  2. #2
    Join Date
    Nov 2008
    Location
    Round Rock, TX
    Posts
    7,835

    Default Re: Quick and Easy Tristate Checkbox in a cCjGridColumn

    Nice, Peter!

  3. #3
    Join Date
    Feb 2009
    Location
    Queens, NY, NY
    Posts
    6,591

    Default Re: Quick and Easy Tristate Checkbox in a cCjGridColumn

    Sweet!.
    Michael Mullan.
    Danes Bridge Enterprises.

    ++++++++++++++++++++++++++++
    There is just today. Tomorrow is a concept
    that is mostly theoretical. -- GM Wylie
    ++++++++++++++++++++++++++++

  4. #4
    Join Date
    Feb 2009
    Location
    Peoria, IL
    Posts
    5,336

    Default Re: Quick and Easy Tristate Checkbox in a cCjGridColumn

    Very nice !
    Chuck Atkinson

    All generalizations are false, including this one - Mark Twain

  5. #5
    Join Date
    Feb 2009
    Location
    Birmingham, UK
    Posts
    977

    Default Re: Quick and Easy Tristate Checkbox in a cCjGridColumn

    .
    Last edited by Peter Bragg; 12-Nov-2019 at 09:48 AM. Reason: posted in haste. Better solution incoming....
    "My wife thinks I over-analyse our marriage, which, to be frank completely contradicts the findings of my report." - @MooseAllain

  6. #6
    Join Date
    Feb 2009
    Location
    Castlegar, BC Canada
    Posts
    3,816

    Default Re: Quick and Easy Tristate Checkbox in a cCjGridColumn

    Nice work Peter!

  7. #7
    Join Date
    Feb 2009
    Location
    Birmingham, UK
    Posts
    977

    Default Re: Quick and Easy Tristate Checkbox in a cCjGridColumn

    The original code - which was really just to show what could be done - assumed that the setting of the '3rd' state would be done programmatically, and that the end-user would/should simply only be able to set the checkbox to True or False. However, there are some circumstances where you may indeed wish to allow the end user to cycle through all the three states.

    Hans van de Laar kindly came up with the following and gave permission for me to post his solution on here. So, thank you Hans

    Code:
        Function NotifyItemChecked Returns Boolean
            Boolean bCancel bTristate bAllowFullCycle
            Integer iValue
            String sOldValue sValue
            
            Get pbTristateCheckbox to bTristate
            Get pbTristateAllowFullCycle to bAllowFullCycle
            If (bTristate and bAllowFullCycle) Begin
                Get SelectedRowValueBeforeEdit to sOldValue
                Get ValueToTristate sOldValue to iValue
                Increment iValue
                If (iValue > 2) Begin
                    Move 0 to iValue
                End
                Get TristateToValue iValue to sValue
                Send UpdateCurrentValue sValue
                Send OnEndEdit sOldValue sValue
            End
            Else Begin
               Forward Get NotifyItemChecked to bCancel
            End
            Function_Return bCancel
        End_Function
    The above should be added to the Column Class, along with the following property:

    Code:
        {Category=Behavior}
        Property Boolean pbTristateAllowFullCycle       False
    This simply allows you to control whether or not you want to allow cycling through all 3 states on a column by column basis (sometimes you might want to, others not)

    Hans also kindly pointed out a slight bug in the original code too:

    Code:
        {MethodType=Property InitialValue=False}
        {Category=Appearance }
        Procedure Set pbTristateCheckbox Boolean bValue
            Set pbCheckbox to True
            Set Private_pbTristateCheckbox to True
        End_Procedure
    This should of course be:

    Code:
        {MethodType=Property InitialValue=False}
        {Category=Appearance }
        Procedure Set pbTristateCheckbox Boolean bValue
            Set pbCheckbox to bValue
            Set Private_pbTristateCheckbox to bValue
        End_Procedure
    (although as "false" was the default, you'd probably not add the code unless you were setting it to True, so I nearly got away with it! That said, if you the column to be a Checkbox column but you're still adding the code "Set pbTristateCheckbox to False", remember to set pbCheckbox to True again afterwards.)

    Thanks Hans.
    "My wife thinks I over-analyse our marriage, which, to be frank completely contradicts the findings of my report." - @MooseAllain

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •