Query relationship with v-autocomplete in Vuetify [ Laravel ] - laravel

I use dropdown v-autocomplete in Vuetify and i want to query relationship from laravel. When select in input field in v-autocomplete, its work well, its show name that i want to query, but when i selected on it, it show to default value.
Here my Vuetify
<template>
<v-autocomplete
:items="purchases"
dense
solo
v-model="model"
item-text="name"
item-value="name"
return-object
clearable
#input="addTocart"
>
<template v-slot:item="{ item }">
{{ item.product.name }}
</template>
</v-autocomplete>
</template>
In my script
<script>
export default {
name: 'Add Purchase',
created() {
this.fetchPurchase()
},
data() {
return {
products: [],
purchases: [],
model: [],
items: [],
purchase_status: ['Received', 'Partial', 'Pending', 'Ordered'],
discount: 0.00,
tax: 0.00,
shipping_cost: 0.00,
}
},
computed: {
total() {
return this.products.reduce((total, item) => {
return total + item.unit;
}, 0);
}
},
methods: {
fetchPurchase() {
this.$axios.$get(`api/purchase`)
.then(res => {
this.purchases = res.data;
console.log(res);
})
.catch(err => {
console.log(err)
})
},
addTocart (item) {
if(this.items.includes(item)) {
alert("already there");
}else {
this.items.push(item);
}
item.unit = 1;
},
removeItem(index) {
this.items.splice(index, 1)
},
}
}
</script>
Is there a way that i can archieve this? Thanks in advance..

Related

Laravel vue js Opening video in modal onClick not working

