How Do I Work with Checkboxes in a Data Grid?
This lesson will demonstrate how to associate the hilite state of a checkbox in a data grid with a row value in the data grid.
Adding a Checkbox to a Form
Be begin, drag a data grid onto a stack and set the style to Form using the Object Inspector.
Now we can add the checkbox. Click the Row Template button to open the template for the data grid.
Edit Row Template Group
Now that the card with the data grid row template is visible, open the Project Browser selecting the Tools > Project Browser menu option.
Select the card with your template (it should be the second card under the Data Grid Templates stack) (1). Next, select the Row Template group on the card (2). Doing so will select the group on the card.
Now select the Object > Edit Group menu option. This will put the group in edit mode which will allow you to drag controls from the tools palette into the group.
Add a Checkbox
From the tools palette, drag a checkbox onto the card and place it in the upper-left corner. The button will appear in the list of controls in the Project Browser.
Edit Checkbox Properties
Open the Object Inspector for the button and change the height to 21. Set the left and top properties to 0.
Delete the Label Field
Now that you have added the checkbox button you no longer need the Label field in the row template. Select the Label (1) field and delete it.
After deleting the field you should have the Background graphic and the Check checkbox in the group. Remember, you are still editing the group so the group is not listed in the card controls at the moment.
Stop Editing Group
You are now done editing the group controls so select the Object > Stop Editing Group menu option.
Edit Row Behavior
Next you need to edit the Row Behavior in order to take into account the new checkbox control.
Click the Edit Script button.
Edit the FillInData Handler
In the FillInData Handler you need to remove references to the Label field and add code for the Check button. The code will set the label of the checkbox to the "label" property of the data grid row. It will set the hilited property to the "checked" property of the row.
Copy & Paste
on FillInData pDataArray -- This message is sent when the Data Grid needs to populate -- this template with the data from a record. pDataArray is an -- an array containing the records data. -- You do not need to resize any of your template's controls in -- this message. All resizing should be handled in resizeControl. set the label of button "Check" of me to pDataArray["label"] set the hilited of button "Check" of me to pDataArray["checked"] end FillInData
Update LayoutControl and ResetData
The LayoutControl and ResetData handlers also have references to the Label field which no longer exists. Update both of those handlers with references to the Check button.
Copy & Paste
on LayoutControl pControlRect local theFieldRect -- This message is sent when you should layout your template's controls. -- This is where you resize the 'Background' graphic, resize fields and -- position objects. -- For fixed height data grid forms you can use items 1 through 4 of pControlRect as -- boundaries for laying out your controls. -- For variable height data grid forms you can use items 1 through 3 of pControlRect as -- boundaries, expanding the height of your control as needed. -- Example: put the rect of button "Check" of me into theFieldRect put item 3 of pControlRect - 5 into item 3 of theFieldRect set the rect of button "Check" of me to theFieldRect set the rect of graphic "Background" of me to pControlRect end LayoutControl on ResetData -- Sent when data is being emptied because the control is no longer being used to display data set the text of button "Check" of me to empty set the hilite of button "Check" of me to false end ResetData
Update Data Grid Row Value When User Changes Checkbox State
When the user clicks on the checkbox the hilited state will change. You need to update the row data in the data grid when this happens so that the dgData array properly represents what is being seen in the interface. You can do this in the mouseUp behavior of the behavior script.
During mouseUp the hilited state of the checkbox has been changed and so it is safe to save the value. You just need to call SetDataOfLine and pass in the hilite of the target (the target being the checkbox button).
Add the following to the behavior script. Make sure and compile the script afterwards.
Copy & Paste
on mouseUp pMouseBtnNum if pMouseBtnNum is 1 then ## did they click on the checkbox? if the short name of the target is "Check" then ## Update internal value in data grid SetDataOfLine the dgLine of me, "checked", the hilite of the target end if end if end mouseUp
Populate the Data Grid
You have now finished configuring the Data Grid so it is time to test. Add a button to the stack and name it Populate grid.
With the Edit tool active, right-click on the button and select Edit Script.
Add a simple script that will populate the data grid with two rows. Each has the "label" and "checked" properties that you referenced in the behavior script earlier.
Paste this script to the button script.
Copy & Paste
on mouseUp local tDataA put "Line 1" into tDataA["label"] put "true" into tDataA["checked"] put "Line 2" into tDataA["label"] put "false" into tDataA["checked"] set the dgData of group "DataGrid 1" to tDataA end mouseUp
After compiling the script, click on the Populate Grid button. Your card should now look similar to this.
Checking/Unchecking All Checkboxes in a Data Grid
When working with lists that have checkboxes it is nice to include the option to check or uncheck all of the items in the list. Let's look at how to do that.
Add a button to the card and name it Check/Uncheck. Edit the script of the button.
The code for checking/unchecking all items in the list isn't too complicated. Here is how the logic is broken up:
- We will use the "checked" value of row 1 to decide what to set all of the other rows to. Get the current value of row 1 and toggle it.
- Loop through all lines of the data grid, setting the value of the "checked" property of each row to the new value. Use SetDataOfLine as this command will not redraw the data grid each time it is called.
- Refresh the data grid so that the new row values are used to display each row.
Copy & Paste
on mouseUp local tCheckedValue ## Get checked value for 1st row dispatch function "GetDataOfLine" to group "DataGrid 1" with 1, "checked" put the result into tCheckedValue ## Get inverse value of 1st row put not tCheckedValue into tCheckedValue ## Update all rows ## SetDataOfLine does not redraw data grid repeat with theLineNo = 1 to the dgNumberOfLines of group "DataGrid 1" dispatch "SetDataOfLine" to group "DataGrid 1" with theLineNo, "checked", tCheckedValue end repeat ## Update datagrid display dispatch "RefreshList" to group "DataGrid 1" end mouseUp
Click the Check/Uncheck button to test. You should see the checkboxes toggle between the checked and unchecked state.
If you get the dgData or dgText property of the data grid then you will see the proper values for the "checked" state of each row.