How can I get value when button clicked ? Vue.js 2 - vue.js

My component vue is like this :
<template>
<div class="modal" tabindex="-1" role="dialog">
...
<div class="form-group">
<input type="file" id="change-image" name="replace">
</div>
<div class="form-group">
<input type="text" class="form-control" id="alt-image">
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Set
</label>
</div>
...
<button type="button" class="btn btn-success" #click="editImageProduct">
{{trans('store.modal.edit.button.save')}}
</button>
...
</div>
</template>
<script>
export default{
...
methods: {
editImageProduct(event) {
// get the data
}
}
}
</script>
When I click the button, I want get value from input type file, input type text and intput type checkbox
I know use javascript or jquery
But I want to get it use vue.js 2
How can I do it?

With checkbox and text input, you can use v-model.
With file input you can get data when user upload image, use event onChange
Example code:
new Vue({
el: '#app',
data: {
image: '',
altImage: '',
set: false,
},
methods: {
onUpload(e) {
this.image = e.target.files || e.dataTransfer.files;
},
editImageProduct() {
console.log('File object', this.image);
console.log('Image name', this.image[0].name);
console.log('Alt Image', this.altImage);
console.log('Set', this.set);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<div id="app">
<div class="form-group">
<input type="file" #change="onUpload">
</div>
<div class="form-group">
<input type="text" class="form-control" v-model="altImage">
</div>
<div class="checkbox">
<label><input type="checkbox" v-model="set"> Set</label>
</div>
<button type="button" class="btn btn-success" #click="editImageProduct">Save</button>
</div>

use v-model in your form
<input type="file" id="change-image" name="replace" v-model="file">
<input type="text" class="form-control" id="alt-image" v-model="text">
<input type="checkbox" v-model="checkbox">
export default {
data: function(){
return {
file: null,
checkbox: null,
text: null,
}
},
methods: {
editImageProduct() {
console.log(this.file, this.checkox, this.text);
}
}
}
EDITED:
try to look into this example for file inputs, hope it'll help you http://codepen.io/Atinux/pen/qOvawK/

Related

how to $emit in vuejs

VueJS emit doesn't work, I'm trying to change the value of a boolean, but it doesn't want to emit the change
here is the first component:
<template>
<div id="reg">
<div id="modal">
<edu></edu>
</div>
<div :plus="plus" v-if="plus" #open="plus = !plus">
abc
</div>
</div>
</template>
the script:
<script>
import edu from './education/edu.vue'
export default {
components: {
edu
},
data() {
return {
plus: false
}
}
}
</script>
the second component with the emit:
<template>
<div id="container">
<h2>Education</h2>
<form action="">
<input type="text" class="input" placeholder="preparatory/bachelor/engineering..">
<input type="text" class="input" placeholder="University..">
<input type="text" class="input" placeholder="Where?..">
<h6>Start date</h6>
<input type="date" class="input" value="2017-09-15" min="2017-09-15" max="2021-09-15">
<div class="end-date">
<h6>End date</h6>
<div class="flexend">
<h6>present</h6><input type="checkbox" name="" id="checkbox" #click="checked">
</div>
</div>
<input type="date" class="input" v-if="show" value="2017-09-15" min="2017-09-15">
<div class="flex-end">
<button class="btn-plus" #click="$emit('open')"><i class="fas fa-plus"></i></button>
</div>
<div class="flex-end">
<button class="btn">next <i class="fas fa-arrow-right"></i></button>
</div>
</form>
</div>
</template>
the script:
<script>
export default {
props:{
plus: Boolean
},
data(){
return{
show: true,
}
},
I thought this is working, but it seems like it's not
You should use the component name instead of the div element :
<edu :plus="plus" v-if="plus" #open="plus = !plus">
abc
</edu>

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property

I am trying make form validation dynamically, all props from the JSON file here I am passing the props parent to child component and that props using for input v-model.
When enter a letter inside the text input, I am getting the following error
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"
parent component
<template>
<!--parent component-->
<form action="" #submit.prevent="onSubmit">
<div v-for="formInput_Item in formInput_list" :key="formInput_Item.id">
<ShortText
v-if="formInput_Item.type === 'text'"
:input_id="formInput_Item.input_id"
:form-input-item="formInput_Item.formInput_Item"
:label_type="label_type"
:validations="formInput_Item.validations"
:is-valid="isValid"
:value="value"
/>
<p v-if="!formIsValid" class="text-danger">
Please fix the above errors and submit again.
</p>
<div class="col-12 mt-4">
<button class="btn btn-primary float-end" type="submit">SUBMIT</button>
</div>
</div>
</form>
</template>
<script>
import ShortText from '#/components/FormInputs/ShortText'
export default {
components: {
ShortText,
},
data() {
return {
label_type: 'floating', // floating, overhead, below, left, right
formIsValid: true,
error: this.formInput_list[3].validations.required,
value: '',
isValid: true,
}
},
methods: {
validateForm() {
this.formIsValid = true
if (this.value === '') {
this.isValid = false
this.formIsValid = false
}
},
onSubmit() {
console.log(this.isValid)
console.log('value' + this.value)
this.validateForm()
alert('form')
console.log(this.validateForm())
if (!this.formIsValid) {
alert('error')
return
}
alert('succses')
},
},
}
</script>
Child component
<template>
<div>
<div v-if="label_type === 'floating'">
<div class="form-outline mt-4">
<!-- ESlint is complaining about the mutation on this line 👇 -->
<input v-model="value" type="text" class="form-control" />
<label for="" class="form-label" style="margin-left: 10px">
{{ formInput_Item }}
</label>
<div class="form-notch">
<div class="form-notch-leading" style="width: 15px"></div>
<div class="form-notch-middle" style="width: 100px"></div>
<div class="form-notch-trailing"></div>
</div>
</div>
<p v-if="!isValid" class="text-danger">
This field is must not be empty.
</p>
</div>
<div v-else-if="label_type === 'overhead'" class="form-group">
<label class="form-label" for="timeType">{{ formInput_Item }}</label>
<input id="timeType" type="text" class="form-control" required />
</div>
<div v-else-if="label_type === 'below'" class="form-group">
<input type="text" class="form-control" required />
<label class="form-label">{{ formInput_Item }}</label>
</div>
<div v-else-if="label_type === 'left'" class="row form-group">
<div class="col-lg-4">
<label class="form-label">{{ formInput_Item }}</label>
</div>
<div class="col-lg-7">
<input type="text" class="form-control" required />
</div>
</div>
<div v-else-if="label_type === 'right'" class="row form-group">
<div class="col-lg-7">
<input type="text" class="form-control" required />
</div>
<div class="col-lg-4">
<label class="form-label">{{ formInput_Item }}</label>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
input_id: {
type: Number,
required: true,
},
formInput_Item: {
type: String,
required: true,
},
label_type: {
type: String,
required: true,
},
validations: {
type: Object,
},
value: {
type: String,
default: '',
},
isValid: {
type: Boolean,
},
},
data() {
return {
error: this.validations.required,
}
},
}
</script>

Reload screen after submitting form - Vue.js

I am creating a Discord command creator app. I have the client talking to the server correctly and outputting what I want. The issue is that once I submit the form, the page doesn't refresh. Below I have the template and script.
<template>
<form v-on:submit="addCommand">
<div id="container" class="col-md-5 m-auto">
<div class="card card-body">
<h1 class="text-center mb-3"><i class="fab fa-discord"></i> Command Creator</h1>
<div class="form-group">
<label for="command">Command</label>
<input type="text" v-model="command" class="form-control" placeholder="Please enter a command." />
</div>
<div class="form-group">
<label for="output">Output</label>
<input type="text" v-model="output" class="form-control" placeholder="Please enter an output." />
</div>
<button type="submit" class="btn btn-primary btn-block">Create</button>
</div>
</div>
</form>
</template>
<script>
export default {
name: 'Dashboard',
data () {
return {
command: '',
output: ''
}
},
methods: {
addCommand (e) {
this.axios.post('http://localhost:3000/server', {
command: this.command,
output: this.output
})
e.preventDefault()
}
}
}
</script>

Vue 2 Vuex - update values via form or add new item

I have following template:
<template>
<div class="is-half">
<form #submit.prevent="save">
<input type="hidden" name="bookID" :value="book.id">
<div class="field">
<label class="label">Title</label>
<div class="control">
<input class="input" type="text" placeholder="Title" :value="book.title">
</div>
</div>
<div class="control">
<div class="select">
<select>
<option
v-for="author in this.$store.state.authors"
:value="author.name"
:selected="author.name == book.author"
>{{ author.name }}</option>
</select>
</div>
</div>
<div class="field">
<label class="label">Description</label>
<div class="control">
<textarea class="textarea" placeholder="Description" :value="book.description"></textarea>
</div>
</div>
<div class="control">
<button class="button is-primary">Submit</button>
</div>
</form>
</div>
</template>
<script>
export default {
data() {
return {
book : {
id: null,
title: '',
isbn: '',
author: '',
description: '',
added: ''
}
}
},
methods: {
save(book) {
console.log(this.book);
}
},
created() {
if(this.$store.state.book != 'undefined'){
this.book = Object.assign({}, this.$store.state.book);
}
},
computed: {}
}
</script>
<style></style>
I am trying to update the value of selected item, but whenever I press save, the object has the same values which it gets on load.
How can I update values if the I load new object, or insert new object if id is null?
If i understand your question, the problem is that when you type something in the input, it doesn't update the model.
The problem is you're using :value to bind the values and this is a one-way binding. For 2 way binding replace all :value with v-model: v-model="book.title"

Posting response data from component to root in vue js

My modal box is inside of a vue component. When the data is submitted, I want the component to send back the response data to the parent so I can append it to the root element.
The component
<template>
<div v-if="value.startsWith('new')">
<!-- Create Client Modal -->
<div class="modal show" id="modal-create-client" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button " class="close" data-dismiss="modal" aria-hidden="true" #click.prevent="close">×</button>
<h4 class="modal-title">Details</h4>
</div>
<div class="modal-body">
<!-- Form Errors -->
<div class="alert alert-danger" v-if="createForm.errors.length > 0">
<p><strong>Whoops!</strong> Something went wrong!</p>
<br>
<ul>
<li v-for="error in createForm.errors">
{{ error }}
</li>
</ul>
</div>
<!-- Create Client Form -->
<form class="form-horizontal" role="form">
<!-- Name -->
<div class="form-group">
<label class="col-md-3 control-label">First Name</label>
<div class="col-md-7">
<input id="create-client-name" type="text" class="form-control" #keyup.enter="store" v-model="createForm.first">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Last Name</label>
<div class="col-md-7">
<input type="text" class="form-control" name="last" #keyup.enter="store" v-model="createForm.last">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Email</label>
<div class="col-md-7">
<input type="text" class="form-control" name="organization" #keyup.enter="store" v-model="createForm.email">
<span class="help-block">Email is required for invoices</span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Organization</label>
<div class="col-md-7">
<input type="text" class="form-control" name="organization" #keyup.enter="store" v-model="createForm.organization">
</div>
</div>
</form>
</div>
<!-- Modal Actions -->
<div class="modal-footer" v-if="value == 'newClient'">
<button type="button" class="btn btn-default" data-dismiss="modal" #click.prevent="close">Close</button>
<button type="button" class="btn btn-primary" #click="storeClient">Create</button>
</div>
<div class="modal-footer" v-else-if="value == 'newLead'">
<button type="button" class="btn btn-default" data-dismiss="modal" #click.prevent="close">Close</button>
<button type="button" class="btn btn-primary" #click="storeLead">Create</button>
</div>
<div class="modal-footer" v-else-if="value == 'newContact'">
<button type="button" class="btn btn-default" data-dismiss="modal" #click.prevent="close">Close</button>
<button type="button" class="btn btn-primary" #click="storeContact">Create</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
createForm: {
errors: [],
first: '',
last: '',
email: '',
organization: ''
},
};
},
props: ['value'],
/**
* Prepare the component (Vue 1.x).
*/
ready() {
this.prepareComponent();
},
/**
* Prepare the component (Vue 2.x).
*/
mounted() {
var vm = this
this.prepareComponent();
},
methods: {
/**
* Prepare the component.
*/
prepareComponent() {
$('#modal-create-client').on('shown.bs.modal', () => {
$('#create-client-name').focus();
});
$("#modal-create-client").on("hide.bs.modal", function(e) {
$(this).removeData('bs.modal');
});
},
close() {
$('#modal-create-client').removeClass('show');
},
/**
* Create a new client for the user.
**/
storeClient() {
this.persistClient(
'post', './clients/add',
this.createForm, '#modal-create-client'
);
},
storeLead() {
this.persistClient(
'post', './leads/add',
this.createForm, '#modal-create-client'
);
},
storeContact() {
this.persistClient(
'post', './contacts/add',
this.createForm, '#modal-create-client'
);
},
/**
* Persist the client to storage using the given form.
*/
persistClient(method, uri, form, modal) {
form.errors = [];
this.$http[method](uri, form).then(response => {
location.reload();
$(modal).modal('hide');
}).catch(response => {
if (typeof response.data === 'object') {
form.errors = _.flatten(_.toArray(response.data));
} else {
form.errors = ['Something went wrong. Please try again.'];
}
});
},
watch: {
value: function (value) {
// update value
$(this.$el).val(value)
},
}
}
}
</script>
The root Element
var MyComponent = Vue.component('my-ajax-component',
require('./components/Toolbar.vue') );
new Vue({
el: '#select',
data: {
selected: ''
},
components: {
// <my-component> will only be available in parent's template
'my-ajax-component': MyComponent
}
});
and my view
<div class="form-group clearfix">
<div class="col-xs-12" id="select">
{!! Form::label('client_id', 'Choose Client:', ['class' => 'control-label']) !!}
{!! Form::select('client_id', ['newClient' => 'New Client', $clients], null, ['title' => 'Select Client', 'class' => 'form-control selectpicker', 'v-model' => 'selected', 'data-live-search' => 'true']) !!}
<br>
<my-ajax-component v-bind:value="selected"></my-ajax-component>
</div>
</div>
Instead of location reload I want to append the response data to the select element which is my roo
I changed my root element to
new Vue({
el: '#select',
data: {
selected: '',
data: ''
},
components: {
// <my-component> will only be available in parent's template
'my-ajax-component': MyComponent
},
methods: {
handler: function(data) {
console.log('this is my data' + data)
}
}
my component now has
this.$emit('data-received',response)
and put v-on in the child component
<my-ajax-component v-bind:value="selected" v-on:data-received='handler(data)'></my-ajax-component>
I get data undefined or nothing
I can see the data returned in the post .. it's the id of my object ...should I json encode it
The easiest way can be to emit the event with data in child component when you get the response.
In child:
this.$emit('data-received',response)
In parrent:
<child-component v-on:data-received='handler(data)'>
In handler function in parrent, do whatever you want with data.
UPDATED:
Your backend should return JSON to follow REST Api standards.
Every endpoint of API should return JSON, even if it is simple string.
Instead of
In parrent:
<child-component v-on:data-received='handler(data)'>
I used In parrent:
<child-component v-on:data-received='handler'>