filesoft.Discuss a project
← FileMaker guides

Worked tutorial · Workflows

Open a FileMaker detail view and return to the same filtered list

Preserve the originating context, open the intended record by ID, and make refresh behavior explicit.

By Plato · Filesoft · Published 21 October 2026

Keep the list in its own window

Someone filters a task list, opens the second task, and expects to return to the same work. If your detail script performs a new find in that list’s window, the original found set can be lost.

Keep the originating list context intact. Open the detail in a separate card, locate the target by a stable primary key, and close the card to return. This preserves the place where the person started without trying to reconstruct it from a row number.

A record number is a position within a found set. It can change after sorting or filtering. Store the TaskUUID for identity and treat selection, sort and scrolling as separate interface state.

Make the expected result concrete

TaskStatusPriorityIn the Open list?
T101 — Confirm briefOpen1Yes, first
T102 — Review supplierOpen2Yes, second
T103 — Approve layoutOpen3Yes, third
T104 — Archive quoteDone4No
T105 — Send receiptDone5No

These short IDs are fictional stand-ins for stored UUIDs. Find Open tasks and sort by Priority ascending. Open T102. Closing an unchanged detail should return to the three-task list with T102 current. That is the first behavior to establish before adding editing or automatic refresh.

Record only the state you actually need

Give each managed origin window a unique name in this file. Store that name and the selected TaskUUID in the editor controller. Keep filter controls scoped to the origin; a global filter shared across windows can still change the list while a separate detail window is open.

For this example, the parent list is read-only and must have no unresolved edits. Its layout triggers must not re-find or re-sort on every window activation. Otherwise returning from the card may replace the context you intended to preserve.

FileMaker script · open an isolated read-only detail

Set Variable [ $taskID ; Value: Tasks::TaskUUID ]
Set Variable [ $origin ; Value: Get ( WindowName ) ]
Set Variable [ $file ; Value: Get ( FileName ) ]
If [ Get ( WindowMode ) ≠ 0 or IsEmpty ( $taskID )
    or Get ( RecordOpenCount ) > 0 ]
    Exit Script [ Text Result: "no_target_or_unfinished_edit" ]
End If
Set Variable [ $card ; Value: "Task detail " & Get ( UUID ) ]
Set Error Capture [ On ]
New Window [ Style: Card ; Name: $card ;
    Using layout: "Task detail" (Tasks) ]
Set Variable [ $windowError ; Value: Get ( LastError ) ]
If [ $windowError ≠ 0 ]
    Exit Script [ Text Result: "detail_window_failed" ]
End If
Set Variable [ $detailError ; Value: "" ]
If [ Get ( FileName ) ≠ $file or Get ( WindowName ) ≠ $card
    or Get ( LayoutName ) ≠ "Task detail"
    or Get ( LayoutTableName ) ≠ "Tasks" ]
    Set Variable [ $detailError ; Value: "unexpected_detail_context" ]
Else
    Enter Find Mode [ Pause: Off ]
    Set Variable [ $modeError ; Value: Get ( LastError ) ]
    If [ $modeError ≠ 0 or Get ( WindowMode ) ≠ 1
        or Get ( FileName ) ≠ $file or Get ( WindowName ) ≠ $card
        or Get ( LayoutName ) ≠ "Task detail"
        or Get ( LayoutTableName ) ≠ "Tasks" ]
        Set Variable [ $detailError ; Value: "find_mode_failed" ]
    Else
        Set Field [ Tasks::TaskUUID ; "==" & $taskID ]
        Set Variable [ $criteriaError ; Value: Get ( LastError ) ]
        If [ $criteriaError ≠ 0 or Get ( WindowMode ) ≠ 1
            or Get ( FileName ) ≠ $file or Get ( WindowName ) ≠ $card
            or Get ( LayoutName ) ≠ "Task detail"
            or Get ( LayoutTableName ) ≠ "Tasks" ]
            Set Variable [ $detailError ; Value: "find_criteria_failed" ]
        Else
            Perform Find [ ]
            Set Variable [ $findError ; Value: Get ( LastError ) ]
            If [ $findError ≠ 0 or Get ( WindowMode ) ≠ 0
                or Get ( FileName ) ≠ $file or Get ( WindowName ) ≠ $card
                or Get ( LayoutName ) ≠ "Task detail"
                or Get ( LayoutTableName ) ≠ "Tasks"
                or Get ( FoundCount ) ≠ 1
                or not Exact ( Tasks::TaskUUID ; $taskID ) ]
                Set Variable [ $detailError ; Value: "task_unavailable" ]
            End If
        End If
    End If
