Can't access component method inside my blade file - laravel-5

I am trying to access a method inside my blade file, with #click but I am getting an error
signup-modal.vue
<template>
<div>
<div v-if="modal" class="animated fadeIn fixed z-50 pin overflow-auto bg-black flex">
<div class="animated fadeInUp fixed shadow-inner max-w-md md:relative pin-b pin-x align-top m-auto justify-end md:justify-center p-8 bg-white md:rounded w-full md:h-auto md:shadow flex flex-col">
<p class="text-xl leading-normal mb-8 text-center">
{{ __("Sign up to name to start socializing") }}
</p>
<div class="justify-center">
<form action="/auth/register" method="post">
<div class="mb-4">
<label class="block text-grey-darker text-sm font-bold mb-2" for="username">
{{ __("Name" )}}
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight" id="username" type="text" placeholder="Username">
</div>
<div class="mb-4">
<label class="block text-grey-darker text-sm font-bold mb-2" for="username">
{{ __("Email" )}}
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight" id="username" type="text" placeholder="Username">
</div>
<div class="mb-4">
<label class="block text-grey-darker text-sm font-bold mb-2" for="username">
{{ __("Password" )}}
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight" id="username" type="text" placeholder="Username">
</div>
<div class="flex items-center justify-end">
<button class="bg-teal hover:bg-teal-dark text-white font-bold py-2 px-4 rounded" type="button">
{{ __("Sign up") }}
</button>
</div>
</form>
</div>
<span #click="toggleModal" class="absolute pin-t pin-r pt-4 px-4">
<svg class="h-6 w-6 text-grey hover:text-grey-darkest" role="button" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><title>Close</title><path d="M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697l2.758-3.15-2.759-3.152a1.2 1.2 0 1 1 1.697-1.697L10 8.183l2.651-3.031a1.2 1.2 0 1 1 1.697 1.697l-2.758 3.152 2.758 3.15a1.2 1.2 0 0 1 0 1.698z"/></svg>
</span>
</div>
</div>
</div>
</template>
<script>
export default {
data: function()
{
return {
modal: false
}
},
methods: {
toggleModal: function() {
console.log("djdjd")
//this.modal = !this.modal
}
}
}
</script>
app.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
Vue.component('signup-modal', require('./components/signup-modal.vue'));
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app'
});
My blade file:
<div id="app">
<button class="bg-blue w-full rounded-full text-white py-2 mb-2" #click="toggleModal">
{{ __("Sign up") }}
</button>
</div>
<div>
<signup-modal></signup-modal>
</div>
</div>
As you can see in my blade file I am trying to access my components method toggleModal but I am getting an error:
app.js:36520 [Vue warn]: Property or method "toggleModal" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
(found in <Root>)
warn # app.js:36520
warnNonPresent # app.js:37826
has # app.js:37859
(anonymous) # VM374:3
Vue._render # app.js:40471
updateComponent # app.js:38715
get # app.js:39069
Watcher # app.js:39058
mountComponent # app.js:38722
Vue.$mount # app.js:44467
Vue.$mount # app.js:46866
Vue._init # app.js:40567
Vue # app.js:40656
(anonymous) # app.js:13896
__webpack_require__ # app.js:20
(anonymous) # app.js:13869
__webpack_require__ # app.js:20
(anonymous) # app.js:63
(anonymous) # app.js:66
app.js:36520 [Vue warn]: Invalid handler for event "click": got undefined
Why is this and how can I fix it?

To achieve what I wanted to do, I went the event-based way. For example, in my component, I added the method mounted, and added the following:
mounted()
{
eventHub.$on('signup-click', this.toggleModal)
}
And my main Vue method I added a simple event emitter method like so:
const app = new Vue({
el: '#app',
methods: {
generateEvent: (event) => {
eventHub.$emit(event);
}
}
});
And then in my blade file, I simple called that method like so:
<button class="bg-blue w-full rounded-full text-white py-2 mb-2" #click="generateEvent('signup-click')">
{{ __("Sign up") }}
</button>
Which simple emits the event, so my component listens to it, then calls that child method.

Related

List recursive with checkbox component data into parent component update values

