How to add validationSchena dynamically in useForm object

250 Views Asked by At

I am new to Vuejs and I am using Vue 3 with composition API. I am creating a Yup schema through custom fields. The problem I am facing that how can I add/assign dynamically created Yup schema to useForm().

Currently, what I have tried so far. I have created a function that returns Yup Shape, which I assign to useForm. Right now this code successfully creates schema within getCustomFieldsData. But I try to access it in the template it's always empty. As in code, it tries declaring variables and assigning them but remains empty. Any help or direction would be a great help.

<template>
    <div class="container-fluid">
        <Loading v-model:active="isLoading">
        </Loading>
        <div class="page-header">
            <div class="row">
                <div class="col-sm-6">
                    <div class="page-header-left">
                        <h3>
                            Add/Edit Asset Category
                        </h3>
                    </div>
                </div>
                <div class="col-sm-6">

                    <ol class="breadcrumb pull-right">

                        <li class="breadcrumb-item">
                            <router-link to="/dashboard">
                                <i class="fa fa-home"></i>
                            </router-link>
                        </li>
                        <li class="breadcrumb-item"><router-link to="/assetcategorylist">Manage Assets
                                Category</router-link></li>
                        <li class="breadcrumb-item active">Add/Edit Asset Category</li>
                    </ol>
                </div>
            </div>
        </div>
    </div>
    <div class="container-fluid">

        <div class="row">
            <div class="col-lg-12">
                <div class="card">
                    <div class="card-body admin-form">
                        <Form :validation-schema="schema">
                            <template v-for="item of formControlList">
                                <h3 class="heading-partition">{{ item.group_display_name }}</h3>
                                <code>{{ errors1 }}</code>
                                <div class="row">
                                    <template v-for="inner of item.InnerData">
                                        <div :class="{
                                            'col-sm-12 col-md-12 float-left': true, 'col-12': inner.layout_type == 'single', 'col-md-6': inner.layout_type == 'double', 'col-lg-4': inner.layout_type == 'triple', 'col-lg-3 col-xl-3':
                                                inner.layout_type == 'four'
                                        }">
                                            <!---->
                                            <input type="hidden" v-if="inner.form_field_visibility == 'NO'" />
                                            <!--v-model="item.value" v-bind:id="item.name"     -->
                                            <label
                                                v-if="inner.form_field_visibility == 'YES' || inner.edit_form_field_visibility == 'YES'">{{
                                                    inner.display_name }}:<span class="text-danger"
                                                    :class="{ 'text-danger': inner.is_required == true }"
                                                    v-if="inner.is_required == true">*</span></label>
                                            <div class="form-group"
                                                v-if="inner.form_field_visibility == 'YES' || inner.edit_form_field_visibility == 'YES'">

                                                <div id="profile_thumb_upload" class="custom-file w-100"
                                                    v-if="inner.dt_code == 'imageurl'">
                                                    <input class="form-control" type="file" ref="file" @change="setFile"
                                                        accept="image/x-png,image/gif,image/jpeg" lang="es" />


                                                </div>
                                                <input type="text" class="form-control" :readonly="inner.is_readOnly"
                                                    v-model="fieldData[inner.form_controlName]" :id="inner.custom_field_id"
                                                    v-if="inner.picklist_options != 'Lookup' && inner.dt_code != 'datetime' && inner.dt_code != 'date' && inner.dt_code != 'radio' && inner.dt_code != 'boolean' && inner.dt_code != 'select' && inner.dt_code != 'textarea' && inner.dt_code != 'checkbox' && inner.dt_code != 'date' && inner.dt_code != 'int' && inner.dt_code != 'decimal' && inner.dt_code != 'bigint' && inner.dt_code != 'imageurl'" />
                                                <input type="text" class="form-control" :readonly="inner.is_readOnly"
                                                    v-model="fieldData[inner.form_controlName]" :id="inner.custom_field_id"
                                                    v-if="inner.dt_code == 'datetime'" [value]="inner.value" />

                                                <input type="text" class="form-control" :readonly="inner.is_readOnly"
                                                    v-model="fieldData[inner.form_controlName]" :id="inner.custom_field_id"
                                                    v-if="inner.dt_code == 'int'" />

                                                <!-- <small v-if="inner.dt_code == 'int' && (form.get(inner.form_controlName).touched &&
                                                    form.get(inner.form_controlName).errors?.pattern)"
                                                    class="text-danger">Please enter valid
                                                    value</small> -->

                                                <input type="text" class="form-control" :readonly="inner.is_readOnly"
                                                    v-model="fieldData[inner.form_controlName]" :id="inner.custom_field_id"
                                                    v-if="inner.dt_code == 'bigint'" />

                                                <!-- <small v-if="inner.dt_code == 'bigint' && (form.get(inner.form_controlName).touched &&
                                                    form.get(inner.form_controlName).errors?.pattern)"
                                                    class="text-danger">Please enter valid
                                                    value</small> -->

                                                <input type="text" class="form-control" :readonly="inner.is_readOnly"
                                                    v-model="fieldData[inner.form_controlName]" :id="inner.custom_field_id"
                                                    v-if="inner.dt_code == 'decimal'" />

                                                <!-- <small v-if="inner.dt_code == 'decimal' && (form.get(inner.form_controlName).touched &&
                                                    form.get(inner.form_controlName).errors?.pattern)"
                                                    class="text-danger">Please enter valid
                                                    value</small> -->


                                                <textarea class="form-control" v-if="inner.dt_code == 'textarea'"
                                                    v-model="fieldData[inner.form_controlName]" rows="3"
                                                    cols="4"></textarea>
                                                <p-calendar inputStyleClass="form-control start-date"
                                                    v-if="inner.dt_code == 'date'"
                                                    v-model="fieldData[inner.form_controlName]" [showTime]="false"
                                                    dateFormat="mm/dd/yy" showButtonBar="true" [monthNavigator]="true"
                                                    [yearNavigator]="true" yearRange="1919:2030"></p-calendar>
                                                <div class="form-control pl-0 border-0 bg-transparent"
                                                    v-if="inner.dt_code == 'checkbox'">

                                                    <div v-for="options of inner.listoptions">

                                                        <div class="form-check form-check-inline"
                                                            v-for="option of options.listoptions" :index="index">
                                                            <div class="custom-control custom-checkbox">

                                                                <input
                                                                    id="chk_{{inner.custom_field_id}}_{{option}}_{{index}}"
                                                                    value="5555" [checked]="checkvalue(inner.value,option)"
                                                                    (change)="onCheckboxChange($event,item,inner)"
                                                                    class="dynamic custom-control-input" type="checkbox">
                                                                <label
                                                                    class="custom-control-label universal-custom-control-label pl-2 pr-1 dynamic"
                                                                    for="chk_{{inner.custom_field_id}}_{{option}}_{{index}}">{{
                                                                        option }}</label>

                                                            </div>

                                                        </div>
                                                    </div>
                                                </div>

                                                <div class="form-control pl-0 border-0 bg-transparent"
                                                    v-if="inner.dt_code == 'boolean'">
                                                    <input class="form-check-input" type="checkbox"
                                                        v-model="fieldData[inner.form_controlName]" id="gridCheck">
                                                    <label class="form-check-label" for="gridCheck">
                                                        &nbsp; Is Active?
                                                    </label>

                                                </div>

                                                <!--Radio button-->
                                                <div class="form-control pl-0 border-0 bg-transparent"
                                                    v-if="inner.dt_code == 'radio'">
                                                    <div v-for="options of inner.listoptions">

                                                        <div class="form-check form-check-inline"
                                                            v-for="option of options.listoptions" :index="index">

                                                            <div class="custom-control custom-radio mx-2  p-0">
                                                                <input id="radio-{{inner.custom_field_id}}_{{option}}"
                                                                    v-model="fieldData[inner.form_controlName]"
                                                                    [value]="option" type="radio">
                                                                <label for="radio-{{inner.custom_field_id}}_{{option}}"
                                                                    class="radio-label">{{ option }}</label>
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>
                                                <ng-select [items]="inner.select_options"
                                                    :class="{ 'disabledddl': inner.is_readOnly }"
                                                    :id="inner.form_controlName" [closeOnSelect]="true" placeholder="Select"
                                                    v-if="inner.dt_code == 'select' && inner.picklist_options == ''"
                                                    v-model="fieldData[inner.form_controlName]" bindLabel="name"
                                                    bindValue="value">

                                                </ng-select>

                                                <ng-select [items]="inner.select_options"
                                                    :class="{ 'disabledddl': inner.is_readOnly }"
                                                    :id="inner.form_controlName" [closeOnSelect]="true" placeholder="Select"
                                                    v-if="inner.dt_code == 'select' && inner.picklist_options == 'true'"
                                                    v-model="fieldData[inner.form_controlName]" [multiple]="true"
                                                    bindLabel="name" bindValue="value">

                                                </ng-select>


                                                <!-- <small
                                                    v-if="((form.get(inner.form_controlName)?.invalid) && (form.get(inner.form_controlName).dirty) || (form.get(inner.form_controlName)?.touched) && (form.get(inner.form_controlName)?.errors?.required))"
                                                    class="text-danger">{{ inner.display_name }} is required</small> -->
                                            </div>
                                        </div>
                                    </template>
                                </div>
                                <div class="form-btn">
                                    <a href="javascript:;" class="btn btn-pill btn-gradient color-4" @click="onSubmit()"
                                        style="width:max-content">Submit</a>

                                    <a href="javascript:;" class="btn btn-pill btn-dashed color-4"
                                        @click="Cancel">Cancel</a>
                                </div>
                            </template>
                        </Form>
                        <AssetAttributelist></AssetAttributelist>

                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
