How to make this three components into a multistep form wizard - vue.js

Here I have made three components. That is displaying one after other I want to make this component to display like multistep form. like step1, step2, step3, Here if we click next button from step1 than it should go to step2. and so on..., So if any one have an idea on this pleas help me thank you.
<head>
<script src="https://unpkg.com/vue#2.5.17/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-form-generator#2.3.4/dist/vfg.js"></script>
<script src="https://unpkg.com/vue-form-generator#2.3.4/dist/vfg.css"></script>
</head>
<div class="container" id="app">
<div class="panel panel-default">
<div class="panel-heading">Form</div>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</div>
</div>
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
<script>
vue.js
var vm = new Vue({
el: "#app",
components: {
"vue-form-generator": VueFormGenerator.component
},
data() {
return {
model: {
id: "",
name: "",
password: "",
age: "",
skills: "",
email: "",
status: ""
},
schema: {
fields: [{
type: "input",
inputType: "text",
label: "ID",
model: "id",
readonly: true,
featured: false,
disabled: true
}, {
type: "input",
inputType: "text",
label: "Name",
model: "name",
readonly: false,
featured: true,
required: true,
disabled: false,
placeholder: "User's name",
}, {
type: "input",
inputType: "password",
label: "Password",
model: "password",
min: 6,
required: true,
}, {
type: "input",
inputType: "number",
label: "Age",
model: "age",
min: 18,
validator: VueFormGenerator.validators.number
}, {
type: "input",
inputType: "email",
label: "E-mail",
model: "email",
placeholder: "User's e-mail address",
validator: VueFormGenerator.validators.email
}, {
type: "checklist",
label: "Skills",
model: "skills",
multi: true,
required: true,
multiSelect: true,
values: ["HTML5", "Javascript", "CSS3", "CoffeeScript", "AngularJS", "ReactJS", "VueJS"]
}, {
type: "switch",
label: "Status",
model: "status",
multi: true,
readonly: false,
featured: false,
disabled: false,
default: true,
textOn: "Active",
textOff: "Inactive"
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
};
},
});

Related

Vuetify datatable not show custom cells with v-slot

I have an asp .net web forms app with Vue 2.7.14 and Vuetify 2.6.13.
I have a table and I want to implement v-slot:item.fieldName to style certain cells but it doesn't work.
<v-data-table :footer-props="{ 'items-per-page-options': [10, 50, 100, 500, 1000] }" :items-per-page="10" :headers="headers" :items="supplierList" :loading="loadingGrid" :loading-text="$t('gral_loading')" :options.sync="options" :server-items-length="totalItems">
<template v-slot:item.businessName="{item}">
Hola
</template>
</v-data-table
headers: [
{ text: this.$t('supplier_code'), value: 'code' },
{ text: this.$t('supplier_businessName'), value: 'businessName' },
{ text: this.$t('supplier_alias'), value: 'alias' },
{ text: this.$t('supplier_isDirect'), value: 'isDirect' },
{ text: this.$t('supplier_isAppendFile'), value: 'isAppendFile' },
{ text: this.$t('supplier_isSendEDINotification'), value: 'isSendEDINotification' },
{ text: this.$t('supplier_cat_PlantId'), value: 'plantName' },
{ text: this.$t('supplier_cat_AnalystId'), value: 'analystProcess' },
{ text: this.$t('supplier_cat_supplierTypeId'), value: 'supplierTypeName' },
{ text: this.$t('supplier_isActive'), value: 'isActive' },
{
text: this.$t('gral_acciones'),
value: 'action',
sortable: false
},
],
This is the array data items :
supplierList: [{
"supplierTypeId": 1,
"name": "Transportista",
"description": "Transportista",
"isScrap": false,
"isSystem": false,
"isActive": true,
"isDelete": false,
"creationDate": "0001-01-01T00:00:00",
"lastUpdate": "0001-01-01T00:00:00",
"createdBy": 1,
"lastUpdateBy": 0,
"systemId": null,
"sessionData": null,
"item": null,
"page": null,
"size": null,
"sortBy": null,
"ascending": null,
"alertNotification": null
}]
After spending some time and play around with the v-data-table demo, I found that as long as the headers value is in lowercase the issue doesn't appear.
Working Demo :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [{ text: 'Code', value: 'code' },
{ text: 'Business Name', value: 'businessname' },
{ text: 'Alias', value: 'alias' },
{ text: 'Is Direct', value: 'isDirect' },
{ text: 'Is Append File', value: 'isAppendFile' },
{ text: 'Notification', value: 'isSendEDINotification' },
{ text: 'Plant Name', value: 'plantName' },
{ text: 'Analyst Process', value: 'analystProcess' },
{ text: 'Supplier Type Name', value: 'supplierTypeName' },
{ text: 'Is Active', value: 'isActive' },
{ text: 'Action', value: 'action' }],
supplierList: [{
"supplierTypeId": 1,
"name": "Transportista",
"description": "Transportista",
"isScrap": false,
"isSystem": false,
"isActive": true,
"isDelete": false,
"creationDate": "0001-01-01T00:00:00",
"lastUpdate": "0001-01-01T00:00:00",
"createdBy": 1,
"lastUpdateBy": 0,
"systemId": null,
"sessionData": null,
"item": null,
"page": null,
"size": null,
"sortBy": null,
"ascending": null,
"alertNotification": null
}],
}
}
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.14/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.14/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"/>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="supplierList"
:items-per-page="5">
<template v-slot:item.businessname="{item}">
<span>Hola</span>
</template>
</v-data-table>
</v-app>
</div>

Show remaining API data on b-table through pagination

I'm trying to hit all the data from API using axios in Nuxt, but it seems only shows 10 data each page, so if there's actually 15 data which I expect to hit, it has to show 2 page (page 1 with 10 data, page 2 with the remaining 5 data). I had no idea why does it only want to show every 10 data
per page.
How to show the remaining data in next page? Here's what I've been doing so far
<script>
// eslint-disable-next-line no-unused-vars
import { getAllProvinces } from '~/api/delivery'
export default {
data() {
return {
filter: null,
filterOn: [],
perPage: 10,
currentPage: 1,
rows: 0,
items: [],
fields: [
{
key: 'id',
sortable: true,
label: 'ID',
class: 'truncate',
},
{
key: 'uploadReference',
sortable: true,
label: 'Upload Reference',
class: 'truncate',
},
{
key: 'requestId',
sortable: true,
label: 'Request ID',
class: 'truncate',
},
{
key: 'storeCode',
sortable: true,
label: 'Store Code',
class: 'truncate',
},
{
key: 'branchCode',
sortable: true,
label: 'Branch Code',
class: 'truncate',
},
{
key: 'b2bId',
sortable: true,
label: 'B2B ID',
class: 'truncate',
},
{
key: 'request',
sortable: true,
label: 'Request',
class: 'truncate',
},
{
key: 'response',
sortable: true,
label: 'Response',
class: 'truncate',
},
{
key: 'createDate',
sortable: true,
label: 'Create Date',
class: 'truncate',
},
{
key: 'errorClassification',
sortable: true,
label: 'Error Classification',
class: 'truncate',
},
],
}
},
watch: {
currentPage: {
handler(value) {
this.getAllStock()
},
},
},
created() {
this.getAllStock()
},
methods: {
getAllStock() {
this.$axios
.get(
'axioslink' +
this.currentPage +
'&status=1'
)
.then((res) => {
// eslint-disable-next-line no-console
console.log(res.data)
this.items = res.data.stocks
this.allStock = res.data
this.rows = res.data.totalDocuments
// eslint-disable-next-line no-console
})
this.rows = this.items.length
},
onFiltered(filteredItems) {
this.rows = filteredItems.length
this.currentPage = 1
},
},
}
</script>
<div class="text-center">
<b-table
id="my-table"
:per-page="perPage"
:current-page="currentPage"
striped
small
hover
dark
responsive
show-empty
:items="items"
:fields="fields"
:filter="filter"
:filter-included-fields="filterOn"
#filtered="onFiltered"
>
<template v-slot:cell()="data">
<span v-b-tooltip.hover :title="data.value">{{
data.value
}}</span>
</template>
</b-table>
</div>
</template>
<div class="overflow-auto">
<b-card-footer class="py-4 d-flex justify-content-end">
<b-pagination
:total-rows="rows"
:per-page="perPage"
aria-controls="my-table"
#change="currentPage = $event"
></b-pagination>
</b-card-footer>
</div>
Thanks and have a great day
new Vue({
el: "#menu",
data: () => ({
filter: null,
filterOn: [],
perPage: 10,
currentPage: 1,
rows: 0,
items: [],
fields: [{
key: 'id',
sortable: true,
label: 'ID',
class: 'truncate',
},
{
key: 'uploadReference',
sortable: true,
label: 'Upload Reference',
class: 'truncate',
},
{
key: 'requestId',
sortable: true,
label: 'Request ID',
class: 'truncate',
},
{
key: 'storeCode',
sortable: true,
label: 'Store Code',
class: 'truncate',
},
{
key: 'branchCode',
sortable: true,
label: 'Branch Code',
class: 'truncate',
},
{
key: 'b2bId',
sortable: true,
label: 'B2B ID',
class: 'truncate',
},
{
key: 'request',
sortable: true,
label: 'Request',
class: 'truncate',
},
{
key: 'response',
sortable: true,
label: 'Response',
class: 'truncate',
},
{
key: 'createDate',
sortable: true,
label: 'Create Date',
class: 'truncate',
},
{
key: 'errorClassification',
sortable: true,
label: 'Error Classification',
class: 'truncate',
},
],
}),
methods: {
getAllStock() {
this.items = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }, { id: 7 }, { id: 8 }, { id: 8 }, { id: 10 }, { id: 11 }, { id: 12 }, ]
// this.allStock = res.data
this.rows = this.items.length
},
onFiltered(filteredItems) {
this.rows = filteredItems.length
this.currentPage = 1
},
},
created() {
this.getAllStock()
},
});
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.18.1/bootstrap-vue.min.css" />
<script src="https://unpkg.com/vue#2.6.12/dist/vue.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.18.1/bootstrap-vue.min.js"></script>
<div id="menu">
<b-table id="my-table" :per-page="perPage" :current-page="currentPage" striped small hover dark responsive show-empty :items="items" :fields="fields" :filter="filter" :filter-included-fields="filterOn" #filtered="onFiltered">
</b-table>
<b-pagination v-model="currentPage" :total-rows="rows" :per-page="perPage" aria-controls="my-table"></b-pagination>
</div>