Help to list recursive with checkbox component data into parent component update values:
Parent File:
<TreeVue :items="props.allModules" :selectedItems="userForm.userModules"/>
TreeVue File:
<template>
<div v-for="item in items" :key="item.name" class="overflow-hidden rounded-lg bg-gray-50">
<div class="px-4 py-5 sm:p-6" >
<div class="flex items-center ">
<input :id="item.id" type="checkbox" :value="item.id" v-model="props.selectedItems" class="w-6 h-6 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="default-checkbox" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">{{ item.name }}</label>
</div>
<div v-if="item.children" class="ml-5">
<Tree :items="item.children" :selectedItems="selectedItems" />
</div>
</div>
</div>
</template>
<script setup>
import { defineProps } from "vue";
const props = defineProps({
items: Object,
selectedItems: Object,
});
</script>
ConsoleLog:
app.js:7839 [Vue warn] Set operation on key "selectedItems" failed: target is readonly. Proxy {items: Proxy, selectedItems: Proxy}
I need to update parent value after selected item on child TreeVue.
I read something about Emit, but I don't know how to implement it, because I'm new to Vue.

Why is TinyMCE throwing "b is not a constructor", and "({default{}) is not a constructor" when attempting to upload images on Laravel Forge, not dev?

I have my image upload functionality working in development, for which my environment is Laravel Sail. It is working in development, but not in production Laravel forge where it is throwing 'b is not a constructor," and "({default{}}) is not a constructor", depending on whether you're using chrome or firefox respectively, which should have similar-identical environments. Only thing I can think I did differently between them is that in production I used npm run dev in development and npm run build for production. For the application, I'm using Laravel, InertiaJS, and Vue3 and It looks like this:
Vue Form and Script:
<form enctype="multipart/form-data" class="mb-4 md:flex md:flex-wrap md:justify-between" action="/dashboard/pages/store"
method="post">>
<input type="hidden" name="_token" :value="csrfToken">
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest" for="title">Title </label>
<input class="border py-2 px-3 text-grey-darkest md:mr-2" type="text" name="title" id="title">
</div>
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest"
for="slug">Slug </label>
<input class="border py-2 px-3 text-grey-darkest md:mr-2" type="text" name="slug" id="slug">
</div>
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest"
for="slug">Status </label>
<select class="border py-2 px-3 text-grey-darkest md:mr-2" name="status" id="status">
<option value="published">Published</option>
<option value="draft">Draft</option>
</select>
</div>
<!-- Page Header Image -->
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest"
for="slug">Page Header Image </label>
<input class="border py-2 px-3 text-grey-darkest md:mr-2" type="file" name="header_image" id="header_image">
</div>
<div class="flex flex-col mb-4 md:w-full">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest" for="content">Content </label>
<editor name="content" id="content" api-key='xxxxxxxxxxxxxxxx'
:init="{
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table contextmenu paste imagetools'
],
toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image ',
image_title: true,
automatic_uploads: true,
file_picker_types: 'image',
images_upload_handler: function (blobInfo, success, failure) {
let data = new FormData();
data.append('file', blobInfo.blob(), blobInfo.filename());
axios.post('/dashboard/pages/upload-images', data)
.then(function (res) {
success(res.data.location);
})
.catch(function (err) {
failure('HTTP Error: ' + err.message);
});
}
}"/>
</div>
<div class="grid mb-4 md:w-full place-items-center">
<button class="bg-red-500 md:w-36 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
type="submit">
Create
</button>
</div>
</form>
Here's the error I'm getting. I don't even know how to get it into the console so I can debug it further:
This is definitely related to the build script, as I ran npm run build on my local machine and it's doing the same thing locally/in development.
This seems to have been an issue with #rollup/plugin-commonjs.
The vite documentation for migration notes that this is the biggest difference between dev and build, so I tried their alternative strategy for removing commonjs because esbuild converts CJS-only dependencies to ESM.
https://vitejs.dev/guide/migration.html#using-esbuild-deps-optimization-at-build-time
To do this, from my Laravel build, in app.js I had to declare my config as a const, then you can use optimizeDeps.disabled: false (the default in v3 is disabled: 'build'). #rollup/plugin-commonjs can be removed by passing build.commonjsOptions: { include: [] }
For me, that left my app.js looking like this:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
const config = defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
ssr: 'resources/js/ssr.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
ssr: {
noExternal: ['#inertiajs/server'],
},
alias: {
src: '/src',
},
});
config.build = { ...config.build, include: [] };
config.optimizeDeps = { disabled: false };
export default config;

