Add button actions to update form field values

This commit is contained in:
Andrew Kingston 2022-04-14 09:46:07 +01:00
parent b068c13972
commit 04b299750d
8 changed files with 265 additions and 16 deletions

View File

@ -654,7 +654,7 @@ export const getSchemaForDatasource = (asset, datasource, options) => {
* Builds a form schema given a form component. * Builds a form schema given a form component.
* A form schema is a schema of all the fields nested anywhere within a form. * A form schema is a schema of all the fields nested anywhere within a form.
*/ */
const buildFormSchema = component => { export const buildFormSchema = component => {
let schema = {} let schema = {}
if (!component) { if (!component) {
return schema return schema

View File

@ -0,0 +1,78 @@
<script>
import { Select, Label, Combobox } from "@budibase/bbui"
import { onMount } from "svelte"
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
import { currentAsset, store } from "builderStore"
import {
getActionProviderComponents,
buildFormSchema,
} from "builderStore/dataBinding"
import { findComponent } from "builderStore/componentUtils"
export let parameters
export let bindings = []
const typeOptions = [
{
label: "Set value",
value: "set",
},
{
label: "Reset to default value",
value: "reset",
},
]
$: formComponent = findComponent($currentAsset.props, parameters.componentId)
$: formSchema = buildFormSchema(formComponent)
$: fieldOptions = Object.keys(formSchema || {})
$: actionProviders = getActionProviderComponents(
$currentAsset,
$store.selectedComponentId,
"ValidateForm"
)
onMount(() => {
if (!parameters.type) {
parameters.type = "set"
}
})
</script>
<div class="root">
<Label small>Form</Label>
<Select
bind:value={parameters.componentId}
options={actionProviders}
getOptionLabel={x => x._instanceName}
getOptionValue={x => x._id}
/>
<Label small>Type</Label>
<Select
placeholder={null}
bind:value={parameters.type}
options={typeOptions}
/>
<Label small>Field</Label>
<Combobox bind:value={parameters.field} options={fieldOptions} />
{#if parameters.type === "set"}
<Label small>Value</Label>
<DrawerBindableInput
{bindings}
value={parameters.value}
on:change={e => (parameters.value = e.detail)}
/>
{/if}
</div>
<style>
.root {
display: grid;
column-gap: var(--spacing-l);
row-gap: var(--spacing-s);
grid-template-columns: 60px 1fr;
align-items: center;
max-width: 400px;
margin: 0 auto;
}
</style>

View File

@ -14,3 +14,4 @@ export { default as DuplicateRow } from "./DuplicateRow.svelte"
export { default as S3Upload } from "./S3Upload.svelte" export { default as S3Upload } from "./S3Upload.svelte"
export { default as ExportData } from "./ExportData.svelte" export { default as ExportData } from "./ExportData.svelte"
export { default as ContinueIf } from "./ContinueIf.svelte" export { default as ContinueIf } from "./ContinueIf.svelte"
export { default as UpdateFieldValue } from "./UpdateFieldValue.svelte"

View File

@ -42,25 +42,29 @@
"name": "Trigger Automation", "name": "Trigger Automation",
"component": "TriggerAutomation" "component": "TriggerAutomation"
}, },
{
"name": "Update Field Value",
"component": "UpdateFieldValue"
},
{ {
"name": "Validate Form", "name": "Validate Form",
"component": "ValidateForm" "component": "ValidateForm"
}, },
{ {
"name": "Log Out", "name": "Change Form Step",
"component": "LogOut" "component": "ChangeFormStep"
}, },
{ {
"name": "Clear Form", "name": "Clear Form",
"component": "ClearForm" "component": "ClearForm"
}, },
{ {
"name": "Close Screen Modal", "name": "Log Out",
"component": "CloseScreenModal" "component": "LogOut"
}, },
{ {
"name": "Change Form Step", "name": "Close Screen Modal",
"component": "ChangeFormStep" "component": "CloseScreenModal"
}, },
{ {
"name": "Refresh Data Provider", "name": "Refresh Data Provider",

View File

@ -1834,7 +1834,12 @@
"icon": "Form", "icon": "Form",
"hasChildren": true, "hasChildren": true,
"illegalChildren": ["section", "form"], "illegalChildren": ["section", "form"],
"actions": ["ValidateForm", "ClearForm", "ChangeFormStep"], "actions": [
"ValidateForm",
"ClearForm",
"ChangeFormStep",
"UpdateFieldValue"
],
"styles": ["size"], "styles": ["size"],
"settings": [ "settings": [
{ {
@ -1975,6 +1980,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Disabled", "label": "Disabled",
@ -2049,6 +2065,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Disabled", "label": "Disabled",
@ -2089,6 +2116,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Disabled", "label": "Disabled",
@ -2125,6 +2163,17 @@
"key": "placeholder", "key": "placeholder",
"placeholder": "Choose an option" "placeholder": "Choose an option"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "select", "type": "select",
"label": "Type", "label": "Type",
@ -2274,6 +2323,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Autocomplete", "label": "Autocomplete",
@ -2399,6 +2459,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Disabled", "label": "Disabled",
@ -2439,6 +2510,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "select", "type": "select",
"label": "Formatting", "label": "Formatting",
@ -2512,6 +2594,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Disabled", "label": "Disabled",
@ -2657,6 +2750,17 @@
"label": "Extensions", "label": "Extensions",
"key": "extensions" "key": "extensions"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Disabled", "label": "Disabled",
@ -2697,6 +2801,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Autocomplete", "label": "Autocomplete",
@ -2742,6 +2857,17 @@
"label": "Default value", "label": "Default value",
"key": "defaultValue" "key": "defaultValue"
}, },
{
"type": "event",
"label": "On change",
"key": "onChange",
"context": [
{
"label": "Field Value",
"key": "value"
}
]
},
{ {
"type": "boolean", "type": "boolean",
"label": "Disabled", "label": "Disabled",

View File

@ -219,10 +219,10 @@
}) })
return valid return valid
}, },
clear: () => { reset: () => {
// Clear the form by clearing each individual field // Reset the form by resetting each individual field
fields.forEach(field => { fields.forEach(field => {
get(field).fieldApi.clearValue() get(field).fieldApi.reset()
}) })
}, },
changeStep: ({ type, number }) => { changeStep: ({ type, number }) => {
@ -241,6 +241,22 @@
currentStep.set(step) currentStep.set(step)
} }
}, },
setFieldValue: (fieldName, value) => {
const field = getField(fieldName)
if (!field) {
return
}
const { fieldApi } = get(field)
fieldApi.setValue(value)
},
resetField: fieldName => {
const field = getField(fieldName)
if (!field) {
return
}
const { fieldApi } = get(field)
fieldApi.reset()
},
} }
// Creates an API for a specific field // Creates an API for a specific field
@ -268,11 +284,11 @@
return !error return !error
} }
// Clears the value of a certain field back to the initial value // Clears the value of a certain field back to the default value
const clearValue = () => { const reset = () => {
const fieldInfo = getField(field) const fieldInfo = getField(field)
const { fieldState } = get(fieldInfo) const { fieldState } = get(fieldInfo)
const newValue = initialValues[field] ?? fieldState.defaultValue const newValue = fieldState.defaultValue
// Update field state // Update field state
fieldInfo.update(state => { fieldInfo.update(state => {
@ -329,7 +345,7 @@
return { return {
setValue, setValue,
clearValue, reset,
updateValidation, updateValidation,
setDisabled, setDisabled,
validate: () => { validate: () => {
@ -354,11 +370,20 @@
// register their fields to step 1 // register their fields to step 1
setContext("form-step", writable(1)) setContext("form-step", writable(1))
const handleUpdateFieldValue = ({ type, field, value }) => {
if (type === "set") {
formApi.setFieldValue(field, value)
} else {
formApi.resetField(field)
}
}
// Action context to pass to children // Action context to pass to children
const actions = [ const actions = [
{ type: ActionTypes.ValidateForm, callback: formApi.validate }, { type: ActionTypes.ValidateForm, callback: formApi.validate },
{ type: ActionTypes.ClearForm, callback: formApi.clear }, { type: ActionTypes.ClearForm, callback: formApi.reset },
{ type: ActionTypes.ChangeFormStep, callback: formApi.changeStep }, { type: ActionTypes.ChangeFormStep, callback: formApi.changeStep },
{ type: ActionTypes.UpdateFieldValue, callback: handleUpdateFieldValue },
] ]
</script> </script>

View File

@ -21,6 +21,7 @@ export const UnsortableTypes = [
export const ActionTypes = { export const ActionTypes = {
ValidateForm: "ValidateForm", ValidateForm: "ValidateForm",
UpdateFieldValue: "UpdateFieldValue",
RefreshDatasource: "RefreshDatasource", RefreshDatasource: "RefreshDatasource",
AddDataProviderQueryExtension: "AddDataProviderQueryExtension", AddDataProviderQueryExtension: "AddDataProviderQueryExtension",
RemoveDataProviderQueryExtension: "RemoveDataProviderQueryExtension", RemoveDataProviderQueryExtension: "RemoveDataProviderQueryExtension",

View File

@ -162,6 +162,19 @@ const executeActionHandler = async (
} }
} }
const updateFieldValueHandler = async (action, context) => {
return await executeActionHandler(
context,
action.parameters.componentId,
ActionTypes.UpdateFieldValue,
{
type: action.parameters.type,
field: action.parameters.field,
value: action.parameters.value,
}
)
}
const validateFormHandler = async (action, context) => { const validateFormHandler = async (action, context) => {
return await executeActionHandler( return await executeActionHandler(
context, context,
@ -295,6 +308,7 @@ const handlerMap = {
["Execute Query"]: queryExecutionHandler, ["Execute Query"]: queryExecutionHandler,
["Trigger Automation"]: triggerAutomationHandler, ["Trigger Automation"]: triggerAutomationHandler,
["Validate Form"]: validateFormHandler, ["Validate Form"]: validateFormHandler,
["Update Field Value"]: updateFieldValueHandler,
["Refresh Data Provider"]: refreshDataProviderHandler, ["Refresh Data Provider"]: refreshDataProviderHandler,
["Log Out"]: logoutHandler, ["Log Out"]: logoutHandler,
["Clear Form"]: clearFormHandler, ["Clear Form"]: clearFormHandler,