coreui-vue icon indicating copy to clipboard operation
coreui-vue copied to clipboard

CFormCheck the invalid and valid props are not reactive

Open jgulledge19 opened this issue 3 years ago • 1 comments

The CFormCheck component properties invalid and valid are not reactive. I have some code like the following

<CForm
        :id="formId"
        class="row g-3 needs-validation"
        novalidate
        @submit.prevent="onSubmit"
        :validated="false"
    >

...

<CCol
    class="col-sm-12 col-md-12 col-lg-12"
>
    Is valid: {{isFieldInvalid('preferred_contact_methods')}}

    <div class="form-check">
        <input
            :class="'form-check-input ' + ((isFieldInvalid('can_contact') || isFieldInvalid('preferred_contact_methods')) ? 'is-invalid' : ( isFieldValid('can_contact') ? 'is-valid' : ''))"
            id="can_contact"
            name="can_contact"
            maxlength="1"
            :checked="!!item.can_contact"
            v-model="item.can_contact"
            type="checkbox"
        >

        <label
            class="form-label form-check-label"
            for="can_contact">It is ok to contact the client
        </label>
    </div>

    <!-- Not working -->
    <CFormInput
        type="checkbox"
        id="can_contact"
        name="can_contact"
        label="It is ok to contact the client"
        maxlength="1"
        :checked="!!item.can_contact"
        v-model="item.can_contact"
        :invalid="isFieldInvalid('can_contact')"
        :valid="isFieldValid('can_contact')"
        :feedback-invalid="getFieldErrorMessage('can_contact')"
    />
</CCol>
...

</CForm>

There is a save button that will submit the form and there is a listener that calls the related onSubmit function. The onSubmit function then validates the form and then the related isFieldInvalid and isFieldValid will now return a bool. I can see that the related functions do return a bool, but the CFormCheck is not updating.

setup(props, { emit }) {
    let formValidationResults = reactive({});
    const onSubmit = function () {
          // real validation would go here, just an example:
          formValidationResults['can_contact'] = false;
    }

        const isFieldInvalid = function (key) {
            let isValid = this.isFieldValid(key);
            if (isValid !== null)  {
                return !isValid;
            }

            return null;
        }
        const isFieldValid = function (key) {
            if (formValidationResults[key])  {
                return formValidationResults[key];
            }

            return null;
        },

     return {
         isFieldInvalid,
         isFieldInValid,
         onSumit,
     }
}

It looks like the className and inputClassName should be computed: https://github.com/coreui/coreui-vue/blob/ecc24f56fe849061db04b487f39a9c757dd61ed6/packages/coreui-vue/src/components/form/CFormCheck.ts#L125 or refactor to be like the CFormInput: https://github.com/coreui/coreui-vue/blob/a5c0ad536950d30cac0ef24fd4982b44a9a1df57/packages/coreui-vue/src/components/form/CFormInput.ts#L175

Core Vue v4.3.1, MacOS Firefox

jgulledge19 avatar Sep 14 '22 17:09 jgulledge19

If you want to use custom validation, please remove novalidate and :validated="false"

Please check example - https://coreui.io/vue/docs/forms/validation.html#custom-validation

mrholek avatar Sep 18 '22 13:09 mrholek