How can I show data names field in vue-multiselect plugin in edit page?

I have a vue laravel SPA, and was working on the edit page of employees page. I already have create employees page and can display data on the vue-multiselect plugin (https://vue-multiselect.js.org/). Right now, I can display the employee id's from an array in vue-multiselect in the edit page. How can I format it to show employee names?
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<script>
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data() {
return {
employee: {
designation_id: [],
position_id: [],
},
designation_names: {},
position_names: {}
}
},
methods: {
updateEmployee() {
this.axios
.patch(`/api/employees/${this.$route.params.id}`, this.employee)
.then((res) => {
this.$router.push({ name: 'employees' });
});
},
async getDesignations(id) {
const { data } = await this.axios.get(`/employees/${id}/designations`);
this.$set(this.designation_names, id, data.join(', '));
},
async getPositions(id) {
const { data } = await this.axios.get(`/employees/${id}/positions`);
this.$set(this.position_names, id, data.join(', '));
},
},
created() {
this.axios
.get(`/api/employees/${this.$route.params.id}`)
.then((res) => {
this.employee = res.data;
});
for(const row of this.rows) { this.getDesignations(row.id); }
for(const row of this.rows) { this.getPositions(row.id); }
},
}
</script>
<template>
<form #submit.prevent="updateEmployee">
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="name">First Name</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="name" id="name" type="text" placeholder="First Name" tabindex="1" v-model="employee.first_name" />
</div>
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="name">Last Name</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="name" id="name" type="text" placeholder="Last Name" tabindex="2" v-model="employee.last_name" />
</div>
</div>
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2 required" for="designation_id">Designation</label>
<multiselect
v-model="employee.designation_id"
:options="designation_options"
:custom-label="opt => designation_options.find(designation => designation.id == opt).name"
:multiple="true"
:taggable="true"
></multiselect>
</div>
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2 required" for="position_id">Position</label>
<multiselect
v-model="employee.position_id"
:options="position_options"
:multiple="true"
:taggable="true"
></multiselect>
</div>
</div>
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="basic_pay">Basic Pay</label>
<div class="relative rounded">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<span class="text-gray-700">₱</span>
</div>
<input class="shadow appearance-none border rounded w-full py-2 pl-8 pr-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="basic_pay" id="basic_pay" type="number" step="any" placeholder="00.00" tabindex="5" v-model="employee.basic_pay" />
<div class="absolute inset-y-0 right-0 flex items-center"><label for="basic_pay" class="sr-only">Basic Pay</label>
</div>
</div>
</div>
<div class="md:w-3/6 mb-4 flex-1"> </div>
</div>
<button type="submit" class="sm:hidden md:flex bg-blue-500 hover:bg-blue-400 text-white font-bold py-2 px-4 border-b-4 border-blue-700 hover:border-blue-500 rounded outline-none focus:outline-none">Update</button>
</form>
</template>
I've managed to solve this by retrieving each field, instead of the previous code which I retrieved all in a single object.
this.axios
.get(`/api/designations/${this.$route.params.id}`)
.then((res) => {
this.form.name = res.data.name;
this.form.description = res.data.description;
});
Before:
this.axios
.get(`/api/designations/${this.$route.params.id}`)
.then((res) => {
this.form= res.data;
});

How can I create an array of id's from the selected option in vue-multiselect plugin?

