Build-On Tutorial:

Tasks

Tasks: Lesson 1

Create, Edit, and Delete Task Records

Lesson Overview

The objective for this lesson is to create functionality for tracking tasks related to an event. While working on this lesson, you will develop all of the tables, fields, relationships, and interface elements necessary to do this. Your finished app will also be updated to validate the creation of tasks to make sure they are entered properly.

Here is a sneak peek of what you will build:

Step 1 - Create the table

Create a new table for tracking tasks.

  1. Open the Manage Database dialog (File > Manage > Database…) and activate the Tables tab.
  2. Duplicate the Template table by selecting it, click Copy, then Paste, at the bottom of the dialog.
  3. Rename the new table to “Task”.
  4. Double-click the Task table to see the list of fields it contains.
  5. Add the following fields to the Task table, by typing the name into the Field Name area, choosing a Type (noted below in parentheses), then clicking Create:
    1. ID_Event (number)
    2. Assigned_To (text)
    3. Category (text)
    4. Date_Start (date)
    5. Date_Due (date)
    6. Task_Name (text)
    7. Task_Notes (text)
    8. Task_Status (text)
  1. For the Task_Status field, you will add an auto-enter calculation:
    1. Select the field and click Options… to open the Options dialog.
    2. In the Auto-enter tab, select Calculated Value and set the calculation to “Pending” in
      the Specify Calculation window.
  1. Back on the Auto-enter tab, make sure Do not replace existing value of field (if any) is turned on. This completes the field setup, so close out of the Manage Database dialog and save your changes.
  1. Open the Manage Layouts dialog (File > Manage > Layouts…) and double click the Task layout. Rename the layout to Task Utility, click OK, then drag it into the Developer folder.  Uncheck the checkmark on the left of the dialog to remove it from showing up in the Layouts dropdown. You will keep this utility layout in case you need to do data analysis in the future with a simple, stripped-down layout.

Step 2 - Add a value list

Create a value list that allows a user to select the status of a task.

  1. Open the Manage Value Lists… dialog (File > Manage > Value Lists…)
  2. Click New… to add a new value list.
  3. Set the name of the value list to "Tasks | Status”.
  4. Select Use custom values and add the following list:   Pending
       In Progress
       On Hold
       Complete
       Canceled
  5. Click OK in the Edit Value List and Manage Value Lists dialogs to save your changes.

Step 3 - Create relationships

The ID_Event field in the Task table is the foreign key that you will use to relate tasks to an event. There is a one-to-many relationship from Event to Task. You will now set up the relationships graph to reflect this.

  1. Open the Manage Database dialog and select the Relationships tab. Notice that when you created the Task table, a new table occurrence was automatically added to the graph.  (It should be on the left side, and you may need to scroll down to see it.)
  2. Double-click the new Task table occurrence and rename it to TASK in the Specify Table dialog. This is done for consistency with the graph organization techniques used in your app.
  1. Use the color tool at the bottom of the graph to change the color of the TASK table occurrence to the same blue used elsewhere and move it to the bottom of the graph.
  1. Click the Add a table button to add a new table occurrence to the graph.
  1. Select the Task table and name the new table occurrence to event_TASK. Move the table occurrence to the right of the EVENT table occurrence.
  2. Select and drag the ID field from the EVENT table occurrence and drag it over to the ID_Event field in the event_TASK table occurrence.
  1. Double-click the line (or the equal sign on the line) that connects the two table occurrences to open the Edit Relationship dialog. Click the option on the right side that reads Delete related records in this table when a record is deleted in the other table.

    Note: This option is called a cascading delete. It means that if an Event record is deleted, any related Task records will also be deleted.
  1. Back on the relationships graph, add a new table occurrence to the graph.
    1. Select the Event table and name the new table occurrence task_EVENT. Move the table occurrence to the right of the TASK table occurrence.
    2. Select the ID_Event field from the TASK table occurrence and drag it over to the ID field in the task_EVENT table occurrence.
    3. Close the dialog to save your changes.

