Vuejs get dynamic form values - vue.js

I have select and input component with made by buefy. Everything is ok till I realize how can I get the data.
I'm sort of new on vuejs. So I will be glad if you help me out.
I'm getting dynamic form from backend
So my question is how can get values these inputs and submit to backend again with getOffer() methot.
Here is my codes;
Input.vue
<template>
<b-field :label="fieldLabel">
<b-input
:name="inputName"
:type="inputType"
:maxlength="inputType == 'textarea' ? 200 : null"
></b-input>
</b-field>
</template>
<script>
export default {
name: "Input",
props: {
inputType: {
type: String,
required: true,
default: "text",
},
inputName: {
type: String,
required: true,
},
fieldLabel: {
type: String,
required: true,
}
}
};
</script>
Home.vue
<template>
<div class="container is-max-desktop wrapper">
<div v-for="element in offer" :key="element.id">
<Input
v-model="element.fieldValue"
:value="element.fieldValue"
:fieldLabel="element.fieldLabel"
:inputType="element.fieldType"
:inputName="element.fieldName"
v-if="element.fieldType != 'select'"
class="mb-3"
/>
<Select
v-model="element.fieldValue"
:fieldLabel="element.fieldLabel"
:options="element.infoRequestFormOptions"
:selectName="element.fieldName"
v-if="element.fieldType == 'select'"
class="mb-3"
/>
</div>
<b-button type="is-danger" #click="getOffer()">GET</b-button>
</div>
</template>
<script>
import axios from "axios";
import Select from "../components/Select.vue";
import Input from "../components/Input.vue";
export default {
name: "Home",
data() {
return {
offer: [],
};
},
components: {
Select,
Input,
},
methods: {
getOfferForm() {
axios({
method: "get",
url: `/GETDYNAMICFORM`,
})
.then((response) => {
this.offer = response.data;
})
.catch(() => {
this.$buefy.toast.open({
duration: 3000,
message: "oops",
position: "is-bottom",
type: "is-danger",
});
});
},
getOffer() {
console.log(this.offer);
},
},
created() {
this.getOfferForm();
},
};
</script>
Example Dynamic Form Response like;
[
{
"id": 58,
"fieldLabel": "Name Surname",
"providerLabel": "Name Surname",
"fieldName": "nmsrnm",
"fieldType": "text",
"fieldValue": null,
},
{
"id": 60,
"fieldLabel": "E-mail",
"providerLabel": "E-mail",
"fieldName": "e_mail_60",
"fieldType": "email",
"fieldValue": null,
},
{
"id": 2,
"fieldLabel": "Budget",
"providerLabel": "Budget",
"fieldName": "bdget",
"fieldType": "select",
"fieldValue": "",
"infoRequestFormOptions": [
{
"id": 1,
"orderNum": 0,
"optionValue": 0,
"optionText": "Select",
"minValue": null,
"maxValue": null
},
{
"id": 2,
"orderNum": 1,
"optionValue": 1,
"optionText": "10-30",
"minValue": 10,
"maxValue": 30
}
]
}
]

Related

Row Ids not assigned with vue ag-grid

I'm trying to have user-defined row-ids to prevent rerendering instead of Application assigned Ids as described in Vue ag-grid docs. However, unique row-ids are not getting assigned to the rows and the callback getRowId is not been called and it's adding the row-ids as 0,1,2,.....
From the documentation, it's not clear at which point in time the callback is called to assign the user-provided row-ids.
I'm using "vue": "^2.6.11" and "#ag-grid-community/vue": "^26.1.0"
Model
<template>
<div>
<template>
<ag-grid-vue
style="height: calc(100vh - 148px)"
class="ag-theme-balham"
:columnDefs="columnDefs"
#grid-ready="onGridReady"
:rowData="rowData"
:getRowId="getRowId"
></ag-grid-vue>
</template>
</div>
</template>
Script
<script>
export default {
name: "My-Component",
data() {
return {
columnDefs: [
{ headerName: "Row ID", valueGetter: "node.id" },
{ field: "id" },
{ field: "make" },
{ field: "model" },
{ field: "price" },
],
gridApi: null,
columnApi: null,
rowData: null,
getRowId: null,
};
},
created() {
this.rowData = [
{ id: "c1", make: "Lima", model: "Celica", price: 35000 },
{ id: "c2", make: "Ford", model: "Mondeo", price: 32000 },
{ id: "c8", make: "Porsche", model: "Boxster", price: 72000 },
{ id: "c4", make: "BMW", model: "M50", price: 60000 },
{ id: "c14", make: "Aston Martin", model: "DBX", price: 190000 },
];
this.getRowId = (params) => {
return params?.data.id;
};
},
};
</script>
I think you didn't read the ag-drid documentation clearly.
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<ag-grid-vue
style="height: calc(100vh - 148px)"
class="ag-theme-balham"
:columnDefs="columnDefs"
#onGridReady="onGridReady"
:rowData="rowData"
:getRowId="getId"
></ag-grid-vue>
</template>
<script>
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
import { AgGridVue } from "ag-grid-vue";
export default {
name: "App",
data() {
return {
columnDefs: [
{ headerName: "Row ID", valueGetter: "node.id" },
{ field: "make" },
{ field: "model" },
{ field: "price" },
],
gridApi: null,
columnApi: null,
rowData: null,
getRowId: null,
getId: (params) => {
return params.data.id;
},
};
},
components: {
AgGridVue,
},
created() {
this.rowData = [
{ id: "c1", make: "Lima", model: "Celica", price: 35000 },
{ id: "c2", make: "Ford", model: "Mondeo", price: 32000 },
{ id: "c8", make: "Porsche", model: "Boxster", price: 72000 },
{ id: "c4", make: "BMW", model: "M50", price: 60000 },
{ id: "c14", make: "Aston Martin", model: "DBX", price: 190000 },
];
},
methods: {
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
},
},
};
</script>
enter image description here

