How to create conditional checkbox ?

Hi Community,

 

How can i make checkbox visible/hidden based on previous DropDown value.

For ex - I have dropdown field as Product having values - KFC, Pizzahut.

I have different checkboxes values if user selects KFC or Pizzahut.

How can i show different checbox dynamically after user selects dropdwon value.

I don't want to show all checkbox value and then hide. Based on the choice KFC/Pizzahut corresponding Checkbox options should dynamically come in form.

Here is the code that i am trying. Please help me with this.

 

    if(
          ri!readOnly,
          a!textField(
            label: "Product",
            labelPosition: "ADJACENT",
            value: ri!record.productGroupAffected.value,
            readOnly: true
          ),
          a!dropdownField(
            label: "Product",
            labelPosition: "ABOVE",
            instructions: "",
            helpTooltip: "",
            placeholderLabel: "--- Select a Value ---",
            choiceLabels: local!productGroupAffectedOptions.value,
            choiceValues: local!productGroupAffectedOptions,
            value: ri!record.productGroupAffected,
            saveInto: ri!record.productGroupAffected,
            required: false
          )
        ),
        
	
		if(
			ri!record.productGroupAffected = "KFC",
			a!textField(
			label: "Tools Affected KFC",
			labelPosition: "ADJACENT",
			value: if(
					or(isnull(ri!record.toolsAffected), count(ri!record.toolsAffected.value)=0),
					"",
				joinarray(ri!record.toolsAffected.value, ", ")
			),
			readOnly: true
			),
			a!checkboxField(
			label: "Tools Affected KFC",
			labelPosition: "ABOVE",
			instructions: "",
			helpTooltip: "",
			choiceLabels: local!checkbox1Value,
			choiceValues: local!checkbox1Value,
			value: ri!record.toolsAffected,
			saveInto: ri!record.toolsAffected,
			required: false
			)
		),
		
		if(
			 ri!record.productGroupAffected = "PizzaHut",
			a!textField(
			label: "Tools Affected PizzaHut",
			labelPosition: "ADJACENT",
			value: if(
					or(isnull(ri!record.toolsAffected), count(ri!record.toolsAffected.value)=0),
					"",
				joinarray(ri!record.toolsAffected.value, ", ")
			),
			readOnly: true
			),
			a!checkboxField(
			label: "Tools Affected PizzaHut",
			labelPosition: "ABOVE",
			instructions: "",
			helpTooltip: "",
			choiceLabels: local!checkbox2Value,
			choiceValues: local!checkbox2Value,
			value: ri!record.toolsAffected,
			saveInto: ri!record.toolsAffected,
			required: false

			)
		),
		

  Discussion posts and replies are publicly visible

