2017년 7월 6일 목요일

Checkboxes as radio buttons



One element of form functionality is the radio button - it provides a user selectable option in answer to a question that cannot be unselected and cannot have multiple selections from the same array.  In App Inventor, we don't have the radio button (at least not yet) but we do have checkboxes, and using checkboxes we can achieve radio button functionality.  This will be a tutorial for how it's done. 

For this example, we will use 8 checkboxes in 2 arrays.  As you can see in the image to the left I have them arranged in vertical arrangements to separate the arrays from each other.  What we want to achieve is that when any of the four boxes is checked in one array, we can't unselect it and we can't select another checkbox in that array.



In order to accomplish this goal, in the blocks editor we need to make sure that the selected checkbox is disabled and that when another one is checked in the array the original one will be unselected and re-enabled.  The first step for this will be to define our arrays, so let's create two global variables and name them appropriately.  We cannot put the components themselves into the defined lists, so both variables will need to be created as empty lists and in the Screen1.Initialize event we will populate them with our checkboxes.  Our next step will be to determine a way to detect which checkbox was selected, disable it, and re-enable & unselect any others in the array.  We will accomplish this using the Advanced Blocks.

For the first step, we need to create our procedure and add two arguments to it; click the blue gear mutator button and add two inputs from the little window that will open and rename them to checkbox and array.  The first block in the procedure will be a for each in list loop that will loop through an array and detect the checked value of each checkbox in that array.  So the list we'll be checking is our array procedure argument.  


I recommend renaming the loop variable to something other than the default, something that better explains what we're checking in the loop (I went with ckb).  Inside the loop, we need an if/else statement that will check whether the current list item (ckb) is equal to the input (checkbox) and if true disable it, else enable it.  For this to work we need to use the advanced blocks for the checkboxes, which can be found in the Any Component > Any Checkbox drawer of the blocks editor.  Drag out two set Checkbox.Enabled...of component...to blocks and place one inside each portion of the if statement.  In the top, if the result of the statement is true, we need to set component ckb to false and, by process of elimination, in the bottom we set the same component to true (meaning it won't be the input of the procedure).  Once that's all setup, the easiest part of the blocks is done.

Now we have to code all of our Checkbox.Changed events.  The easiest way to do this is probably going to be to create one event, copy it, then paste it seven times and adjust the values accordingly.  What do we need to do here?  We need an if statement to check whether this checkbox is checked and uncheck all the others, then disable it.  Remember that our checkboxes are setup in arrays of four, so we only need three set checkbox.enabled to events inside.  Set all three of these to false, then drag out the procedure we created earlier from the procedure drawer and place it underneath the last event but inside the if statement.


The first argument, checkbox, is actually the component we're setting the changed event for (if you're working with Checkbox1.Changed you'll put Checkbox1 into this spot, etc).  The array input will be whichever of the two arrays this checkbox is in (which you set in the Screen.Initialize event).  That's all for the blocks.

The last step is to test it, and make sure that when you select a checkbox you can't unselect it and you can't select two from the same array.  You can download the source code below.

CheckboxRadios.aia


댓글 없음:

댓글 쓰기