Package com.smartgwt.client.data

# Class SavedSearches

java.lang.Object
com.smartgwt.client.core.JsObject
com.smartgwt.client.core.DataClass
com.smartgwt.client.data.SavedSearches

All Implemented Interfaces:
  `HasHandlers`

public class SavedSearches extends DataClass
Data components such as `ListGrid` or `TileGrid` may allow users to set up their own search criteria within an application, either via an external `SearchForm`, or through built in UI such as the `ListGrid.filterEditor`.

The "Saved Search" subsystem allows users to save out their criteria (and in some cases user-configured view state) so when the application is reloaded they can easily restore a search or view from a previous session.

Note: The SavedSearches feature requires Smart GWT Pro or better.

User interface components for storing and retreiving saved searches are available via the built in ListGrid features `ListGrid.canSaveSearches` and `ListGrid.savedSearchStoredState`, as well as the explicit the SavedSearchForm and `SavedSearchItem` classes.

#### The SavedSearches class

`SavedSearches` is a "singleton" class that provides central handling of storing and loading saved search data.

You acquire the `SavedSearches` singleton via `get()` and you can configure defaults via Class.addProperties() or Class.changeDefaults().

Saved searches are stored `serialized as JSON` in `DataSource` Records.
By default saved searches are stored in HTML5 browser localStorage via automatically generated custom DataSources. In this mode the searches are only retained for a specific user on a particular machine, and searches cannot be shared with other users - but this approach is sufficient for many applications, works out of the box, does not require any storage and has no impact on scalability.

For more capable saved search storage and retrieval, an explicit saved search dataSource backed by permanent storage such as an SQL database table may be specified.
Typically this is done by setting up the `defaultDataSource`. This will store searches for all users and for every component and the same dataSource may even be used for multiple applications.
For finer grained control, individual saved search dataSources may also be specified `per component`.

See `getSavedSearchDataSource()` for how to retrieve the dataSource for a component.

A SavedSearch dataSource has the following fields, some of which are optional, all of which can be renamed as needed. (Click the links to see the purpose of each field):

- `"pk"` (primary key field, typically of type "sequence")
- `"data"`
- `"searchName"`
- `"componentId"`
- `"projectId"`
- `"screenId"`
- `"applicationId"`
- `"userId"`
- `"admin"` See "Admin-Configured Shared Searches" below.
- `"isDefault"`, See "Default Searches" below.
- `"isSharedDefault"`, See "Default Searches" below.

In your SDK, look for `sc_SavedSearches.ds.xml` for a sample SQL-based implementation of saved-search (entirely declarative). Note that `DataSource.cacheAllData` is set to true - this causes all searches applicable to a given user to be loaded in advance, the first time any component requests saved searches. For most applications, this is the right approach, and is much better than performing server requests each time a new component is shown that might have saved searches.

Note that the SavedSearches system can be used to store any kind of component setting; in particular, `ListGrids` used `SavedSearches` to store complete `viewState`, which includes field order & visibility, sorting and group state in addition to search criteria.

#### Admin-Configured Shared Searches

Shared searches (also referred to as "Admin Searches") are special searches that appear for all users, as pre-configured default saved searches. While any user can create and edit their own personal saved searches, admin searches can only be created or edited by users with the `adminRole` (see below).

Admin searches are not available when no dataSource was configured to store the savedSearch data. In this case a user's searches are stored to their machine rather than in a central database, and the concept of sharing admin-created searches does not apply.

Admin searches are identified by either having the `userIdField` null, or by the separate boolean `adminField` set to true.

UI components such as `SavedSearchItem` will offer a UI for adding, editing and removing admin searches if the user has the `adminRole`, as determined by `Authentication.hasRole()`.

In addition to this, for security reasons the server should also enforce role-based authentication for creating and editing admin searches.
Note: the sample `sc_SavedSearches.ds.xml` dataSource has no "admin" field to identify shared or "admin" searches. Instead records in this dataSource with "userId" set to null are considered to be shared searches.
The `ownerIdField`, `ownerIdNullAccess` and `ownerIdNullRole` attributes enforce the appropriate restrictions for editing admin searches -- these settings allow all users to view records with `userId:null` but only users with the "admin" role may create or edit them.

#### Default Searches

