JSFiddle - React, Tailwind, and code Playground
by lid0
HTML
<div id="app">
<p>
app form state: {{form}}
<div>
Hello {{form.first}} {{form.last}}
</div>
</p>
<span class="title">Enter First and last name</span>
<template v-for="f,k in form">
<div>
<div class="field-title">
{{k}}
</div>
<field class="editable" v-model="form[k]" :key=k></field>
</div>
</template>
</div>
CSS
.editable {
border: 5px dashed cadetblue;
width: 200px;
max-width: 400px;
color: red;
font-size: 28px;
padding: 4px;
display: inline-block;
}
.editable:hover {
background: #cfcfcf
}
.editable input {
font-size: 28px;
width: 180px;
}
.title {
font-size: 25px;
background: #4abf5c;
color: white;
padding: 5px;
display: inherit;
}
.field-title {
font-size: 31px;
display: inline-block;
border: 5px solid #b9b9b9;
padding: 5px 20px 5px 20px;
}
JavaScript
// lidlanca 2021
/**
<field>
|_ view props: val
|_ edit props: val
by default a field is rendered in view mode.
when clicked, will switch to edit mode.
in edit mode a user can edit the value, then save or cancel.
on save, the new value will be emitted
*/
Vue.component('view1', {
props: ['val'],
template: `<h1 @click="$emit('click')">{{val}}</h1>`
});
Vue.component('edit1', {
emits: ["save"],
props: ['val'],
template: `<h1>
<input v-model="value"></input>
<button @click="$emit('cancel')">cancel</button>
<button @click="$emit('input',edit)">save</button>
</h1>`,
data() {
return {
edit: ""
}
},
computed: {
value: {
get() {
this.edit = this.val
return this.val
},
set(v) {
this.edit = v
}
}
}
});
Vue.component('field', {
props: ["value"],
template: `
<component
v-on:cancel="cancel"
@input="save"
@click="toggle()"
:val="value"
v-bind:is="current"></component>
`,
data() {
return {
current: "view1"
}
},
methods: {
toggle() {
this.current = this.current == "view1" ? "edit1" : "view1"
},
cancel() {
this.toggle()
},
// onSave
save(a) {
//this.value = a
this.toggle();
this.$emit('input', a) // emit input to update model value.
}
}
});
new Vue({
el: "#app",
data: {
form: {
first: "cudi",
last: "fredu"
}
}
})