Vuelidate nested validations - vuelidate object only includes the last component's validations

I am attempting to use Vuelidate nested validations, but I am surely missing something.
I have a simple component that only contains an input, and a validation making that input required.
<template>
<input type="text" v-model="value" />
</template>
<script>
import useVuelidate from "#vuelidate/core";
import { required } from "#vuelidate/validators";
export default {
name: "MyInput",
setup() {
return { v$: useVuelidate() };
},
props: {
modelValue: String,
},
computed: {
value: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
},
},
},
validations() {
return {
value: { required },
};
},
};
</script>
And my app just includes two instances of this component, and prints the Vuelidate object for my inspection.
<template>
<pre>{{ v$ }}</pre>
<my-input v-model="myValue1"></my-input>
<br />
<my-input v-model="myValue2"></my-input>
</template>
<script>
import useVuelidate from "#vuelidate/core";
import MyInput from "./components/my-input.vue";
export default {
name: "App",
components: {
MyInput,
},
setup() {
return { v$: useVuelidate() };
},
data() {
return {
myValue1: "",
myValue2: "",
};
},
};
</script>
<style scoped>
</style>
This is what's getting printed:
{
"$dirty": false,
"$path": "__root",
"$model": null,
"$error": false,
"$errors": [],
"$invalid": true,
"$anyDirty": false,
"$pending": false,
"$silentErrors": [
{
"$propertyPath": "value",
"$property": "value",
"$validator": "required",
"$uid": "value-required",
"$message": "Value is required",
"$params": {
"type": "required"
},
"$response": false,
"$pending": false
}
],
"$validationGroups": {},
"_vuelidate_undefined": {
"$dirty": false,
"$path": "__root",
"$model": null,
"$error": false,
"$errors": [],
"$invalid": true,
"$anyDirty": false,
"$pending": false,
"$silentErrors": [
{
"$propertyPath": "value",
"$property": "value",
"$validator": "required",
"$uid": "value-required",
"$message": "Value is required",
"$params": {
"type": "required"
},
"$response": false,
"$pending": false
}
],
"$validationGroups": {},
"value": {
"$dirty": false,
"$path": "value",
"required": {
"$message": "Value is required",
"$params": {
"type": "required"
},
"$pending": false,
"$invalid": true,
"$response": false
},
"$externalResults": [],
"$invalid": true,
"$pending": false,
"$error": false,
"$silentErrors": [
{
"$propertyPath": "value",
"$property": "value",
"$validator": "required",
"$uid": "value-required",
"$message": "Value is required",
"$params": {
"type": "required"
},
"$response": false,
"$pending": false
}
],
"$errors": [],
"$model": "",
"$anyDirty": false
}
}
}
Only the second input component is showing up- updating the second input makes the data update, but not the first one. Also note the property "_vuelidate_undefined" which looks like something went wrong. Is some sort of key missing on my components? Am I supposed to namespace the properties I'm validating somehow?
Sandbox with this code can be found here.

How to make multiple search filters work with a for loop in Vue Bootstrap?