I've created an Laravel Vue SPA app. Right now, I can successfully retrieved the data in object format and can display the names in vue-multiselect (https://vue-multiselect.js.org/) when selected. Also, I can already save the selected options to the database in an object format. My question is how can I save only the id's in an array?
This is the results from api:
[
{
"id": 1,
"name": "Shoe Machine Operators",
"description": "Iusto cupiditate quo veniam.",
"created_at": "2022-03-23T10:23:35.000000Z",
"updated_at": "2022-03-23T10:23:35.000000Z"
},
{
"id": 2,
"name": "Librarian",
"description": "Vero eius quidem quo fugiat.",
"created_at": "2022-03-23T10:23:35.000000Z",
"updated_at": "2022-03-23T10:23:35.000000Z"
}
]
Here's my markup code where my vue-multiselect element is:
<form #submit.prevent="addEmployee">
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="name">First Name</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="name" id="name" type="text" placeholder="First Name" tabindex="1" v-model="employee.first_name" />
</div>
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="name">Last Name</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="name" id="name" type="text" placeholder="Last Name" tabindex="2" v-model="employee.last_name" />
</div>
</div>
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="designation_id">Designation</label>
<multiselect v-model="employee.designation_id"
:options="designation_options"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:preserve-search="true"
placeholder="Pick one or many"
label="name"
track-by="name"
:preselect-first="true"
>
<template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">{{ values.length }} options selected</span></template>
</multiselect>
<pre class="language-json"><code>{{ employee.designation_id }}</code></pre>
</div>
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="position_id">Position</label>
<multiselect v-model="employee.position_id"
:options="position_options"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:preserve-search="true"
placeholder="Pick one or many"
label="name"
track-by="name"
:preselect-first="true"
>
<template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">{{ values.length }} options selected</span></template>
</multiselect>
<pre class="language-json"><code>{{ employee.position_id }}</code></pre>
</div>
</div>
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="basic_pay">Basic Pay</label>
<div class="relative rounded">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<span class="text-gray-700">₱</span>
</div>
<input class="shadow appearance-none border rounded w-full py-2 pl-8 pr-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="basic_pay" id="basic_pay" type="number" step="any" placeholder="00.00" tabindex="5" v-model="employee.basic_pay" />
<div class="absolute inset-y-0 right-0 flex items-center"><label for="basic_pay" class="sr-only">Basic Pay</label>
</div>
</div>
</div>
<div class="md:w-3/6 mb-4 flex-1"> </div>
</div>
<button type="submit" class="sm:hidden md:flex bg-blue-500 hover:bg-blue-400 text-white font-bold py-2 px-4 border-b-4 border-blue-700 hover:border-blue-500 rounded outline-none focus:outline-none">Create</button>
</form>
Here's my script:
<script>
export default {
data() {
return {
employee: {},
designation_id: [],
designation_options: [],
}
},
methods: {
addEmployee() {
this.axios.post('/api/employees', this.employee).then(response => (this.$router.push({
name: 'employees'
}))).catch(err => console.log(err)).finally(() => this.loading = false)
},
getDesignationNames() {
this.axios.get('/api/designation').then((res) => {
this.designation_options = res.data;
}).catch(err => console.log(err))
},
},
created: function() {
this.getDesignationNames();
},
}
</script>
Any help is much appreciated.
I tried getting only the id using .map() function but it caused the vue-multiselect to not show the names and return only the first clicked result in an id format.
getDesignationNames() {
this.axios.get('/api/designation').then((res) => {
this.designation_options = res.data.map((a) => {
return a.id;
});
}).catch(err => console.log(err))
},
Use v-model.
Define v-model binding as an array.
Check this example
<script setup>
import { ref } from 'vue'
const data = ref([{id:1,name:"first"},{id:2,name:"second"},{id:3,name:"third"},{id:4,name:"forth"},{id:5,name:"fifth"}])
const selected = ref(["2","4"])
</script>
<template>
<select v-model="selected" multiple>
<option v-for="item in data" :value="item.id">{{item.name}}</option>
</select>
<div>Selected: {{selected}}</div>
</template>

How do you use confirm dialogues in a custom Laravel Nova tool?

