Update Global Component data - laravel

I am updating this with my new code. I need to get a reference to the "allImages" property of the data object within the dropzones "onSuccess" method. Is there any way to do it.
<template>
<div class="container">
<div class="row">
<form action="/user/album_images" id="dropzone" class="dropzone" method="post">
<input type="hidden" id="album_id" name="album_id" :value=image.id>
</form>
</div>
<div class="row">
<div class="col-md-3" v-for="image in albumImages">
<img src="https://mysite.nyc3.digitaloceanspaces.com/users/62MY43og3ZNCLU4y53iwoqdEfUZUWFEfDM2f9krn.png" class="img-responsive" style="width: 120px; height: 90px;">
</div>
</div>
</div>
</template>
<script>
export default {
props: ['theImage','theAlbumImages'],
data() {
return {
image: this.theImage,
albumImages: this.theAlbumImages
}
},
methods: {
},
}
let csrfToken = document.querySelectorAll('meta[name=csrf-token]')[0].getAttributeNode('content').value
Dropzone.options.dropzone = {
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 10, // MB
acceptedFiles: "image/*",
addRemoveLinks: true,
init: function() {
this.on("success", function(file,albumImage) {
// I want to get a reference to the vue instances "albumImages" property
});
},
headers: {
'x-csrf-token': csrfToken
}
};
</script>

You can try to use vue-script2
You will be able to access vue variables like in template.
<script2>
....
this.on("success", function(file,albumImage) {
var x = {{albumImages}}
});
....
</script2>
Although it might not work. Other option would be to try load function in mounted. E.g.
import VS2 from 'vue-script2'
export default {
name: 'freshchat',
mounted() {
VS2.load('yourdropzonejs script').then(() => {
var vm = this
.....
this.on("success", function(file,albumImage) {
vm.albumImages
});
})
}
}

Related

How get quill and other form to JS submit function?

I wanna use quill rich editor and other fields on my form. But cant get access to quill innerHTML from JS function. I am using Laravel with Alpinejs and my code is
<form x-data="contactForm()" #submit.prevent="submit">
<div class="col-12">
<div class="mt-2 w-100 bg-white" wire:ignore>
<div
x-data
x-ref="quillEditor"
x-init="
quill = new Quill($refs.quillEditor, {
theme: 'snow',
modules: {toolbar: '#toolbar'}
});
quill.on('text-change', function () {
$dispatch('input', quill.root.innerHTML);
});"
wire:model.debounce.2000ms="description"
class="sign__textarea"
style="height: 300px;"
>{{ old('description', $services_users->description) }}
</div>
</div>
</div>
<div class="col-12">
<input name="message" x-model="data.title">
</div>
<div class="col-12 col-xl-3 mt-5">
<button type="submit" x-text="buttonText" :disabled="loading"></button>
</div>
</form>
<script>
function contactForm() {
return {
data: {
title: "",
myQuill: quill.root.innerHTML,
},
buttonText: "Save",
loading: false,
submit() {
this.buttonText = "Saving...";
this.loading = true;
fetch('myurl.endpoint', {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
body: JSON.stringify(this.data),
}).then(() => {
alert("Form submitted");
}).catch(() => {
alert("Something went wrong");
}).finally(() => {
this.data.title = ""
this.buttonText = "Save";
this.loading = false;
});
},
};
}
</scirpt>
Now i have an error Can't find variable: quill how can i get all fields from form and send to backend event if quill is not a form field?
It doesn't work because you're calling the variable "quill" in the parent and you're declaring it in the child. To fix it declare the x-init directive in the form.
listening to the "text-change" event is not necessary. A good option is to add the content of the container before submitting the form.
see : https://alpinejs.dev/directives/data#scope
<form x-data="contactForm()" x-init="
quill = new Quill($refs.quillEditor, {
theme: 'snow'
});
quill.on('text-change', function () {
$dispatch('input', quill.root.innerHTML);
});" #submit.prevent="submit">
<div class="col-12">
<div class="mt-2 w-100 bg-white" wire:ignore>
<div
x-ref="quillEditor"
wire:model.debounce.2000ms="description"
class="sign__textarea"
style="height: 300px;"
>{{ old('description', $services_users->description) }}
</div>
</div>
</div>
<div class="col-12">
<input name="message" x-model="data.title">
</div>
<div class="col-12 col-xl-3 mt-5">
<button type="submit" x-text="buttonText" :disabled="loading"></button>
</div>
</form>
<script>
function contactForm() {
return {
quill:null,
data: {
title: "",
// myQuill: function(){ return this.quill.root.innerHTML}
},
buttonText: "Save",
loading: false,
submit() {
this.buttonText = "Saving...";
//add content quill here
this.data.myQuill = this.quill.root.innerHTML;
this.loading = true;
fetch('myurl.endpoint', {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
body: JSON.stringify(this.data),
}).then(() => {
alert("Form submitted");
}).catch(() => {
alert("Something went wrong");
}).finally(() => {
this.data.title = ""
this.buttonText = "Save";
this.loading = false;
});
},
};
}
</script>
Ok this is what i did
<form x-data="contactForm()" x-init="initQuill()" x-on:submit="submit()" method="POST" action="target.url">
<div x-ref="editor"></div>
<input x-ref="editorValue" type="hidden" name="hidden_input">
<button>Save</button>
</form>
<script>
function contactForm(){
return {
initQuill(){
new Quill(this.$refs. editor, {theme: 'snow'});
},
submit(){
console.log(this.$refs. editor.__quill.root.innerHTML);
this.$refs.editorValue.value = this.$refs.editor.__quill.root.innerHTML;
}
}
}
</script>
Now is ok and works with basic. You can extend function with new features etc. Thx for help guys.

