first commit
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
<script setup>
|
||||
const delay = ref(null)
|
||||
delay.value = 10
|
||||
|
||||
async function getItemsSearch(query, el$) {
|
||||
const { data } = await useFetch('/api/address?search=' + query, {
|
||||
lazy: true,
|
||||
server: false,
|
||||
})
|
||||
return data.value.map((d) => {
|
||||
return {
|
||||
value: d,
|
||||
label: d.display,
|
||||
}
|
||||
})
|
||||
// const addressesString = data.value.map((value) => {
|
||||
// var result = value.villages ? 'Desa/Kel ' + value.villages + ', ' : ''
|
||||
// result += value.districts ? 'Kec ' + value.districts + ', ' : ''
|
||||
// result += value.cities ? 'Kota/Kab ' + value.cities + ', ' : ''
|
||||
// result += value.states ? 'Prov ' + value.states + ', ' : ''
|
||||
// result += value.countries ? value.countries : ''
|
||||
// return { value: value, label: result }
|
||||
// })
|
||||
// return addressesString
|
||||
}
|
||||
|
||||
async function getPostal(query) {
|
||||
const { data } = await useFetch('/api/address?search=' + query, {
|
||||
lazy: true,
|
||||
server: false,
|
||||
})
|
||||
return data.value
|
||||
}
|
||||
|
||||
function onSelectSearch(option, el$) {
|
||||
const postal = getPostal(option.value.states.regencies.districts)
|
||||
el$.$parent.$parent.children$.country.update(option.value)
|
||||
el$.$parent.$parent.children$.state.update(option.value.states)
|
||||
el$.$parent.$parent.children$.city.update(option.value.states.regencies)
|
||||
el$.$parent.$parent.children$.district.update(
|
||||
option.value.states.regencies.districts,
|
||||
)
|
||||
el$.$parent.$parent.children$.village.update(
|
||||
option.value.states.regencies.districts.villages,
|
||||
)
|
||||
el$.$parent.$parent.children$.postalCode.update(postal[0])
|
||||
}
|
||||
|
||||
function onSelectCountry(option, el$) {
|
||||
el$.$parent.$parent.children$.state.clear()
|
||||
el$.$parent.$parent.children$.city.clear()
|
||||
el$.$parent.$parent.children$.district.clear()
|
||||
el$.$parent.$parent.children$.village.clear()
|
||||
el$.$parent.$parent.children$.postalCode.clear()
|
||||
}
|
||||
|
||||
function onSelectState(option, el$) {
|
||||
el$.$parent.$parent.children$.city.clear()
|
||||
el$.$parent.$parent.children$.district.clear()
|
||||
el$.$parent.$parent.children$.village.clear()
|
||||
el$.$parent.$parent.children$.postalCode.clear()
|
||||
}
|
||||
|
||||
function onSelectCity(option, el$) {
|
||||
el$.$parent.$parent.children$.district.clear()
|
||||
el$.$parent.$parent.children$.village.clear()
|
||||
el$.$parent.$parent.children$.postalCode.clear()
|
||||
}
|
||||
|
||||
function onSelectDistrict(option, el$) {
|
||||
el$.$parent.$parent.children$.village.clear()
|
||||
el$.$parent.$parent.children$.postalCode.clear()
|
||||
console.log(el$)
|
||||
}
|
||||
|
||||
function onSelectVillage(option, el$) {
|
||||
el$.$parent.$parent.children$.postalCode.clear()
|
||||
}
|
||||
|
||||
async function onChange(input, el$) {
|
||||
delay.value = input.length > 0 ? 5000 : 10
|
||||
}
|
||||
|
||||
function formatData(name, value) {
|
||||
return { [name]: value.name }
|
||||
}
|
||||
function formatLine(name, value) {
|
||||
return { [name]: value.split('\n') }
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<ListElement name="address">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement
|
||||
:name="index"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 12,
|
||||
},
|
||||
}"
|
||||
>
|
||||
<TextareaElement
|
||||
name="line"
|
||||
placeholder="Alamat"
|
||||
:format-data="formatLine"
|
||||
/>
|
||||
<SelectElement
|
||||
name="search"
|
||||
@select="onSelectSearch"
|
||||
:search="true"
|
||||
:native="false"
|
||||
input-type="search"
|
||||
autocomplete="off"
|
||||
placeholder="🔎 Cari Alamat"
|
||||
:resolve-on-load="false"
|
||||
:delay="20"
|
||||
:items="getItemsSearch"
|
||||
:submit="false"
|
||||
no-results-text="Alamat Tidak Ditemukan"
|
||||
:object="true"
|
||||
:filter-results="false"
|
||||
:caret="false"
|
||||
/>
|
||||
<SelectElement
|
||||
name="country"
|
||||
allow-absent
|
||||
@select="onSelectCountry"
|
||||
items="/api/address/countries"
|
||||
:format-data="formatData"
|
||||
:search="true"
|
||||
:native="false"
|
||||
:object="true"
|
||||
:resolve-on-load="true"
|
||||
autocomplete="on"
|
||||
value-prop="_id"
|
||||
label-prop="name"
|
||||
input-type="search"
|
||||
placeholder="Negara"
|
||||
:conditions="[
|
||||
[
|
||||
['address.*.line', 'not_empty'],
|
||||
['address.*.search', 'not_empty'],
|
||||
],
|
||||
]"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
<SelectElement
|
||||
name="state"
|
||||
allow-absent
|
||||
@select="onSelectState"
|
||||
@search-change="onChange"
|
||||
items="/api/address/states?parent={address.*.country}"
|
||||
:format-data="formatData"
|
||||
:search="true"
|
||||
:native="false"
|
||||
:object="true"
|
||||
:delay="delay"
|
||||
:resolve-on-load="false"
|
||||
autocomplete="on"
|
||||
value-prop="_id"
|
||||
label-prop="name"
|
||||
input-type="search"
|
||||
placeholder="Provinsi"
|
||||
:conditions="[['address.*.country', 'not_empty']]"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
<SelectElement
|
||||
name="city"
|
||||
allow-absent
|
||||
@select="onSelectCity"
|
||||
@search-change="onChange"
|
||||
items="/api/address/cities?parent={address.*.state}"
|
||||
:format-data="formatData"
|
||||
:search="true"
|
||||
:native="false"
|
||||
:object="true"
|
||||
:delay="delay"
|
||||
:resolve-on-load="false"
|
||||
autocomplete="on"
|
||||
value-prop="_id"
|
||||
label-prop="name"
|
||||
input-type="search"
|
||||
placeholder="Kota / Kabupaten"
|
||||
:conditions="[['address.*.state', 'not_empty']]"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
<SelectElement
|
||||
name="district"
|
||||
allow-absent
|
||||
@select="onSelectDistrict"
|
||||
@search-change="onChange"
|
||||
items="/api/address/districts?parent={address.*.city}"
|
||||
:format-data="formatData"
|
||||
:search="true"
|
||||
:native="false"
|
||||
:object="true"
|
||||
:delay="delay"
|
||||
:resolve-on-load="false"
|
||||
autocomplete="on"
|
||||
value-prop="_id"
|
||||
label-prop="name"
|
||||
input-type="search"
|
||||
placeholder="Kecamatan"
|
||||
:conditions="[['address.*.city', 'not_empty']]"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
<SelectElement
|
||||
name="village"
|
||||
allow-absent
|
||||
@select="onSelectVillage"
|
||||
@search-change="onChange"
|
||||
items="/api/address/villages?parent={address.*.district}"
|
||||
:format-data="formatData"
|
||||
:search="true"
|
||||
:native="false"
|
||||
:object="true"
|
||||
:delay="delay"
|
||||
:resolve-on-load="false"
|
||||
autocomplete="on"
|
||||
value-prop="_id"
|
||||
label-prop="name"
|
||||
input-type="search"
|
||||
placeholder="Desa / Kelurahan"
|
||||
:conditions="[['address.*.district', 'not_empty']]"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
<SelectElement
|
||||
name="postalCode"
|
||||
allow-absent
|
||||
@search-change="onChange"
|
||||
items="/api/address/postal?parent={address.*.district}"
|
||||
:native="false"
|
||||
:object="false"
|
||||
:delay="delay"
|
||||
:resolve-on-load="false"
|
||||
autocomplete="off"
|
||||
placeholder="Kode Pos"
|
||||
:conditions="[['address.*.district', 'not_empty']]"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</template>
|
||||
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<ListElement name="communication">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<GroupElement name="container2_2">
|
||||
<GroupElement name="column1" :columns="{
|
||||
container: 1,
|
||||
}">
|
||||
<ToggleElement name="preferred" :labels="{
|
||||
on: 'Aktif',
|
||||
off: 'Pasif',
|
||||
}" :default="true" size="lg" align="right" />
|
||||
</GroupElement>
|
||||
<GroupElement name="column2" :columns="{
|
||||
container: 11,
|
||||
}">
|
||||
<ListElement name="language" :controls="{
|
||||
add: false,
|
||||
remove: false,
|
||||
}">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<SelectElement name="text" :items="[
|
||||
{
|
||||
value: 'Indonesia',
|
||||
label: 'Indonesia',
|
||||
},
|
||||
{
|
||||
value: 'Inggris',
|
||||
label: 'Inggris',
|
||||
},
|
||||
{
|
||||
value: 'jawa',
|
||||
label: 'Jawa',
|
||||
},
|
||||
{
|
||||
value: 'Sunda',
|
||||
label: 'Sunda',
|
||||
},
|
||||
]" :search="true" :native="false" input-type="search" autocomplete="off" placeholder="Bahasa"
|
||||
:create="true" :append-new-option="false" />
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</GroupElement>
|
||||
</GroupElement>
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,77 @@
|
||||
<script setup>
|
||||
const parsedName = ref({})
|
||||
const onChange = (newValue, oldValue, el$) => {
|
||||
const i = parseInt(el$.$parent.$parent.path.split('.')[1])
|
||||
parsedName.value[i] = parseName(el$.$parent.$parent.children$.text.value)
|
||||
el$.$parent.$parent.children$.prefix.update(parsedName.value[i].prefix)
|
||||
el$.$parent.$parent.children$.given.update(parsedName.value[i].given)
|
||||
el$.$parent.$parent.children$.family.update(parsedName.value[i].family)
|
||||
el$.$parent.$parent.children$.suffix.update(parsedName.value[i].suffix)
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<ListElement
|
||||
name="name"
|
||||
:controls="{
|
||||
add: true,
|
||||
remove: false,
|
||||
}"
|
||||
:rules="['min:1']"
|
||||
:min="1"
|
||||
:max="1"
|
||||
:initial="1"
|
||||
>
|
||||
<template #default="{ index }">
|
||||
<ObjectElement
|
||||
:name="index"
|
||||
:columns="{
|
||||
sm: {
|
||||
container: 12,
|
||||
},
|
||||
}"
|
||||
>
|
||||
<TextElement
|
||||
@change="onChange"
|
||||
name="text"
|
||||
placeholder="Nama Lengkap"
|
||||
/>
|
||||
<HiddenElement name="prefix" :meta="true" />
|
||||
<HiddenElement name="given" :meta="true" />
|
||||
<HiddenElement name="family" :meta="true" />
|
||||
<HiddenElement name="suffix" :meta="true" />
|
||||
<!-- <FormLibParsedName :name="parsedName" :path="'address.0'" /> -->
|
||||
<StaticElement name="parsed-name" size="m">
|
||||
<div v-if="parsedName[index]" class="d-flex flex-row">
|
||||
<v-chip
|
||||
v-for="(prefix, index) in parsedName[index].prefix"
|
||||
:key="`prefix-${index}`"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ prefix }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-for="(given, index) in parsedName[index].given"
|
||||
:key="`given-${index}`"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue-darken-3"
|
||||
>{{ given }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-show="parsedName[index].family"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue"
|
||||
>{{ parsedName[index].family }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-for="(suffix, index) in parsedName[index].suffix"
|
||||
:key="`suffix-${index}`"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ suffix }}</v-chip
|
||||
>
|
||||
</div>
|
||||
</StaticElement>
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</template>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script setup>
|
||||
import items from '~/assets/data/identifier/practitioner.json'
|
||||
|
||||
function onChange(oldValue, newValue, el$) {
|
||||
el$.$parent.$parent.children$.value.update(el$.value)
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<ListElement name="identifier" :rules="['min:1']">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<GroupElement name="type">
|
||||
<SelectElement name="name" :search="true" :items="items" data-key="option" :native="false" default="ktp"
|
||||
:columns="{
|
||||
container: 3,
|
||||
}" :can-clear="false" :can-deselect="false" />
|
||||
|
||||
<TextElement v-for="item in items" :conditions="[['identifier.*.type.name', item.value]]" name="value_element"
|
||||
@change="onChange" :rules="['nullable', item.regex]" :messages="{
|
||||
regex: 'Format Nomor ID salah!',
|
||||
}" :placeholder="item.placeholder" :columns="{
|
||||
container: 9,
|
||||
}" :submit="false" />
|
||||
|
||||
<HiddenElement name="value" :meta="true" />
|
||||
</GroupElement>
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</template>
|
||||
@@ -0,0 +1,52 @@
|
||||
<script setup>
|
||||
// Define props with validation
|
||||
const props = defineProps({
|
||||
path: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: Object,
|
||||
required: true,
|
||||
validator: (value) => {
|
||||
// Basic validation to ensure data has a name property
|
||||
return value && value.name
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StaticElement name="parsed-name" size="m">
|
||||
<div v-show="name" class="d-flex flex-row">
|
||||
<span> {{ index }}</span>
|
||||
<v-chip
|
||||
v-for="(prefix, index) in name.value[path].prefix"
|
||||
:key="`prefix-${index}`"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ prefix }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-for="(given, index) in name.value[path].given"
|
||||
:key="`given-${index}`"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue-darken-3"
|
||||
>{{ given }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-show="name.value[path].family"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue"
|
||||
>{{ name.family }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-for="(suffix, index) in name.value[path].suffix"
|
||||
:key="`suffix-${index}`"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ suffix }}</v-chip
|
||||
>
|
||||
</div>
|
||||
</StaticElement>
|
||||
</template>
|
||||
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<ListElement name="telecom">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<SelectElement name="system" :items="[
|
||||
{
|
||||
value: 'phone',
|
||||
label: '📞',
|
||||
},
|
||||
{
|
||||
value: 'email',
|
||||
label: '📧',
|
||||
},
|
||||
{
|
||||
value: 'url',
|
||||
label: '🌐',
|
||||
},
|
||||
]" :search="true" :native="false" input-type="search" autocomplete="off" :can-deselect="false"
|
||||
:can-clear="false" default="phone" :columns="{
|
||||
default: {
|
||||
container: 2,
|
||||
},
|
||||
sm: {
|
||||
container: 1,
|
||||
},
|
||||
}" :caret="false" />
|
||||
<SelectElement name="use" :items="[
|
||||
{
|
||||
value: 'home',
|
||||
label: '🏠',
|
||||
},
|
||||
{
|
||||
value: 'mobile',
|
||||
label: '📱',
|
||||
},
|
||||
{
|
||||
value: 'work',
|
||||
label: '🏢',
|
||||
},
|
||||
]" :search="true" :native="false" input-type="search" autocomplete="off" :columns="{
|
||||
default: {
|
||||
container: 2,
|
||||
},
|
||||
sm: {
|
||||
container: 1,
|
||||
},
|
||||
}" :caret="false" :can-deselect="false" :can-clear="false" default="home" />
|
||||
<GroupElement name="value" :columns="{
|
||||
default: {
|
||||
container: 8,
|
||||
},
|
||||
sm: {
|
||||
container: 10,
|
||||
},
|
||||
}">
|
||||
<PhoneElement name="phone" :allow-incomplete="true" :unmask="true" default="+62"
|
||||
:conditions="[['telecom.*.system', 'in', ['phone']]]" />
|
||||
<TextElement name="email" input-type="email" :rules="['nullable', 'email']" placeholder="eg. example@mail.com"
|
||||
:conditions="[['telecom.*.system', 'in', ['email']]]" />
|
||||
<TextElement name="url" input-type="url" :rules="['nullable', 'url']" placeholder="eg. http(s)://domain.com"
|
||||
:floating="false" :conditions="[['telecom.*.system', 'in', ['url']]]" />
|
||||
</GroupElement>
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,80 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
definePageMeta({
|
||||
title: 'Vue Form',
|
||||
icon: 'mdi-checkbox-blank-off-outline',
|
||||
drawerIndex: 0,
|
||||
})
|
||||
|
||||
const data = ref({})
|
||||
const humanName = ref({})
|
||||
const onChange = () => {
|
||||
humanName.value = parseName(data.value.nama)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="ma-4">
|
||||
<Vueform v-model="data" @change="onChange" sync>
|
||||
<TextElement
|
||||
name="nama"
|
||||
placeholder="Nama Lengkap"
|
||||
:rules="['required', 'min:3', 'max:100']"
|
||||
/>
|
||||
<StaticElement name="parsed-name" size="sm">
|
||||
<div class="d-flex flex-row">
|
||||
<v-chip
|
||||
v-for="prefix in humanName.prefix"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ prefix }}</v-chip
|
||||
><v-chip
|
||||
v-for="given in humanName.given"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue-darken-3"
|
||||
>{{ given }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-show="humanName.family"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue"
|
||||
>{{ humanName.family }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-for="suffix in humanName.suffix"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ suffix }}</v-chip
|
||||
>
|
||||
</div>
|
||||
</StaticElement>
|
||||
<RadiogroupElement
|
||||
name="gender"
|
||||
view="tabs"
|
||||
label="Jenis Kelamin"
|
||||
:items="[
|
||||
{
|
||||
value: 'unknown',
|
||||
label: '⭕',
|
||||
},
|
||||
{
|
||||
value: 'male',
|
||||
label: '♂️ Laki-laki',
|
||||
},
|
||||
{
|
||||
value: 'female',
|
||||
label: '♀️ Perempuan',
|
||||
},
|
||||
{
|
||||
value: 'other',
|
||||
label: '⚧️ Lainnya',
|
||||
},
|
||||
]"
|
||||
default="unknown"
|
||||
/>
|
||||
</Vueform>
|
||||
</div>
|
||||
<span>{{ data }}</span>
|
||||
<span>{{ humanName }}</span>
|
||||
</template>
|
||||
@@ -0,0 +1,222 @@
|
||||
<script>
|
||||
import { FormLibAddress, FormLibHumanName, FormLibTelecom } from '#components'
|
||||
import Identifier from '../Lib/Identifier.vue'
|
||||
|
||||
const data = ref('')
|
||||
const handleResponse = (response, form$) => {
|
||||
console.log(response) // axios response
|
||||
console.log(response.status) // HTTP status code
|
||||
console.log(response.data) // response data
|
||||
|
||||
console.log(form$) // <Vueform> instance
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Vueform v-model="data" validate-on="change|step" endpoint="/api/patient/create" method="post"
|
||||
@response="handleResponse">
|
||||
<StaticElement name="identifierTitle" tag="h2" content="Nomor Identitas" />
|
||||
<FormLibIdentifier />
|
||||
<StaticElement name="divider" tag="hr" />
|
||||
<StaticElement name="personalInfoTitle" tag="h2" content="Personal Info" />
|
||||
<FormLibHumanName />
|
||||
<!-- <ListElement name="nestedList" :controls="{
|
||||
add: false,
|
||||
remove: false,
|
||||
}">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<SelectElement name="humanNameUse" :items="[
|
||||
{
|
||||
value: 'official',
|
||||
label: '👨💼 Resmi',
|
||||
},
|
||||
{
|
||||
value: 'usual',
|
||||
label: '👨🦱 Biasa',
|
||||
},
|
||||
{
|
||||
value: 'temp',
|
||||
label: '🦲 Sementara',
|
||||
},
|
||||
// {
|
||||
// value: 'nickname',
|
||||
// label: '🙋♂️ Panggilan',
|
||||
// },
|
||||
// {
|
||||
// value: 'anonymous',
|
||||
// label: '👤 Anonim',
|
||||
// },
|
||||
// {
|
||||
// value: 'old',
|
||||
// label: '💇♂️ Nama Lama',
|
||||
// },
|
||||
// {
|
||||
// value: 'maiden',
|
||||
// label: '👧 Nama Gadis',
|
||||
// },
|
||||
]" :columns="{
|
||||
default: {
|
||||
container: 5,
|
||||
},
|
||||
sm: {
|
||||
container: 3,
|
||||
},
|
||||
lg: {
|
||||
container: 2,
|
||||
},
|
||||
}" :rules="['required']" :native="false" :can-deselect="false" :can-clear="false" :close-on-select="false"
|
||||
:caret="false" default="official" />
|
||||
<TextElement name="text" :columns="{
|
||||
default: {
|
||||
container: 7,
|
||||
},
|
||||
sm: {
|
||||
container: 9,
|
||||
},
|
||||
lg: {
|
||||
container: 10,
|
||||
},
|
||||
}" placeholder="Nama Lengkap" />
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement> -->
|
||||
<GroupElement name="container2">
|
||||
<GroupElement name="column1" :columns="{
|
||||
container: 6,
|
||||
}">
|
||||
<RadiogroupElement name="gender" view="tabs" label="Jenis Kelamin" :items="[
|
||||
{
|
||||
value: 'male',
|
||||
label: 'Laki-laki',
|
||||
},
|
||||
{
|
||||
value: 'female',
|
||||
label: 'Perempuan',
|
||||
},
|
||||
// {
|
||||
// value: 'other',
|
||||
// label: 'Lainnya',
|
||||
// },
|
||||
// {
|
||||
// value: 'unknown',
|
||||
// label: ' ',
|
||||
// },
|
||||
]" default="unknown" />
|
||||
</GroupElement>
|
||||
<GroupElement name="column_2" :columns="{
|
||||
container: 6,
|
||||
}">
|
||||
<ListElement name="maritalStatus" :controls="{
|
||||
add: false,
|
||||
remove: false,
|
||||
}">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<ListElement name="coding" :controls="{
|
||||
add: false,
|
||||
remove: false,
|
||||
}">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<SelectElement name="select" :items="[
|
||||
{
|
||||
value: 'UNK',
|
||||
label: 'Tidak Tahu',
|
||||
},
|
||||
{
|
||||
value: 'U',
|
||||
label: 'Belum Menikah',
|
||||
},
|
||||
{
|
||||
value: 'M',
|
||||
label: 'Menikah',
|
||||
},
|
||||
{
|
||||
value: 'D',
|
||||
label: 'Cerai Hidup',
|
||||
},
|
||||
{
|
||||
value: 'W',
|
||||
label: 'Cerai Mati',
|
||||
},
|
||||
]" :search="true" :native="false" label="Status Perkawinan" input-type="search" autocomplete="off"
|
||||
:can-deselect="false" :can-clear="false" default="UNK" />
|
||||
<HiddenElement name="system" default="http://terminology.hl7.org/CodeSystem/v3-MaritalStatus" />
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
</GroupElement>
|
||||
</GroupElement>
|
||||
<SelectElement name="birthPlace" :search="true" :native="false" input-type="search" autocomplete="on" :items="[
|
||||
{
|
||||
value: 'malang',
|
||||
label: 'Malang',
|
||||
},
|
||||
{
|
||||
value: 'surabaya',
|
||||
label: 'Surabaya',
|
||||
},
|
||||
]" placeholder="Tempat Lahir" :columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
lg: {
|
||||
container: 6,
|
||||
},
|
||||
}" />
|
||||
<DateElement name="birthDate" placeholder="Tanggal Lahir" :columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
lg: {
|
||||
container: 6,
|
||||
},
|
||||
}" />
|
||||
<StaticElement name="divider_1" tag="hr" />
|
||||
<StaticElement name="addressTitle" tag="h2" content="Alamat" />
|
||||
<FormLibAddress />
|
||||
|
||||
<StaticElement name="divider_2" tag="hr" />
|
||||
<StaticElement name="contactTitle" tag="h4" content="Kontak" />
|
||||
<FormLibTelecom />
|
||||
<StaticElement name="divider_3" tag="hr" />
|
||||
<StaticElement name="communicationTitle" tag="h2" content="Komunikasi" />
|
||||
<FormLibCommunication />
|
||||
<GroupElement name="container" :columns="{
|
||||
default: {
|
||||
container: 7,
|
||||
},
|
||||
sm: {
|
||||
container: 8,
|
||||
},
|
||||
lg: {
|
||||
container: 9,
|
||||
},
|
||||
}" />
|
||||
<GroupElement name="container2_3" :columns="{
|
||||
default: {
|
||||
container: 5,
|
||||
},
|
||||
sm: {
|
||||
container: 4,
|
||||
},
|
||||
lg: {
|
||||
container: 3,
|
||||
},
|
||||
}">
|
||||
<GroupElement name="column1" :columns="{
|
||||
container: 6,
|
||||
}">
|
||||
<ButtonElement name="secondaryButton" button-label="Batal" :secondary="true" align="center" size="lg" />
|
||||
</GroupElement>
|
||||
<GroupElement name="column2" :columns="{
|
||||
container: 6,
|
||||
}">
|
||||
<ButtonElement name="submit" button-label="Simpan" :submits="true" align="center" size="lg" />
|
||||
</GroupElement>
|
||||
</GroupElement>
|
||||
</Vueform>
|
||||
</template>
|
||||
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
definePageMeta({
|
||||
title: 'Vue Form',
|
||||
icon: 'mdi-checkbox-blank-off-outline',
|
||||
drawerIndex: 0,
|
||||
})
|
||||
|
||||
const data = ref({})
|
||||
const humanName = ref({})
|
||||
const onChange = () => {
|
||||
humanName.value = parseName(data.value.nama)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="ma-4">
|
||||
<Vueform v-model="data" @change="onChange" sync>
|
||||
<TextElement
|
||||
name="nama"
|
||||
placeholder="Nama Lengkap"
|
||||
:rules="['required', 'min:3', 'max:100']"
|
||||
/>
|
||||
<StaticElement name="parsed-name" size="sm">
|
||||
<div class="d-flex flex-row">
|
||||
<v-chip
|
||||
v-for="prefix in humanName.prefix"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ prefix }}</v-chip
|
||||
><v-chip
|
||||
v-for="given in humanName.given"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue-darken-3"
|
||||
>{{ given }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-show="humanName.family"
|
||||
size="x-small"
|
||||
class="mr-1 bg-blue"
|
||||
>{{ humanName.family }}</v-chip
|
||||
>
|
||||
<v-chip
|
||||
v-for="suffix in humanName.suffix"
|
||||
size="x-small"
|
||||
class="mr-1 bg-indigo-lighten-3"
|
||||
>{{ suffix }}</v-chip
|
||||
>
|
||||
</div>
|
||||
</StaticElement>
|
||||
<RadiogroupElement
|
||||
name="gender"
|
||||
view="tabs"
|
||||
label="Jenis Kelamin"
|
||||
:items="[
|
||||
{
|
||||
value: 'male',
|
||||
label: '♂️ Laki-laki',
|
||||
},
|
||||
{
|
||||
value: 'female',
|
||||
label: '♀️ Perempuan',
|
||||
},
|
||||
]"
|
||||
default="unknown"
|
||||
/>
|
||||
</Vueform>
|
||||
</div>
|
||||
<span>{{ data }}</span>
|
||||
<span>{{ humanName }}</span>
|
||||
</template>
|
||||
@@ -0,0 +1,146 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const data = ref({ name: '' })
|
||||
|
||||
const handleResponse = (response, form$) => {
|
||||
console.log(response) // axios response
|
||||
console.log(response.status) // HTTP status code
|
||||
console.log(response.data) // response data
|
||||
|
||||
console.log(form$) // <Vueform> instance
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Vueform v-model="data" validate-on="change|step" endpoint="/api/practitioner/basic" method="post"
|
||||
@response="handleResponse">
|
||||
<StaticElement name="identifierTitle" tag="h3" content="Nomor Identitas" />
|
||||
<FormLibIdentifier />
|
||||
<StaticElement name="divider" tag="hr" />
|
||||
<StaticElement name="nameTitle" tag="h4" content="Personal Info" />
|
||||
<FormLibHumanName />
|
||||
<RadiogroupElement name="gender" view="tabs" :items="[
|
||||
{
|
||||
value: 'unknown',
|
||||
label: '⭕',
|
||||
},
|
||||
{
|
||||
value: 'male',
|
||||
label: '♂️',
|
||||
},
|
||||
{
|
||||
value: 'female',
|
||||
label: '♀️',
|
||||
},
|
||||
{
|
||||
value: 'other',
|
||||
label: '⚧️',
|
||||
},
|
||||
]" default="unknown" />
|
||||
<SelectElement name="birthPlace" :search="true" :native="false" input-type="search" autocomplete="on"
|
||||
placeholder="Tempat Lahir" :columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}" items="/jsondata/birth-place.json" value-prop="name" label-prop="name" search-param="name" />
|
||||
<DateElement name="birthDate" placeholder="Tanggal Lahir" :columns="{
|
||||
sm: {
|
||||
container: 6,
|
||||
},
|
||||
}" />
|
||||
<FileElement name="photo" accept="image/*" view="image" :rules="[
|
||||
'mimetypes:image/jpeg,image/png,image/gif,image/webp,image/svg+xml,image/tiff',
|
||||
]" :urls="{}" :drop="true" label="Pas Foto" />
|
||||
<StaticElement name="divider_1" tag="hr" />
|
||||
<StaticElement name="addressTitle" tag="h4" content="Alamat" />
|
||||
<FormLibAddress />
|
||||
<StaticElement name="divider_2" tag="hr" />
|
||||
<StaticElement name="contactTitle" tag="h4" content="Kontak" />
|
||||
<ListElement name="telecom">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<SelectElement name="system" :items="[
|
||||
{
|
||||
value: 'phone',
|
||||
label: '📞',
|
||||
},
|
||||
{
|
||||
value: 'email',
|
||||
label: '📧',
|
||||
},
|
||||
{
|
||||
value: 'url',
|
||||
label: '🌐',
|
||||
},
|
||||
]" :search="true" :native="false" input-type="search" autocomplete="off" :can-deselect="false"
|
||||
:can-clear="false" default="phone" :columns="{
|
||||
default: {
|
||||
container: 2,
|
||||
},
|
||||
sm: {
|
||||
container: 1,
|
||||
},
|
||||
}" :caret="false" />
|
||||
<SelectElement name="use" :items="[
|
||||
{
|
||||
value: 'home',
|
||||
label: '🏠',
|
||||
},
|
||||
{
|
||||
value: 'mobile',
|
||||
label: '📱',
|
||||
},
|
||||
{
|
||||
value: 'work',
|
||||
label: '🏢',
|
||||
},
|
||||
]" :search="true" :native="false" input-type="search" autocomplete="off" :columns="{
|
||||
default: {
|
||||
container: 2,
|
||||
},
|
||||
sm: {
|
||||
container: 1,
|
||||
},
|
||||
}" :caret="false" :can-deselect="false" :can-clear="false" default="home" />
|
||||
<GroupElement name="value" :columns="{
|
||||
default: {
|
||||
container: 8,
|
||||
},
|
||||
sm: {
|
||||
container: 10,
|
||||
},
|
||||
}">
|
||||
<PhoneElement name="phone" :allow-incomplete="true" :unmask="true" default="+62"
|
||||
:conditions="[['telecom.*.system', 'in', ['phone']]]" />
|
||||
<TextElement name="email" input-type="email" :rules="['nullable', 'email']"
|
||||
placeholder="eg. example@mail.com" :conditions="[['telecom.*.system', 'in', ['email']]]" />
|
||||
<TextElement name="url" input-type="url" :rules="['nullable', 'url']" placeholder="eg. http(s)://domain.com"
|
||||
:floating="false" :conditions="[['telecom.*.system', 'in', ['url']]]" />
|
||||
</GroupElement>
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
<StaticElement name="divider_3" tag="hr" />
|
||||
<StaticElement name="communicationTitle" tag="h4" content="Komunikasi" />
|
||||
<ListElement name="communication">
|
||||
<template #default="{ index }">
|
||||
<ObjectElement :name="index">
|
||||
<ObjectElement name="language">
|
||||
<SelectElement name="text" :items="[
|
||||
{
|
||||
value: 'INDONESIA',
|
||||
label: 'INDONESIA',
|
||||
},
|
||||
]" :search="true" :native="false" input-type="search" autocomplete="off" placeholder="Bahasa" />
|
||||
</ObjectElement>
|
||||
<HiddenElement name="preferred" :default="true" :meta="true" />
|
||||
</ObjectElement>
|
||||
</template>
|
||||
</ListElement>
|
||||
<ToggleElement name="active" text="Catatan praktisi ini digunakan secara aktif" :default="true" />
|
||||
|
||||
<ButtonElement name="submit" button-label="Submit" :submits="true" align="right" />
|
||||
</Vueform>
|
||||
<p>{{ data }}</p>
|
||||
<!-- <p>{{ data.value.name }}</p> -->
|
||||
</template>
|
||||
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<ObjectElement name="test">
|
||||
<TextElement name="text" placeholder="Test Element" />
|
||||
</ObjectElement>
|
||||
</template>
|
||||
Reference in New Issue
Block a user