Default searches are searches which will be automatically applied to a component on draw. The SavedSearch subsystem supports two notions of "default" searches. A user may select their personal default search, in which case the next time they load the page this search will be applied to the component automatically. Or an administrator may mark a shared admin search as the default for all users. In this case anyone who loads the application will see this search applied.

If a user has a stored personal default search preference, this always takes precedence over any admin-default search.

Like any admin-searches, admin-default searches only apply when a dataSource was configured to store the savedSearch data.

### Saving default searches

If `saveDefaultSearchToServer` is false (the default), the user-default search preference will be stored in browser `localStorage`.
This is done because the user may choose an Admin Search as their default search, and since Admin Search records are shared between all users, we can't mark the Admin Search record in the database as the default for a specific user (at least not without more complex storage).
The drawback is that a user switching browsers or device will not have their default search preserved.

If you want to persist default searches chosen by the user to permanent storage on the server, you can set `saveDefaultSearchToServer` to true. In this case the SavedSearch dataSource must include a boolean `defaultField`. Typically this will need to be populated via custom server logic when fetching records to indicate that the record in question is the chosen default for the current user. When `saveDefaultSearchToServer` is true, the client will issue a custom update operation when the user wants to modify their default search - see `setDefaultUserSearchOperation`.

Admin default searches are stored on the server regardless of whether `saveDefaultSearchToServer` is true. The dataSource should include a boolean `adminDefaultField` to indicate that an admin search record is the shared-default search.
If an admin user updates a record to be the new shared default search, the client will issue a different custom update operation - see `setDefaultAdminSearchOperation`.
Note that we'd recommend marking this operation as `requiresRole="admin"` on the server, as in the sample `sc_SharedSearches.ds.xml` dataSource configuration.

#### Identifying components associated with Saved Searches

Stored saved search records will have the `componentId` field set to the identifier returned by `getSavedSearchId()` for a component. By default this method returns an identifer based on the a `local ID` and `DataSource ID`. This means that if you assign a unique ID to a component that saves searches, and don't change that ID, stored saved searches will always be associated with the component and its current DataSource.

If you don't set a unique global ID on the component, and your component isn't part of a Reify screen, and so doesn't have a separate `local ID`, the default saved search identifier is not guaranteed to be consistent across changes to your app, and in that case, previously stored searches will no longer be associated with the component.

Alternatively you can bypass the `ID` dependency altogether and define an explicit `DataBoundComponent.savedSearchId`. This allows you to define a stable identifier for storing saved searches without setting a component `ID`.

Note that developers may explicitly change the `DataBoundComponent.savedSearchId` at runtime. In this case, if the saved search ID changes, the component will be associated with a new set of saved searches. When an explicit `savedSearchId` is provided, it will not automatically be changed if a new DataSource is bound to the component. To keep the saved searches applicable to the current DataSource, developers may want to explicitly update `savedSearchId` in this case.

#### Security Concerns

If you provide your own `DataSource for storing searches`, you should enforce the following restrictions on the server:

- Limiting fetch operations such that the logged-in user can only see their own searches (searches where the current userId matches the `userIdField`), and shared or "admin" searches (searches where the `adminField` is `true`, or if there is no admin field, searches where the `userIdField` value is null).
- Ensuring that logged in users without the `adminRole` can only add, edit and remove records where the `userIdField` matches their userId.
- For logged in users with the `adminRole`, also allowing users to add, update and remove admin searches. What this means in concrete terms depends on whether the dataSource includes an `adminField`.
  If an adminField exists, admin users are exempt from userId restrictions when editing or removing records where this field value is set to true. When adding a new record it is still recommended the admin user's own userId should be stored in the `userIdField`.
  If no adminField exists, admin searches are identified by having the `userIdField` set to `null`. In this case admin users should be able to add, remove and edit records where the `userIdField` matches their own userId, or is null.

If you are not providing your own `DataSource for storing searches`, searches will be stored to each user's browser LocalStorage. Developers should be aware that objects stored in LocalStorage are accessible by all applications deployed to the same host + port. This means that if you're loading multiple Smart GWT applications from the save server they could potentially access each others' SavedSearches from localStorage, if the same userName and componentId exist in both applications.
This should not typically be an issue, as we default the `applicationId` value to the `window.location.pathname` which can't be shared by two applications deployed to the same server, but it could come up if `allowNullApplicationId` was set to true.