How to bind "v-model" property in vue?

I want to show list of inputs dynamically.
I am not asking about using v-bind OR v-model, I want to bind v-model property itself (like v-bind:v-model).
Here is the code but it does not work.
<template>
<div class="form-outside">
<form>
<div v-for="(input, index) in inputs" :key="index">
<div class="caption">{{input.caption}}</div>
<input :type="input.type" :v-model="input.model" />
</div>
<div v-if="error" class="error-message">{{error}}</div>
<div v-if="kind=='login'" class="suggestion">
Don't have an account?
<nuxt-link to="/signup">Sign up</nuxt-link> instead!
</div>
<div v-if="kind=='signup'" class="suggestion">
Have an account?
<nuxt-link to="/login">Log in</nuxt-link> instead!
</div>
<div v-if="loading" class="loading">Loading</div>
<button #click.prevent="submitted" v-if="!loading">{{button_text}}</button>
</form>
</div>
</template>
<script>
export default {
name: "AuthForm",
props: ["kind", "error", "loading"],
methods: {
submitted() {
this.$emit("submitted", {
email: this.email,
password: this.password,
confirm_password: this.confirm_password,
full_name: this.full_name,
login: this.login,
username: this.username
});
}
},
computed: {
button_text() {
if (this.kind == "login") return "Log in";
if (this.kind == "signup") return "Sign up";
},
inputs() {
return this.possible_inputs.filter(
input => input.when == "always" || input.when == this.kind
);
}
},
data() {
return {
email: "",
password: "",
confirm_password: "",
full_name: "",
login: "",
username: "",
possible_inputs: [
{
caption: "Full Name",
type: "text",
when: "signup",
model: this.full_name
},
{
caption: "Email",
type: "email",
when: "signup",
model: this.email
},
{
caption: "Email or Username",
type: "text",
when: "login",
model: this.login
},
{
caption: "Username",
type: "text",
when: "signup",
model: this.username
},
{
caption: "Password",
type: "password",
when: "always",
model: this.password
},
{
caption: "Confirm Password",
type: "password",
when: "signup",
model: this.confirm_password
}
]
};
}
};
</script>
(This is some additional text because stackoverflow says “It looks like your post is mostly code, please add some more details”, just ignore it)
In data(){} you cannot assign in this way model: this.email so you need to assign it in mounted() {} hook, check the code below:
<script>
export default {
data() {
return {
email: "",
password: "",
confirm_password: "",
full_name: "",
login: "",
username: "",
possible_inputs: []
};
},
mounted() {
this.possible_inputs = [
{
caption: "Full Name",
type: "text",
when: "signup",
model: this.full_name
}, {
caption: "Email",
type: "email",
when: "signup",
model: this.email
}, {
caption: "Email or Username",
type: "text",
when: "login",
model: this.login
}, {
caption: "Username",
type: "text",
when: "signup",
model: this.username
}, {
caption: "Password",
type: "password",
when: "always",
model: this.password
}, {
caption: "Confirm Password",
type: "password",
when: "signup",
model: this.confirm_password
},
];
},
};
</script>

