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

  • +2
    Certified Lead Developer

    Some of the advice you got in your previous thread would likely be beneficial here as well (for example, someone suggested reading up on the SAIL recipes), but I will take a shot at this new use case.

    You haven't given much info on what you would want the different checkbox values to be, but I'll assume Pizza Hut gets one set of food options and KFC gets a completely separate set - and the values will dynamically change when one or the other is picked.

    I'll create everything using LOAD and WITH variables so this can be copied and pasted into a new interface editor without needing to worry about RI values, etc.

    load(
    
      local!restaurantChoices: {
        {id: 1, name: "KFC"}, 
        {id: 2, name: "Pizza Hut"}
      },
      local!selectedRestaurant,
      local!menuSelection: {},
      
      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( 
        /* assuming 17.1 or prior, btw... if using 17.2, change this to a!formLayout_17r1 */
          
          firstColumnContents: {
            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: local!menuSelection
              ),
              {}
            )
          } 
        )
      )
    )

    Let me know if this is close to what you're after.

  • Mike Schmitt, your explanation is awesome.
  • 0
    Certified Lead Developer

    Hi prup1852 I suggest, you better explore SAIL Recipes to know some basics about SAIL before you start working on it. However if you can attach your complete code, then it will be easy to understand your requirement.

  • Try to get habit of using rule!APN_isBlank() rule instead of isnull() for single variables. This rule internally checks for null or empty.

    Here is the code of APN_isBlank() rule:
    =or(ri!singlePV="", isnull(ri!singlePV))

    where singlePV is a variable of type AnyType.

    For checking CDT type and multiple type variables, use rule!APN_isEmpty() which internally does null and length checks.
    Here is the code of APN_isEmpty()

    if(fn!isnull(ri!array),true(),length(ri!array)=0)

    where array is of type AnyType
  • 0
    Certified Lead Developer
    in reply to kondetiv
    I completely agree, and almost always do use the apn_isBlank() and apn_isEmpty() rules -- however for the sake of my code example above I used the primitive functions because that's the only way to guarantee that any user could copy/paste my code into a blank interface editor and have it work right away, since not all environments will have the appian common objects installed.
  • Hi , I want to modify my form. My new requirement is like if user selects "KFC" and then selects food choices say (Fried Chicken and Gravy) then i want to auto populate new checkbox/radio field for selecting the size (Say Large, Medium, Small). If user selects Fried Chicken and Gravy then i want to show size option for both food (Large,Medium,Small). If user selects 3 food choices then for all 3. I know this can be achieved using loops and i tried everything to learn a!ForEach() and repeat() but not able to achieve this feature yet. Can you please help me with this additional requirement ?
  • +1
    Certified Lead Developer
    in reply to prais1852

    Since it sounds like you're in 17.2 and have a!forEach available, I'll switch my example over to a 17.2 layout real quick.

    In this updated version i've added one new LOAD variable, which at first is an empty set, but which we will populate with an array of dictionary data, where each dictionary entry will be like {item: "biscuits", size: 1}, where sizes are represented by a number array (1=small, 2=medium, 3=large).  Also note that I've set it up to retain size selections even when menu items are selected and unselected, and even when the restaurant is changed.  This can all be customized to your preference by tweaking the code as needed.

    Note: just for fun, I've made each size selection appear in its own dynamic column, now that we're allowed to have an arbitrary number of columns on a form.

    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!radioButtonField(
                        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
                              }
                            )
                          )
                        }
                      )
                    }
                  )
                )
              )
            )
          }
        )
      )
    )
  • Great that helped me. Earlier i was using a!formLayout_17r1 so used firstColumnContents and secondColumnContents to divide my interface. However i can't use it with a!formLayout. I used Contents instead but i can't divide my interface now. Is there any other keyword to do so in new version ?

  • Got it. I can do it with a!columnsLayout and columns. You have certainly increased my interest in SAIL. Thank you so much.