@huntsman-cancer-institute/search-select
v12.15.3
Published
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.
Downloads
396
Keywords
Readme
Search Select
This library was generated with Angular CLI version 12.2.0.
Code scaffolding
Run ng generate component component-name --project reporting-framework to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module --project search-select.
Note: Don't forget to add
--project search-selector else it will be added to the default project in yourangular.jsonfile.
Build
Run ng build search-select to build the project. The build artifacts will be stored in the dist/ directory.
Publishing
After building your library with ng build search-select, go to the dist folder cd dist/search-select and run npm publish.
Running unit tests
Run ng test search-select to execute the unit tests via Karma.
Further help
To get more help on the Angular CLI use ng help or go check out the Angular CLI Overview and Command Reference page.
#Project Specs and Info
Concept
this was built to replace the hci-autocomplete for use cases that used the virtual scroll because of the difficulty in making cdk virtual scroll WCAG/ADA compliant/accessible. The hci-autocomplete remains in use, minus the virtual scroll, for its ability to auto-complete but more for smaller dictionaries that can be entirely loaded and rendered without causing UI delay or slowdown.
The idea was that for a dictionary that has as many entries as a virtual scroll would be necessary, a user would never actually be scrolling through the entries, hence why auto-complete is also included. So this component takes the "auto complete" and moves it into a back-end search functionality. That returns limited results into a grid that the user can choose from.
Design
As with the original hci-autocomplete, there is a single-select and a multi-select
capability built into the component, chosen via the isMulti configuration flag.
For both types, the HCISearchSelect or <hci-search-select\>
is the main component that is placed in app's templates. It will show a readonly
text input with a button to open a popup where the user can do their search.
For single-select, the value will display as text in the text input, the popup "accept" button will say "Choose" and close when clicked. For Multi-select, "pills" will show inside the text input with the multiple values and small close "X" icons to remove a single value. The popup's "accept" button will say "Add" and will not close upon click, allowing multiple additions/searches in a row, until the user clicks "cancel".
NOTE: Some functionality that is built in as default may want to be made customizable or changed in the future. It's still a work in progress, I understand, and I only have one perspective.
Dictionary Framework
The ability to hook into the Dictionary Framework back end is already
implemented into the library, but it is possible for app devs to implement their own
api's in the cases that there is a custom dictionary or not-quite-dictionary that
wants to use the component. (see examples in resources\examples\*.example for full
code implementations and template\component reference snippets)
Popup: Material vs Bootstrap
The HCISearchSelectSearch component is the interior component that implements the
back end search, grid display and choose/add ability. It is nested into a popup
that is currently @hunstman-cancer-institute\dialog package only, which is material-
based, but designed so that the popup can be either converted to be dynamically
configured as material or bootstrap, or just converted to bootstrap (when moved to ng17,
say).
Config object
Configuration of the component is kept and passed through the various sub-components
via the HciSearchSelectConfig, which
can be created and passed in for more complicated setups, or will be created and
initialized by setting a few limited @Input variables directly on the <hci-search-select\>.
If you mix including a config and setting the @Input variables, for most variable,
they will not override a variable that already exists in the config. The few exceptions
are:
idKeyidDisplaysortKeysortNumericisRequiredshowErrorerrorMessage
This is because they have defaults built into the config, and in
order to overwrite them if set as @Inputs in an async component initialization,
I had to allow them to force the overwrite
Search Template
The search inside the popup has the ability to allow devs to implement their own
"search template". It uses a default template ( HCISSDefaultTemplate )
that has a single text search term and uses the config to determine the kinds of
Angular parameters to send, etc, but devs can extend the HciSSTemplateBase
to implement their own version with multiple terms, parameter types, validation, etc.
For an example of a template implementation with multiple terms/fields and validation,
see the AssocSearchTemplate example
component, which was implemented in ARTAdmin (and copied here).
The template can be changed in the config by setting the Type as the searchTemplateType
this.defaultConfig.searchTemplateType = AssocSearchTemplate;API Strategy
To pair with the custom search template, or even with the default search template,
devs can implement the HCISSStrategy interface
in order to hook up their own back end API other than the default dictionary framework
(which is implemented via the HCISSDictStrategy).
There are two parts to a strategy, the search and the "lookup". The search half is an API for searching the back end for results to display in the grid for the users to choose from. The lookup half is so the component can look up the display for existing values upon record load. It will call the lookup API upon writeValue and store the data in a local structure so the template display function can refresh without calling the back end 6 million times a second. This works for single and multi select.
The lookup half is technically optional (as seen in the example
AssocSSStrategy) if you choose
to use the valueTemplate.
The strategy needs to be created and passed in to each component, whether the default
dictionary strategy or a custom one. This is because the dictionary strategy has fields
that need to be set/initialized in time. (See RequestComponent
for full example snippets of setting up the strategies and components)
this.iirStrategy = new HCISSDictStrategy(http);
this.iirStrategy.dictionaryEndpoint = '/artadmin/api/dictionaries/';
this.iirStrategy.dictionaryClassName = 'hci.artadmin.model.IIRStatus';If the custom search strategy returns different numbers, names, or nesting than the
Dictionary Framework default, you can specify some simplified column definitions
via the config customColDefs (HCISSGridColDef)
for the ag-grid to display and respTreeAttrNames
to drill down into the response if, for example, the results are deeper because of
XML-to-JSON conversion from legacy JAC apps.
Legacy JAC apps using the old commands
may want to use POST and form-content for the http calls, which can be set as flags
using usePOSTParams and postAsFormContent
(Example from RequestComponent
this.addlPiConfig.postAsFormContent = true;
this.addlPiConfig.usePOSTParams = true;
this.addlPiConfig.customColDefs = [
{
field: 'fullName',
headerName: 'Full Name',
width: 400
},
{
field: 'peopleSoftId',
headerName: 'PeopleSoft ID'
}
];
this.addlPiConfig.respTreeAttrNames = ['AllUsers', 'Associate'];Dictionary API Strategy
The Dictionary Framework default API Strategy has been set up to work with a new endpoint
in the JAC (starting 4.8.7) and Spring 3 (2.0.6) dictionary frameworks.
This allows for a single search term that will be used to search the dictionary. The default will
search the DictionaryDisplay field, but in the case where that is a Getter-Only type field (aka
where that is not an actual column in the database but only a getter method), the API will require
one or more fields/columns as specified in the
HciSearchSelectConfig field searchFieldsArr.
That is just an array of strings that say which other columns to search instead, as ORs. These can
also be used to search along side the normal display column, as in the case where the code id
column would like to be searched as well.
There is a limit on the searchTerm where if it is less than three characters, in order to keep too
large of a search from being run, it will reject the searchTerm as invalid unless a % is included
in the string. If the searchTerm is less than 3 AND includes a %, it will allow the search to continue,
but will limit the values returned to only those that are ALSO less than 3 characters. This will allow
dictionary entries that are smaller than 3 to be found and returned without running too large of a search
in order to do so. A search term that is larger than 3 that contains a % will not have any
extra limits added.
If fields are included in the searchFieldsArr, each field has the limit of 3
added separately. So, for example, if the search term was "we%", searching Researchers, with a searchFieldArr
of ['firstName', lastName'], a result of "Wei, Weo" could be returned as could "Wen, Peng", and "Xaon, Wei"
but not "Welm, Alana"
There is currently no guidance on the screen for the users on how this special character limit works. There is only normal validation for the three character limit.
Along with the results, another data structure is returned containing metadata about the
request and the results. The class HHCISSDictMetadata
holds that metadata on the Angular side.
The results are limited by default to 30, though there is an optional parameter that can change
that amount (up to 100). The default strategy/config keeps this limit, though if can be overrdden
via the HciSearchSelectConfig field
resultLimitOverride. If the number of results exceeds the limit
(whatever it was, default 30 or passed in), the isTruncated flag will be set in the metadata,
which will also contain what that limit was (resultLimit) how many were returned (count, in
case the limit was not reached), and other information. If the results were truncated, a warning
message will be displayed to the user informing them.
