Add ability for select options to be loaded from a data provider

This commit is contained in:
Andrew Kingston 2021-08-16 11:24:25 +01:00
parent 73def04951
commit 641e61773b
3 changed files with 115 additions and 3 deletions

View File

@ -32,9 +32,29 @@
if (!control) {
return false
}
if (setting.dependsOn && isEmpty(componentInstance[setting.dependsOn])) {
return false
// Parse dependant settings
if (setting.dependsOn) {
let dependantSetting = setting.dependsOn
let dependantValue = null
if (typeof setting.dependsOn === "object") {
dependantSetting = setting.dependsOn.setting
dependantValue = setting.dependsOn.value
}
if (!dependantSetting) {
return false
}
// If no specific value is depended upon, check if a value exists at all
// for the dependent setting
if (dependantValue == null) {
return !isEmpty(componentInstance[dependantSetting])
}
// Otherwise check the value matches
return componentInstance[dependantSetting] === dependantValue
}
return true
}
</script>

View File

@ -1893,6 +1893,7 @@
"type": "select",
"label": "Type",
"key": "optionsType",
"defaultValue": "select",
"placeholder": "Pick an options type",
"options": [
{
@ -1915,6 +1916,54 @@
"label": "Disabled",
"key": "disabled",
"defaultValue": false
},
{
"type": "select",
"label": "Options source",
"key": "optionsSource",
"defaultValue": "schema",
"placeholder": "Pick an options source",
"options": [
{
"label": "Schema",
"value": "schema"
},
{
"label": "Data provider",
"value": "provider"
},
{
"label": "Custom",
"value": "custom"
}
]
},
{
"type": "dataProvider",
"label": "Options Provider",
"key": "dataProvider",
"dependsOn": {
"setting": "optionsSource",
"value": "provider"
}
},
{
"type": "field",
"label": "Label Column",
"key": "labelColumn",
"dependsOn": {
"setting": "optionsSource",
"value": "provider"
}
},
{
"type": "field",
"label": "Value Column",
"key": "valueColumn",
"dependsOn": {
"setting": "optionsSource",
"value": "provider"
}
}
]
},

View File

@ -8,10 +8,51 @@
export let disabled = false
export let optionsType = "select"
export let defaultValue
export let optionsSource = "schema"
export let dataProvider
export let labelColumn
export let valueColumn
let fieldState
let fieldApi
let fieldSchema
$: flatOptions = optionsSource == null || optionsSource === "schema"
$: options = getOptions(
optionsSource,
fieldSchema,
dataProvider,
labelColumn,
valueColumn
)
const getOptions = (
optionsSource,
fieldSchema,
dataProvider,
labelColumn,
valueColumn
) => {
// Take options from schema
if (optionsSource == null || optionsSource === "schema") {
return fieldSchema?.constraints?.inclusion ?? []
}
// Extract options from data provider
if (optionsSource === "provider" && valueColumn) {
let optionsSet = {}
dataProvider?.rows?.forEach(row => {
const value = row?.[valueColumn]
if (value) {
const label = row[labelColumn] || value
optionsSet[value] = { value, label }
}
})
return Object.values(optionsSet)
}
return []
}
</script>
<Field
@ -31,9 +72,11 @@
id={$fieldState.fieldId}
disabled={$fieldState.disabled}
error={$fieldState.error}
options={fieldSchema?.constraints?.inclusion ?? []}
{options}
{placeholder}
on:change={e => fieldApi.setValue(e.detail)}
getOptionLabel={flatOptions ? x => x : x => x.label}
getOptionValue={flatOptions ? x => x : x => x.value}
/>
{:else if optionsType === "radio"}
<RadioGroup