Step 4 - View event tasks

  1. Enter Layout mode using the Edit Layout button in the status toolbar.
  2. Use the Layout pulldown menu in the status toolbar to navigate to the Desktop > Event > Event Detail layout.
  3. Select the Tab Control object from the Objects tab in the Objects pane, and note the x's on the object that denote it is locked. Currently there are four panels in the tab control: Overview, Attendees, Sessions, and Notes. If the Objects tab is not open, click the objects pane icon in the status toolbar, and then click Objects.
  1. Use the Arrange > Unlock menu to unlock the tab control.
  2. Double-click on the tab control to open the Tab Control Setup dialog and create a new tab panel named Tasks. (Type “Tasks” in the Tab Name area, then click Create and OK to close the dialog.)
  1. Click the Tasks tab to make sure it is the active tab. You will see an object off the right edge of the layout. Copy and paste the blue horizontal line and drag it under the Tasks tab name.
  1. Copy the portal containing the list of sessions from the Sessions tab, and paste it onto the Tasks tab.
  2. Select the new portal and in the Position tab of the Inspector, set the position so the portal’s Left position is 272 pt and Top position is 272 pt.
  1. Delete the session fields that were copied over with the portal. Do not delete the transparent button that covers the portal row - you will use that later.
  2. Double-click the portal to enter the Portal Setup dialog and set the Show records from: to event_TASK.
  1. Back on the layout, navigate to the Fields tab in the Objects pane. At the bottom of the tab, set Field Placement to horizontal and Labels to none, then drag and drop the following fields onto the portal:
    1. Task_Name
    2. Assigned_To
    3. Task_Status
    4. Date_Due 
  2. Select the fields added above and in the Styles tab of the inspector, set the style for the fields to txt Minimal.Black.Left. You do not want users to edit these fields from the portal so in the Data tab of the Inspector (with the fields still selected), under Field Entry uncheck Browse Mode
  3. Add placeholder text to each of the fields in the portal. Select the field and in the Data tab of the Inspector add the following Placeholder text to the corresponding field:
    1. “Task Name”
    2.  “Assigned to"
    3. “Task Status"
    4.  “Due Date”
  4. Arrange and resize the fields as shown below, then select the Text tool from the status toolbar and add a new label next to the Date_Due field with the text “Due”. Style it Label inPortal.Right.
  1. Select the Due label and using the Data tab of the Inspector, set Hide object when to IsEmpty ( event_TASK::Date_Due ) or _in_mode_Find. This condition will hide the label if the event_TASK::Due_Date is empty, or if you’re in Find mode.

    Note: _in_mode_Find is a custom function that is defined as Get(WindowMode) = 1.
  1. In the Position tab of the Inspector, set the Task_Name field to anchor top, right, and left. Set the Assigned_To, Task_Status, Due_Date fields and the Due label to anchor top and right.
  2. Save your changes and enter Browse mode to review your work.

Step 5 - Create the task card layout

The portal you created is ideal for viewing an event task. For creating and editing tasks,
however, you will make a new card window.

  1. Open the Manage Layouts dialog (File > Manage > Layouts...).
  2. Locate the Blank > Blank | Desktop - Card layout and Duplicate it.
  3. With the new layout selected, click the Edit button to open the Layout Setup dialog, and make the following changes:
    1. Set the Layout Name to "Task | Card"
    2. Set the Show records from: to TASK
    3. Set the Menu Set: to Minimal
  1. Select the dropdown menu next to the New button and create a new Folder named Task, then move the new layout into it.
  1. Click the Open button to open the Task | Card layout, and enter Layout mode.
  2. Edit the merge field at the top of the layout to say "<<$$CARD_ACTION>> Task".

    The $$CARD_ACTION global variable will contain either "New" or "Edit" and will be set by scripts you create later in this lesson. This way, you can use the same layout both for creating new records and for editing an existing one.
  3. Double-click the sample field to bring up the Specify Field dialog. In the dropdown, change the table occurrence to Current Table (“TASK”) and select the Task_Name field. Change the text label to “Task Name”.
  4. Duplicate the label and the field. Change the field to Task_Status and the label to Status. Repeat this to create the following fields and labels:
    1. Assigned_To with a label of "Assigned To”
    2. Date_Start with a label of “Start Date”
    3. Date_Due with a label of “Due Date”
    4. Category with a label of “Category”
    5. Task_Notes with a label of “Notes”
  5. Use the Data tab of the Inspector to set the Control style for the Date_Start and Date_Due fields to Drop-down Calendar and select Include icon to show and hide calendar.
  6. Set the Control style for the Task_Status field to Pop-up Menu, selecting the Task | Status value list that you created earlier. Select Include arrow to show and hide list and Override data formatting with value list checkboxes.
  7. Add placeholder text to the Status field: "Select…"
  8. Resize and arrange the fields and labels so they look similar to the screenshot below:
  1. Enter Browse mode to save and review your work.