`searchName` field escaping: by default, any character is allowed in the `searchName` field, and `searchName` are `escaped` when displayed by built-in UI components. If you provide your own UI for saved searches, you should escape the `searchName` field before displaying. Otherwise, users could render your application partly non-functional by using special characters or inline script, or a malicious admin could inject code into other user's browsers. If you prefer to just limit the `searchName` field to non-special characters, you can just add a `dataSourceField validator` to do this, and the built-in UIs for saved search will handle the validation error as expected (block the save or edit and tell the user what's wrong).

If you fail to implement all of the above, then it will be possible for users to save searches for other users or as admin searches, and those saved searches could have malicious code that is then injected into other user's browsers.

As noted above - the SavedSearches feature requires Smart GWT Pro or better.

- ## Field Summary

  ### Fields inherited from class com.smartgwt.client.core.DataClass

  `factoryCreated, factoryProperties`

  ### Fields inherited from class com.smartgwt.client.core.JsObject

  `jsObj`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `SavedSearches()`
  `SavedSearches(JavaScriptObject jsObj)`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static SavedSearches`
  `get()`
  Singleton accessor method.
  `String`
  `getAdminDefaultField()`
  Type "boolean".
  `String`
  `getAdminField()`
  (optional), type "boolean".
  `String`
  `getAdminRole()`
  The name of the adminRole (used via `Authentication.hasRole()`) to check to see if the current user has admin privileges.
  `boolean`
  `getAllowNullApplicationId()`
  If `applicationId` is not explicitly specified, it will be defaulted to the current window.location.pathname.
  `String`
  `getApplicationId()`
  The applicationId that will be saved to `"applicationIdField"` to disambiguate from other applications that use the same dataSource.
  `String`
  `getApplicationIdField()`
  Type: "string" (optional).
  `String`
  `getComponentIdField()`
  Type: "string".
  `String`
  `getDataField()`
  Type: "string".
  `DataSource`
  `getDefaultDataSource()`
  Default DataSource used for persistence of saved searches.
  `String`
  `getDefaultDataSourceAsString()`
  Default DataSource used for persistence of saved searches.
  `String`
  `getDefaultField()`
  optional, type "boolean".
  `DataSource`
  `getLocalDataSource(Canvas componentId)`
  This method returns an automatically generated custom DataSource to store saved searches for a component in HTML5 localStorage.
  `DataSource`
  `getLocalDataSource(String componentId)`
  This method returns an automatically generated custom DataSource to store saved searches for a component in HTML5 localStorage.
  `String`
  `getOfflineStorageKey()`
  If no explicit `defaultDataSource` was provided, a custom HTML5 `local storage` backed dataSource will be automatically created per component to store saved searches (see `getLocalDataSource()`).
  `static SavedSearches`
  `getOrCreateRef(JavaScriptObject jsObj)`
  `String`
  `getPrimaryKeyField()`
  Type: "string".
  `String`
  `getProjectIdField()`
  Type: "string".
  `boolean`
  `getSaveDefaultSearchToServer()`
  Should a user's default search preferences be stored to the server?
  `DataSource`
  `getSavedSearchDataSource(DataBoundComponent component)`
  Retrieves the DataSource used for persistence of saved searches for some component.
  `String`
  `getSavedSearchId(Canvas component)`
  Returns the identifier used to uniquely identify saved searches for some component.
  `String`
  `getSavedSearchIDPrefix()`
  Prefix applied to a specified `DataBoundComponent.savedSearchId` by `getSavedSearchId()`.
  `String`
  `getScreenIdField()`
  Type: "string".
  `String`
  `getSearchNameField()`
  Type: "string".
  `String`
  `getSetDefaultAdminSearchOperation()`
  `operationId` for the custom update operation to invoke when updating the default admin search.
  `String`
  `getSetDefaultUserSearchOperation()`
  `operationId` for the custom update operation to invoke when updating the default user search if `saveDefaultSearchToServer` is true.
  `String`
  `getUserIdField()`
  Type: "string" (optional).
  `SavedSearches`
  `setAllowNullApplicationId(boolean allowNullApplicationId)`
  If `applicationId` is not explicitly specified, it will be defaulted to the current window.location.pathname.
  `void`
  `setDefaultAdminSearch(DataBoundComponent component, boolean isDefault, Record searchRecord, String callback)`
  Update the admin default search for some component
  `void`
  `setDefaultUserSearch(DataBoundComponent component, boolean isDefault, Record searchRecord, String callback)`
  Update the user's default search.
  `SavedSearches`
  `setOfflineStorageKey(String offlineStorageKey)`
  If no explicit `defaultDataSource` was provided, a custom HTML5 `local storage` backed dataSource will be automatically created per component to store saved searches (see `getLocalDataSource()`).
  `SavedSearches`
  `setSaveDefaultSearchToServer(boolean saveDefaultSearchToServer)`
  Should a user's default search preferences be stored to the server?
  `SavedSearches`
  `setSavedSearchIDPrefix(String savedSearchIDPrefix)`
  Prefix applied to a specified `DataBoundComponent.savedSearchId` by `getSavedSearchId()`.
  `SavedSearches`
  `setSetDefaultAdminSearchOperation(String setDefaultAdminSearchOperation)`
  `operationId` for the custom update operation to invoke when updating the default admin search.
  `SavedSearches`
  `setSetDefaultUserSearchOperation(String setDefaultUserSearchOperation)`
  `operationId` for the custom update operation to invoke when updating the default user search if `saveDefaultSearchToServer` is true.

  ### Methods inherited from class com.smartgwt.client.core.DataClass

  `applyFactoryProperties, doAddHandler, fireEvent, getAttribute, getAttributeAsBoolean, getAttributeAsBoolean, getAttributeAsDate, getAttributeAsDouble, getAttributeAsDoubleArray, getAttributeAsElement, getAttributeAsFloat, getAttributeAsInt, getAttributeAsIntArray, getAttributeAsJavaScriptObject, getAttributeAsLong, getAttributeAsMap, getAttributeAsObject, getAttributeAsRecord, getAttributeAsString, getAttributeAsStringArray, getAttributes, getHandlerCount, isFactoryCreated, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttribute, setAttributeAsJavaObject, setFactoryCreated`

  ### Methods inherited from class com.smartgwt.client.core.JsObject

  `equals, getJsObj, hashCode, isCreated, setJavaScriptObject, setJsObj`

  ### Methods inherited from class java.lang.Object

  `clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### SavedSearches

    public SavedSearches()

  - ### SavedSearches

    public SavedSearches(JavaScriptObject jsObj)