Parents
  • To get a!forEach() functionality to work in 17.1 use a!apply() or a!appyComponents().
  • Hi can you suggest alternative for a!columnsLayout() and a!columnLayout() as well in 17.1 which has written for 17.2 ?
  • In 17.1, you have only chance to implements columns is using the form Layout or dashboard Layout with first column contents and second column contents.
  • 0
    Certified Lead Developer
    in reply to prais1852
    I'm afraid that pre-17.2 you'll need to abandon the horizontal component concept i came up with above and instead resort to traditional vertically stacked components.
  • understood, looks like horizontal looping structure we can use in 17.2 and above only. Can you please help me with the code to make "Select sizes" option as checkbox instead of radio buttons ?
  • 0
    Certified Lead Developer
    in reply to prais1852
    Well, the first step is just changing them to checkbox instead of radio button fields. Have you tried that / is it not working?
  • Hi , Yes i tried that. Checkboxes are coming but they are behaving like radio button. Also if select "Medium" size on 'Fried Chicken' and then select the "Small" size on 'Buiscuits' then it automatically removes "Medium" selection of 'Fried Chicken' (previous selection) i.e. I can check only one checkbox for all the categories.
  • 0
    Certified Lead Developer
    in reply to prais1852
    Can you post the code you're currently using?
  • Here it is -

    load(
    
      local!restaurantChoices: {
        {id: 1, name: "KFC"}, 
        {id: 2, name: "Pizza Hut"}
      },
      local!selectedRestaurant,
      local!menuSelection: {},
      
      /* set up Menu Selection Sizes to be an array of dictionary -
        the CDT would resemble {item: "item name", size: sizeId} */
      local!menuSelectionSizes: {},
      
      with(
        
        /* dynamically set the menu choices based on which restaurant is picked */
        local!menuChoices: if(
          isnull(local!selectedRestaurant),
          {},
          if(
            tointeger(local!selectedRestaurant) = 1,
            {
              "Fried Chicken", "Mashed Potatoes", "Cole Slaw", "Biscuits", "Gravy"
            },
            if(
              tointeger(local!selectedRestaurant) = 2,
              {
                "Pizza", "Bread Sticks", "Salad Bar", "Soft Drinks"
              },
              {}
            )
          )
        ),
        
        a!formLayout( 
        /* now assuming 17.2 or newer */
          
          contents: {
            a!radioButtonField(
              label: "Chain:",
              labelPosition: "ADJACENT",
              choiceLabels: local!restaurantChoices.name,
              choiceValues: local!restaurantChoices.id,
              value: local!selectedRestaurant,
              saveInto: {
                local!selectedRestaurant,
                
                /* the below will clear the previous menu selection when the restaurant is changed */
                a!save(
                  local!menuSelection,
                  {}
                )
              }
            ),
            
            if(
              not(isnull(local!selectedRestaurant)),
              a!checkboxField(
                label: "Make your food choices:",
                labelPosition: "ADJACENT",
                choiceLabels: local!menuChoices,
                choiceValues: local!menuChoices,
                value: local!menuSelection,
                saveInto: {
                  a!save(
                    local!menuSelection,
                    /* this weird saveInto style will attempt to keep the saved value array in the same order as the
                    initial checkboxes, since Appian versions 17.1 and later no longer do this automatically */
                    index(
                      local!menuChoices,
                      whereContains(
                        save!value,
                        local!menuChoices
                      )
                    )
                  )
                }
              ),
              {}
            ),
            a!columnsLayout(
              columns: a!forEach(
                local!menuSelection,
                with(
                  local!currentIndex: wherecontains(
                    fv!item,
                    touniformstring(property(local!menuSelectionSizes, "item", {}))
                  ),
                  a!columnLayout(
                    contents: {
                      a!checkboxField(
                        label: "Select Size: '" & fv!item & "'",
                        labelPosition: "ABOVE",
                        /*instructions: "current index: " & local!currentIndex,*/
                        choiceLabels: {"Small", "Medium", "Large"},
                        choiceValues: {1, 2, 3},
                        value: property(
                          index(
                            local!menuSelectionSizes,
                            local!currentIndex,
                            {}
                          ),
                          "size",
                          null()
                        ),
                        saveInto: {
                          a!save(
                            local!menuSelectionSizes,
                            append(
                              if(
                                isnull(local!currentIndex),
                                local!menuSelectionSizes,
                                remove(local!menuSelectionSizes, local!currentIndex)
                              ),
                              {
                                item: fv!item,
                                size: save!value
                              }
                            ) 
                          )
                        }
                      )
                    }
                  )
                )
              )
            )
          } 
        )
      )
    )

  • 0
    Certified Lead Developer
    in reply to prais1852
    This is the 17.2 version - are you able to use 17.2 again?
  • We are upgrading our all servers to 17.2 in next few days, so that will not be any issue now. Also as you earlier said it is very tough to get similar feature in 17.1 so i am looking for solution in 17.2 only if possible.
  • +1
    Certified Lead Developer
    in reply to prais1852

    I was able to get it working - basically it required somewhat different handling of the local variable being used to store sizes, storing it as an array instead of a singular in the local dictionary, and special handling for when the user de-selects back down to the empty set.

    load(
    
      local!restaurantChoices: {
        {id: 1, name: "KFC"}, 
        {id: 2, name: "Pizza Hut"}
      },
      local!selectedRestaurant,
      local!menuSelection: {},
      
      /* set up Menu Selection Sizes to be an array of dictionary -
        the CDT would resemble {item: "item name", size: sizeId} */
      local!menuSelectionSizes: {},
      
      with(
        
        /* dynamically set the menu choices based on which restaurant is picked */
        local!menuChoices: if(
          isnull(local!selectedRestaurant),
          {},
          if(
            tointeger(local!selectedRestaurant) = 1,
            {
              "Fried Chicken", "Mashed Potatoes", "Cole Slaw", "Biscuits", "Gravy"
            },
            if(
              tointeger(local!selectedRestaurant) = 2,
              {
                "Pizza", "Bread Sticks", "Salad Bar", "Soft Drinks"
              },
              {}
            )
          )
        ),
        
        a!formLayout( 
        /* now assuming 17.2 or newer */
          
          contents: {
            a!radioButtonField(
              label: "Chain:",
              labelPosition: "ADJACENT",
              choiceLabels: local!restaurantChoices.name,
              choiceValues: local!restaurantChoices.id,
              value: local!selectedRestaurant,
              saveInto: {
                local!selectedRestaurant,
                
                /* the below will clear the previous menu selection when the restaurant is changed */
                a!save(
                  local!menuSelection,
                  {}
                )
              }
            ),
            
            if(
              not(isnull(local!selectedRestaurant)),
              a!checkBoxField(
                label: "Make your food choices:",
                labelPosition: "ADJACENT",
                choiceLabels: local!menuChoices,
                choiceValues: local!menuChoices,
                value: local!menuSelection,
                saveInto: {
                  a!save(
                    local!menuSelection,
                    /* this weird saveInto style will attempt to keep the saved value array in the same order as the
                    initial checkboxes, since Appian versions 17.1 and later no longer do this automatically */
                    index(
                      local!menuChoices,
                      whereContains(
                        save!value,
                        local!menuChoices
                      )
                    )
                  )
                }
              ),
              {}
            ),
            a!columnsLayout(
              columns: a!forEach(
                local!menuSelection,
                with(
                  local!currentIndex: wherecontains(
                    fv!item,
                    touniformstring(property(local!menuSelectionSizes, "item", {}))
                  ),
                  a!columnLayout(
                    contents: {
                      a!checkboxField(
                        label: "Select Size: '" & fv!item & "'",
                        labelPosition: "ABOVE",
                        choiceLabels: {"Small", "Medium", "Large"},
                        choiceValues: {1, 2, 3},
                        value: tointeger(
                          property(
                            index(
                              local!menuSelectionSizes,
                              local!currentIndex,
                              null()
                            ),
                            "sizes",
                            null()
                          )
                        ),
                        saveInto: {
                          a!save(
                            local!menuSelectionSizes,
                            append(
                              if(
                                isnull(local!currentIndex),
                                local!menuSelectionSizes,
                                remove(local!menuSelectionSizes, local!currentIndex)
                              ),
                              if(
                                apn_isEmpty(save!value),
                                /* indicates all size choices have been de-selected, so we'll save an empty set here to remove this menu choice from the saved data set */
                                {},
                                {
                                  item: fv!item,
                                  sizes: save!value
                                }
                              )
                            ) 
                          )
                        }
                      )
                    }
                  )
                )
              )
            ),
            
            /*a!paragraphField(*/
              /*label: "debug",*/
              /*value: local!menuSelectionSizes*/
            /*),*/
            
            {}
          } 
        )
      )
    )

