Laravel vuejs get inital value - javascript

I want to autofill my input value with the value of my server, this works if I do not use vue, but since I use vue for other reasons it does not.
Vue overrides the value with an empty string how can my vue take that value and update it in my axios post.
<input type="text" id="title" name="title" value="{{ $snippet->title }}" v-model="title">
new Vue({
el: '#snippet-form',
data: {
title: '',
},
methods: {
publishSnippet (e) {
var self = this;
axios.post('/snippets', {
title: this.title,
})
.then(function (response) {
console.log("success");
})
.catch(function (error) {
console.log(error);
})
},
},
});

You have to use use props which allows you to pass a value to the component. The thing is, you can't use it on Vue root instance. You need to use components.
In your resources/assets/js/components/, create a folder/file SnipperForm/SnippetForm.vue.
SnippetForm.vue, will be like:
<template>
<form>
<input type="text"
id="title"
name="title"
v-model="title">
<button #click.prevent="publishSnippet()">Submit</button>
</form>
</template>
<script>
export default {
props: {
snippetTitle: {
type: String,
default: ''
},
},
data: {
title: '',
},
mounted() {
this.title = this.snippetTitle;
},
methods: {
publishSnippet () {
axios.post('/snippets', {
title: this.title,
})
.then(function (response) {
console.log("success");
})
.catch(function (error) {
console.log(error);
})
},
},
}
</script>
And finally, in your app.js:
Vue.component('snippet-form', require('SnippetForm/SnippetForm.vue'));
And your, again, in your app.js, edit your Vue instance:
const app = new Vue({
el: '#app',
});
And in your blade view, use the SnippetForm.vue component like:
<snippet-form snippet-title="{{ $snippet->title }}"><snippet-form>

Related

How can I set a value input that uses the v-model? - Laravel

How can I set a value input that uses the v-model?
I Googled for this problem but not solved
I have an input like this:
<input type="text" name="customer_email" v-model="form.customer_email" id="email">
I need to set this input value to {{ auth()->user()->email }}
TRY THIS :)
data() {
return {
form: {
customer_email: "",
}
}
},methods:{
user(){
axios.get("api/profile").then(({data})=>{
(this.user = data)
this.form.customer_emeail = this.user.email
})
},
},created(){
this.user();
}
In your controller add this
public function profile()
{
return auth('api')->user();
}
then put this in your api.php
Route::get('profile','YourController#profile');
As you are using two way data binding v-model, you can simply set this value in the vue end.
let app = new Vue({
el:"#app",
data() {
return {
form: {
customer_email: "{{ auth()->user()->email }}",
......
......
}
}
},
......
......
});

Get value from emit in input field with Vue

I know this has a simple answer but I appear to be stuck. I have an upload image input in a form. Following several tutorials, I have successfully created the upload method. My issue is once the image is uploaded to Firestore storage I use this.$emit('imgurl', downloadURL)
My problem is I do not know how to get that value so when the user submits the form the url gets added to the database.
Parts of the code:
HTML:
<div class="field avatar">
<label for="avatar">Avatar</label>
<input type="file" name="imgurl" accept="image/*" #change="detectFiles($event.target.files)">
<div class="progress-bar green" :style="{ width: progressUpload + '%'}">{{ progressUpload }}%</div>
<img class="avatar" v-bind:src="this.downloadURL">
</div>
Methods:
detectFiles (fileList) {
Array.from(Array(fileList.length).keys()).map( x => {
this.upload(fileList[x])
})
},
upload (file) {
var storage = firebase.storage();
this.uploadTask = storage.ref('avatars/'+file.name).put(file);
}
Watch:
watch: {
uploadTask: function() {
this.uploadTask.on('state_changed', sp => {
this.progressUpload = Math.floor(sp.bytesTransferred / sp.totalBytes * 100)
},
null,
() => {
this.uploadTask.snapshot.ref.getDownloadURL().then(downloadURL => {
this.downloadURL = downloadURL
this.$emit('imgurl', downloadURL)
})
})
}
}
Add to the database:
db.collection('teams').add({
team_name: this.team_name,
team_id: this.team_id,
bio: this.bio,
url: this.imgurl,
}).then(() => {
this.$router.push({ name: 'Admin' })
}).catch(err => {
console.log(err)
})
You can pass a function as a prop to a child component, then call this function passing your downloadURL as argument.
Parent Component
HTML
<child passURL="getDownloadURL">
JS
data: {
return {
downloadURL: null
}
},
methods: {
getDownloadURL: function(url) {
this.downloadURL = url
}
}
Child Component
JS
props: ['passURL'],
Inside your watcher, you can call
this.passURL(downloadURL)
Instead of $emit.
I found the answer. I added a hidden input field
<input type="hidden" name="imgurl" v-model="imgurl">
and replaced the emit with this.imgurl = downloadURL

Pass JS object to component Vue.js