- ## Method Details

  - ### getOrCreateRef

    public static SavedSearches getOrCreateRef(JavaScriptObject jsObj)

  - ### getAdminDefaultField

    public String getAdminDefaultField()
    Type "boolean". Designates an admin search as the shared default search for all users.

    The user's chosen default search is normally stored separately; the `adminDefaultField` exists as a way to mark a search as the default for a user that hasn't chosen one yet.

    See the "Default Searches" section of the `SavedSearches overview` for more information.

    Returns:
      Current adminDefaultField value. Default value is "isSharedDefault"

  - ### getAdminField

    public String getAdminField()
    (optional), type "boolean". Designates this search as an admin search, visible to all users
    Returns:
      Current adminField value. Default value is "admin"

  - ### getAdminRole

    public String getAdminRole()
    The name of the adminRole (used via `Authentication.hasRole()`) to check to see if the current user has admin privileges.
    Returns:
      Current adminRole value. Default value is "admin"

  - ### setAllowNullApplicationId

    public SavedSearches setAllowNullApplicationId(boolean allowNullApplicationId)
    If `applicationId` is not explicitly specified, it will be defaulted to the current window.location.pathname.

    Set this flag to true to disable this behavior and allow SavedSearches to be stored with no explicit applicationId.

    Note : This is an advanced setting

    Parameters:
      `allowNullApplicationId` - New allowNullApplicationId value. Default value is false
    Returns:
      `SavedSearches` instance, for chaining setter calls

  - ### getAllowNullApplicationId

    public boolean getAllowNullApplicationId()
    If `applicationId` is not explicitly specified, it will be defaulted to the current window.location.pathname.

    Set this flag to true to disable this behavior and allow SavedSearches to be stored with no explicit applicationId.

    Returns:
      Current allowNullApplicationId value. Default value is false

  - ### getApplicationId

    public String getApplicationId()
    The applicationId that will be saved to `"applicationIdField"` to disambiguate from other applications that use the same dataSource.

    If no applicationId was specified, `getApplicationId()` will return the current window.location.pathname by default. This behavior can be turned off by setting `allowNullApplicationId:true`.

    The `applicationId` allows the same dataSource to be used to store savedSearches for different applications. It also ensures that if no `explicit dataSource` was specified, and searches are being stored to `browser local storage`, saved searches will be associated with the current application even if another application running under the same domain/port has a component with the same `componentId`.

    Returns:
      Retrieves the value to saves as the link{SavedSearches.applicationIdField,"applicationIdField"} value for saved searches within this application.

      Returns `this.applicationId` if specified, otherwise the current window.location.pathname will be returned by default.
      Set `allowNullApplicationId` to suppress this behavior of defaulting to the location.pathname. Default value is null

  - ### getApplicationIdField

    public String getApplicationIdField()
    Type: "string" (optional). This field exists to allow a single DataSource to be used across multiple applications without colliding on `componentId`. Set `applicationId` to cause all search lookups to use `applicationId` as criteria, and all newly saved searches to store that `applicationId`.

    Note that if `applicationId` is not explicitly set, the window.location.pathname will be used as a default. This behavior can be disabled by setting `allowNullApplicationId` to true.

    Returns:
      Current applicationIdField value. Default value is "applicationId"

  - ### getComponentIdField

    public String getComponentIdField()
    Type: "string". Stores a unique ID for the component the saved search is associated with. This does not have to be the `Canvas.ID` and is usually a `AutoTestLocator`
    Returns:
      Current componentIdField value. Default value is "componentId"

  - ### getDataField

    public String getDataField()
    Type: "string". Name dataSource field used for storing the saved search itself with at least 8k of storage (it's possible for searches to get yet larger, but rare).
    Returns:
      Current dataField value. Default value is "data"

  - ### getDefaultDataSource

    public DataSource getDefaultDataSource()
    Default DataSource used for persistence of saved searches. This may be overridden for individual components via `component.savedSearchDS`.

    If no default dataSource is explicitly provided, the system will automatically generated a custom DataSource for each component that stores saved searches in HTML5 `localStorage`. See `getLocalDataSource()`.

    This means the searches are only retained for that specific user on that particular machine, and searches cannot be shared with other users. However, this approach does mean that you don't have to provide storage for saved searches and saving searches has no impact on scalability.

    Returns:
      Retrieves the DataSource used for persistence of saved searches.

      If a `defaultDataSource` was explicitly specified, it will be returned, otherwise this method returns null.

      To retrieve the dataSource used to store savedSearches for a specific component see `getSavedSearchDataSource()`. Default value is null

  - ### getDefaultDataSourceAsString

    public String getDefaultDataSourceAsString()
    Default DataSource used for persistence of saved searches. This may be overridden for individual components via `component.savedSearchDS`.

    If no default dataSource is explicitly provided, the system will automatically generated a custom DataSource for each component that stores saved searches in HTML5 `localStorage`. See `getLocalDataSource()`.

    This means the searches are only retained for that specific user on that particular machine, and searches cannot be shared with other users. However, this approach does mean that you don't have to provide storage for saved searches and saving searches has no impact on scalability.

    Returns:
      Retrieves the DataSource used for persistence of saved searches.

      If a `defaultDataSource` was explicitly specified, it will be returned, otherwise this method returns null.

      To retrieve the dataSource used to store savedSearches for a specific component see `getSavedSearchDataSource()`. Default value is null

  - ### getDefaultField

    public String getDefaultField()
    optional, type "boolean". Designates this search as the default search for this user.

    This field is only required if `saveDefaultSearchToServer` is true.
    See the "Default Searches" section of the `SavedSearches overview` for more information.

    Returns:
      Current defaultField value. Default value is "isDefault"

  - ### setOfflineStorageKey

    public SavedSearches setOfflineStorageKey(String offlineStorageKey)
    If no explicit `defaultDataSource` was provided, a custom HTML5 `local storage` backed dataSource will be automatically created per component to store saved searches (see `getLocalDataSource()`).

    This property denotes a base storage key for these dataSources.
    The `calculated savedSearch identifier` for the component will be appended to this value to create the key to use when storing serialized searches in local storage.

    Parameters:
      `offlineStorageKey` - New offlineStorageKey value. Default value is "isc_savedSearch_"
    Returns:
      `SavedSearches` instance, for chaining setter calls

  - ### getOfflineStorageKey

    public String getOfflineStorageKey()
    If no explicit `defaultDataSource` was provided, a custom HTML5 `local storage` backed dataSource will be automatically created per component to store saved searches (see `getLocalDataSource()`).

    This property denotes a base storage key for these dataSources.
    The `calculated savedSearch identifier` for the component will be appended to this value to create the key to use when storing serialized searches in local storage.

    Returns:
      Current offlineStorageKey value. Default value is "isc_savedSearch_"

  - ### getPrimaryKeyField

    public String getPrimaryKeyField()
    Type: "string". Name dataSource field used as the primary key.

    This is expected to be populated automatically when new search records are added to the data set, so will typically be of `type:sequence`.

    Returns:
      Current primaryKeyField value. Default value is "pk"

  - ### getProjectIdField

    public String getProjectIdField()
    Type: "string". Required because component IDs are not unique if components are loaded as `screens`, especially `Reify Screens`.
    Returns:
      Current projectIdField value. Default value is "projectId"

  - ### setSaveDefaultSearchToServer

    public SavedSearches setSaveDefaultSearchToServer(boolean saveDefaultSearchToServer)
    Should a user's default search preferences be stored to the server?

    Default user searches are normally saved in browser `localStorage` - see the "Default Searches" section of the `SavedSearches` doc and also the docs for `ListGrid.saveDefaultSearch`.

    If you want to store the default search on the server instead, you can add an `OperationBinding` of type "update" called `"setDefaultUserSearch"` to your `defaultDataSource`. This will be called with the PK value of the record to be made the default search, plus a boolean true value for the `defaultField`. The expectation is that the search identified by the PK is marked as default and any other searches previously marked as default are unmarked.

    Since Admin Search records are shared among all users, the expectation is that the underlying storage actually stores default markers separately from admin searches, and the `defaultDataSource` is acting as a `facade DataSource`.

    Updating a user's default search in the dataSource data should not modify any admin-default search.

    Parameters:
      `saveDefaultSearchToServer` - New saveDefaultSearchToServer value. Default value is false
    Returns:
      `SavedSearches` instance, for chaining setter calls

  - ### getSaveDefaultSearchToServer

    public boolean getSaveDefaultSearchToServer()
    Should a user's default search preferences be stored to the server?

    Default user searches are normally saved in browser `localStorage` - see the "Default Searches" section of the `SavedSearches` doc and also the docs for `ListGrid.saveDefaultSearch`.

    If you want to store the default search on the server instead, you can add an `OperationBinding` of type "update" called `"setDefaultUserSearch"` to your `defaultDataSource`. This will be called with the PK value of the record to be made the default search, plus a boolean true value for the `defaultField`. The expectation is that the search identified by the PK is marked as default and any other searches previously marked as default are unmarked.

    Since Admin Search records are shared among all users, the expectation is that the underlying storage actually stores default markers separately from admin searches, and the `defaultDataSource` is acting as a `facade DataSource`.

    Updating a user's default search in the dataSource data should not modify any admin-default search.

    Returns:
      Current saveDefaultSearchToServer value. Default value is false

  - ### setSavedSearchIDPrefix

    public SavedSearches setSavedSearchIDPrefix(String savedSearchIDPrefix)
    Prefix applied to a specified `DataBoundComponent.savedSearchId` by `getSavedSearchId()`. This is required to handle the case where a component's savedSearchId matches the ID of some other component.

    Note : This is an advanced setting

    Parameters:
      `savedSearchIDPrefix` - New savedSearchIDPrefix value. Default value is "SSID:"
    Returns:
      `SavedSearches` instance, for chaining setter calls

  - ### getSavedSearchIDPrefix

    public String getSavedSearchIDPrefix()
    Prefix applied to a specified `DataBoundComponent.savedSearchId` by `getSavedSearchId()`. This is required to handle the case where a component's savedSearchId matches the ID of some other component.
    Returns:
      Current savedSearchIDPrefix value. Default value is "SSID:"

  - ### getScreenIdField

    public String getScreenIdField()
    Type: "string". Required because component IDs are not unique if components are loaded as `screens`, especially `Reify Screens`.
    Returns:
      Current screenIdField value. Default value is "screenId"

  - ### getSearchNameField

    public String getSearchNameField()
    Type: "string". Name dataSource field used for storing names of saved searches.
    Returns:
      Current searchNameField value. Default value is "searchName"

  - ### setSetDefaultAdminSearchOperation

    public SavedSearches setSetDefaultAdminSearchOperation(String setDefaultAdminSearchOperation)
    `operationId` for the custom update operation to invoke when updating the default admin search.

    The update data for this operation will be the saved search record to mark as the shared default with the `adminDefaultField` set to indicate whether the saved search is being set or cleared.

    When marking a search as the new shared default, the dataSource implementation for this custom update operation must clear the adminDefaultField value on any previous shared default search. The server should also use the `dsResponse.relatedUpdates` feature to notify the client that the previous default was unset.

    Parameters:
      `setDefaultAdminSearchOperation` - New setDefaultAdminSearchOperation value. Default value is "setDefaultAdminSearch"
    Returns:
      `SavedSearches` instance, for chaining setter calls

  - ### getSetDefaultAdminSearchOperation

    public String getSetDefaultAdminSearchOperation()
    `operationId` for the custom update operation to invoke when updating the default admin search.

    The update data for this operation will be the saved search record to mark as the shared default with the `adminDefaultField` set to indicate whether the saved search is being set or cleared.

    When marking a search as the new shared default, the dataSource implementation for this custom update operation must clear the adminDefaultField value on any previous shared default search. The server should also use the `dsResponse.relatedUpdates` feature to notify the client that the previous default was unset.

    Returns:
      Current setDefaultAdminSearchOperation value. Default value is "setDefaultAdminSearch"

  - ### setSetDefaultUserSearchOperation

    public SavedSearches setSetDefaultUserSearchOperation(String setDefaultUserSearchOperation)
    `operationId` for the custom update operation to invoke when updating the default user search if `saveDefaultSearchToServer` is true.

    The update data for this operation will be the saved search record to mark as the user default with the `defaultField` set to indicate whether the saved search is being set or cleared.

    Note : This is an advanced setting

    Parameters:
      `setDefaultUserSearchOperation` - New setDefaultUserSearchOperation value. Default value is "setDefaultUserSearch"
    Returns:
      `SavedSearches` instance, for chaining setter calls

  - ### getSetDefaultUserSearchOperation

    public String getSetDefaultUserSearchOperation()
    `operationId` for the custom update operation to invoke when updating the default user search if `saveDefaultSearchToServer` is true.

    The update data for this operation will be the saved search record to mark as the user default with the `defaultField` set to indicate whether the saved search is being set or cleared.

    Returns:
      Current setDefaultUserSearchOperation value. Default value is "setDefaultUserSearch"

  - ### getUserIdField

    public String getUserIdField()
    Type: "string" (optional). This stores the `userId` of the user saving the search, populated from `the current userId`. This field is only optional in the sense that you could instead build a DataSource that returns user-specific saved searches through some other mechanism (for example, by inserting a userId value and forcing userId criteria on the server side).
    Returns:
      Current userIdField value. Default value is "userId"

  - ### getLocalDataSource

    public DataSource getLocalDataSource(Canvas componentId)
    This method returns an automatically generated custom DataSource to store saved searches for a component in HTML5 localStorage. Note that this dataSource will only be used to store savedSearches if there is no `shared default dataSource` specified, and if `ListGrid.savedSearchDS` is not set for the component.

    The offline storage key for the data will be generated by combining the `offlineStorageKey` with the component identifier retrieved from `getSavedSearchId()`.

    Note: The dataSources returned by this method will suppress logging their requests to the `Developer Console RPC tag` by default. This is done so developers can more easily see dataSource requests and responses that were explicitly initiated by application code, to simplify debugging. However, if a developer has explicitly created a SavedSearch dataSource either as the `global default` or at the `component level`, requests to access and update SavedSearch data will be logged as with any other dataSource.

    Parameters:
      `componentId` - Component to retrieve the dataSource for, or saved search component identifier as returned by `getSavedSearchId()`
    Returns:
      dataSource for SavedSearches backed by HTML5 local storage.

  - ### getLocalDataSource

    public DataSource getLocalDataSource(String componentId)
    This method returns an automatically generated custom DataSource to store saved searches for a component in HTML5 localStorage. Note that this dataSource will only be used to store savedSearches if there is no `shared default dataSource` specified, and if `ListGrid.savedSearchDS` is not set for the component.

    The offline storage key for the data will be generated by combining the `offlineStorageKey` with the component identifier retrieved from `getSavedSearchId()`.

    Note: The dataSources returned by this method will suppress logging their requests to the `Developer Console RPC tag` by default. This is done so developers can more easily see dataSource requests and responses that were explicitly initiated by application code, to simplify debugging. However, if a developer has explicitly created a SavedSearch dataSource either as the `global default` or at the `component level`, requests to access and update SavedSearch data will be logged as with any other dataSource.

    Parameters:
      `componentId` - Component to retrieve the dataSource for, or saved search component identifier as returned by `getSavedSearchId()`
    Returns:
      dataSource for SavedSearches backed by HTML5 local storage.

  - ### getSavedSearchDataSource

    public DataSource getSavedSearchDataSource(DataBoundComponent component)
    Retrieves the DataSource used for persistence of saved searches for some component.

    If `component.savedSearchDS` is specified this will be returned.
    Otherwise if an explicit `default dataSource` was specified, it will be used.

    If no explicit dataSource was provided either at the component level or as a default for all SavedSearches, this method will return the result of `getLocalDataSource()`.

    Parameters:
      `component` - component to retrieve the SavedSearch dataSource for
    Returns:
      the DataSource used to store saved searches for the target component

  - ### getSavedSearchId

    public String getSavedSearchId(Canvas component)
    Returns the identifier used to uniquely identify saved searches for some component.

    This is the value that will be set on the `componentIdField` when storing saved searches to a DataSource.
    If there is no explicly specified dataSource for storing saved searches, it will also be used to configure the offline storage key for data stored by the automatically generated `local storage backed dataSource` for the component.

    The returned value is calculated as follows:

    - If `DataBoundComponent.savedSearchId` is set, this method will return the `savedSearchIDPrefix` + `component.savedSearchId`.
    - Otherwise, the component's `local ID` (which falls back to the `global ID` if no local ID is present) will be returned. If `DataBoundComponent.showSavedSearchesByDS` is set and the component has a DataSource, the method will instead return the local ID + ":" + the DataSource ID, where the delimiter avoids potential collisions otherwise possible.
    Note: The returned ID string is not guaranteed to be immutable over a widget's lifespan.

    If no explicit component `savedSearchId` was set, the system will rely on the widget's local or global ID, which can change unless explicit due to app changes, and on the DataSource ID bound to the component, which may change at runtime. Since this property is used to identify the savedSearch records associated with this component, when it changes a different set of saved searches will be available to the user.

    If you want to control this explicitly, you can do so by setting an explicit `savedSearchId`. Changing the `savedSearchId` at runtime also allows you to deliberately associate a component with a new set of SavedSearches depending on application state. One common case where this might be desirable is if a component is bound to a dataSource and you want to bind to a new DataSource where the savedSearch criteria would not be applicable.

    Parameters:
      `component` - component to retrieve the identifier for
    Returns:
      component saved search ID

  - ### setDefaultAdminSearch

    public void setDefaultAdminSearch(DataBoundComponent component, boolean isDefault, Record searchRecord, String callback)
    Update the admin default search for some component

    This will invoke the `setDefaultAdminSearchOperation` to update the admin search record on the server.

    Parameters:
      `component` - component being updated
      `isDefault` - whether the default is being set to true or false
      `searchRecord` - record containing details of the search to be updated
      `callback` - callback to invoke when the search has been updated. Takes no arguments. See `Callback`

  - ### setDefaultUserSearch

    public void setDefaultUserSearch(DataBoundComponent component, boolean isDefault, Record searchRecord, String callback)
    Update the user's default search.

    This will invoke the `setDefaultUserSearchOperation` if `saveDefaultSearchToServer` is true, otherwise it will persist the default into offline storage

    Parameters:
      `component` - component being updated
      `isDefault` - whether the default is being set to true or false
      `searchRecord` - record containing details of the search to be updated
      `callback` - callback to invoke when the search has been updated. Takes no arguments. See `Callback`

  - ### get

    public static SavedSearches get()
    Singleton accessor method.
    Returns:
      an instance of SavedSearches