Vuejs2- How to do an inline alignment of a radio button in vue-form-generator?

Iam using "vue-form-generator" plugin for dynamic loading of form fields. Among the fields, I am using "radio-button" for the "gender" field. Options are displayed in one below the other but I want the option should be displayed in the "inline" style
How to align the radio button option in the same row(inline)?
Here is my code: addMember.vue
<template>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
<input type="submit" value="Submit">
</div>
</template>
<script>
import Vue from 'vue'
import VueFormGenerator from "vue-form-generator";
import "vue-form-generator/dist/vfg.css";
Vue.use(VueFormGenerator);
export default {
data: () => ({
model: {
building: "",
unitCategory: "",
unit: "",
fullName: "",
gender: "",
},
schema: {
groups: [{
fields: [{
type: "select",
inputType: "text",
label: "Building",
model: "building",
required: true,
styleClasses:'col-md-6',
values: [
{ id: "", name: 'Select Building' },
{ id: 'A', name: 'Block-A'},
{ id: 'B', name: 'Block-B'},
],
selectOptions: {
hideNoneSelectedText: true,
}
}]
},{
fields: [{
type: "select",
inputType: "text",
label: "Unit Category",
model: "unitCategory",
required: true,
styleClasses:'col-md-3',
values: [
{ id: "", name: 'Select Unit Category' },
],
selectOptions: {
hideNoneSelectedText: true,
}
},{
type: "select",
inputType: "text",
label: "Unit",
model: "unit",
required: true,
styleClasses:'col-md-3',
values: [
{ id: "", name: 'Select Unit' },
],
selectOptions: {
hideNoneSelectedText: true,
}
}]
},{
fields: [{
type: "input",
inputType: "text",
label: "Full Name",
model: "fullName",
placeholder: "Enter Full Name",
required: true,
styleClasses:'col-md-3'
},
{
type: "radios",
label: "Gender",
model: "gender",
values: [
"Male",
"Female",
"Other"
],
styleClasses:'col-md-3'
}]
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}),
}
</script>
You can add custom css to your radio input
{
type: "radios",
label: "Gender",
model: "gender",
values: [
"Male",
"Female",
"Other"
],
styleClasses:'col-md-3 display-inline'
}
and in your css
.display-inline label {
display: inline !important;
}
var vm = new Vue({
el: "#app",
components: {
"vue-form-generator": VueFormGenerator.component
},
data() {
return {
model: {
},
schema: {
fields: [{
type: "radios",
label: "Select your gender",
model: "friend",
values: [
"Male",
"Female",
"Others"
],
styleClasses: "display-inline"
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
};
}
});
.display-inline label {
display: inline !important;
}
<link href="https://cdn.jsdelivr.net/npm/vue-form-generator#2.2.2/dist/vfg.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue-form-generator#2.2.2/dist/vfg.min.js"></script>
<script src="https://unpkg.com/vue#2.2.1/dist/vue.min.js"></script>
<h1 class="text-center">Demo of vue-form-generator</h1>
<div class="container" id="app">
<div class="panel panel-default">
<div class="panel-heading">Form</div>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</div>
</div>
</div>

Vuejs2- Issue in vue-form-generator

I am using "vue-form-generator" plugin for loading fields dynamically but I have encountered an error
[Vue warn]: Failed to mount component: template or render function not defined. found in vue-form-generator
Here is my code:
<template>
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</template>
<script>
import Vue from 'vue'
import VueFormGenerator from "vue-form-generator";
Vue.use(VueFormGenerator);
export default {
components: { VueFormGenerator },
data: () => ({
model: {
id: 1,
name: "John Doe",
password: "J0hnD03!x4",
skills: ["Javascript", "VueJS"],
email: "john.doe#gmail.com",
status: true
},
schema: {
fields: [{
type: "input",
inputType: "text",
label: "ID (disabled text field)",
model: "id",
readonly: true,
disabled: true
},{
type: "input",
inputType: "text",
label: "Name",
model: "name",
placeholder: "Your name",
featured: true,
required: true
},{
type: "input",
inputType: "password",
label: "Password",
model: "password",
min: 6,
required: true,
hint: "Minimum 6 characters",
validator: VueFormGenerator.validators.string
},{
type: "select",
label: "Skills",
model: "skills",
values: ["Javascript", "VueJS", "CSS3", "HTML5"]
},{
type: "input",
inputType: "email",
label: "E-mail",
model: "email",
placeholder: "User's e-mail address"
},{
type: "checkbox",
label: "Status",
model: "status",
default: true
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
})
}
</script>
To use it as local component, you should use this syntax
import VueFormGenerator from "vue-form-generator";
//component javascript
export default{
components:{
"vue-form-generator": VueFormGenerator.component
}
}
If you use
import VueFormGenerator from "vue-form-generator";
Vue.use(VueFormGenerator);
then it already registered VueFormGenerator as global. You don't need to register in components section of your code.
Here is our code with local component:
<template>
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</template>
<script>
import Vue from 'vue'
import VueFormGenerator from "vue-form-generator";
export default {
components:{
"vue-form-generator": VueFormGenerator.component
},
data: () => ({
model: {
id: 1,
name: "John Doe",
password: "J0hnD03!x4",
skills: ["Javascript", "VueJS"],
email: "john.doe#gmail.com",
status: true
},
schema: {
fields: [{
type: "input",
inputType: "text",
label: "ID (disabled text field)",
model: "id",
readonly: true,
disabled: true
},{
type: "input",
inputType: "text",
label: "Name",
model: "name",
placeholder: "Your name",
featured: true,
required: true
},{
type: "input",
inputType: "password",
label: "Password",
model: "password",
min: 6,
required: true,
hint: "Minimum 6 characters",
validator: VueFormGenerator.validators.string
},{
type: "select",
label: "Skills",
model: "skills",
values: ["Javascript", "VueJS", "CSS3", "HTML5"]
},{
type: "input",
inputType: "email",
label: "E-mail",
model: "email",
placeholder: "User's e-mail address"
},{
type: "checkbox",
label: "Status",
model: "status",
default: true
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
})
}
</script>