End If
If [ not IsEmpty ( $detailError ) ]
    # Never close the origin or an unrelated window.
    If [ Get ( FileName ) = $file and Get ( WindowName ) = $card ]
        Close Window [ Current Window ]
    End If
    Exit Script [ Text Result: $detailError ]
End If
# The detail is read-only here.
# Its Return button closes only the current managed card.

Recreate the options in Script Workspace. Here the layout is named Task detail and its table occurrence is named Tasks; adapt both checks together with the field references. Use a genuinely unique stored key, configure the card layout so no business fields are editable, and keep layout triggers free of business-data writes or window switching. Do not run Show All Records or a detail find in the origin window.

Check Find mode before setting the criterion: an OnModeExit trigger can cancel the mode change. Without that gate, Set Field could write the criterion into a real record in Browse mode. Capture each step’s error immediately, and stop if its mode or context is wrong. The final identity check also rejects a result that is not the requested task.

The caller must display a returned error and verify that the managed card closed. If a trigger prevents closing, leave the origin unchanged and offer controlled recovery; never close whichever other window happens to be active. Native review must verify these trigger and cleanup paths in your file.

Add editing without disturbing the origin

If the detail needs editing, use the buffered Save/Cancel pattern from the previous tutorial. A failed Save keeps the proposal in the card. Cancel discards the proposal and returns without changing the business record.

Persist origin identity in editor state if separate button scripts need it; local variables in the opening script are not a durable shared controller. Clear that state when the card closes and initialize it again on every opening. Avoid a single unscoped $$origin variable if multiple origins are supported.

Choose a policy for a task that no longer matches

Suppose the user saves T102 as Done. Its fields have changed, but an existing FileMaker found set is not a promise that a status search has been rerun. Decide whether Return preserves the current review set or explicitly reapplies the filter.

Return policyWhat the user seesImplementation rule
Preserve review setT102 may remain in the current set; show that the list needs refreshDo not run a new find on return
Refresh to current filterT102 disappears from the Open list; explain whyRe-run the saved criteria and sort, then select by ID if still present

Use Preserve review set for this tutorial’s initial implementation, with an explicit Refresh list button. If FileMaker’s maintained-sort behavior changes ordering after a field edit, account for that in your native review. A preserved found set is not an immutable visual snapshot.

For the refresh option, rebuild only the documented filter criteria. Remember the prior selected UUID, perform the find and sort, and locate that UUID within the resulting set without replacing the set with a single-record find. If it is absent, choose a documented fallback such as the first row and show “The updated task no longer matches Open.” Handle an empty result with a clear message.

Test Return, not just Open

Run the five-task fixture through unchanged Return, Cancel, failed Save, valid Save and a status change. Confirm the parent filter controls, found count, sort and selected UUID after each action. Repeat the open-and-return cycle twice; old editor state must not leak into the next task.

Also try a deleted or inaccessible target and a stale link. The detail should report that the record is unavailable and leave the origin usable. Do not fall back to a different record just because it occupies the same row number.

In the disposable fixture, deliberately cancel leaving Browse mode with OnModeExit, then separately make setting the find criterion fail. Both paths must stop before Perform Find. Compare the original TaskUUID bytes, parent found set and selected UUID before and after; none may change. Also test a blocked card close and confirm that recovery never closes the parent window.

Test scrolling separately at the supported window size and client version. If exact pixel restoration matters, measure it in the native app before promising it. The reliable design goal here is stable identity and a predictable list-return policy.

References

Primary references checked during preparation. Provider-specific contracts and native behavior still require review for your implementation.