Reply
  • +1
    Certified Lead Developer
    in reply to prais1852

    I was able to get it working - basically it required somewhat different handling of the local variable being used to store sizes, storing it as an array instead of a singular in the local dictionary, and special handling for when the user de-selects back down to the empty set.

    load(
    
      local!restaurantChoices: {
        {id: 1, name: "KFC"}, 
        {id: 2, name: "Pizza Hut"}
      },
      local!selectedRestaurant,
      local!menuSelection: {},
      
      /* set up Menu Selection Sizes to be an array of dictionary -
        the CDT would resemble {item: "item name", size: sizeId} */
      local!menuSelectionSizes: {},
      
      with(
        
        /* dynamically set the menu choices based on which restaurant is picked */
        local!menuChoices: if(
          isnull(local!selectedRestaurant),
          {},
          if(
            tointeger(local!selectedRestaurant) = 1,
            {
              "Fried Chicken", "Mashed Potatoes", "Cole Slaw", "Biscuits", "Gravy"
            },
            if(
              tointeger(local!selectedRestaurant) = 2,
              {
                "Pizza", "Bread Sticks", "Salad Bar", "Soft Drinks"
              },
              {}
            )
          )
        ),
        
        a!formLayout( 
        /* now assuming 17.2 or newer */
          
          contents: {
            a!radioButtonField(
              label: "Chain:",
              labelPosition: "ADJACENT",
              choiceLabels: local!restaurantChoices.name,
              choiceValues: local!restaurantChoices.id,
              value: local!selectedRestaurant,
              saveInto: {
                local!selectedRestaurant,
                
                /* the below will clear the previous menu selection when the restaurant is changed */
                a!save(
                  local!menuSelection,
                  {}
                )
              }
            ),
            
            if(
              not(isnull(local!selectedRestaurant)),
              a!checkBoxField(
                label: "Make your food choices:",
                labelPosition: "ADJACENT",
                choiceLabels: local!menuChoices,
                choiceValues: local!menuChoices,
                value: local!menuSelection,
                saveInto: {
                  a!save(
                    local!menuSelection,
                    /* this weird saveInto style will attempt to keep the saved value array in the same order as the
                    initial checkboxes, since Appian versions 17.1 and later no longer do this automatically */
                    index(
                      local!menuChoices,
                      whereContains(
                        save!value,
                        local!menuChoices
                      )
                    )
                  )
                }
              ),
              {}
            ),
            a!columnsLayout(
              columns: a!forEach(
                local!menuSelection,
                with(
                  local!currentIndex: wherecontains(
                    fv!item,
                    touniformstring(property(local!menuSelectionSizes, "item", {}))
                  ),
                  a!columnLayout(
                    contents: {
                      a!checkboxField(
                        label: "Select Size: '" & fv!item & "'",
                        labelPosition: "ABOVE",
                        choiceLabels: {"Small", "Medium", "Large"},
                        choiceValues: {1, 2, 3},
                        value: tointeger(
                          property(
                            index(
                              local!menuSelectionSizes,
                              local!currentIndex,
                              null()
                            ),
                            "sizes",
                            null()
                          )
                        ),
                        saveInto: {
                          a!save(
                            local!menuSelectionSizes,
                            append(
                              if(
                                isnull(local!currentIndex),
                                local!menuSelectionSizes,
                                remove(local!menuSelectionSizes, local!currentIndex)
                              ),
                              if(
                                apn_isEmpty(save!value),
                                /* indicates all size choices have been de-selected, so we'll save an empty set here to remove this menu choice from the saved data set */
                                {},
                                {
                                  item: fv!item,
                                  sizes: save!value
                                }
                              )
                            ) 
                          )
                        }
                      )
                    }
                  )
                )
              )
            ),
            
            /*a!paragraphField(*/
              /*label: "debug",*/
              /*value: local!menuSelectionSizes*/
            /*),*/
            
            {}
          } 
        )
      )
    )