I don't know why this error comes inside Laravel?

I have made this code, I want to facilitate user to dynamically enter text and display fields which have values, but I'm unable to get the result when I run it laravel+VueJs component view. below is my code
<template>
<div>
<div>
<label>Name</label>
<input type="text" #change="addRow">
</div>
<div> <label>Email</label>
<input type="text" #change="addRow1">
</div>
<div v-for="row in rows" :key="row.id">
<button-counter :id="row.id" :value="row.value"></button-counter>
</div>
</div>
<script type="text/javascript">
Vue.component('button-counter', {
props: {
value: {
default: ''
}
},
template: '<input type="text" style="margin-top: 10px;" v-model="value" >',
})
export default {
mounted() {
console.log('Component mounted.')
},
data: {
rows: [],
count:0
},
methods: {
addRow: function () {
var txtCount=1;
id='txt_'+txtCount;
this.rows.push({ value:'MyName' , description: "textbox1", id });
},
addRow1: function () {
var txtCount=1;
id='txt2_'+txtCount;
this.rows.push({ value: "myEmail", description: "textbox2", id });
}
}
}
data should be a function that returns an object holding data you want to manipulate, and you need to define the id as a variable, here's a working Vue SFC
<template>
<div>
<div>
<label>Name</label>
<input type="text" #change="addRow" />
</div>
<div>
<label>Email</label>
<input type="text" #change="addRow1" />
</div>
<div v-for="row in rows" :key="row.id">
<button-counter :id="row.id" :value="row.value"></button-counter>
</div>
</div>
</template>
<script type="text/javascript">
Vue.component("button-counter", {
props: {
value: {
default: ""
}
},
template: '<input type="text" style="margin-top: 10px;" v-model="value" >'
});
export default {
data() {
return {
rows: [],
count: 0
};
},
methods: {
addRow: function() {
var txtCount = ++this.count;
let id = "txt_" + txtCount;
this.rows.push({ value: "MyName", description: "textbox1", id });
},
addRow1: function() {
var txtCount = ++this.count;
let id = "txt2_" + txtCount;
this.rows.push({ value: "myEmail", description: "textbox2", id });
}
}
};
</script>
Hope this helps

Property or method not defined on instance

