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 ?
  • 0
    Certified Lead Developer
    in reply to prais1852

     First of all, migrating from Higher Version to Lower version is never a good approach. Because this require lot of changes to be done in your application.

    Now coming back to your requirement, there are no alternative for a!columnsLayout(). Till 17.1 version, we had max 2 columns for each UI, while UI designing, whereas from 17.2 on-wards a!columnsLayout() added more flexibility to have multiple columns as per our need.

    So, if you have switched from 17.2 to 17.1, i recommend change your layouts and their contents. And also replace all those functions which are introduced in 17.2 with their similar one in 17.1 as already been discussed above

  • Hi i guess you missed the full conversation. Version is not a point of worry now. It's just some feature which are not working with rule input in 17.2 but working with local variables.
  • 0
    Certified Lead Developer
    in reply to prais1852
    One initial issue I see in your code & cdt definition is: when you're saving into ri!CCC.NodesAffected, my original rule is assuming the local variable (local!menuSelectionSizes) is capable of holding dictionary data - i'm saving {item: fv!item, sizes: save!value} -- you're doing the same thing (except turned into Tool/Nodes), except the data type you're saving it into is Text, not Dictionary or CDT or "Any Type".

    You might want to consider making a new CDT consisting of the fields "Tool" (single) and "Nodes" (multiple), and switching the NodesAffected property in your original CDT to be of that new type (also multiple). After that your saves might work.

    If you have the need to not do a nested CDT, however, you could also consider converting the value being saved into a JSON string, which you can store in a single text field like your CDT already has, except that would require conversion to be done both at saving and at loading time.
  •  If i would like to go with saving in JSON string. How can i do that ? Can you share some links for help if possible ? I am really scared of dealing with Nested CDTs, Managin CDTs is tough for me.

  • +1
    Certified Lead Developer
    in reply to prais1852

    Since I'm feeling generous, I went back to my old example and converted it to be able to store its saved values in a new CDT containing fields pretty much exactly like yours:

    I'm doing the JSON conversion like I referenced in my prior reply - notice that I created a new WITH variable which checks whether there's any value in the "Size" array (in your version that would be "NodesAffected"), and if so, translates each one back from a JSON string to dictionary data (like was originally used in my original version); then in the checkbox field, it uses this local variable for display, but saves directly into ri!menuSelectionCdt.Size (converting the saved values into a JSON string prior to storing them in the text varray).  You should be able to translate this pretty much directly into your use case.

    load(
    
      local!restaurantChoices: {
        {id: 1, name: "KFC"}, 
        {id: 2, name: "Pizza Hut"}
      },
      local!selectedRestaurant,
      local!menuSelection: {},
      
      /*local!menuSelectionSizes: {},*/
      
      with(
        
        /* dynamically set the menu choices based on which restaurant is picked */
        local!menuChoices: if(
          isnull(ri!menuSelectionCdt.RestaurantSelected),
          {},
          if(
            tointeger(ri!menuSelectionCdt.RestaurantSelected) = 1,
            {
              "Fried Chicken", "Mashed Potatoes", "Cole Slaw", "Biscuits", "Gravy"
            },
            if(
              tointeger(ri!menuSelectionCdt.RestaurantSelected) = 2,
              {
                "Pizza", "Bread Sticks", "Salad Bar", "Soft Drinks"
              },
              {}
            )
          )
        ),
        
        
        /* set up Menu Selection Sizes to be an array of dictionary -
          the format will resemble this: 
          {
            item: "item name",
            size: {sizeIds}
          }
        */
        
        /* NEW: so we can store these selections safely in a TEXT cdt value, we 
        will convert them to JSON strings for storage in the CDT, and back
        into dictionary data for use in the form. */    
        local!menuSelectionSizes: if(
          apn_isEmpty(ri!menuSelectionCdt.Size),
          {},
          apply( /* since there will be a separate JSON string for each menu selection */
            a!fromJson,
            ri!menuSelectionCdt.Size
          )
        ),
        
        a!formLayout( 
        /* now assuming 17.2 or newer */
          
          contents: {
            a!radioButtonField(
              label: "Chain:",
              labelPosition: "ADJACENT",
              choiceLabels: local!restaurantChoices.name,
              choiceValues: local!restaurantChoices.id,
              value: ri!menuSelectionCdt.RestaurantSelected,
              saveInto: {
                ri!menuSelectionCdt.RestaurantSelected,
                
                /* the below will clear the previous menu selection when the restaurant is changed */
                a!save(
                  ri!menuSelectionCdt.MenuSelections,
                  {}
                )
              }
            ),
            
            if(
              not(isnull(ri!menuSelectionCdt.RestaurantSelected)),
              a!checkBoxField(
                label: "Make your food choices:",
                labelPosition: "ADJACENT",
                choiceLabels: local!menuChoices,
                choiceValues: local!menuChoices,
                value: ri!menuSelectionCdt.MenuSelections,
                saveInto: {
                  a!save(
                    ri!menuSelectionCdt.MenuSelections,
                    /* 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(
                ri!menuSelectionCdt.MenuSelections,
                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(
                            ri!menuSelectionCdt.Size,
                            append(
                              if(
                                isnull(local!currentIndex),
                                ri!menuSelectionCdt.Size,
                                remove(ri!menuSelectionCdt.Size, 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 */
                                a!toJson({}),
                                a!toJson(
                                  {
                                    item: fv!item,
                                    sizes: save!value
                                  }
                                )
                              )
                            ) 
                          )
                        }
                      )
                    }
                  )
                )
              )
            ),
            
            a!paragraphField(
              label: "(debug info)",
              value: "Menu Selection Size choices converted back from JSON: " & char(10) & local!menuSelectionSizes
            ),
            
            {}
          } 
        )
      )
    )

  • Hi  Sorry to disturb you again for the same problem. As you know i had to change my CDT to maintain DB naming convention of tables and columns. Can you please help me now with the original requirment ?

    Attached are 3 CDTs that i have created. 1 parent and 2 child which have 1 to many relationship.

    To give you idea CCCNumber in my Parent CDT is a PK and auto-incremented filed. Similarly NodesAffectedID and ToolsAffectedID in other 2 CDTs.

    NodesAffectedCCCNumber and ToolsAffectedCCCNumber are Foreign key which map to CCCNumber. So as soon as user enters the record i want NodesAffectedCCCNumber and ToolsAffectedCCCNumber  to be same as CCCNumber because then only i will get a joining condition to query from my DB and get 1 to many relationship result. I know you suggested JSON approch to make checkboxes filed work when i was using Text array but know i am using Nested CDT. Can you please still be able to help me for the last time ?

    Let me know if you need any other information on this.

  • 0
    Certified Lead Developer
    in reply to prais1852

    Having reached nearly 50 replies on this thread alone (and a not inconsiderable quantity of code), there's more than enough information to complete this requirement in this post, the other post regarding data structures, and the documentation.

    FYI, the answer to the latest point is pretty much "use dot notation", which, again, is explained in Appian's extensive documentation.

  • 0
    Certified Lead Developer
    in reply to prais1852
    As said, there should be enough info here already for you to go on. I guess my one last suggestion now that you've moved back to a nested CDT approach is, you don't need the JSON stuff anymore, and an approach somewhat closer to my original code should work (just need to take care of the extra new fields you've added).
Reply Children
No Data