-
Notifications
You must be signed in to change notification settings - Fork 20
Advanced Search
Given the need to implement an 'Advanced Search' function, paired with the fact that each source has different methods available, let's discuss a system implementation which will allow a source to flexible create it's own advanced search page.
Currently, searching supports a static list of fields.
export interface SearchRequest {
title?: string
includeDemographic?: string[]
includeTheme?: string[]
includeFormat?: string[]
includeContent?: string[]
includeGenre?: string[]
excludeDemographic?: string[]
excludeTheme?: string[]
excludeFormat?: string[]
excludeContent?: string[]
excludeGenre?: string[]
includeOperator?: number
excludeOperator?: number
author?: string
artist?: string
status?: number
hStatus?: boolean
}
I do not believe that even the SearchRequest
object is flexible enough to translate data between the source and the app. The source should be able to EXPLICITELY state what fields it's requesting, and the type of field that each should be.
export interface SearchField {
abstract humanReadableTitle: string
abstract fieldId: string
}
export class TextSearchField implements SearchField {
humanReadableTitle: string
fieldId: string = "TextField" // Is this required?
filledField: string // What the user wrote into the app
constructor(readableTitle: string) {
this.humanReadableTitle = readableTitle
}
}
export class MultiPickerField implements SearchField {
pickerValues: string[]
selectedValues: string[] // When sent back to the source on 'submit' can this field be updated and sent back?
// This way both the 'type' submission and the 'response' submission can be the same object
humanReadableTitle: string
fieldId: string = "MultiPickerField" // This might not be required
// Define what values this picker should display
constructor(values: string[], readableTitle: string) {
this.pickerValues = values
this.humanReadableTitle = readableTitle // Call it 'Genres' or something
}
}
With a use case of..
requestAdvancedSearchSkeleton(): SearchField[] { // This also could just be a const export, doesn't need to be a funct
let fields: SearchField[] = []
// All of these should be given a 'createField({..})' wrapper if swift requires it
let titleField = new TextSearchField("Title")
let authorField = new TextSearchField("Author")
let genres: string[] = ["Fantasy", "Romance"]
let genreField = new MultiPickerField(genres, "Genre Selection")
// Push all of these to the array and return
}
Given the nature on how each object can be turned into JSON, this returned array can be stringified to look something like..
{
[
{
humanReadableTitle: "Title",
fieldId: "TextField",
filledField: ""
},
{
humanReadableTitle: "Author",
fieldId: "TextField",
filledField: ""
},
{
humanReadableTitle: "Genre Selection",
fieldId: "MultiPickerField",
pickerValues: ["Fantasy", "Romance"],
selectedValues: []
}
]
}
This is something I'm sure the app could decode and render into the app.
Afterwards, the skeleton could be passed back to the source with filled data, and JSON.decoded(..)
back to a SearchField[]
type.
[
{
humanReadableTitle: "Title",
fieldId: "TextField",
filledField: "My Mom is Pretty Great"
},
{
humanReadableTitle: "Author",
fieldId: "TextField",
filledField: "Conrad Weiser"
},
{
humanReadableTitle: "Genre Selection",
fieldId: "MultiPickerField",
pickerValues: ["Fantasy", "Romance"],
selectedValues: ["Romance"]
}
]
}
This is something which the search function can use.