So what i'm trying to do is pretty simple but for some reason is not working please let me show you.
This is my navigation bar written in vue js and here i'm holding almost all my vue components.
Navigation.vue
<template>
<single-video :user_id="user_id" :video="this.video" :videoUser="this.videoUser"
:videoOptions="videoOptions"></single-video>
</template>
<script>
export default {
name: "Navigation",
data: function () {
return {
user_id: user_id,
// isLogin: isLogin,
video: {},
videoUser: {},
videoOptions: {
autoplay: true,
controls: true,
sources: [
{
src: "",
type: "application/x-mpegURL"
}
]
}
}
},
methods: {
openVideoModal(video){
this.videoOptions.sources[0].src = 'storage/videos/' + video.id + '/' + video.id + '.m3u8';
axios.get('video/' + video.channel_id).then(response => {
this.videoUser = response.data;
}).catch(error => {
if (error.response.status == 422) {
this.errors = error.response.data.errors;
}
console.log('Error');
});
this.video = video;
$('#singleVideo').modal('show');
},
},
}
</script>
In one of my child component i have this method which calling openVideoModal() function in navigation. With the video id. So far it's working.
<a #click="$parent.openVideoModal(video)">
This one is my single video component which display the video itself.And is in modal ("singleVideo" modal)
single-video.vue
<video v-if="this.video"
ref="videoPlayer"
id="my-video"
class="video-js vjs-default-skin vjs-big-play-centered"
controls
preload="auto"
width="749"
height="421"
:poster="this.video.thumbnail"
data-setup="{}">
</video>
<script>
import videojs from 'video.js';
export default {
props: ['user_id', 'video', 'videoUser', 'videoOptions'],
data: function () {
return {
errors: {},
singleVideo: {},
player: null
}
},
mounted() {
if(this.videoOptions.sources[0].src) {
this.player = videojs(this.$refs.videoPlayer, this.videoOptions, function onPlayerReady() {
})
}
},
methods: {
beforeDestroy() {
if (this.player) {
this.player.dispose()
}
}
}
</script>
Please don't delete my question it is very important to me to solve this. I'm going nuts over it. :(

How to pass data from a child component to the parent component using Laravel and Vue

I am using Vue.js 2 and Laravel 7.
I want to pass some errors from the child component to the parent controller. But for some reasons emit did not work.
This is the method of the child component AllocateTask:
methods: {
assignTask: function() {
this.form.task_id = this.user.tasks;
this.form.user_id = this.dev.id;
alert(this.form.task_id);
alert(this.form.user_id);
axios.post('/ticketsapp/public/api/store_task_user', this.form)
.then((response) => {
console.log(response.data);
alert('ok');
this.errors = response.data;
alert(Object.keys(this.errors).length);
if (Object.keys(this.errors).length === 0) {
alert('viva');
} else {
alert('noviva');
this.$emit('failure');
this.$emit('pass-errors', this.errors);
}
})
.catch(error => {
alert('no ok');
console.log(error);
});
}
}
This is the parent component TheReporterTickets:
<template>
<div>
<allocate-task :dev="dev" :tasks="tasks" #pass-errors="onPassErrors" #failure="displayErrors=true" #success="displaySuccess=true"></allocate-task>
<hr>
<validated-errors :errorsForm="errorsTicket" v-if="displayErrors===true"></validated-errors>
</div> </template>
<script>
import AllocateTask from "./AllocateTask.vue"
import ValidatedErrors from "./ValidatedErrors.vue"
export default {
components: {
'allocate-task': AllocateTask,
'validated-errors': ValidatedErrors
},
props: {
dev: {
type: Array,
required: true,
default: () => [],
},
tasks: {
type: Array,
required: true,
default: () => [],
}
},
mounted() {
console.log('Component mounted.');
},
data: function() {
return {
displayErrors: false,
errorsTicket: []
}
},
methods: {
onPassErrors(value) {
alert('error');
console.log('errors passed');
const values = Object.values(value);
this.errorsTicket = values;
console.log(this.errorsTicket);
}
}
} </script>
As you can imagine, I am unable to call the method onPassErrors located in the parent component. I visualize correctly the alert in the else statement of the child component, so I suppose that I am unable to pass the data from the child to the parent component.
Can help?

Inline Editor - disable editor and display HTML / render content (Vue)

I am using CKEditor5 with Vue. In my Vuex store, I have the following property:
const state = {
EditMode: false,
}
On a button click by a user with permission, I modify the Vuex store. If EditMode: true, I want to display the in-line editor. Else, display the raw HTML editorData (the user is not authorized to edit, or not in edit mode). I do that below:
<template>
<vx-card :title="editorName" v-if="this.$store.state.EditMode">
<ckeditor :editor="editor" v-model="editorData" :config="editorConfig"></ckeditor>
</vx-card>
<vx-card :title="editorName" v-else>
<div v-html="editorData"></div>
</vx-card>
</template>
<script>
import InlineEditor from '#ckeditor/ckeditor5-build-inline'
export default {
name: "RichTextEditor",
props: {
editorName: {
type: String,
required: true,
},
},
data() {
return {
loaded: false,
time: null,
timeElapsedSinceEdit: 0,
editor: InlineEditor,
editorData: 'New entry!',
editorConfig: {
toolbar: {
items: [
'|',
'heading',
'fontFamily',
'fontSize',
'fontColor',
'bold',
'underline',
'italic',
'alignment',
'link',
'highlight',
'superscript',
'subscript',
'|',
'indent',
'outdent',
'|',
'blockQuote',
'horizontalLine',
'imageUpload',
'insertTable',
'mediaEmbed',
'undo',
'redo'
]
},
language: 'en',
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:full',
'imageStyle:side'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells',
'tableCellProperties',
'tableProperties'
]
},
},
}
},
// Below code is situation-specific and not completely relevant
watch: {
editorData: function() {
if (this.loaded) {
this.upsertData()
}
}
},
methods: {
async pollData() {
await
this.$http.get('/api/rte/' + this.editorName)
.then((response) => {
this.editorData = response.data.content
})
.catch((error) => {
if (window.environment == "production") {
location.href = 'pages/error-500/'
} else {
console.log(error.stack)
}
})
this.loaded = true;
},
async upsertData() {
console.log('up')
await
this.$http.post('/api/rte/' + this.editorName + '/upsert', {
data: this.editorData,
})
.then((response) => {
this.$vs.notify({
title: 'Action Completed',
text: response.data.message,
color: 'success',
position: 'top-right'})
})
.catch((error) => {
if (window.environment == "production") {
location.href = 'pages/error-500/'
} else {
console.log(error)
}
})
},
},
created() {
this.pollData();
},
}
</script>
This works, but the in-line styling isn't respected with v-html (sizing and centering). If this.$store.state.EditMode: false, I get the following output:
If this.$store.state.EditMode: true I get this in the in-line editor (as expected).
Raw HTML (editorData property after pollData() is called)
<figure class="image image_resized" style="width:25.51%;"><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcTRJO0xRohucbxcjlRoiRaw2cWYTbilYch5NQ&usqp=CAU" alt="Free clipart megaphone announcement public domain vectors - Clipartix"></figure><h2 style="text-align:center;"><span style="color:hsl(30,75%,60%);"><strong>We have a new Intranet!</strong></span></h2><p style="text-align:center;">Summer / Fall Wellness Challenge Link</p>
Research showed that Vue's v-html doesn't respect scoped styling. I'm not entirely sure how that applies to in-line styling. To test output, I replaced my else with the raw HTML and got the same visual output as when I used v-html:
<vx-card :title="editorName" v-else>
<figure class="image image_resized" style="width:25.51%;"><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcTRJO0xRohucbxcjlRoiRaw2cWYTbilYch5NQ&usqp=CAU" alt="Free clipart megaphone announcement public domain vectors - Clipartix"></figure><h2 style="text-align:center;"><span style="color:hsl(30,75%,60%);"><strong>We have a new Intranet!</strong></span></h2><p style="text-align:center;">Summer / Fall Wellness Challenge Link</p>
</vx-card>
What is the proper way to disable the inline editor and maintain visual consistency?
<template>
<vx-card :title="editorName" v-if="loaded">
<ckeditor :editor="editor" v-model="editorData" :config="editorConfig" :readonly="editorDisabled" :disabled="editorDisabled" ></ckeditor>
</vx-card>
</template>
//...
watch:{
'$store.state.EditMode'(value, oldValue) {
if(value) {
this.editorDisabled = false;
} else {
this.editorDisabled = true;
}
},
},
//...
Question answered here:
https://github.com/ckeditor/ckeditor5-vue/issues/154