Step 6 - Add a script for opening the card window

There are two use cases for the new task card layout: creating a new task and editing an existing task. Because these processes will be defined in separate scripts you will write later in this lesson, it will be helpful to create a subscript to handle opening the card window and specifying the layout so that this logic is only defined once.

First, the script will check to make sure the current window is not a card window, since you cannot open a card window on top of an existing one. Then the script will open the Task | Card layout as a card window.

Note: If you have not worked with scripts before, you will find it helpful to review the Creating and Editing Scripts section of the FileMaker Pro Advanced Help system before starting this task.

  1. Open the Script Workspace (Scripts > Script Workspace...)
  2. Create a new subfolder within the DESKTOP UI folder named “TASK”
  3. Duplicate the Template Script, from the EXAMPLE SCRIPTS folder. Rename the new script (right-click > Rename) to "Open Task Card" and move it into the folder you just created.

    Note: Any time you create a new script or copy an existing one, amend the comments at the top to fit your current script.  
  4. Add the following script steps after the existing Freeze Window script step.

    NOTE: See step 5 for further instructions on the New Window steps.

Allow User Abort [ Off ]
Set Error Capture [ Off ]
Enter Browse Mode [ Pause: Off ]
Freeze Window

# close existing card window (if applicable)
If [Get ( WindowStyle ) = 3 ]
   Perform Script [Specified from list; "Close Window" ; Parameter: ]
End If

# open card window
New Window [ Style: Card; Name: "Task" ; Using layout "Task | Card" (TASK] ]

  1. For the New Window script step, set the Window Name to “Task” and turn off Close under Window Options.
  1. Save and close the script.

Step 7 - Script for adding a task

Next, you will create a script for adding a new task record. Later in this lesson, you will attach this script to a button on the Task tab of the Event Detail layout.

The script begins by using the #Assign custom function to parse any script parameters and test to make sure they are are valid. It then proceeds to open the card window, set the $$CARD_ACTION variable, create a new record, and put the cursor into the Task_Name field so the user can immediately begin typing.

Note: The #( ) and #Assign ( ) custom functions are used to pass and parse parameters. The #( ) custom function is generally used to define a script parameter and accepts a key-value pair; the #Assign ( ) custom function is called in the script and turns the key-value pair into a script variable.

  1. Create a new script by duplicating the Template Script.
    1. Name the script “Add New Task ( id_event )”
    2. Move it into the TASK folder.
  2. Modify the script by adding the highlighted steps below.

    NOTE: See Step 3 for details on the Show Custom Dialog script step.

Allow User Abort [ Off ]
Set Error Capture [ Off ]
Enter Browse Mode [Pause: Off ]
Freeze Window