Children
  • Hi Your code worked with local variables but i am getting problem when trying to save value in Rule input (ri!) fields. Could you please explain what your functions are trying to do in 2nd parameter (expression) of a!ForEach() ?
  • 0
    Certified Lead Developer
    in reply to prais1852
    Do you mean you're having trouble getting it to work in a task, or just when trying to convert some of the local variables to rule inputs instead? Can you provide a little more detail about the setup you've done and what's going wrong? And which code are you referring to that you need an explanation on?
  • I have problem with rule Inputs when i am translating the code for Rule Inputs. Here is the part of code that i am using for my application and looking for the explanation of this part of answer suggested by you - 

    a!columnsLayout(
    			columns: a!forEach(
    				ri!CCC.toolsaffected,
    				with(
    					local!currentIndex: wherecontains(
    					fv!item,
    					touniformstring(property(ri!CCC.NodesAffected, "item", {}))
    				),
    		
            a!columnLayout(
    					contents: {
              	a!checkboxField(
                  label: "Nodes Affected for : '" & fv!item & "'",
                  labelPosition: "ABOVE",
                  /*instructions: "current index: " & local!currentIndex,*/
                  choiceLabels: {"1262", "1264", "1266","1268","1270","1272","1274","1276"},
                  choiceValues: {1262, 1264, 1266, 1268, 1270, 1272, 1274, 1276},
                  value: tointeger(
                  property(
                      index(
                        ri!CCC.NodesAffected,
                        local!currentIndex,
                        null()
                       ),
                       "nodes",
                       null()
                     )
                   ),
                   saveInto: {
                     a!save(
                       ri!CCC.NodesAffected,
                         append(
                           if(isnull(local!currentIndex),
                             ri!CCC.NodesAffected,
                             remove(ri!CCC.NodesAffected, local!currentIndex)
                            ),
                            if(
                                rule!APN_isEmpty(save!value),
                                /* indicates all size choices have been de-selected, so we'll save an empty set here to remove this menu choice from the saved data set */
                                {},
                                {
                                  item: fv!item,
                                  nodes: save!value
                                }
                              )
            							)
          						)
        						}
      						)
        				}
      				)
      			)
      		),
    		  showwhen: not(isnull(ri!CCC.ProductGroupAffected))
    		),
    	

  • 0
    Certified Lead Developer
    in reply to prais1852
    Can you share the configuration of ri!CCC?
  • I am using a CDT for this rule input. Do you need XSD of that CDT ?
  • Here is the XSD of the CDT -

    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:com:appian:types:CCCD" targetNamespace="urn:com:appian:types:CCCD">
      <xsd:complexType name="CCC_Details">
        <xsd:annotation>
          <xsd:documentation><![CDATA[Information]]></xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
          <xsd:element name="CCCNumber" nillable="true" type="xsd:int">
            <xsd:annotation>
              <xsd:appinfo source="appian.jpa">@Id @GeneratedValue</xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <xsd:element name="Approved" nillable="true" type="xsd:string">
            <xsd:annotation>
              <xsd:appinfo source="appian.jpa">@Column(length=50)</xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <xsd:element name="ApprovalDate" nillable="true" type="xsd:date" />
          <xsd:element name="PRNumber" nillable="true" type="xsd:int" />
          <xsd:element name="ProductGroupAffected" nillable="true" type="xsd:string" />
          <xsd:element maxOccurs="unbounded" minOccurs="0" name="ToolsAffected" nillable="true" type="xsd:string" />
          <xsd:element maxOccurs="unbounded" minOccurs="0" name="NodesAffected" nillable="true" type="xsd:string" />
          <xsd:element name="ApprovedBy" nillable="true" type="xsd:string">
          
          <xsd:element name="Bundled" nillable="true" type="xsd:string">
            <xsd:annotation>
              <xsd:appinfo source="appian.jpa">@Column(length=5)</xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <xsd:element name="CreatedBy" nillable="true" type="xsd:string">
            <xsd:annotation>
              <xsd:appinfo source="appian.jpa">@Column(length=100)</xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <xsd:element name="CreatedOn" nillable="true" type="xsd:dateTime" />
          <xsd:element name="UpdatedBy" nillable="true" type="xsd:string">
            <xsd:annotation>
              <xsd:appinfo source="appian.jpa">@Column(length=100)</xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <xsd:element name="UpdatedOn" nillable="true" type="xsd:dateTime" />
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>

  • 0
    Certified Lead Developer
    in reply to prais1852
    I don't really need an XSD, just maybe a description of how some of the CDT properties you're using are configured (such as NodesAffected for instance), or maybe a screenshot. And also you didn't mention what error you're getting.
  • My problem is same as earlier. Still if i click one of the Nodes Affected ( Product Sizes in earlier examples ) and then select the some other from list of checkboxes, my previous selection gets removed. However it is working fine for the code you mentioned above using local variables but not working with rule inputs.

  • Hi on saving values in rule input it is not working compared to the above code written by you. Is there any other way to store the data with item & sizes pair ?
  • Hi It works only when i click all the checkboxes before page reloads with selected options. I checked on the interface also. The values are getting inserted in the interface input but once i click on any other text field of my form the checkbox selection gets removed.

    If you can explain the use of property() in your code then that will also be very helpful. I am not getting the idea why you have used property method.