I am having trouble displaying product via product component.
First in my vue.js app, I load Products via ajax like so:
var app = new Vue({
el: '#app',
data: {
products: [] // will be loaded via Ajax
},
mounted: function () {
var self = this;
ajaxGetProducts(0, self); // ajax, to fetch products
},
methods: {
getProducts: function (event) {
let groupID = Number(document.getElementById("GroupSelect").value);
ajaxGetProducts(groupID, this);
}
}
});
//Ajax call to fetch Products
function ajaxGetProducts(groupID, self) {
$.ajax({
type: "POST",
url: "/Data/GetProducts",
data: { Id: groupID },
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
dataType: "json"
, success: function (response) {
self.products = response; // Loading products into the App instance
},
error: function (jqXHR, textStatus, errorThrown) {
self.products = [];
}
}).done(function () {
});
}
Then I display those produdcts, and it works just fine:
<!-- HTML -->
<div id="app">
<div v-for="prod in products" >{{prod.Id}}</div>
</div>
Question: if I want to use a component. How do I do that?
This is how my component looks so far:
Vue.component('product', {
props: [],
template: `<div>ProdID: {{product.Id}} {{product.Qty}}</div>`,
data() {
return {
Id: "test id"
}
}
})
Example Product object has following properties:
{
Id: 1,
Qty: 5,
Title: "Nike shoes",
Price: 200,
Color: "Green"
}
And eventually I would like to use it in HTML like so:
<!-- HTML -->
<div id="app">
<!-- need to pass prod object into product component -->
<div v-for="prod in products" >
<product></product>
</div>
</div>
I know that I have to pass the object via Component properties somehow?
Passing each property 1 by 1 is not a good idea, cause this product is subject to change, so property name can change, or be added more. I think there should be a way to pass a whole Product object to Product component somehow, right?
You can pass the information into your component via the props
something like this;
Vue.component('product', {
props: ['item'],
template: `<div>ProdID: {{item.Id}} {{item.Qty}}</div>`
})
and pass it on like this;
<div id="app">
<div v-for="prod in products" :key='prod.Id'>
<product :item='prod'></product>
</div>
</div>
What about passing it as
<product v-for="prod in products" :key="prod.Id" :product="prod"></product> and in the component: props: {product:{type: Object, required: true}}?
Then in the component template you can use things like {{product.Id}}

Vuejs not updating list but updating obect

I am learning Vuejs and I am stuck. Why can I see the messages get added to the object (in Chrome Vue debugger) yet it is not added to the div that contains the list?
My Vue Component:
<template>
<div id="round-status-message" class="round-status-message">
<div class="row">
<div class="col-xs-12" v-for="sysmessage in sysmessages" v-html="sysmessage.message"></div>
</div>
</div>
</template>
<script>
export default {
props: ['sysmessages'],
methods: {
scrollToTop () {
this.$el.scrollTop = 0
}
}
};
</script>
My Vue instance:
$(document).ready(function()
{
Vue.component('chat-system', require('../components/chat-system.vue'));
var chatSystem = new Vue({
el: '#system-chat',
data: function () {
return {
sysmessages: []
};
},
created() {
this.fetchMessages();
Echo.private(sys_channel)
.listen('SystemMessageSent', (e) => {
this.sysmessages.unshift({
sysmessage: e.message.message,
});
this.processMessage(e);
});
},
methods: {
fetchMessages() {
axios.get(sys_get_route)
.then(response => {
this.sysmessages = response.data;
});
},
processMessage(message) {
this.$nextTick(() => {
this.$refs.sysmessages.scrollToTop();
});
// updateGame();
}
}
});
});
My template call in HTML:
<div id="system-chat">
<chat-system ref="sysmessages" v-on:systemmessagesent="processMessage" :sysmessages="sysmessages" :player="{{ Auth::user() }}"></chat-system>
</div>
There are no compile or run time errors and I can see records added to the props in the vue chrome tool. I can also see empty HTML elements added to the div.
What have I missed?
UPDATE: My record structures:
response.data is an array of objects, each like this:
{"data":[
{"id":100,
"progress_id":5,
"message":"start message",
"action":"welcome"
},
{"id"....
e.message.message contains the text message entry, so just a string.
I am trying to access the message variable in each object during the fetchMessages method.
You're adding objects with sysmessage as the property.
this.sysmessages.unshift({
sysmessage: e.message.message,
});
But you are trying to view
v-for="sysmessage in sysmessages" v-html="sysmessage.message"
Based on your update, the code should be:
this.sysmessages.unshift({
message: e.message.message,
});
And you can leave the template as
v-html="sysmessage.message"

Passing Parent Function to Child Component in VueJS

I'm having my practice in VueJS 1.0 and I am learning about Components.
in this example, there is an input element and has to supply coupon or some kind of a code from an API. and I have to validate. I have my <coupon > component and has props of when-applied. The when-applied must call the parent function setCoupon but it won't.
I only got this error this.whenApplied is not a function.
<div id="demo" class="list-group">
<script id="coupon-template" type="x-template">
<input type="text" v-model="coupon" v-on:blur="whenCouponHasBeenEntered">
<div v-text="text"></div>
</script>
<coupon when-applied="setCoupon"></coupon>
</div>
Here is my app.js file
Vue.component('coupon', {
template: '#coupon-template',
props: ['whenApplied'],
data: function() {
return {
coupon: '',
invalid: false,
text: ''
}
},
methods: {
whenCouponHasBeenEntered: function() {
this.validate();
},
validate: function() {
if( this.coupon == 'FOOBAR') {
this.whenApplied(this.coupon);
return this.text = '20% OFF!!';
}
return this.text = 'that coupon doesn`t exists';
}
}
});
new Vue({
el: '#demo',
methods: {
setCoupon: function(coupon) {
alert('set coupon'+ coupon);
}
}
});
Someone pls help. Suggestions pretty much appreciated.
You should bind the property:
<coupon v-bind:when-applied="setCoupon"></coupon>
or you could use the shorthand syntax for v-bind:
<coupon :when-applied="setCoupon"></coupon>
Read more about the props here.

Categories