# load parameter(s)
Set Variable [ $parameter_parsing_ok: Value: #Assign ( Get ( ScriptParameter ))]
If [ $parameter_parsing_ok = False ]
   # parameters could not be parsed, exit this script and report back
   Exit Script [ Text Result: "error" ]
Else If [ IsEmpty ( $id_event ) ]
   # invalid parameter(s) passed
   Show Custom Dialog [ "Error" ; "Invalid parameter(s) passed to script: " & Get (ScriptName) ]
   Exit Script [ Text Result: "error" ]
End If

# set card action
Set Variable [ $$CARD_ACTION ; Value: "New" ]

# open card window
Perform Script [ Specified From list ; "Open Task Card"; Parameter: ]

# create record
New Record/Request
Set Field [ TASK::ID_Event ; $id_event ]
Commit Records/Requests [ With dialog: Off ]

# leave the cursor in the task name field
Go to Field [ TASK::Task_Name ]

Exit Script [ Text Result ; $null ]

  1. The Show Custom Dialog script step should match the screenshot below. Be sure to remove the Button 2 text.
  1. Save and close the script.

Step 8 - Script for validating task dates

When a new task is added, you should validate that the due date is after the start date. You will use script triggers to accomplish this.

  1. Open the Script Workspace and duplicate the TRIGGER Require Event End Date after Start Date script.
  2. Rename the script to TRIGGER Require Task Due Date after Start Date
  3. Move the script to the TASK scripts folder.
  4. Add or amend the highlighted script steps so the script reads as follows:

Allow User Abort [ Off ]
Set Error Capture [ Off ]
Freeze Window

#required context
If [ Get ( LayoutTableName ) ≠ "TASK" ]
        Show Custom Dialog [ "Alert"; "This script can only be run from a Task
screen."]

        Exit Script [ Result: "error" ]
End If

#validate task dates
If [ not IsEmpty ( TASK::Date_Start ) and not IsEmpty ( TASK::Date_Due ) and
TASK::Date_Due < TASK::Date_Start ]

        Select All
        Show Custom Dialog [ "Alert"; "The due date can't be before the start date."]

        #exit false to prevent update and keep cursor in field
        Exit Script [ Result: False ]

Else
        Exit Script [ Result: True ]

End If

  1. Exit Script Workspace and save the script when prompted. Go to the Task | Card layout and enter Layout mode.
  2. Select the Date_Start and Date_Due fields and go to the Format > Set Script Triggers… dialog.
  3. In the Set Script Triggers dialog, select the OnObjectExit event and choose the TRIGGER Require Task Due Date after Start Date script from the list. The script will run when the user exits either the Date_Start or Date_Due fields and check to make sure the due date is after the start date.
  1. Exit the Set Script Triggers dialog and save your changes.

Step 9 - Script for finding a task

Finally, you will write a script that will be used to view existing task records.

  1. Open the Script Workspace and duplicate the Template Script.
    1. Name the new script "Find Task by ID (Id_task)"
    2. Move it into the TASK script folder
  2. Modify the script by adding the highlighted steps below.

    NOTE: See Step 3 for details on the Show Custom Dialog script step.

Allow User Abort [ Off ]
Set Error Capture [ Off ]
Enter Browse Mode [ Pause: Off ]
Freeze Window

# load parameter(s)
Set Variable [ $parameter_parsing_ok; Value: #Assign ( Get ( ScriptParameter ) ) ]
If [ $parameter_parsing_ok = False ]
        # parameters could not be parsed, exit this script and report back
        Exit Script [ Text Result: "error" ]
Else If [ IsEmpty ( $id_task ) ]
       # invalid parameter(s) passed
       Show Custom Dialog ["Error"; "Invalid parameter(s) passed to script: " & Get
( ScriptName ) ]
       Exit Script [ Text Result: "error" ]
End If

#set card action
Set Variable [ $$CARD_ACTION; Value: "Edit" ]

# open card window
Perform Script [ Specified: From list; “Open Task Card”; Parameter: ]

# find record
Enter Find Mode [ Pause: Off ]
Set Field [ TASK::ID; "==" & $id_task ]
Set Error Capture [ On ]
Perform Find [ ]
Set Variable [ $error; Value: Get ( LastError ) ]
Set Error Capture [ Off ]

If [ $error ]
        Perform Script [ Specified: From list; “Close Window”; Parameter: ]
        Show Custom Dialog ["Error"; If ( $error = 401 ; "The task could not be found."
; "FileMaker error: " & $error & "." ) & " Unable to perform this action."]
       Exit Script [ Text Result: "error" ]
End If


Exit Script [ Text Result: $null ]

  1. For the Custom Dialog, click Specify and add the following calculation:

If ( $error = 401 ; "The task could not be found." ; "FileMaker error: " & $error & "." ) & " Unable to perform this action."

  1. Save and close the script.

Step 10 - Adding buttons

With all of the scripts now in place, your final task is to make buttons to trigger the scripts. On the Tasks tab of the Event Detail layout, you will create buttons for adding and editing tasks. On the card window, you will modify the existing buttons to call the  appropriate actions for validating and saving a task record.

  1. Enter Layout mode and navigate to the Tasks tab of the Event Detail layout.
  2. Use the Button tool in the status toolbar to create a button below the tasks portal for
    adding tasks.
  1. In the Position tab of the Inspector, turn on left and bottom anchors in the Autosizing options, turning off the top anchor.
  2. In the Button Setup dialog, set the following properties for the button:
    1. Set the button name to "Add Task”.
    2. Set the Action: to Perform Script.
    3. Select the Add New Task (id_event) script.
    4. For the script parameter, specify the formula as # ( "id_event" ; EVENT::ID ).
  1. For editing a task, you will use the existing button that is on the Sessions portal row. This button will allow you to select a task from the portal and display it in the card window that you created earlier in the lesson.
    1. Double-click the button to enter the Button Setup dialog.
    2. Select the script Find Task by ID ( id_task ) and modify the script parameter as follows: # ( "id_task" ; event_TASK::ID )
  1. At the bottom of the Task | Card layout, there are two sets of stacked buttons. If you temporarily move or hide the Cancel and Create buttons, you will see Delete and Close buttons underneath them (see below). Hide conditions have been specified for these objects so the first pair displays when $$CARD_ACTION is "New" and the second pair when it is not.

    The Cancel and Delete buttons are specified to call the Delete Record ( msg ) script. These do not require any modification by you.
  1. Enter Browse mode so you can save and review your work.

Step 11 - Create a calculation field

As you start to populate tasks in the Events Detail layout, you will want to be able to see at a glance how many tasks are currently related to the event you are viewing.

  1. Open the Manage Database dialog and activate the Fields tab, selecting the Event table.
  2. Create a new calculation field called “Count_Tasks”. In the Specify Calculation dialog:
    1. Set the calculation formula to Count ( event_TASK::ID)
    2. Set the calculation result to Number.
    3. Uncheck the Do not evaluate if all referenced fields are empty option.
  1. Close the Manage Database dialog, saving your changes. Enter Layout Mode on the Event Detail layout, and go to the Tasks tab.
  2. Using the Text tool, add a merge field on the layout. Select Insert > Merge Field… from the menu. From the dropdown, select Current Table (“EVENT”) and select the Count_Tasks field. Edit the text object to read: “Tasks: <>” and style it as Label Left. Position it near the top of the Tasks tab.

    Note: Merge fields are text objects that show field data.  Users cannot click into them or modify them as they can with regular field objects.
  1. Enter Browse mode so you can save and review your work

Step 12 - Review your work

You have completed the Tasks Build-On! With all of the schema, interface, and scripting now in place, you can test the new task features.

  1. When you go to the Event Detail layout, you should see a tab that lists the tasks for the event and a button for adding a new task.
  2. When you click the Add Task button, you should see the Task | Card layout with a new, blank task. The header should display "New Task" and the buttons at the bottom should be Cancel and Create
  3. If you click the Cancel button, you should get no confirmation dialog, and there should be no new record in the portal.
  4. If you click the Create button, you should get a new record in the portal.
  5. When you return to the Event Detail record for that event, you should see the new task record in the portal.
  6. If you enter a due date that is before the start date, you should see a validation message letting you know to correct the format of the data entered.
  7. If you click on the portal row, the card window should reappear and display the data for the task you created previously. The header should display Edit Task and the buttons at the bottom should be Delete and Close. Close should close the task, and Delete should delete it.