Example: Creating a List of People
This lesson provides a low detail, step-by-step example of creating a custom data grid form. You can download the sample stack to see the scripts using the link below.
What You Will Create
This is the data grid that you will create. Each row displays a name, a title and an image.
Add Data Grid to Card
To begin, drag a data grid from the Tools palette onto your card.
Change Data Grid Style
Bring up the Property Inspector by double clicking on the datagrid. Select the data grid tab and change the style of the data grid to Form.
The Data That Is Going to Be Displayed In Each Row
Now you are going to design the row template for the data grid form. The row template dictates how each record in the data grid will be displayed.
Before you start editing the row template you need to know about the data that will be displayed each row. This screenshot shows an excerpt from the code that populates the data grid using a multi-dimensional array (look in the card script of the example stack). Each row will have access to the data stored in the FirstName, LastName, Title and ImageURL keys of the array.
You are now going to add UI controls to the row template in order to display the data for each of these keys.
Edit the Row Template
With the data grid tab selected, click on the Row Template button in the property inspector to open the card containing row template controls.
Edit the Row Template Group
In order to customize the look we need to edit the contents of the template group.
1) Make sure the Edit tool is selected.
2) Make sure that Select Grouped IS NOT active.
3) Select the row template group.
4) Click Edit Group (4) in the LiveCode toolbar.
Rename Label Field
The default template group has a field named "Label". Click on the left side of the gray rectangle to select it.
Open the Property Inspector and on the Basic tab change the name of the field to Name. On the Contents tab assign Name as the content (3).
Make Name Field Bold
With the Name field still selected change the Style to Bold from the Text Formatting tab of the Property Inspector.
Add Title Field
Drag a label field from the Tools palette (1). Name it Title on the Basic tab (2) and assign Title to the content (3).
Change Text Alignment
Change the text alignment of the field to the left side using the Text Formatting pane of the property inspector.
Add An Image and Resize The Background Graphic
Now drag an image object into the group using the Tools palette (1). With the image selected open the Property Inspector for the image
- set the name of the image to "image" in the Basic Properties pane
- set the width to 48 pixels in the Position tab
- set the height to 48 pixels in the Position tab
Resize the "Background" graphic so that it frames the other controls (2). In the example stack the width of the graphic is 214 and the height is 56.
NB: The Background graphic is a very slightly darker grey on grey in this template. Click on the background of the template near the top with the Basic tab open until you see you have selected "Background".
Stop Editing the Row Template Group
You are now done adding the UI objects to the row template group. From the Object menu, select Stop Editing Group.
Edit the Row Behavior
Now that you have designed the controls for each row you need to write the script that will move data into the controls and position them on the screen.
Click on the Edit Script button in the Property Inspector to begin editing the row behavior script.
The FillInData Message
In the script that opens when you click the Row Behavior button you will find a command named FillInData. This is where you move data from the pDataArray parameter into the controls you created.
pDataArray is an array with the keys FirstName, LastName, Name and Title. The code that moves the values from the array into the UI controls is pretty straightforward.
1) Assign the values of the FirstName and LastName keys to the Name field.
2) Assign the value of the Title key to the Title field.
3) Assign the value of the Image URL key to the filename property of the image control.
You don't need to worry about positioning any of your controls in the FillInData command. You just need to write the code that assigns the data to the UI controls.
==========
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.
-- Example:
set the text of field "Name" of me to pDataArray["LastName"] & \
comma & space & pDataArray["FirstName"]
set the text of field "Title" of me to pDataArray["Title"]
set the filename of image "image" of me to pDataArray["Image URL"]
end FillInData
The LayoutControl Message
The LayoutControl message is where you position all of your controls. For this template you begin by positioning the image (1). Next you extend the "Name" and "Title" fields to the edge of the image (2). Finally you resize the "Background" graphic to fill the entire row rectangle.
==========
Copy & Paste
==========
on LayoutControl pControlRect
local theLeft,theRect
-- 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.
-- The first thing you should do is capture 'the rect of me'.
-- For fixed height data grid forms you can use items 1 through 4 of the rect as
-- boundaries for laying out your controls.
-- For variable height data grid forms you can use items 1 through 3 of the rect as
-- boundaries.
-- Example:
set the right of image "image" of me to item 3 of pControlRect - 5
put the left of image "image" of me into theLeft
put the rect of field "name" of me into theRect
put theLeft - 10 into item 3 of theRect
set the rect of field "Name" of me to theRect
put the rect of field "title" of me into theRect
put theLeft - 10 into item 3 of theRect
set the rect of field "Title" of me to theRect
set the rect of graphic "Background" of me to pControlRect
end LayoutControl
Set the Data of the Control
This is an example of a handler that populates the data grid with data by setting the dgData property. The dgData property accepts a multi-dimensional array. The first dimensions is an integer representing the row. The second dimension are the key/values you want to pass to each row.
You can find this handler in the card script of the example stack. Copy and paste it into your card script (you can open this from the Object menu).
==========
Copy & Paste
==========
command uiPopulatePeople
put "images/" into theImageFolder
put "Lucky" into theDataA[1]["FirstName"]
put "Day" into theDataA[1]["LastName"]
put "Three Amigo" into theDataA[1]["Title"]
put theImageFolder & "monkey.jpg" into theDataA[1]["Image URL"]
put "Dusty" into theDataA[2]["FirstName"]
put "Bottoms" into theDataA[2]["LastName"]
put "Three Amigo" into theDataA[2]["Title"]
put theImageFolder & "monkey.jpg" into theDataA[2]["Image URL"]
put "Ned" into theDataA[3]["FirstName"]
put "Nederlander" into theDataA[3]["LastName"]
put "Three Amigo" into theDataA[3]["Title"]
put theImageFolder & "monkey.jpg" into theDataA[3]["Image URL"]
put "Jane" into theDataA[4]["FirstName"]
put "Blue" into theDataA[4]["LastName"]
put "Secret Agent" into theDataA[4]["Title"]
put theImageFolder & "monkey.jpg" into theDataA[4]["Image URL"]
put "Jefferson" into theDataA[5]["FirstName"]
put "Blue" into theDataA[5]["LastName"]
put "Secret Agent" into theDataA[5]["Title"]
put theImageFolder & "monkey.jpg" into theDataA[5]["Image URL"]
lock screen
set the dgData of group "DataGrid 1" to theDataA
## Hilite first row
set the dgHilitedLines of group "DataGrid 1" to 1
unlock screen
end uiPopulatePeople
The Result
Open the message box and enter uiPopulatePeople, then press enter.
After calling the uiPopulatePeople command the Data Grid should look something like the screenshot above.
You may also get an error: an error has occurred in behavior for the row template
chunk: no such object
This is because we are calling a field in resetData that no longer exists. Open the row behavior script again, locate resetData and delete the line:
set the text of field "Label" of me to empty
Once you have set the dgData property you can refresh the data grid to see any changes you might make to the row template. You can send the ResetList message to the data grid, or press the Refresh Data Grid button on the Data Grid tab of the property inspector to redraw the data using the updated template.
Troubleshooting: Row Height
You'll see that the row height in my screenshot is cutting off the images. Open the Property Inspector with the Datagrid selected, and change the row height to 52.
By default a data grid uses a fixed height for each row. If you have not set the row height the first time you populate the data grid with data then the value is automatically filled in based on the height of your row template. If you then change the height of the row template later on you will need to update the row height in the property inspector.
Luis Gonzalez
Hello we are working with the "style form" and trying to integrate the "data grid" with the database.
We created some fields to fill it and we want to add the data displayed in the list of the datagrid.
We modified the templates ( similar as an example of a list of contacts ) now we are trying to enter the data in the fields of the database and display them.
It'll be very helpful were students from Colombia and were learning the world of livecode.
Trevor DeVore
@Luis - take a look at the chapter on editing content in a data grid: http://lessons.runrev.com/s/lessons/m/datagrid/c/2433
kee nethery
The link to download the example stack "or download it here" is a dead link. It is not obvious to me how to call uiPopulatePeople. I'm not sure where the target is, how to define where that script lives.
Heather Laine
The link has been corrected, you should now be able to download the sample stack.
Michel F. Lukawecki
Hi.
I'm confused about the role of the handler "FillInData".
If we were reading the (real) data from disk, each record would contain (in addition to the record number) four fields, in this sequence: "FirstName", "LastName", "Title" and "Image". In the above example, there would be five records, one for each person. And the handler "uiPopulatePeople" would put this data in a container named "dgData" which is a property of the datagrid.
Problem: the row template does NOT contain four fields; it contains only three: "name", "title" and "Image".
But there is a handler, named "FillInData" which, among other things, does the concatenation of FirstName and LastName, into a field named "Name" which is what we renamed the original field named "Label" to, on the row template.
Where is FillInData called???
Michel F. Lukawecki
Re: my post of today at 3:30 PM
Alternatively, is there a "where used" facility in the IDE?
Thanks.
Elanor Buchanan
Hi Michel,
FillInData is called when the dgData or dgText property of the Data Grid is set. You can read a little more about it in this article
http://lessons.livecode.com/m/datagrid/l/7345-template-custom-properties-messages
I hope that helps.
Kind regards,
Elanor
Hugh Senior
In this tutorial, the LayoutControl Message script appears as follows:
on LayoutControl pControlRect
local theFieldRect,theRect
The local declaration looks like a typo that should be:
on LayoutControl pControlRect
local theLeft,theRect
Best regards,
Hugh
Elanor Buchanan
Hi Hugh, thanks for bringing that to our attention. I have updated the lesson with the correction.
Kind regards
Elanor
Rachel
Hi Again,
I know that you have posted that the download link for this exercise was corrected, but when I select the link, I get a xml page that is prohibited. Any help with a corrected link would be greatly appreciated. :-)
Thank you...
Heather Laine
Hello Rachel, thank you for pointing that out. The link is now fixed.
Rachel
At the risk of filling up the comments with "thank you's", I'm going to do it this time. I appreciate the way you support people. I'm certainly a long way from a good coder, but I'm trying. LiveCode has such a good group of people that you all inspire me to keep going.
Heather Laine
:) you're welcome. I'm glad you are enjoying your LiveCode experience!