Creating a field
You can create a custom field either by extending another field, or create one from scratch.
Fields consists of 4 vue templates: Filter.vue
, Index.vue
, Detail.vue
and Field.vue
Getting started
Let's create a basic field from scratch.
Back-end
The component
is the name of the Vue component:
class Example extends Field
{
public function component(): string
{
return 'Example';
}
}
When you extend an existing Field like Select
, and you need a custom component for your index, make sure to set:
public bool $rendersTextOnIndex = false;
For performance reasons, please set this to true
if your field only renders text.
This means it will never render a component in a table, because the value will always be text. When having lots of columns and rows it can get intensive for Vue to render these components.
We can use this field now in our resources, or on a custom page:
public function fields(): FieldCollection
{
return new FieldCollection(
Example::make(__('My label'), 'table_column_name'),
);
}
Front-end
Let's create an Example
directory in components/fields
.
Field in the form
The field is used in the forms. Properties like validation errors, debouncing, hints and more can be defined.
<template>
<!-- The input, fieldProps contain label, validation messages etc. -->
<q-input
v-bind="fieldProps"
:rules="rules"
v-model="value"
debounce="250"
@input="onInput"
:type="type"
>
<!-- Mark label with a red star if required -->
<template v-slot:label>
<field-label :field="field"/>
</template>
<!-- Field hint -->
<template
v-slot:hint
v-if="field.hint"
>
{{ field.hint }}
</template>
<!-- Field tooltip -->
<template
v-if="field.tool_tip"
v-slot:after
>
<field-tooltip :field="field"/>
</template>
</q-input>
</template>
<script>
import Field from 'qore/mixins/resource/Field'
export default {
mixins: [Field],
methods: {
// setState will make sure the value is updated in the form
onInput() {
this.setState(this.field.name, this.value)
}
}
}
</script>
As you can see, we use the Field
mixin. This mixin has all data from the form available
(the other fields in the form, the values of these fields, error messages and more).
The Field
mixin also exposes a setState
method. This method will update the field value.
Field for the detail page
<template>
<div>
My detail for field: {{field.name}} with value: {{value}}
</div>
</template>
<script>
export default {
props: ['field', 'value']
}
</script>
Field for the index page
<template>
<div>
My index for field: {{column.name}} with value: {{value}}
</div>
</template>
<script>
export default {
props: ['column', 'value']
}
</script>
Field for the table filter
<template>
<q-input
v-model="value"
dense
clearable
filled
debounce="250"
@input="onInput"
/>
</template>
<script>
import Filter from 'qore/mixins/resource/Filter'
export default {
mixins: [Filter],
methods: {
onInput() {
this.emitValue(this.value)
}
}
}
</script>
Similar to the Field.vue
, the filter includes the Filter
mixin.
This mixin exposes the emitValue
method to apply the filter.
Registering the components
Let's register our example components in boot/fields.js
:
import ExampleField from 'components/fields/Example/Field'
import ExampleDetail from 'components/fields/Example/Detail'
import ExampleIndex from 'components/fields/Example/Index'
import ExampleFilter from 'components/fields/Example/Filter'
Vue.component('ExampleField', ExampleField)
Vue.component('ExampleDetail', ExampleDetail)
Vue.component('ExampleIndex', ExampleIndex)
Vue.component('ExampleFilter', ExampleFilter)