A Seeker is a special ViewModel that lets your users search persistent data with one or more criteria and work from the objects returned in its result collection.
What a Seeker does
Use a Seeker when the user must find objects before opening or editing them. For example, a user can search for Person objects by a name fragment, a department, and a registration date, then select a returned person to continue their work.
A Seeker evaluates its search expressions in the database. The expressions use OCLps, the persistent-storage subset of OCL that MDriven translates to SQL. This lets the database filter the data instead of loading all candidate objects into the ViewModel.
A Seeker has three main parts:
| Part | Purpose | Example |
|---|---|---|
| Input variables | Hold values entered or selected by the user. | vName holds a name fragment; vDepartment holds a selected Department object.
|
| Search expressions | Define the database criteria that use the input variables. | Search Persons whose name matches vName, or whose Department is vDepartment.
|
| Result variable | Holds the objects returned by the search. | vSeekerResult is a collection displayed in a grid.
|
Create a basic Seeker
- Create a ViewModel for the search interface.
- Add variables for the criteria the user can supply. Use types that match the values you search for. For example, use a String variable for a name and an object-reference variable for a Department selection.
- Add columns that expose these variables in the user interface. A reference variable can be presented as a PickList.
- In MDriven Designer, right-click the ViewModel column and choose Add nested and then Add search expr.
- Define the criterion in the search expression and, when needed, define when that criterion is active.
- Display the
vSeekerResultcollection in a grid or other result presentation. - Run the ViewModel and enter a criterion to search.
When you add the first search expression, MDriven Designer adds default Seeker implementation details, including vSeekerResult and SeekString. These additions are a starting point. The required convention is that the ViewModel has a variable named vSeekerResult whose type is a collection.
Combine criteria without forcing empty fields
A multi-variable Seeker can have several criteria. MDriven intersects the active criteria on the server: a returned object must satisfy every active criterion.
Because criteria are intersected, make each optional criterion conditional when it depends on user input. Use the criterion's Active Expression to determine whether MDriven includes it. If you leave the Active Expression empty, it defaults to true, so the criterion is always active.
For example, a Person Seeker can offer these inputs:
vNamefor a name fragment.vDepartmentfor a Department reference.vAfterDatefor a registration-date limit.
If the user supplies only a department, activate only the department criterion. If the user also supplies a date, the result contains people in that department registered on or after that date. Do not leave a criterion always active if its input can be empty and should not restrict the search.
Search batches and repeated searches
A Seeker can contain multiple batches of search expressions. The first search uses the first batch. If the user runs the search again without changing any search variable, MDriven uses the next batch. Further unchanged searches continue through the batches in round-robin order.
Changing any search variable resets this sequence, so the next search starts with the first batch again. This supports an interface where a user can try a different predefined search approach after an initial search returns no useful results.
Use selfVM.Search to start the normal Seeker search behavior. To refresh the current result set without advancing to another search batch, use selfVM.ReQuery; see Documentation:OCLOperators ReQuery.
Choose the result type
By default, vSeekerResult is created as a collection of the ViewModel root type. If the search must return another type, declare it explicitly as Collection(YourDesiredType). Seeker logic then uses that type as the search result type.
For example, a ViewModel rooted in Department can still return people when vSeekerResult is declared as Collection(Person).
Date criteria
Use a DateTime variable when searching dates. Do not pass a date as text, because databases represent dates in different formats.
For example, a criterion can search for persons registered on or after the value in vAfterDate:
Person.allInstances->select(p|p.Registrered>=vAfterDate)->orderBy(p|p.Registrered)You can also set a date criterion without displaying it. For example, a search action can limit results to the last six months before running the search:
vAfterDate:= DateTime.Today.addMonths(-6);
selfVM.SearchPresent and control results
Display vSeekerResult in the result grid. If the page has more than one grid, identify the grid that displays the Seeker result with the IsSeekerResultGrid=true tagged value on its nesting. See Documentation:Nesting.IsSeekerResultGrid.
By default, pressing Enter in a Seeker starts the search. To prevent this behavior for a span, use Documentation:Span.DoNotSearchOnEnter.
Use MaxFetch to limit how many records the Seeker returns. The default when MaxFetch is not used is 20 records. For result-page navigation and the variables required to enable it, see Documentation:Search result pages.
Design guidance
- Start with criteria users understand, such as name, department, status, or date.
- Keep optional criteria inactive until their input has a meaningful value; otherwise the intersection can unintentionally return no objects.
- Put result columns in an order that helps users identify the correct object.
- Use a bounded result size with MaxFetch when a criterion can match many objects.
- Use
ReQueryfor a Refresh action after data changes; use normal Search when you want the standard search-batch behavior.
For the complete Seeker walkthrough, including ordering, result limits, and additional examples, see Training:Seeker view.