Property not defined error But it is defined Vue js Laravel

I have defined the function in my vue js file but it is giving me error for nameWithLang() function Please have a look
My Form
<multiselect v-model="selected" track-by="id" label="name" :options="options" :loading="isLoading" :internal-search="false" #search-change="getData" :multiple="true" :close-on-select="false" :hide-selected="true":internal-search="false" name="books[]" :show-labels="false" :custom-label="nameWithLang"></multiselect>
My vue js file
import AppForm from '../app-components/Form/AppForm';
Vue.component('coupon-form', {
mixins: [AppForm],
data: function() {
return {
form: {
name: '' ,
description: '' ,
valid_from: '' ,
valid_till: '' ,
discount: '' ,
enabled: false,
books: [],
},
isLoading: false,
options: [],
selected: [],
}
},
methods: {
nameWithLang({ name, sku }) {
return `${name} — ${sku}`
},
getData(query){
this.isLoading = true;
axios.post('/admin/books/find/'+query)
.then((response) => {
this.options = response.data;
this.isLoading = false;
})
.catch((error) => {
this.isLoading = false;
});
},
},
watch: {
selected (newValues) {
this.form.books = newValues.map(obj => obj.id)
}
}
});
Other properties and functions are working nameWithLang is not working
It gives me error this
Property or method "nameWithLang" is not defined on the instance but referenced during render.
why not you just return the value into a variable in data, and set the function into mounted/watch instead using the function to get the value.
just for refer, you can make the script like this :
import AppForm from '../app-components/Form/AppForm';
Vue.component('coupon-form', {
mixins: [AppForm],
data: function() {
return {
form: {
name: '' ,
description: '' ,
valid_from: '' ,
valid_till: '' ,
discount: '' ,
enabled: false,
books: [],
},
isLoading: false,
options: [],
selected: [],
newName: '',
}
},
methods: {
nameWithLang({ name, sku }) {
this.newName = `${name} — ${sku}`;
},
getData(query){
this.isLoading = true;
axios.post('/admin/books/find/'+query)
.then((response) => {
this.options = response.data;
this.isLoading = false;
})
.catch((error) => {
this.isLoading = false;
});
},
},
watch: {
selected (newValues) {
this.form.books = newValues.map(obj => obj.id)
this.nameWithLang();
}
}
});
then you can make the template like this:
<multiselect v-model="selected" track-by="id" label="name" :options="options" :loading="isLoading" :internal-search="false" #search-change="getData" :multiple="true" :close-on-select="false" :hide-selected="true":internal-search="false" name="books[]" :show-labels="false" :custom-label="newName"></multiselect>
this is just another way you can make it and the way i'm understand what actually you want to do. you want to pass the name with lang value into the :custom-label right? so why not just defined one more variable and add the value into the variable. so you just need to pass the value instead the function. in v-bind it's more appropiate to pass a property instead of a method

Vue: event emitted is not getting picked up

I am able to pick up fire emitgetcartitems but for some reason the other listener, emitaddnotes, is not firing handleAddNotes(). I checked in context of the component as well by checking this.$listeners and I only saw emitgetcartitems listed for it. I'm not sure why the other event is not working at all.
blade template
<div id = "app">
<Modal
:modal-type="modalType"
:selected-product="selectedProduct"
:variant-data="variantData"
#emitgetcartitems="handleGetCartItems"
#emitaddnotes="handleAddNotes"
>
</Modal>
<Cart>
</Cart>
</div>
app.js
window.Vue = require('vue');
window.axios = require('axios');
Vue.component('Modal',
require('./components/Modal.vue').default);
new Vue({
el: "#app",
data() {
return {
modalType: null,
orderNotes: null,
couponCode: null,
selectedProduct: {},
variantData: [],
cart: {}
}
},
methods: {
handleChangeTab: function(tab) {
this.activeTab = tab
},
handleHideFlashMsg: function() {
this.flashStatus = false
},
handleAddNotes: function(){
console.log("!!!!!!!")
},
handleGetCartItems: function() {
axios
.get('/api/a-cart')
.then(response => {
this.cart = response.cart;
});
},
}
)}
Modal.vue
<template>
<div>
<button v-on:click="addNotes()"></button>
</div>
</template>
<script>
export default {
data() {
return {
couponInput: '',
}
},
props: {
selectedProduct: {type: Object},
orderNotes: {type: String},
couponCode: {type: String}
},
methods: {
getCartItems: function() {
console.log("GET CART")
this.$emit('emitgetcartitems')
},
addNotes: function() {
console.log("ADD NOTES")
this.$emit('emitaddnotes')
},
}
}
</script>

Resources