I have a table with some filters in each column but when I type anything all the items disappear. The console does not return any error.
Here’s the code:
<template>
<div>
<b-table
id="the-table"
:per-page="perPage"
:current-page="currentPage"
:items="filteredItems"
:fields="fields"
>
<template slot="top-row" slot-scope="{ fields }">
<td v-for="field in fields" :key="field.key">
<input v-model="filters[field.key]" :placeholder="field.label" />
</td>
</template>
</b-table>
<b-pagination v-model="currentPage" :total-rows="rows" :per-page="perPage" aria-controls="the-table"></b-pagination>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
filters: {
option: "",
style: "",
stock: "",
},
items: [],
fields: [
{ key: "options", label: "Options", sortable: true },
{ key: "style", label: "Style", sortable: true },
{ key: "stock", label: "Stock", sortable: true },
{ key: "type", label: "Type", sortable: true },
{ key: "class", label: "Class.", sortable: true },
],
perPage: 15,
currentPage: 1,
};
},
created() {
this.getTable();
},
methods: {
getTable() {
axios
.get("./data/options.json")
.then((res) => (this.items = res.data))
.catch((error) => console.log(error));
},
},
computed: {
rows() {
return this.items.length;
},
filteredItems() {
return this.items.filter((d) => {
return Object.keys(this.filters).every((f) => {
return this.filters[f].length < 1 || this.filters[f].includes(d[f]);
});
});
},
},
};
</script>
I am trying to filter an array of objects like this:
[{"option": "ABEVH160", "style": "American", "stock": "ABEV3", "type": "CALL", "class": "ITM"},
{"option": "BBAS230", "style": "European", "stock": "BBAS3", "type": "PUT", "class": "ATM"},
{"option": "BBDC180", "style": "American", "stock": "BBDC4", "type": "CALL", "class": "OTM"}]
My goal is to be able to filter each of the columns individually:
Does anyone know what I’m missing?
The problem is with the condition:
return this.filters[f].length < 1 || this.filters[f].includes(d[f]);
d[f] is the full value and this.filters[f] is the search string. Obviously this does not work since it checks if the full word is contained in a substring. Simply invert the condition:
return this.filters[f].length < 1 || d[f].includes(this.filters[f]);
You can see it working here.
What you want seems to be something like DataTable Filter | Filter Row in PrimeVue. I tried to find something similar in the documentation of bootstrap-vue (documentation), but couldn´t find anything like that.
Maybe you are in a stage where you can still implement PrimeVue in your project. I´m using Filter Row from PrimeVue by myself and can recommend it.

Ant design vue different data in nested tables

I'm trying to make nested table, in documentation into the nested table they push one same data, how can i change it and push different data for every parent table row?
<script>
const columns = [
{ title: 'Status', dataIndex: 'Status', key: 'Status' },
{ title: 'Date', dataIndex: 'DateCreated', key: 'DateCreated' }
];
const innerColumns = [
{ title: 'Price', dataIndex: 'Price', key: 'Price' },
{ title: 'Status', dataIndex: 'Status', key: 'Status' },
];
const data = [
{
key: 0,
"Status": "u",
"DateCreated": "2019-10-11"
},
{
key: 1,
"Status": "u",
"DateCreated": "2019-09-20"
},
];
const innerData = [
[
{
key: 0,
"Price": 10623,
"Status": "u",
}
],
[
{
key: 0,
"Price": 15084,
"Status": "u",
},
{
key: 1,
"Price": 15084,
"Status": "u",
}
],
];
export default {
data() {
return {
data,
columns,
innerColumns,
innerData,
};
},
};
</script>
<template>
<div class="hello">
<a-table
:columns="columns"
:dataSource="data"
class="components-table-demo-nested">
<a-table
slot="expandedRowRender"
:columns="innerColumns"
:dataSource="innerData[1]"
:pagination="false"
>
</a-table>
</a-table>
</div>
</template>
Here my code
This worked for me
Template:
<a-table :data-source="data" :defaultExpandAllRows="true" v-on:expandedRowsChange="console.log">
<a-table-column title="First Col" data-index="firstCol" />
<template v-slot:expandedRowRender="record, index, indent, expanded">
<a-table :data-source="record.nestedData"
:pagination="false">
<a-table-column title="File Name" data-index="filename" />
</a-table>
</template>
</a-table>
Script:
Vue.component('demo', {
data: function() {
return {
data: [
{
firstCol: '1',
nestedData: [{filename: 'nested 11'}, {filename: 'nested 12'}]
},
{
firstCol: '2',
nestedData: [{filename: 'nested 22'}, {filename: 'nested 22'}]
}
]
}
}
});

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>