Form component now supports edit recprd
This commit is contained in:
parent
6a4ac519aa
commit
208f5b33c1
|
@ -1,5 +1,5 @@
|
||||||
import regexparam from "regexparam"
|
import regexparam from "regexparam"
|
||||||
import { routerStore } from "../state/store"
|
import { appStore } from "../state/store"
|
||||||
import { getAppId } from "./getAppId"
|
import { getAppId } from "./getAppId"
|
||||||
|
|
||||||
export const screenRouter = ({ screens, onScreenSelected, window }) => {
|
export const screenRouter = ({ screens, onScreenSelected, window }) => {
|
||||||
|
@ -49,7 +49,7 @@ export const screenRouter = ({ screens, onScreenSelected, window }) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
routerStore.update(state => {
|
appStore.update(state => {
|
||||||
state["##routeParams"] = params
|
state["##routeParams"] = params
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,6 +8,7 @@ export const bbFactory = ({
|
||||||
store,
|
store,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
onScreenSlotRendered,
|
onScreenSlotRendered,
|
||||||
|
getCurrentState,
|
||||||
}) => {
|
}) => {
|
||||||
const apiCall = method => (url, body) => {
|
const apiCall = method => (url, body) => {
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
|
@ -53,6 +54,8 @@ export const bbFactory = ({
|
||||||
store: store,
|
store: store,
|
||||||
api,
|
api,
|
||||||
parent,
|
parent,
|
||||||
|
// these parameters are populated by screenRouter
|
||||||
|
routeParams: () => getCurrentState()["##routeParams"],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,14 @@ export const createStateManager = ({
|
||||||
routeTo,
|
routeTo,
|
||||||
}) => {
|
}) => {
|
||||||
let handlerTypes = eventHandlers(routeTo)
|
let handlerTypes = eventHandlers(routeTo)
|
||||||
let currentState
|
|
||||||
|
|
||||||
|
// creating a reference to the current state
|
||||||
|
// this avoids doing store.get() ... which is expensive on
|
||||||
|
// hot paths, according to the svelte docs.
|
||||||
|
// the state object reference never changes (although it's internals do)
|
||||||
|
// so this should work fine for us
|
||||||
|
let currentState
|
||||||
|
appStore.subscribe(s => (currentState = s))
|
||||||
const getCurrentState = () => currentState
|
const getCurrentState = () => currentState
|
||||||
|
|
||||||
const bb = bbFactory({
|
const bb = bbFactory({
|
||||||
|
|
|
@ -13,14 +13,14 @@
|
||||||
number: "number",
|
number: "number",
|
||||||
}
|
}
|
||||||
|
|
||||||
let newModel = {
|
let record
|
||||||
modelId: model,
|
|
||||||
}
|
|
||||||
let store = _bb.store
|
let store = _bb.store
|
||||||
let schema = {}
|
let schema = {}
|
||||||
let modelDef = {}
|
let modelDef = {}
|
||||||
let saved = false
|
let saved = false
|
||||||
let saving = false
|
let saving = false
|
||||||
|
let recordId
|
||||||
|
let isNew = true
|
||||||
|
|
||||||
let inputElements = {}
|
let inputElements = {}
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
$: fields = Object.keys(schema)
|
$: fields = Object.keys(schema)
|
||||||
|
|
||||||
|
$: Object.values(inputElements).length && setForm(record)
|
||||||
|
|
||||||
async function fetchModel() {
|
async function fetchModel() {
|
||||||
const FETCH_MODEL_URL = `/api/models/${model}`
|
const FETCH_MODEL_URL = `/api/models/${model}`
|
||||||
const response = await _bb.api.get(FETCH_MODEL_URL)
|
const response = await _bb.api.get(FETCH_MODEL_URL)
|
||||||
|
@ -42,7 +44,8 @@
|
||||||
if (saving) return
|
if (saving) return
|
||||||
saving = true
|
saving = true
|
||||||
const SAVE_RECORD_URL = `/api/${model}/records`
|
const SAVE_RECORD_URL = `/api/${model}/records`
|
||||||
const response = await _bb.api.post(SAVE_RECORD_URL, newModel)
|
const response = await _bb.api.post(SAVE_RECORD_URL, record)
|
||||||
|
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
|
@ -51,7 +54,13 @@
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
|
||||||
resetForm()
|
// wipe form, if new record, otherwise update
|
||||||
|
// model to get new _rev
|
||||||
|
if (isNew) {
|
||||||
|
resetForm()
|
||||||
|
} else {
|
||||||
|
record = json
|
||||||
|
}
|
||||||
|
|
||||||
// set saved, and unset after 1 second
|
// set saved, and unset after 1 second
|
||||||
// i.e. make the success notifier appear, then disappear again after time
|
// i.e. make the success notifier appear, then disappear again after time
|
||||||
|
@ -72,29 +81,58 @@
|
||||||
el.checked = false
|
el.checked = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newModel = {
|
record = {
|
||||||
modelId: model
|
modelId: model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setForm = rec => {
|
||||||
|
if (isNew || !rec) return
|
||||||
|
for (let fieldName in inputElements) {
|
||||||
|
if (typeof rec[fieldName] === "boolean") {
|
||||||
|
inputElements[fieldName].checked = rec[fieldName]
|
||||||
|
} else {
|
||||||
|
inputElements[fieldName].value = rec[fieldName]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleInput = field => event => {
|
const handleInput = field => event => {
|
||||||
let value
|
let value
|
||||||
|
|
||||||
if (event.target.type === "checkbox") {
|
if (event.target.type === "checkbox") {
|
||||||
value = event.target.checked
|
value = event.target.checked
|
||||||
newModel[field] = value
|
record[field] = value
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.target.type === "number") {
|
if (event.target.type === "number") {
|
||||||
value = parseInt(event.target.value)
|
value = parseInt(event.target.value)
|
||||||
newModel[field] = value
|
record[field] = value
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
value = event.target.value
|
value = event.target.value
|
||||||
newModel[field] = value
|
record[field] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const routeParams = _bb.routeParams()
|
||||||
|
recordId = Object.keys(routeParams).length > 0 && (routeParams.id || routeParams[0])
|
||||||
|
isNew = !recordId || recordId === "new"
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
record = { modelId: model }
|
||||||
|
} else {
|
||||||
|
const GET_RECORD_URL = `/api/${model}/records/${recordId}`
|
||||||
|
_bb.api.get(GET_RECORD_URL)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(rec => {
|
||||||
|
record = rec
|
||||||
|
setForm(rec)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="form" on:submit|preventDefault>
|
<form class="form" on:submit|preventDefault>
|
||||||
|
|
|
@ -13,33 +13,39 @@
|
||||||
number: "number",
|
number: "number",
|
||||||
}
|
}
|
||||||
|
|
||||||
let newModel = {
|
let record
|
||||||
modelId: model,
|
|
||||||
}
|
|
||||||
let store = _bb.store
|
let store = _bb.store
|
||||||
let schema = {}
|
let schema = {}
|
||||||
let modelDef = {}
|
let modelDef = {}
|
||||||
let saved = false
|
let saved = false
|
||||||
let saving = false
|
let saving = false
|
||||||
|
let recordId
|
||||||
|
let isNew = true
|
||||||
|
|
||||||
let inputElements = {}
|
let inputElements = {}
|
||||||
|
|
||||||
$: if (model && model.length !== 0) {
|
$: if (model && model.length !== 0) {
|
||||||
fetchModel()
|
fetchModel()
|
||||||
}
|
}
|
||||||
|
|
||||||
$: fields = Object.keys(schema)
|
$: fields = Object.keys(schema)
|
||||||
|
|
||||||
|
$: Object.values(inputElements).length && setForm(record)
|
||||||
|
|
||||||
async function fetchModel() {
|
async function fetchModel() {
|
||||||
const FETCH_MODEL_URL = `/api/models/${model}`
|
const FETCH_MODEL_URL = `/api/models/${model}`
|
||||||
const response = await _bb.api.get(FETCH_MODEL_URL)
|
const response = await _bb.api.get(FETCH_MODEL_URL)
|
||||||
modelDef = await response.json()
|
modelDef = await response.json()
|
||||||
schema = modelDef.schema
|
schema = modelDef.schema
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
// prevent double clicking firing multiple requests
|
// prevent double clicking firing multiple requests
|
||||||
if (saving) return
|
if (saving) return
|
||||||
saving = true
|
saving = true
|
||||||
const SAVE_RECORD_URL = `/api/${model}/records`
|
const SAVE_RECORD_URL = `/api/${model}/records`
|
||||||
const response = await _bb.api.post(SAVE_RECORD_URL, newModel)
|
const response = await _bb.api.post(SAVE_RECORD_URL, record)
|
||||||
|
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
|
@ -48,7 +54,13 @@
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
|
||||||
resetForm()
|
// wipe form, if new record, otherwise update
|
||||||
|
// model to get new _rev
|
||||||
|
if (isNew) {
|
||||||
|
resetForm()
|
||||||
|
} else {
|
||||||
|
record = json
|
||||||
|
}
|
||||||
|
|
||||||
// set saved, and unset after 1 second
|
// set saved, and unset after 1 second
|
||||||
// i.e. make the success notifier appear, then disappear again after time
|
// i.e. make the success notifier appear, then disappear again after time
|
||||||
|
@ -69,26 +81,58 @@
|
||||||
el.checked = false
|
el.checked = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newModel = {
|
record = {
|
||||||
modelId: model
|
modelId: model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setForm = rec => {
|
||||||
|
if (isNew || !rec) return
|
||||||
|
for (let fieldName in inputElements) {
|
||||||
|
if (typeof rec[fieldName] === "boolean") {
|
||||||
|
inputElements[fieldName].checked = rec[fieldName]
|
||||||
|
} else {
|
||||||
|
inputElements[fieldName].value = rec[fieldName]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleInput = field => event => {
|
const handleInput = field => event => {
|
||||||
let value
|
let value
|
||||||
|
|
||||||
if (event.target.type === "checkbox") {
|
if (event.target.type === "checkbox") {
|
||||||
value = event.target.checked
|
value = event.target.checked
|
||||||
newModel[field] = value
|
record[field] = value
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.target.type === "number") {
|
if (event.target.type === "number") {
|
||||||
value = parseInt(event.target.value)
|
value = parseInt(event.target.value)
|
||||||
newModel[field] = value
|
record[field] = value
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
value = event.target.value
|
value = event.target.value
|
||||||
newModel[field] = value
|
record[field] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const routeParams = _bb.routeParams()
|
||||||
|
recordId = Object.keys(routeParams).length > 0 && (routeParams.id || routeParams[0])
|
||||||
|
isNew = !recordId || recordId === "new"
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
record = { modelId: model }
|
||||||
|
} else {
|
||||||
|
const GET_RECORD_URL = `/api/${model}/records/${recordId}`
|
||||||
|
_bb.api.get(GET_RECORD_URL)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(rec => {
|
||||||
|
record = rec
|
||||||
|
setForm(rec)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="form" on:submit|preventDefault>
|
<form class="form" on:submit|preventDefault>
|
||||||
|
@ -127,7 +171,7 @@
|
||||||
{buttonText || "Submit Form"}
|
{buttonText || "Submit Form"}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Reference in New Issue