Is it possible to use the built in Laravel Nova confirm dialogue in your own tool? All I would like to use is interact with it how Nova does itself.
The docs are quite light on the JS topic, as the only built in UI you seem to be able to work with is the toasted plugin: https://nova.laravel.com/docs/1.0/customization/frontend.html#javascript
You can use <modal> component whenever you want.
Here is how it work internally in Nova:
<template>
<modal
data-testid="confirm-action-modal"
tabindex="-1"
role="dialog"
#modal-close="handleClose"
class-whitelist="flatpickr-calendar"
>
<form
autocomplete="off"
#keydown="handleKeydown"
#submit.prevent.stop="handleConfirm"
class="bg-white rounded-lg shadow-lg overflow-hidden"
:class="{
'w-action-fields': action.fields.length > 0,
'w-action': action.fields.length == 0,
}"
>
<div>
<heading :level="2" class="border-b border-40 py-8 px-8">{{ action.name }}</heading>
<p v-if="action.fields.length == 0" class="text-80 px-8 my-8">
{{ __('Are you sure you want to run this action?') }}
</p>
<div v-else>
<!-- Validation Errors -->
<validation-errors :errors="errors" />
<!-- Action Fields -->
<div class="action" v-for="field in action.fields" :key="field.attribute">
<component
:is="'form-' + field.component"
:errors="errors"
:resource-name="resourceName"
:field="field"
/>
</div>
</div>
</div>
<div class="bg-30 px-6 py-3 flex">
<div class="flex items-center ml-auto">
<button
dusk="cancel-action-button"
type="button"
#click.prevent="handleClose"
class="btn text-80 font-normal h-9 px-3 mr-3 btn-link"
>
{{ __('Cancel') }}
</button>
<button
ref="runButton"
dusk="confirm-action-button"
:disabled="working"
type="submit"
class="btn btn-default"
:class="{
'btn-primary': !action.destructive,
'btn-danger': action.destructive,
}"
>
<loader v-if="working" width="30"></loader>
<span v-else>{{ __('Run Action') }}</span>
</button>
</div>
</div>
</form>
</modal>
</template>
<script>
export default {
props: {
working: Boolean,
resourceName: { type: String, required: true },
action: { type: Object, required: true },
selectedResources: { type: [Array, String], required: true },
errors: { type: Object, required: true },
},
/**
* Mount the component.
*/
mounted() {
// If the modal has inputs, let's highlight the first one, otherwise
// let's highlight the submit button
if (document.querySelectorAll('.modal input').length) {
document.querySelectorAll('.modal input')[0].focus()
} else {
this.$refs.runButton.focus()
}
},
methods: {
/**
* Stop propogation of input events unless it's for an escape or enter keypress
*/
handleKeydown(e) {
if (['Escape', 'Enter'].indexOf(e.key) !== -1) {
return
}
e.stopPropagation()
},
/**
* Execute the selected action.
*/
handleConfirm() {
this.$emit('confirm')
},
/**
* Close the modal.
*/
handleClose() {
this.$emit('close')
},
},
}
</script>
Here is simplified example:
<modal>
<form
autocomplete="off"
class="bg-white rounded-lg shadow-lg overflow-hidden"
>
<div>
<heading :level="2" class="border-b border-40 py-8 px-8">test</heading>
test
</div>
<div class="bg-30 px-6 py-3 flex">
<div class="flex items-center ml-auto">
<button
type="button"
class="btn text-80 font-normal h-9 px-3 mr-3 btn-link"
>
{{ __('Cancel') }}
</button>
<button
ref="runButton"
type="submit"
class="btn-danger"
>
<span>{{ __('Run Action') }}</span>
</button>
</div>
</div>
</form>
</modal>
You need to create a new component in the same folder of Tool.vue
I'll attach the component I used here
Then in the "handleConfirm" method, you can add a Ajax call to API
You can add you logic in that API.
You can find the API file in path, ToolName/routes/api.php
/* CustomModal.vue */
<template>
<modal tabindex="-1" role="dialog" #modal-close="handleClose">
<form #keydown="handleKeydown" #submit.prevent.stop="handleConfirm" class="bg-white rounded-lg shadow-lg overflow-hidden w-action">
<div>
<heading :level="2" class="border-b border-40 py-8 px-8">Confirm action</heading>
<p class="text-80 px-8 my-8"> Are you sure you want to perform this action? </p>
</div>
<div class="bg-30 px-6 py-3 flex">
<div class="flex items-center ml-auto">
<button type="button" #click.prevent="handleClose" class="btn btn-link dim cursor-pointer text-80 ml-auto mr-6">
Cancel
</button>
<button :disabled="working" type="submit" class="btn btn-default btn-primary">
<loader v-if="working" width="30"></loader>
<span v-else>Confirm</span>
</button>
</div>
</div>
</form>
</modal>
</template>
<script>
export default {
methods: {
handleConfirm() {
// Here you can add an ajax call to API and you can add your logic there.
},
handleClose() {
// Logic to hide the component
},
},
}
</script>
For more detailed explanation : https://medium.com/vineeth-vijayan/how-to-use-confirm-dialogs-in-a-laravel-nova-tool-b16424ffee87

Resources