import { ref, onMounted, onBeforeMount } from "vue";
import { Form, Field, useField, useForm } from 'vee-validate';
import DynamicSelect from '@/views/shared/singleSelect/singleDrp.vue';
import InputMask from '@/views/shared/inputmask/inputmasktemplate.vue';
import createYupSchema from '@/views/shared/common/yupSchemaCreater';
import * as Yup from 'yup';
//Services
import AssetCategoryService from "@/service/crmservice/assetcategoryservice";
import CommonService from "@/service/crmservice/commonService";
//Components
import AssetAttributelist from "@/views/crm/assetcategory/categoryattributelist.vue"
export default {
    name: 'addeditassestcategory',
    components: {
        "dynamic-select": DynamicSelect,
        InputMask,
        Form,
        Field, AssetAttributelist

    },
    setup(props) {
        const assetCategoryService = ref(new AssetCategoryService());
        const commonService = ref(new CommonService());

        const primaryKey = ref(null);
        const userId = ref(null);
        const companyId = ref(null);
        const moduleCode = ref('6001');
        const subModuleCode = ref('6001');
        const otherData = ref(null);
        const refId = ref(null);
        const displayCode = ref('Add');
        const isFor = ref(null);
        const deviceType = ref('Desktop');
        const layoutType = ref('Add');
        const formControlList = ref([]);
        const checkboxdata1 = ref([]);
        const customFields = ref(null);
        const formData = ref([]);
        const fieldData = ref({});
        const formSchemaObject = [];
        const isLoading = ref(false);
        const createSchema = ref(createYupSchema);
        const handleSubmit1 = ref(null);
        const errors1 = ref(null);
        const meta1 = ref(null);
        const getUserInfo = () => {
            userId.value = localStorage.getItem("userId");
            companyId.value = localStorage.getItem("companyId");
        }

        const getCustomFieldsData = () => {
            commonService.value.getCustomFieldsData(primaryKey.value, moduleCode.value, subModuleCode.value, otherData.value, refId.value, displayCode.value, companyId.value, userId.value,
                isFor.value, deviceType.value, layoutType.value)
                .then(response => {
                    customFields.value = response.data.data;
                    customFields.value.forEach(t => {
                        let groupCheck = formControlList.value.filter(y => y.group_id == t.group_id);

                        if (t.dt_code == 'radio') {
                            t.listoptions = JSON.parse(t.listoptions);
                        }
                        if (t.dt_code == 'checkbox') {
                            t.listoptions = JSON.parse(t.listoptions);
                            let checkdata = {
                                controlname: t.form_controlName
                            };
                            checkboxdata1.value.push(checkdata);
                        }


                        if (groupCheck == null || groupCheck.length == 0) {
                            let obj = {
                                group_id: t.group_id,
                                group_name: t.group_name,
                                group_display_name: t.group_display_name,
                                InnerData: customFields.value.filter(x => x.group_id == t.group_id)
                            }

                            formControlList.value.push(obj);
                        }
                    });

                    //const group = {};
                    customFields.value.forEach(cnt => {

                        let val = null;
                        if (cnt.actual_data_type == 'bit') {
                            val = cnt.value == 1 ? true : false;
                        }
                        // else if (cnt.dt_code == 'datetime') {
                        //     val = (cnt.value == '' ? null : convertdatetime.transform(cnt.value, null)); // to convert to local time
                        // }
                        // else if (cnt.dt_code == 'date') {
                        //     val = (cnt.value == '' ? null : convertdatetime.transform(cnt.value, 'Date')); // to convert to local time
                        // }
                        else {
                            val = (cnt.value == '' ? null : cnt.value);
                        }
                        checkboxdata1.value.forEach((item) => { if (cnt.form_controlName == item.controlname) { item.controlvalues = cnt.value; } });//for checkboxes on form
                        if (cnt.actual_data_type == 'checkbox') {
                            try {
                                checkboxdata1.value.forEach((item) => { // // console.log(item.controlname, item.controlvalues);
                                    this.form.get(item.controlname).setValue(item.controlvalues.split(','));
                                });
                            }
                            catch (err) { }
                        }
                        fieldData.value[cnt.form_controlName] = '';
                        formSchemaObject.push({
                            id: cnt.form_controlName,
                            label: cnt.display_name,
                            placeholder: cnt.display_name,
                            type: cnt.dt_code,
                            validationType: 'string',
                            value: '',
                            validations: [
                                {
                                    type: "required",
                                    params: ["this field is required"]
                                },
                                {
                                    type: "min",
                                    params: [5, "name cannot be less than 5 characters"]
                                },
                                {
                                    type: "max",
                                    params: [10, "name cannot be more than 10 characters"]
                                }
                            ]
                        });
                    });
                    const { handleSubmit, errors, meta } = generateForm(formSchemaObject);
                    handleSubmit1.value = handleSubmit;
                    errors1.value = errors;
                    meta1.value = meta;
                    console.log("errors1", errors1)
                })
        }
        const { handleSubmit, errors, meta } =  useForm({
            validationSchema:  generateForm(),
        });
        const generateForm = (formArray) => {
            const yepSchema = formArray.reduce(createSchema.value, {});
            const schema = Yup.object().shape(yepSchema);
            return schema;
        }

        const onSubmit = async () => {
            var dataModel = new JsonData();
            console.log('asdsad', fieldData.value);
            dataModel.Id = primaryKey.value;
            dataModel.ModuleCode = moduleCode.value;
            dataModel.SubModuleCode = subModuleCode.value;
            dataModel.CompanyId = companyId.value;
            dataModel.UserId = userId.value;
            dataModel.FormJsonData = JSON.stringify(fieldData.value);
            console.log('dataModel', dataModel);
            await assetCategoryService.value.addEditAssetCategory(dataModel).then(response => {
                console.log(response);
                // if (response.data.statusCode == 200) {
                //     toaster.success(response.data.responseMessage);
                //     setTimeout(() => { isLoading.value = false; router.push({ path: '/managelayoutList' }); }, 500);
                // }
                // else {
                //     isLoading.value = false;
                //     toaster.error(response.data.responseMessage);
                // }
            }).catch(error => { isLoading.value = false; console.log('error', error.response) })
        }
        onBeforeMount(() => {
            getUserInfo();
            getCustomFieldsData();
        });
        onMounted(() => {

        });

        return {
            formControlList, fieldData, formSchemaObject, errors1,
            onSubmit
        }

    }
}
export class JsonData {
    Id
    FormJsonData
    ModuleCode
    SubModuleCode
    CompanyId
    UserId
    constructor() {
        this.Id = null;
        this.FormJsonData = "";
        this.ModuleCode = "";
        this.SubModuleCode = "";
        this.CompanyId = "";
        this.UserId = "";
    }
}
export class Group {

    id
    group_id
    group_name
    group_display_name
    group_layout_type
    layout_type
    table_name
    is_inserted
    is_updated
    display_order
    visibility_condition
    visibility_condition_label
    default_value
    controls

    constructor(
        id,
        group_id,
        group_name,
        group_display_name,
        group_layout_type,
        layout_type,
        table_name,
        is_inserted,
        is_updated,
        display_order,
        visibility_condition,
        visibility_condition_label,
        default_value,
        controls

    ) {
        this.id = id,
            this.group_id = group_id,
            this.group_name = group_name,
            this.group_display_name = group_display_name,
            this.group_layout_type = group_layout_type,
            this.layout_type = layout_type,
            this.table_name = table_name,
            this.is_inserted = is_inserted,
            this.is_updated = is_updated,
            this.display_order = display_order,
            this.visibility_condition = visibility_condition,
            this.visibility_condition_label = visibility_condition_label,
            this.default_value = default_value,
            this.controls = controls


    }
}
</script>
<style scoped></style>
0

There are 0 best solutions below