VueJS Get the name of the clicked Button If the v-on directive is in the Form Tag - vue.js

Is it possible to get the submit button name that is being clicked if the v-on:submit is placed on the form tag and not in the button?
Form
<form method="post" #submit.prevent="getButtonName($event)">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form>
Script
methods: {
getButtonName(event) {
}
}

v-on:submit won't work. but v-on:click will. See #click="handleClick($event)"
<template>
<div class="hello">
<form method="post" #click="handleClick($event)" #submit.prevent="getButtonName($event)">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form>
</div>
</template>
<script>
export default {
name: 'hello',
data () {
return {
}
},
methods: {
getButtonName(event) {
// console.log(event);
},
handleClick(e) {
console.log(e.target.name);
}
}
}
</script>
e.g.
https://codesandbox.io/s/6jwvy6l96k

new Vue({
el: "#app",
data() {
return {
clickedButton: null,
}
},
methods: {
getButtonName(event) {
this.clickedButton = event.target.name
}
}
})
<html>
<head></head>
<body>
<div id="app">
<form method="post" #click.prevent="getButtonName">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form>
<div v-text="clickedButton" v-if="clickedButton"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</body>
</html>

You can easely access to the button's name with submitter.name
Check below:
new Vue({
el: "#app",
data() {
return {
clickedButton: null,
}
},
methods: {
getButtonName(e) {
this.clickedButton = e.submitter.name
}
}
})
<html>
<head></head>
<body>
<div id="app">
<form method="post" #submit.prevent="getButtonName">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form><br />
<div>Pressed: {{clickedButton}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</body>
</html>

Related

I made the form a component, it disappeared with Vue.js

overview
Currently, the created new.vue and edit.vue have similar form parts, so I would like to make them common and componentized.
Therefore, I would like to create a new form.vue and display the page in the form of calling it.
However, when I made it into a component, the page disappeared.
(There is no such description in the log, and there is no error display in Console)
I think the data transfer isn't working, but I'm not sure where to fix it.
I would appreciate it if you could tell me how to fix it.
Original code before componentization
New.vue
<template>
<main>
<form>
<section>
<div>
<div>
<fieldset>
<div class="form-row">
<div class="form-group col-3">
<label>タイトル</label>
<input v-model="latest_information.title" type="text">
</div>
<div class="form-group col-3">
<label>詳細</label>
<input v-model="latest_information.detail" type="text">
</div>
</div>
</fieldset>
</div>
</div>
</section>
<div class="btn-container d-flex justify-content-center">
<button class="button-square btn-send" type="button" #click="createLatestInformation">保存する</button>
</div>
</form>
</main>
</template>
<script>
export default {
data() {
return {
latest_information: {
title: '',
detail: '',
},
}
},
methods: {
createLatestInformation() {
this.$loading.load(this.$auth.api.post('admin/latest_informations/', {
latest_information: this.latest_information
})
.then(response => {
this.$router.push({name: 'AdminLatestInformationIndex'})
}))}
},
}
</script>
Code after componentization (not behaving well)
New.vue
<template>
<form :latest_information="latest_information" #click="createLatestInformation"></form>
</template>
<script>
import Form from './Form.vue';
export default {
components:{
Form
},
data() {
return {
latest_information: {
title: '',
detail: '',
},
}
},
methods: {
createLatestInformation() {
this.$loading.load(this.$auth.api.post('admin/latest_informations/', {
latest_information: this.latest_information
})
.then(response => {
this.$router.push({name: 'AdminLatestInformationIndex'})
}))}
},
}
</script>
Form.vue
<template>
<main>
<form>
<section>
<div>
<div>
<fieldset>
<div class="form-row">
<div class="form-group col-3">
<label>タイトル</label>
<input v-model="latest_information.title" type="text">
</div>
<div class="form-group col-3">
<label>詳細</label>
<input v-model="latest_information.detail" type="text">
</div>
</div>
</fieldset>
</div>
</div>
</section>
<div class="btn-container d-flex justify-content-center">
<button class="button-square btn-send" type="button" #click="$emit('click')">保存する</button>
</div>
</form>
</main>
</template>
<script>
export default {
props: {
latest_information: {
title: '',
detail: '',
},
}
}
</script>
<style>
</style>
Environment
rails 6
vue#2.6.10
form was a reserved word.Changed to tform.
<template>
<tform :latest_information="latest_information" #click="createLatestInformation"></form>
</template>
<script>
import Form from './Form.vue';
export default {
components:{
Tform: Form
},

How to pass data which is coming as response from backend to the another component in vue.js?

I am developing one page which is responsible for placing order Cart.vue which contains two api calls, handleMail() method is sending email and generating a orderID and i am getting response from backend in network section like this.
{
"message":"order created successfully",
"orderID":87450588
}
i am catching that orderID and stored as a orderNumber,Now i want to pass that orderNumber to another component called orderPlace.vue and i want to display that orderNumber inside template section.for this i am creating Event bus it's not working ,please help me to pass orderNumber to another component ...
Cart.vue
<template>
<div class="main">
<div class="first-section">
<div class="content">
<h5>My Cart({{books.length}})</h5>
</div>
<div v-for="book in books" :key="book.id" class="container">
<div class="mid-section">
<img class="img-section" v-bind:src="book.file" alt="not found">
<p class="title-section">{{book.name}}</p>
</div>
<div class="author-section">
<p class="author-name">by {{book.author}}</p>
</div>
<div class="price-section">
<h6>Rs.{{book.price}}</h6>
</div>
<div class="icons">
<i class="fas fa-minus-circle"></i>
<input class="rectangle" value=1>
<i class="fas fa-plus-circle"></i>
</div>
</div>
<div class="btn-grps">
<button class="btn" v-on:click="flip()" v-if="hide==true" type="submit">Place Order</button>
</div>
</div>
<div class="second -section">
<div class="details-box">
<input type="text" v-if="hide==true" class="initial-btn" placeholder="Customer Details" />
</div>
<div v-if="hide==false" class="fill-details">
<form #submit.prevent="" class="address">
<h4 class="heading">Customer Details</h4>
<div class="name">
<input type="name" required pattern="[A-Za-z]{3,10}" v-model="name">
<label class="label">Name</label>
</div>
<div class="name">
<input type="text" required v-model="phoneNumber">
<label class="label">Phone Number</label>
</div>
<div class="pin">
<input type="text" required v-model="pincode">
<label class="label">PinCode</label>
</div>
<div class="pin">
<input type="text" required v-model="locality">
<label class="label">Locality</label>
</div>
<div class="address-block">
<input class="address" type="text" required v-model="address">
<label id="Add" class="label">Address</label>
</div>
<div class="city-landMark">
<input type="text" required v-model="city">
<label class="label">City/Town</label>
</div>
<div class="city-landMark">
<input type="text" required v-model="landmark">
<label class="label">LandMark</label>
</div>
<div class="Radio-Buttons">
<p>Type</p>
<div class="radio-btns flex-container">
<div>
<input type="radio" id="Home" value="Home" name="type" v-model="type">
<div class="first-radio"> <label class="home" for="Home">Home</label></div>
</div>
<div>
<input class="work-round" type="radio" id="Work" value="Work" name="type" v-model="type">
<div class="second-radio"> <label for="Work" class="work-label">Work</label></div>
</div>
<div>
<input class="other-round" type="radio" id="Other" value="Other" name="type" v-model="type">
<div class="third-radio"><label class="other-label" for="Other">Other</label></div>
</div>
</div>
<div class="btn-continue">
<button type="submit" #click="handlesubmit();handleMail();" class="continue">continue</button>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User';
import { EventBus } from "./event-bus.js";
export default {
created() {
if (localStorage.getItem("reloaded")) {
localStorage.removeItem("reloaded");
} else {
localStorage.setItem("reloaded", "1");
location.reload();
}
service.userDisplayCart().then(response => {
this.books = response.data;
})
},
data() {
return {
flag: true,
hide: true,
booksCount: 0,
name: '',
phoneNumber: '',
pincode: '',
locality: '',
city: '',
address: '',
landmark: '',
type: '',
books: [],
cart:'MyCart',
nameField:'Name',
phoneField:'Phone Number',
pincodeField:'PinCode',
AddressField:'Address',
localityField:'Locality',
cityField:'CityTown',
landmarkField:'LandMark',
orderNumber:''
}
},
methods: {
flip() {
this.hide = !this.hide;
},
Togglebtn() {
this.flag = !this.flag;
},
handlesubmit() {
let userData = {
name: this.name,
phoneNumber: this.phoneNumber,
pincode: this.pincode,
locality: this.locality,
city: this.city,
address: this.address,
landmark: this.landmark,
type: this.type,
}
service.customerRegister(userData).then(response => {
return response;
}).catch(error=>{
alert("invalid customer address");
return error;
})
},
// handleMail(){
// service.confirmMail().then(response=>{
// alert("order placed successfully");
// let orderNumber= response.data.orderID;
// this.$router.push({path: '/ordersuccess'});
// console.log(response);
// return orderNumber;
// }).catch(error=>{
// alert("Error in sending email");
// return error;
// })
// }
handleMail(){
service.confirmMail().then(response=>{
alert("order placed successfully");
let orderNumber= response.data.orderID;
console.log("my num",orderNumber);
EventBus.$emit("emitting-order", orderNumber);
this.$router.push({path: '/ordersuccess'});
console(response);
return orderNumber;
})
},
}
}
</script>
<style lang="scss" scoped>
#import "#/styles/Cart.scss";
</style>
OrderPlace.vue
<template>
<div class="order-place">
<div class="image-container">
<img src="../assets/success.png" alt="not found" />
</div>
<div class="title-container">
<p>Order placed Successfully</p>
</div>
<div class="message-section">
<p>Hurray!!!your order is confirmed {{orderNumber}} and placed successfully contact us in below details
for further communication..</p>
</div>
<div class="title-section">
<div class="email-us">
<p>Email-us</p>
</div>
<div class="contact-us">
<p>Contact-us</p>
</div>
<div class="address">
<p>Address</p>
</div>
</div>
<div class="email-sec">
<p>admin#bookstore.com</p>
</div>
<div class="contact-sec">
<p>+918163475881</p>
</div>
<div class="address-sec">
42, 14th Main, 15th Cross, Sector 4 ,opp to BDA complex, near Kumarakom restaurant, HSR Layout, Bangalore 560034
</div>
<div class="button">
<router-link to="/dashboard" class="btn">Continue Shopping</router-link>
</div>
</div>
</template>
<script>
import { EventBus } from "./event-bus.js";
export default {
name: 'OrderPlace',
data(){
return{
successTitle:'Order placed Successfully',
adminEmailSection:'Email-us',
adminContactSection:'Contact-us',
adminAddressSection:'Address',
adminEmail:'admin#bookstore.com',
adminMobNum:'+918163475881',
orderNumber: ''
}
},
mounted() {
EventBus.$on("emitting-order", orderNo=> {
this.orderNumber = orderNo;
console.log(`Oh, that's great ${orderNo})`);
return orderNo;
});
}
}
</script>
<style lang="scss" scoped>
#import "#/styles/OrderPlace.scss";
</style>
event-bus.js
import Vue from 'vue';
export const EventBus = new Vue();
If the orderPlace.vue component is not active when you do the emit. It cannot receive the element.
You can try to register your order number, in the localStorage. Or call orderPlace.vue as a child component and pass the order number to the props

Cannot use 'in' operator to search for 'xxxxx' in undefined in vue.js

I'm trying to create a modal form that will add a record. I am able to display the default values from data but as soon as I try to modify the field, I get the following error whenever I try to type changes to the input box.
*vue.min.js:6 TypeError: Cannot use 'in' operator to search for 'fullname' in undefined
at a.ke [as $set] (vue.min.js:6)
at input (eval at Ya (vue.min.js:1), <anonymous>:3:2182)
at He (vue.min.js:6)
at HTMLInputElement.n (vue.min.js:6)
at HTMLInputElement.Yr.o._wrapper (vue.min.js:6)*
In given Below I added the code of the component I'm trying to create:
Any help, please.
var bus = new Vue();
Vue.component('leagues_add', {
props: {
show: Boolean,
is_admin: Boolean,
},
data: function () {
return {
newLeague: {"fullname":"a", "notes":"b", "group_image_path": "c"} // remember to always enclose the fieldnames in doublequotes
}
},
methods: {
closeModal() {
this.show = false;
},
showModal() {
this.show = true;
},
addLeague() {
event.preventDefault();
var formData = this.toFormData(this.newLeague);
axios.get("http://"+ window.location.hostname +"/db/leagues/index.php?action=create").then(function(response){
if (response.data.error) {
app.errorMessage = response.data.message;
} else {
app.leagues = response.data.leagues;
}
});
},
toFormData(obj) {
var fd = new FormData();
for (var i in obj) {
fd.append(i, obj[i]);
}
return fd;
},
}
,
template:
`
<!-- Add new Leage -->
<div>
<div class="text-center pb-3" >
<button type="button" class="btn btn-outline-primary bg-success text-white" #click="showModal"><b class="" style="">Add League</b></button>
</div>
<transition name="modal">
<div id="overlay" v-show="this.show">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add League</h5>
<button type="button" class="close" #click="closeModal"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<form action="#" method="POST">
<div class="form-group">
<input type="text" v-model="this.newLeague.fullname" class="form-control form-control-md" placeholder="Name of League">
</div>
<div class="form-group">
<textarea v-model="this.newLeague.notes" rows="3" cols="100%" name="notes" class="form-control form-control-md" placeholder="Describe this league">
</textarea>
</div>
<div class="form-group form-inline ">
<div class="col-12 p-0">
<input type="url" v-model="this.newLeague.group_image_path" class="col-5 pull-left form-control form-control-md" placeholder="Image URL">
<button class="col-4 btn btn-primary btn-md">Image</button>
</div>
</div>
<div class="form-group">
<button class="btn btn-info btn-block btn-md" #click="closeModal();addLeague();">Add this league</button>
</div>
</form>
</div>
</div>
</div>
</div>
</transition>
<div>
`
});
<div class="row">
<div class="col-md-12">LEAGUES SECTION</div>
</div>
<div class="row mt-2">
<div class="col-md-12">
<leagues_add :show="true" />
</div>
</div>
The problem is here:
v-model="this.newLeague.fullname"
You cannot use this. with v-model. Instead it should be:
v-model="newLeague.fullname"
You should also remove all other references to this within your template. In many cases they are harmless but sometimes, such as with v-model, they will cause problems.
Complete examples below. Note how the first input does not function correctly when editing the text.
new Vue({
el: '#app1',
data () {
return { newLeague: { fullname: 'League 1' } }
}
})
new Vue({
el: '#app2',
data () {
return { newLeague: { fullname: 'League 1' } }
}
})
<script src="https://unpkg.com/vue#2.6.11/dist/vue.js"></script>
<div id="app1">
<input type="text" v-model="this.newLeague.fullname">
{{ newLeague.fullname }}
</div>
<div id="app2">
<input type="text" v-model="newLeague.fullname">
{{ newLeague.fullname }}
</div>
I followed the way #skirtle wrote the data section and it worked.
My original syntax was:
data: function () {
return {
newLeague: {"fullname":"a", "notes":"b", "group_image_path": "c"} }
}
to
data () {
return { newLeague: { fullname: 'League 1' } }
}

Get all Input values - Vuejs

I have multiple input elements in a simple VueJs application. But I don't have and form elements. Now I want to get all the input values at once and send to server-side [laravel] for processing?
<div>
<input v-model="foo-bar" placeholder="edit me">
<input v-model="bar-foo" placeholder="edit me">
<input v-model="foo-foo" placeholder="edit me">
<input v-model="bar-bar" placeholder="edit me">
</div>
<div>
<input type="button" #click="getAllData">Send</input>
</div>
getAllData(){
// I have no idea how to get all at once!
}
How about you store everything in a convenient form object, eg
new Vue({
el: '#app',
data: {
form: {} // create an object to hold all form values
},
methods: {
getAllData() {
console.info(this.form)
// axios.post('/some/url', this.form)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<div>
<input v-model="form['foo-bar']" placeholder="edit me">
<input v-model="form['bar-foo']" placeholder="edit me">
<input v-model="form['foo-foo']" placeholder="edit me">
<input v-model="form['bar-bar']" placeholder="edit me">
</div>
<div>
<button type="button" #click="getAllData">Send</button>
</div>
</div>
As you can see in the demo, all you need to do is reference this.form for all the values.
<form v-on:submit.prevent="getAllData" id="frm">
<input name="input1" placeholder="edit me">
<input name="input2" placeholder="edit me">
<input name="input3" placeholder="edit me">
<input name="input4" placeholder="edit me">
<input type="submit" >Send</input>
</form>
<script>
....
//your method parts
methods:{
getAllData(){
let myForm = document.getElementById('frm');
let formData = new FormData(myForm);
const data = {};
// need to convert it before using not with XMLHttpRequest
for (let [key, val] of formData.entries()) {
Object.assign(data, {[key]: val})
}
console.log(data);
},
}
....
<script>
Bind the inputs to Vues data option:
new Vue({
el: "#app",
data: {
myArray: [null, null, null, null]
},
methods: {
getAllData() {
console.log(this.myArray)
// send to server
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<input v-for="(arr, index) in myArray" v-model="myArray[index]" #key="index" placeholder="edit me">
</div>
<div>
<button type="button" #click="getAllData">Send</button>
</div>
</div>

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

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/