put id and mode in state sub-object => fix processing of 'new' response

This commit is contained in:
Helmut Merz 2023-03-23 23:07:44 +01:00
parent b68ee113c2
commit a377688175
7 changed files with 27 additions and 35 deletions

View file

@ -1,5 +1,6 @@
// comp-data.ts - definition and methods of the Data component
import { reactive } from 'petite-vue'
import { sendMsg } from './common'
// Data component
@ -8,23 +9,24 @@ import { sendMsg } from './common'
export function Data(name: string, conf: any): object {
const domain = conf.domain || this.conf.domain
const comp = {
state: {
id: this.conf.itemid,
mode: 'view'
},
name: name, // also used as class of incoming/outgoing message
action: conf.action, // (default) action of outgoing message
domain: domain, // domain of incoming/outgoing message
data: {}, // model (2-way data store)
data_bak: {}, // backup copy when leaving view or edit mode
meta: {}, // metadata (params) for each data field
mode: 'view',
handle, // handle incoming messages
exec, // default function to execute upon button click
initField, // initialize field (= @mounted)
chmode,
copynew
}
this.components[name] = comp
if (comp.id) {
sendMsg(this.conf, [domain, 'query', name, comp.id], {})
this.components[name] = reactive(comp)
if (comp.state.id) {
sendMsg(this.conf, [domain, 'query', name, comp.state.id], {})
}
return comp
}
@ -32,16 +34,12 @@ export function Data(name: string, conf: any): object {
// Data methods
function handle(parent: any, domain, action, class_, item, payload: string) {
if (action == 'data') {
if (action == 'data') { // && this.state.id
const data = JSON.parse(payload)
Object.assign(this.data, data)
this.id = item
this.mode = 'view'
this.data_bak = {}
this.state.mode = 'view'
} else if (action == 'response') {
this.id = item
this.mode = 'view'
this.data_bak = {}
this.state.id = item
window.location.hash = item
sendMsg(parent.conf, [this.domain, 'query', this.name, item], {})
}
@ -59,7 +57,7 @@ function exec(action: string) {
console.log('exec:', value)
const msgbase = [this.domain, action, this.name]
if (this.mode != 'new') {
msgbase.push(this.id)
msgbase.push(this.state.id)
}
sendMsg(conf, msgbase, data)
}
@ -73,12 +71,9 @@ function initField(name: string, meta: any) {
}
function chmode(action: string) {
if (this.mode == action) {
if (this.state.mode == action) {
return
}
if (this.mode == 'view') {
Object.assign(this.data_bak, this.data)
}
switch(action) {
case 'query':
setQuery(this)
@ -86,15 +81,12 @@ function chmode(action: string) {
case 'new':
setNew(this)
break
default:
Object.assign(this.data, this.data_bak)
}
this.mode = action
this.state.mode = action
}
function copynew(action: string) {
Object.assign(this.data, this.data_bak)
this.mode = 'new'
this.state.mode = 'new'
}
// helper functions for data manipulation (used by Data component)

View file

@ -8,7 +8,10 @@ import { sendMsg } from './common'
export function List(name: string, conf: any): object {
const domain = conf.domain || this.conf.domain
const comp = {
state: {
id: this.conf.itemid,
mode: 'view'
},
name: name, // also used as class of incoming/outgoing message
action: conf.action, // (default) action of outgoing message
domain: domain, // domain of incoming/outgoing message

View file

@ -27,11 +27,11 @@ cyberscopes example site - view / edit person (user) data.
{{< pv/button mode="new" label="Create Item" >}}
<br>
{{< pv/display linkto="id"
{{< pv/display linkto="state.id"
expr="`${data.firstname} ${data.lastname}`.trim() || '???'" >}}
<br>
{{< pv/link >}}
Reload page with id {{< pv/display name="id" >}}
Reload page with id {{< pv/display expr="state.id" >}}
{{< /pv/link >}}
{{< /pv/fieldset >}}

View file

@ -5,6 +5,6 @@
{{- $action := .Get "action" | default "" -}}
{{- $mode := .Get "mode" -}}
<button type="{{ $type }}" name="{{ $name }}"
{{- with $mode }}v-show="mode == '{{ . }}'"{{ end -}}
{{- with $mode }}v-show="state.mode == '{{ . }}'"{{ end -}}
@click="{{ $exec }}('{{ $action }}')">{{$label}}</button>

View file

@ -4,7 +4,7 @@
<div>
<input type="{{ $type }}" name="{{ $name }}"
{{- with .Get "attrs" }} {{ . }}{{ end }}
:readonly="mode == 'view' || meta['{{ $name }}'].readonly ? '' : null"
:readonly="state.mode == 'view' || meta['{{ $name }}'].readonly ? '' : null"
v-model="data.{{ $name }}"
@vue:mounted="initField('{{ $name }}', {{ $meta }})"
{{- with .Get "onchange" }} @change="{{ . }}"{{ end }} />

View file

@ -1,6 +1,3 @@
{{- $target := .Get "target" | default "id" -}}
{{- $target := .Get "target" | default "state.id" -}}
{{- $prefix := .Get "prefix" | default "#" -}}
this.id = item
this.mode = 'view'
this.data_bak = {}
<a :href="'{{ $prefix }}' + {{ $target }}">{{ .Inner }}</a>

View file

@ -1,15 +1,15 @@
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" @click.prevent="chmode('view')" href="#"
:class="mode == 'view' ? 'active' : null">View</a>
:class="state.mode == 'view' ? 'active' : null">View</a>
</li>
<li class="nav-item">
<a class="nav-link" @click.prevent="chmode('edit')" href="#"
:class="mode == 'edit' ? 'active' : null">Edit</a>
:class="state.mode == 'edit' ? 'active' : null">Edit</a>
</li>
<li class="nav-item">
<a class="nav-link" @click.prevent="chmode('new')" href="#"
:class="mode == 'new' ? 'active' : null">New</a>
:class="state.mode == 'new' ? 'active' : null">New</a>
</li>
</ul>
</ul>