I'm trying to create a watcher to bind the value from an input run it through a method and display that value on the page. Its a fairly straightforward sample of code I'm working with but I believe I have a scoping issue but I don't see anything wrong.
I tried changing a few things such as the convertTitle function scoping. e.g. But I got the same error
convertTitle() {
return Slug(this.title)
}
My Vue Component -
<template>
<div class="slug-widget">
<span class="root-url">{{url}}</span>
<span class="slug" v-if="slug !== nil">{{slug}}</span>
</div>
</template>
<script>
export default {
props: {
url: {
type: String,
required: true
},
title: {
type: String,
required: true
}
},
data: function() {
return {
slug: this.convertTitle()
}
},
methods: {
convertTitle: function() {
return Slug(this.title)
}
},
watch: {
title: function(val) {
this.slug = this.convertTitle();
}
}
}
</script>
My Blade Partial with input -
#extends('admin.admin')
#section('content')
<div class="row">
<div class="col-md-9">
<div class="row">
<h1>Create new page</h1>
</div>
<div class="row">
<div class="pcard">
<form action="" method="POST" class="">
{{ csrf_field() }}
<label>Title</label>
<input type="text" name="page-title" placeholder="" v-model="title">
<slug-widget url="{{url('/')}}" :title="title"></slug-widget>
</form>
</div>
</div>
</div>
</div>
#endsection
#section('scripts')
<script>
var app = new Vue({
el: '#app',
data: {
title: ''
}
});
</script>
#endsection
Full error Trace -
[Vue warn]: Property or method "title" 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>)
Updated with compute -
export default {
props: {
url: {
type: String,
required: true
},
title: {
type: String,
required: true
}
},
computed: {
slug() {
return Slug(this.title)
}
}
}
The error was resolved by removing the following snippet from app.js
const app = new Vue({
el: '#app'
});
You shouldn't have, and shouldn't ever need, a function call to supply the value of something in your data.
It sounds like you just need to put convertTitle() into a computed and away you go?

Vue Object is Empty

I'm using Vuejs to display data from an API to a template. I'm trying to figure out why I am not returning data for the team so I can display in for the template. Right now when I use the VueJS Chrome Extention it shows that the team is an empty object.
<div v-if="team">
<div class="row">
<div class="col-12 col-sm-12">
<div class="fw-700 pb3 mb5" style="border-bottom: 1px solid #333;">Name:</div>
<div class="mb10" style="font-size: 20px;">{{ team.name }}</div>
</div>
</div>
<script>
module.exports = {
http: {
headers: {
'X-CSRF-TOKEN': window.Laravel.csrfToken
}
},
props: [ 'id', 'editable' ],
data: function(){
return {
modalName: 'additionalInfo',
team:{
}
}
};
},
methods: {
fetchInfo: function(){
this.$http.get('/api/teams/info', { params: { id: this.id } }).then((response) => {
this.team = response.data;
});
},
},
}
}
</script>
It is empty because your method fetchInfo isn't being called, so you need to do something like this:
created () {
this.fetchInfo()
}
This will call the function fetchInfo which in turn will fetch and fill this.team

Parsing dynamically loaded directives in Vue

I have a Vue component that makes a post request, and then outputs the returned html.
Sometimes, the html that is returned by the post contains Vue directives.
Is there a way to have Vue parse the returned html before it is output?
(In the longer term, I will rewrite this as a pure Vue solution, with the post request returning data rather than html. I'm after a short term solution if its possible).
EDIT:
Here's my stab based on thanksd's suggestion but I'm not sure how to bind the new Vue instance to an html element.
<template>
<div>
<input type="text" class="form-control" v-model="value" #change="getResults" ></input>
<div>
<template v-bind="results"></template>
</div>
</div>
</template>
<script>
import{eventHub} from '../utils/event.js'
export default {
data : function(){
return {
value : '',
results : {}
}
},
methods:{
getResults(){
if(this.value.length < 3){return;}
this.$http.post('/ajax/search',{search:this.value}).then((response)=>{
this.results = Vue({template:response.body});
});
},
},
}
After the post request returns you could create a new Vue instance, passing the html as the template and binding it to an element in your current Vue instance's template:
<template>
<div>
<input type="text" class="form-control" v-model="value" #change="getResults" ></input>
<div>
<div id="results"></div>
</div>
</div>
</template>
<script>
export default {
data() {
return { value: '' }
},
methods: {
getResults() {
if (this.value.length < 3) {
return;
}
this.$http.post('/ajax/search', { search: this.value }).then((response) => {
new Vue({ el: '#results', template: response.body });
});
}
}
}
</script>
Or as #Bert pointed out, you could add a <component> tag to your template and pass its definition via the is prop:
<template>
<div>
<input type="text" class="form-control" v-model="value" #change="getResults" ></input>
<component :is="results"/>
</div>
</template>
<script>
export default {
data() {
return {
value: '',
results: null
}
},
methods: {
getResults() {
if (this.value.length < 3) {
return;
}
this.$http.post('/ajax/search', { search: this.value }).then((response) => {
this.results = { template: response.body };
});
}
}
}
</script>

Resources