Extending On Frontend
#Extending Schema
In most of the cases you'll have everything defined on the backend but sometimes you still need to add certain features to elements on the frontend. Luckily everything you define on the frontend schema
property will be merged with what you have on the backend.
Let's see an example. Create App\Forms\RegistrationForm.php
:
<?php
namespace App\Forms;
class RegistrationForm extends \Laraform
{
public function schema() {
return [
'name' => [
'type' => 'text',
'label' => 'Name'
],
'email' => [
'type' => 'text',
'label' => 'Email'
],
'country' => [
'type' => 'select',
'label' => 'Country'
],
// ...
];
}
}
As you can see we haven't defined items
for country
select - this is because we're planning to have them loaded asynchronously.
We're going to use a similar solution than select element's Async Options example to add async loading for our country
field.
First, let's create a resources/js/forms/RegistrationForm.vue
:
<script>
export default {
mixins: [Laraform],
data() {
return {
schema: {
country: {
items: {},
search: true,
slots: {
noOptions: Vue.extend({
props: ['el$'],
template: `<span>Start typing...</span>`
})
},
options: {
'internal-search': false
},
created() {
this.loading = true
this.on('searchChange', (searchQuery) => {
axios.get(`/countries?q=${this.select$.search}`).then((response) => {
this.loading = false
this.items = response.data
})
})
}
}
}
}
}
}
</script>
Notice that we're not defining any of the existing options of country
element like type
or label
because those are already provided by the backend and will be merged.
Next register the component in your app.js
or main JS file and add that as a component to the backend form:
class RegistrationForm extends \Laraform
{
public $component = 'registration-form';
// ...
}
There you go! Now if you render the form you'll notice that the options of select have been merged and you have async loading for select items.
#Extending Buttons
Buttons are quite familiar to elements and sometimes we need to add some frontend featues to buttons which are already existing on the backend.
Let's see an example for that too. Having the same form as previously we're adding some buttons to it:
<?php
namespace App\Forms;
class RegistrationForm extends \Laraform
{
public $component = 'registration-form';
public function schema() {
// ...
}
public function buttons() {
return [
[
'label' => 'Submit'
],
[
'label' => 'Reset',
'prevent' => true
]
];
}
}
By default each button will submit the form unless it has the prevent
option set to true
. So we're good with Submit
as it will submit the form, but Reset
will do nothing at all. Let's change that!
In our previously created RegistrationForm.vue
we're going to add some definition for the Reset
button:
<script>
export default {
mixins: [Laraform],
data() {
return {
schema: {
// ...
},
buttons: [
// Submit button - nothing added
{},
// Reset button
{
onClick() {
this.form$.reset()
}
}
]
}
}
}
</script>
That's it! The onClick
option will be merged with the button's other options from the backend and now it will actually reset the form when clicked.
#Extending Other Properties
The two main properties were discussed in the last two sections, but there are couple of other properties Laraform is using to operate.
The rule of thumb is that everything you define on the frontend will overwrite what you have on the backend. This is of course not true for everything as we've already seen previously. The following properties are being merged instead of being replaced: