How to refference input in vue js with v-model? - javascript

I'm new in vue, and I am trying to make a get request from a field that has a v-model="embed.url" after pasting the link. Event after paste works well but, I don't know how to reference to input with v-model="embed.url" and get the data.
When I try code below error appear:
[Vue warn]: Error in v-on handler: "ReferenceError: embed is not defined"
and
ReferenceError: "embed is not defined"
My vue code:
<script type="text/javascript">
axios.defaults.xsrfHeaderName = "X-CSRFToken";
new Vue({
el: '#app',
delimiters: ['!!', '!!'],
data () {
return {
embed: {
url: '',
title: '',
description: '',
type: '',
thumbnail_url: '',
html: '',
},
isPaste: false,
embedsinfo: [],
}
},
methods: {
formSubmit(e) {
e.preventDefault();
let currentObj = this;
axios.post('http://wegemoc.local:8000/recipes/recipe/embed/add/', {
url: this.url,
})
.then(function (response) {
currentObj.output = response.data;
})
.catch(function (error) {
currentObj.output = error;
});
},
paste() {
this.isPaste = true;
},
input() {
if (this.isPaste) {
axios.get('http://iframe.ly/api/oembed?url=' + embed.url + '&api_key=493c9ebbdfcbdac2a10d6b')
.then(response => (this.embedsinfo = response))
isPaste = false;
}
}
},
});
My form:
<div id="app">
!! embedsinfo.title !!
<form method="post" class="margin-bottom-25" #submit="formSubmit">
{% csrf_token %}
<div class="form-group">
<label for="formGroupExampleInput">Adres przepisu*</label>
<input type="url" class="form-control" placeholder="Url" #paste="paste" #input="input" v-model="embed.url">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Tytuł</label>
<input class="form-control" placeholder="Title" v-model="embed.title">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Description</label>
<input type="textarea" class="form-control" id="formGroupExampleInput2" placeholder="Description" v-model="embed.description">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Thumbnail_url</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Tthumbnail_url" v-model="embed.thumbnail_url">
</div>
<button type="submit" class="btn btn-success-gradiant">Dodaj link</button>
</form>
</div>

When you are not using Vue as Single Component files, your data property must be an object and not a function. Change your data property to an object and then give it a try.
new Vue({
el: '#app',
delimiters: ['!!', '!!'],
data: {
return {
embed: {
url: '',
...
};
},
...
Also you must access your data embed.url property using "this" like how you have referenced other properties in your code.
if (this.isPaste) {
axios.get('http://iframe.ly/api/oembed?url=' + this.embed.url + '&api_key=493c9ebbdfcbdac2a10d6b')
.then(response => (this.embedsinfo = response))
isPaste = false;
}

Related

How can I check if fields are empty on Send Message button?

<template>
<div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" v-model="firstName" placeholder="Enter your name">
</div>
<div class="form-group">
<label for="lastName">Last name</label>
<input type="text" class="form-control" v-model="lastName" placeholder="Enter your last name">
</div>
<div class="form-group">
<label for="message">Type Your message</label>
<textarea class="form-control" v-model="message" rows="3"></textarea>
</div>
<div class="form-group form-check" v-for="number in numbers" :key="number">
<input type="checkbox" :value="number.Broj" v-model="checkedNumbers">
<label class="form-check-label" >{{number.Broj}}</label>
</div>
<button type="submit" class="btn btn-primary" v-on:click="alert" #click="sendMessage">Send message</button>
</div>
</template>
<script>
import http from "../http-common.js";
import userServices from "../services/userServices.js";
export default {
data()
{
return {
firstName: null,
lastName: null,
message: null,
numbers: "",
checkedNumbers: [],
success: 'You have submitted form successfully'
};
},
methods:
{
async sendMessage()
{
await http.post("/message", {firstName: this.firstName, lastName: this.lastName, message: this.message, numbers: this.checkedNumbers});
this.$data.firstName = "",
this.$data.lastName = "",
this.$data.checkedNumbers = [],
this.$data.message = "";
},
alert() {
alert(this.success)
if(event)
alert(event.target.tagName)
},
retrieveNumbers() {
userServices.getNumbers().then(response => {
this.numbers = response.data;
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
},
created() {
this.retrieveNumbers();
}
}
</script>
So I want to add the option of checking input fields when user clicks "Send Message" button. I tried some options but I faield at that. So please I would appretiate if someone would help me. I'm still learning.
I know I have to use v-if and create the method for checking the fields.
So if you would be most kind and help me solve this problem I would be really grateful.
Thank you dev, community <3
Can I please get a concrete answer. Because I'll learn in that way, so please without condescending and "no-answers"
You can do it manually :
<script>
import http from "../http-common.js";
import userServices from "../services/userServices.js";
export default {
data()
{
return {
firstName: null,
lastName: null,
message: null,
numbers: "",
checkedNumbers: [],
success: 'You have submitted form successfully'
};
},
methods:
{
async sendMessage()
{
if(!(this.firstName && this.lastName && this.numbers)) return;
await http.post("/message", {firstName: this.firstName, lastName: this.lastName, message: this.message, numbers: this.checkedNumbers});
this.$data.firstName = "",
this.$data.lastName = "",
this.$data.checkedNumbers = [],
this.$data.message = "";
},
alert() {
alert(this.success)
if(event)
alert(event.target.tagName)
},
retrieveNumbers() {
userServices.getNumbers().then(response => {
this.numbers = response.data;
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
},
created() {
this.retrieveNumbers();
}
}
</script>
Or you can this usefull library
https://vuelidate.js.org/#sub-basic-form
You can simply define a method to check the fields and call that before the HTTP request in the sendMessage method.
You can initialize your data as an empty string "" and have a method like this:
validateForm() {
return this.firstName != "" && this.lastName != "" && this.message != ""
}
Update your sendMessage method to something like this:
async sendMessage() {
const isFormValid = this.validateForm()
if (isFormValid) {
await http.post(....)
...
}
}

Display data in Vuejs

I need to display only name from request in my form, can't figure out how to do it. I'm just starting with js, need help.
I have tried this {{ request.name }} but doesn't work. {{request}} shows me full data.
const app = new Vue({
el:'#valuation-request',
data() {
return {
step:1,
request:{
name:null,
industry:'{{ $company->industry }}',
valuation_date:null,
similar_comp:null,
total_raised:null,
sales_transactions:null
}
}
},
methods:{
prev() {
this.step--;
},
next() {
this.step++;
}
}
});
If name has a value, it should display as you wrote it. If it's null, nothing will be displayed.
const app = new Vue({
el:'#valuation-request',
data() {
return {
step:1,
request:{
name: null,
industry:'{{ $company->industry }}',
valuation_date:null,
similar_comp:null,
total_raised:null,
sales_transactions:null
}
}
},
methods:{
prev() {
this.step--;
},
next() {
this.step++;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="valuation-request">
{{request.name}}
<hr>
Name: <input type="text" class="uk-input" name="name" v-model="request.name" id="name" placeholder="e.g. John Doe" required>
</div>

After Filling all Fields laravel sending 'required' error

I am trying to submit a form using axios post request in laravel. In this form i have 3 fields, name,age and a file called image.
here is the form
<form action="{{route('forms.store')}}" method="post" enctype="multipart/form-data">
#{{name}}
#csrf
<span v-if="errors.name">#{{errors.name[0]}}</span>
<label for="name">Name:</label>
<input type="text" name="name" id="name" v-model="name">
<span v-if="errors.age">#{{errors.age[0]}}</span>
<label for="age">Age:</label>
<input type="text" name="age" id="age" v-model="age">
<label for="image">Image:</label>
<span v-if="errors.image">#{{errors.image[0]}}</span>
<input type="file" name="image" id="image" #change="imageChanged">
<button #click.prevent="submitForm">Submit</button>
</form>
Here is my vueJs code:
const app = new Vue({
el: '#app',
data:{
name:'',
age:'',
image:'',
errors:{}
},
methods:{
imageChanged(e){
app.image = e.target.files[0]
console.log(e.target.files[0]);
},
submitForm(){
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
const fd = new FormData(this.$data);
fd.append('image',this.image);
axios.post('{{route('forms.store')}}',this.fd,config).then((response)=>{
console.log(response.data);
}).catch((error)=>{
//console.log(error.response.data);
this.errors = error.response.data.errors;
})
}
}
});
And here is my controller
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'age' => 'required',
]);
if ($request->hasFile('image')) {
$image = $request->file('image');
return $ext = $image->extension();
} else {
return "NOT OK";
}
}
So here I am validating name and age. But my problem is when I fill the form and submit the form,
It sends back errors that name and age field is required.
where am I doing wrong and how to receive this data in the controller.
Thank you in advance.
I believe your code is in error in this part. changes:
axios.post('{{route('forms.store')}}',this.fd,config)
to:
axios.post('{{route('forms.store')}}',fd,config)

can not change data in the #change vuejs handler

There is a component that contains input[type=file].
Also, this field has an uploadFile handler, which calls the validateMessage method, which attempts to change the error. As you can see, after changing this.error it shows that everything is correct. But in div.error it is not displayed and if you look in vueDevtool, then there is also empty.
data in vueDevTools
data() {
return {
error: ''
}
},
methods: {
validateFile(file) {
if (! file.type.includes('video/')) {
this.error = 'wrong format';
console.log(this.error); // wrong format
}
},
uploadFile(e) {
const file = e.target.files[0];
this.validateFile(file);
},
}
<input type="file"
id="im_video"
name="im_video"
#change="uploadFile"
class="hidden">
<div class="error">
{{ error }}
</div>
Here is working example.
new Vue({
el:'#app',
data() {
return {
error: ''
}
},
methods: {
validateFile(file) {
console.log(file.type);
if (! file.type.includes('video/')) {
this.error = 'wrong format';
//console.log(this.error); // wrong format
}
},
uploadFile(e) {
this.error = '';
const file = e.target.files[0];
this.validateFile(file);
},
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<input type="file"
id="im_video"
name="im_video"
#change="uploadFile"
class="hidden">
<div class="error">
{{ error }}
</div>
</div>
If you are using component this would help more to share data from child to parent in your case setting error from child component to parent
Vue.component('upload-file',{
template:`<div><input type="file"
id="im_video"
name="im_video"
#change="uploadFile"
class="hidden"></div>`,
data() {
return {
error: ''
}
},
methods: {
validateFile(file) {
//
if (! file.type.includes('video/')) {
vm.$emit('filerror', 'wrong format');
}
},
uploadFile(e) {
vm.$emit('filerror', '');
const file = e.target.files[0];
this.validateFile(file);
},
}
});
const vm = new Vue({
el:'#app',
mounted(){
this.$on('filerror', function (msg) {
this.error = msg;
})
},
data:{
error:''
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<upload-file></upload-file>
<div class="error">
{{ error }}
</div>
</div>

Data variable in vue.js is not appears in the view when populated by ajax request

I have the code below, the 'tarefas' variable is not appear in my v-for, and I verify the response from the server and its ok, the data are coming. When I add new data in the input field, it works correctly
JS:
var app = new Vue({
el: '#app',
data: {
titulo: 'Lista de Tarefas',
tarefas: [],
tarefa: ''
},
methods: {
addTarefa: function () {
console.log(this.tarefa);
if (this.tarefa !== '') {
this.tarefas.push({identificador: 0, descricao: this.tarefa, feito: 0});
this.postTasks();
//this.tarefa = '';
}
},
removerTarefa: function (tarefa) {
this.tarefas.splice(this.tarefas.indexOf(tarefa), 1)
},
syncTasks: function () {
jQuery.get('http://localhost:51622/api/tarefa', function (data, status) {
this.tarefas = data;
console.log(data);
console.log(this.tarefas);
});
},
postTasks: function () {
jQuery.post('http://localhost:51622/api/tarefa', {identificador: 0, descricao: this.tarefa, feito: 0});
},
},
created: function () {
console.log("passei no mounted");
this.syncTasks();
},});
HTML:
<p class="text-primary center">{{ titulo }}</p>
<div class="col-xs-3">
<input type="text" placeholder="digite a tarefa" v-model="tarefa" class="form-control" />
</div>
<button v-on:click="addTarefa" class="btn btn-default">add tarefa</button>
<br />
<br />
<div class="col-xs-3">
<ul class="list-group">
<li v-for="tarefa in tarefas" class="list-group-item">{{ tarefa }} <button class="btn" v-on:click="removerTarefa(tarefa)">X</button></li>
</ul>
</div>
</div>
</div>
<script src="app.js"></script>
Since your callback is a regular function, your this is not pointing to the Vue. Try an arrow function.
jQuery.get('http://localhost:51622/api/tarefa', (data, status) => {
this.tarefas = data;
console.log(data);
console.log(this.tarefas)
});
See How to access the correct this inside a callback?

Categories

Resources