Apply 'k-...' classes to html textarea

1 Answer 310 Views
Input Validator wrapper
Vincent
Top achievements
Rank 3
Iron
Iron
Iron
Vincent asked on 31 Aug 2021, 10:05 AM | edited on 01 Sep 2021, 09:22 AM

On most Native Kendo Vue components the following classes are applied depending on the state: 

  • 'k-floating-label-container'         
  • 'k-state-focused'          
  • 'k-state-empty'         
  • 'k-autofill'         
  • 'k-state-invalid'         
  • 'k-rtl'

'k-state-invalid' for instance adds a red border around the Kendo Input component:



In this example the red line isn't added to the html textarea:
https://www.telerik.com/kendo-vue-ui/components/form/guidelines-with-examples/#toc-vue-form-inputs


Is there an easy and efficient way to add (some of) these classes to a native html textarea?

1 Answer, 1 is accepted

Sort by
2
Accepted
Petar
Telerik team
answered on 03 Sep 2021, 09:45 AM

Hi Vincent,

Here is a StackBlitz example demonstrating how we can add the k-state-invalid class to the native TextArea, in the context of the example you linked.

To achieve the targeted functionality, I've edited the FormTextArea.vue file by defining the marked in yellow code below:

<template>
    <fieldwrapper>
        <klabel :editor-id="id" :editor-valid="valid">
        {{label}}
        </klabel>
        <div class="k-form-field-wrap">
        <span :class="['k-textarea', textAreaValidClass]">
            <textarea 
                class="k-input"
                style="margin-top: 0px; margin-bottom: 0px; height: 36px;"
                :valid="valid"
                :value="value"
                :id="id"
                @change="handleChange"
                @blur="handleBlur"
                @focus="handleFocus"
            ></textarea>
          </span>
            <error v-if="showValidationMessage">
                {{validationMessage}}
            </error>
            <hint v-else>{{hint}}</hint>
        </div>
    </fieldwrapper> 
</template>

To make the above work as expected, the textAreaValidClass is defined as a computed property as follows:

textAreaValidClass(){
    return this.valid?"":"k-state-invalid"
}

Using the above approach, you can add the classes you listed to the TextArea when you need a given stylization.

Check the linked example and let me know if it demonstrates what you need to implement in your application.

Regards,
Petar
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Vincent
Top achievements
Rank 3
Iron
Iron
Iron
commented on 08 Sep 2021, 08:31 AM

Hi Petar,

This is a great way to add the k-state invalid class however for the focused class I've made this little wrapper component which copies some of the logic from Kendo Input:

<script>
import { h, ref, computed } from "vue";

export default {
    props: {
        component: String,
        dir: String,
        placeholder: String,
        className: String,
        floatingLabelContainer: { type: Boolean, default: false },
        valid: { type: Boolean, default: true },
    },
    setup(props, { emit, slots }) {
        const focused = ref(false);
        // const autofill = ref(false)

        const computedValue = computed(() => {
            return false;
        });

        const spanClasses = computed(() => {
            // console.log(props.className)

            // const local = props.className
            return {
                [props.className]: true,
                "k-floating-label-container": props.floatingLabelContainer,
                "k-state-focused": focused.value,
                "k-state-empty": !(
                    (
                        (computedValue.value === 0
                            ? true
                            : computedValue.value) || props.placeholder
                    )
                    // || autofill.value
                ),
                // "k-autofill": autofill.value,
                "k-state-invalid": !props.valid,
                "k-rtl": props.dir === "rtl",
            };
        });

        const newProps = {
            onChange(e) {
                // console.log('onchange')
                emit("change", e);
            },

            onBlur(e) {
                // console.log('onblur')
                focused.value = false;
                emit("blur", e);
            },

            onFocus(e) {
                // console.log('onfocus')
                focused.value = true;
                emit("focus", e);
            },
        };

        const slot = slots.default ? slots.default() : [];
        const namedSlot = slots.namedSlot
            ? slots.namedSlot(props.component)
            : [];
        // Check if component prop was set, if so use it's name to pass prop functions to render template
        const template = (prop) =>
            slots[props.component] ? slots[props.component](prop) : [];

        return () =>
            h(
                "span",
                {
                    class: spanClasses.value,
                    // onChange: props.handleChange,
                },
                [template({ props: newProps }), namedSlot, slot]
            );
    },
};
</script>

<style></style>

This then allows me to wrap my textarea like so:

 <KendoStateWrapper :valid="valid"
                               @change="handleChange"
                               @blur="handleBlur"
                               @focus="handleFocus"
                               :className="`k-textarea`"
                               :component="'inputTemplate'">
                <template #inputTemplate="{ props }">
                    <textarea :id="id"
                              :value="value"
                              :placeholder="placeholder"
                              v-bind="props"
                              @blur="props.onBlur"
                              @change="props.onChange"
                              @focus="props.onFocus"
                              rows="3"
                              class="k-input">
                    </textarea>
                </template>
            </KendoStateWrapper>
Petar
Telerik team
commented on 08 Sep 2021, 08:40 AM

Hi Vincent,

Thank you for sharing your implementation with the community! It will surely help someone who needs to style the textarea DOM element.

Tags
Input Validator wrapper
Asked by
Vincent
Top achievements
Rank 3
Iron
Iron
Iron
Answers by
Petar
Telerik team
Share this question
or