The following code gives me some next error.
All I'm trying to do is input data, then the button should do an alert and output the data that's inputted.
<template>
<div class="hello">
<h1> {{ greeting }} </h1>
<label for="value"> Name </label>
<input type="text" v-model="value" placeholder="input name">
<button type="submit" v-on:click="clickHandler" class="btn btn-primary">Submit</button>
</div>
</template>
<script src="./main.js"></script>
<script>
export default {
name: 'input-data',
data: function() {
return {
value: String,
greeting: "Welcome to Heaven Stranger"
}
},
methods: {
clickHandler: function() {
alert("Name of SIR: " + value);
}
}
}
methods: {
clickHandler: function() {
alert("Name of SIR: " + this.value);
}
}
here your code to sandbox and play
Related
I am trying to submit form which will redirect to different page containing post request data . Basically I hit redirectCompo component from another component
return this.$router.push({path: '/form-submit-component'});
form submit component but it's not redirecting
<template>
<div style="visibility: hidden;">
<form name="PostForm" id="PostForm" method="POST" action="www.google.com">
<input type="text" name="email_id" value="xyz#gmail.com">
<input type="text" name="gender" value="male">
</form>
</div>
</template>
<script>
export default {
name: 'redirectCompo',
computed: {},
components: {},
data: function () {
return {}
},
mounted() { },
created() {
document.getElementById("PostForm").submit();
},
methods: {},
}
</script>
<template>
<div>
<form name="PostForm" id="PostForm" method="POST" action="www.google.com">
<input type="text" name="email_id" value="xyz#gmail.com" />
<input type="text" name="gender" value="male" />
<button type="submit">submit</button>
</form>
</div>
</template>
<script>
export default {
name: "redirectCompo",
computed: {},
components: {},
created() {
this.submit();
},
methods: {
submit() {
console.log("form has been submitted");
this.$router.push({ path: "/home" });
},
},
data: function () {
return {};
},
};
</script>
Why does it work on the first, and it doesn't work on the second?
First row work: https://imgur.com/b45QlU3
Last row doesn't work: https://imgur.com/S79Gq5M
vue:
<template>
<div>
<div class="form-group" v-for="(input,index) in inputs" :key="index">
<input type="text" name="medicine[]" class="form-control">
<span>
Add
Remove
</span>
</div>
</div>
</template>
<script type="text/javascript">
export default{
data(){
return{
inputs:[{}]
}
},
methods:{
add(){
this.inputs.push({
medicine:''
})
},
remove(index)
{
this.inputs.splice(index,1)
}
}
}
</script>
I have a component that dynamically adds inputs to my application. One input is a text input and another is a file input. In the case of text input everything works, I take the value via v-model. In the case of file input it is not possible to use v-model, instead v-on: change is used. How do I add the filename to the lists object dynamically?
Template
<template lang="html">
<div v-for="list in lists">
<input type="text" v-model="list.text" >
<input type="file" #change="upload">
</div>
<button #click="addItem">Add Item</button>
</template>
Script
<script>
export default {
data() {
return {
lists:[{text: '', filename: '',}]
}
},
methods: {
addItem() {
this.lists.push({ text: '', filename: '' })
},
upload(event) {
this.lists.filename = event.target.files[0].name
},
}
}
</script>
I'm using Vue 3.
Thanks in advance.
You can iterate with the index as well, then pass the index to the upload function, like this:
<script>
export default {
data() {
return {
lists:[{text: '', filename: '',}]
}
},
methods: {
addItem() {
this.lists.push({ text: '', filename: '' })
},
upload(event, index) {
this.lists[index].filename = event.target.files[0].name
},
}
}
</script>
<template lang="html">
<div v-for="(list, index) in lists">
<input type="text" v-model="list.text" >
<input type="file" #change="upload($event, index)">
</div>
<button #click="addItem">Add Item</button>
</template>
You can bind with array index, do not need upload method
new Vue({
el: '#app',
data() {
return {
title: "Vue app",
lists:[{text: '', filename: '',}]
};
},
methods:{
addItem() {
this.lists.push({ text: '', filename: '' })
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"><h2>{{title}}</h2>
<div v-for="(list,i) in lists">
<input type="text" v-model="lists[i].text" >
<input type="file" v-model="lists[i].filename">
</div>
<button #click="addItem">Add Item</button>
<pre>{{lists}}</pre>
</div>
You can do it like this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<input id='inputfile' type='file' name='inputfile' onChange='getoutput()'>
new Vue({
el: '#app',
data() {
return {
title: "Vue app",
lists:[{text: '', filename: '',}]
};
},
methods:{
addItem() {
this.lists.push({ text: '', filename: '' })
},
getFile(filePath) {
return filePath.substr(filePath.lastIndexOf('\\') + 1).split('.')[0];
},
getoutput(e, index) {
let fileName = this.getFile(e.target.value);
let fileExtention = e.target.value.split('.')[1];
this.lists[index].filename = `${fileName}.${fileExtention}`;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"><h2>{{title}}</h2>
<div v-for="(list,i) in lists">
<input type="text" v-model="lists[i].text" >
<input type="file" #change="getoutput($event, i)">
</div>
<button #click="addItem">Add Item</button>
<pre>{{lists}}</pre>
</div>
I am new to Vue and Nuxt and I am building simple forms with simple-vue-validator for validating the form before I submit it to the back-end. I did follow the Nuxtjs plugin's documentation but I am getting some errors 😞
The error I am getting is TypeError: Cannot read property 'Validator' of undefined.
I can't find any $SimpleValidator on this. Not sure if I did something wrong or forgot something, but I keep reading the documentation and this is all I understand. Thanks in advance.
./plugins/simple-validator.js
import Vue from 'vue'
import SimpleValidator from 'simple-vue-validator'
Vue.use(SimpleValidator)
./nuxt.config.js
export default {
...
plugins: [
{ src: '#/plugins/simple-validator.js', ssr: true }
],
...
}
./pages/index.vue*
<template>
<form>
<div class="field-holder">
first name *
<input type="text" v-model="formValues.firstName" :value="formValues.firstName" />
<span v-if="validation.hasError('firstName')">
{{ validation.firstError('firstName') }}
</span>
</div>
<div class="field-holder">
middle name
<input type="text" v-model="formValues.middleName" :value="formValues.middleName" />
</div>
<div class="field-holder">
last name *
<input type="text" v-model="formValues.lastName" :value="formValues.lastName" />
<span v-if="validation.hasError('lastName')">
{{ validation.firstError('lastName') }}
</span>
</div>
<button #click="submit">Submit</button>
</form>
</template>
<script>
export default {
data () {
formValues: {
firstName: '',
middleName: '',
lastName: ''
}
},
validators: {
'formValues.firstName' (value) {
return this.$SimpleValidator.Validator.value(value).required()
},
'formValues.lastName' (value) {
return this.$SimpleValidator.Validator.value(value).required()
}
},
methods: {
submit (event) {
event.preventDefault()
this.$validate()
.then(function (success) {
if (success) {
console.log('Validation succeeded!')
}
})
}
}
}
</script>
I fixed my issue! 🎊
We just need to add import { Validator } from 'simple-vue-validator' to the component that requires it. So the updated component will look like this:
./pages/index.vue
<template>
<form>
<div class="field-holder">
first name *
<input type="text" v-model="formValues.firstName" :value="formValues.firstName" />
<span v-if="validation.hasError('firstName')">
{{ validation.firstError('firstName') }}
</span>
</div>
<div class="field-holder">
middle name
<input type="text" v-model="formValues.middleName" :value="formValues.middleName" />
</div>
<div class="field-holder">
last name *
<input type="text" v-model="formValues.lastName" :value="formValues.lastName" />
<span v-if="validation.hasError('lastName')">
{{ validation.firstError('lastName') }}
</span>
</div>
<button #click="submit">Submit</button>
</form>
</template>
<script>
import { Validator } from 'simple-vue-validator'
export default {
data () {
formValues: {
firstName: '',
middleName: '',
lastName: ''
}
},
validators: {
'formValues.firstName' (value) {
return Validator.value(value).required()
},
'formValues.lastName' (value) {
return Validator.value(value).required()
}
},
methods: {
submit (event) {
event.preventDefault()
this.$validate()
.then(function (success) {
if (success) {
console.log('Validation succeeded!')
}
})
}
}
}
</script>
I want to re-use a form component through my website, but the submit button will have to handle different things every time (display different data, depending which page is calling the form-component)
I'm a little bit new to paying around with Vue components and passing data between them, up until now I did messy one-page apps.
My current plan is have the form get the inputs/filters (from the form component), and when clicking submit, it should send this data (somehow?) to the element that called it - and will know how to handle it to the specific case from where it was called. I hope this is the right approach to this kind of scenario (?).
Is my plan a proper use of Vue / a proper way to submit a form from an external form-component?
In what way do I trigger the submit to send data / run a method outside of my DashboardForm.vue component?
How do I send fetched data of DashboardForm.vue component from ReportType1.vue and re-use this functionality in ReportType2.vue.
This is my Vue Form component (DashboardForm.vue):
<template>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<form id="mainForm" class="form-material row" method="POST">
<div class="" id="date-range">
<datepicker v-model="startDate" input-class="form-control inputDate" placeholder="Start Date" required></datepicker>
<div class="input-group-append">
<span class="input-group-text b-0 text-white"> to </span>
</div>
<datepicker v-model="endDate" input-class="form-control inputDate" placeholder="End Date" required></datepicker>
<input type="button" class="btn btn-info waves-effect waves-light" v-on:click="groupFilterDisplay(true);" value="Filter by Group"/>
<!-- <input type="button" id="submit-btn" class="btn btn-success waves-effect waves-light" v-on:click="loadNew" value="Submit"/> -->
<input type="button" id="submit-btn" class="btn btn-success waves-effect waves-light" value="Submit"/>
</div>
</form>
</div>
</div>
</div>
<transition name="fade">
<div id="groupFilter" class="popupGroupFilter" v-if="groupFilter">
<div id="filterArea">
<input type="text" v-model="searchGroupInput" placeholder="Search" class="gfSearch">
<span class="gfTitle">Filter by Group</span>
<hr>
</div>
<div class="ulTree">
<ul>
<tree_item class="item" v-bind:model="groupTree"></tree_item>
</ul>
</div>
<div v-on:click="applyGroupFilter();" class="gfClose gfApply"><span>✔ Apply</span></div>
<div v-on:click="groupFilterDisplay(false);" class="gfClose"><span>X Close</span></div>
</div>
</transition>
</div>
</template>
<script>
// import { GF } from '../mixins/GF.js';
export default {
name: 'DashboardForm',
// mixins: [GF],
data() {
return {
groupTree: window.groups,
searchGroupInput: '',
searchGroupArray: [],
groupFilterApplied: false,
groupFilterBackup: [],
selectedIds: [],
groupFilter: false,
startDate: null,
endDate: null,
mode: 0,
}
},
props: {
options: Array
},
watch: {
'searchGroupInput': function (newVal, oldVal) {
this.groupTree = this.searchGroupResult();
}
},
methods: {
recurseGroups: function (arr, action) {
},
applyGroupFilter: function () {
},
groupFilterDisplay: function (display) {
},
searchGroupResult: function () {
},
fetchGroupIds: function () {
}
}
};
</script>
This is the component that uses the DashboardForm for example (
ReportType1.vue):
<script>
import DashboardForm from "../tools/DashboardForm.vue";
export default {
components: {
DashboardForm
},
data() {
return {
};
},
created() {
},
mounted() {
},
destroyed() {
},
watch: {
},
methods: {
}
}
</script>
<!-- Template -->
<template>
<div>
<!-- Form -->
<DashboardForm/>
<!-- form result -->
<div id="resultContainer"> <datatable/> </div>
</div>
</template>
Okay if I understood you well, we are trying to build a reusable form component.
I will give you a quick overview of how VUE components communicate.
The component takes its necessary inputs using the props.
The component inner HTML can be passed from its user by using slot.
The component fire events to tell its user that there is something happened inside me.
Example of the three cases:
Your component my-form template:
<form>
<div class="row">
<slot></slot>
</div>
<div class="row">
<div class="col-12">
<button type="button" class="btn btn-default" #click="onSubmit"></button>
<button v-if="hasReset" class="btn btn-danger" #click="onReset"></button>
</div>
</div>
</form>
Your component js file:
export default {
name: 'my-form',
data() {
return {
}
},
props: {
reset: boolean
},
computed: {
hasReset: function(){
return this.reset;
}
}
methods: {
onSubmit: function(){
let data = { "name": "dummy data" };
this.$emit("submit", data);
},
onReset: function(){
let data = { "name": "" };
this.$emit("reset", data);
}
}
}
After that, you can use my-form component as below:
<my-form :reset="formHasReset" #submit="onFormSubmit" #reset="onFormReset">
<input class="col-12" type="text" name="name">
<input class="col-12" type="text" name="username">
<input class="col-12" type="password" name="password">
<input class="col-12" type="email" name="email">
</my-form>
And the javascript is:
data(){
formHasReset: true
},
methods: {
onFormSubmit: function(data){
console.log(data.name); //Should give you 'dummy data'
},
onFormReset: function(data){
console.log(data.name); //Should give you ''
}
}
I hope it is clear now for you :).