Reusable Field Validators

3 Answers 62 Views
Form
Noah
Top achievements
Rank 1
Noah asked on 04 Jan 2024, 04:43 PM

Hello,

I recently asked a question about an infinite form re-render, and I was able to track it down to a problem misusing the Field component's validator prop.  Unfortunately, I'm struggling to achieve the desired functionality using kendo-react's recommended usage.

We'd like to be able to have a set of reusable and minimally customizable validators, for example, a length validator with a configurable maxLength value.

Here's what we have so far:


importReactfrom'react';
import { Field, FieldArray, Form, FormElement, FormRenderProps, FormSubmitClickEvent, FormValidatorType, KeyValue } from'@progress/kendo-react-form';
import { lengthValidator } from'./validators.tsx'exportconstUserForm = (props: UserFormProps) => {

    return (
        <Form
            render={() => {
                console.log("Form Render");
                return (
                    <FormElement>
                        <div className="form-content-container" style={{ overflowY: "scroll" }}>
                            <Field
                               name="test"
                               component={FormInput}
                               validator={lengthValidator(10)}
                           />
                        </div>
                    </FormElement>
                );
            }}
        />
    );
};


export const lengthValidator = (maxLength: number) => {
    return (value: any, _valueGetter: (name: string) => any) => { 
        if ( value ) {
            const valueStripped: string = value.replace(stripMaskRegex,""); 
            if ( valueStripped.length > maxLength ) {
                return  " Cannot exceed length " + maxLength;
            }
        }
        return undefined;
    };
};


Here is a stackblitz session demonstrating what we're wanting to do.  As you can see, it causes an infinite loop, as demonstrated by the re-render log in the Form's render function.

https://stackblitz-starters-oys53t.stackblitz.io

Obviously we are not doing this in the correct way, but I'm hoping someone can show me that there is a way to correctly create reusable validators that can take configuration arguments like this maxLength on a per-field basis.

Thanks!

3 Answers, 1 is accepted

Sort by
0
Konstantin Dikov
Telerik team
answered on 08 Jan 2024, 04:40 PM

Hello Noah,

I will need some addition time testing the scenario and I will get back to you with the results.

 

Regards,
Konstantin Dikov
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Kendo family, check out our getting started resources!

0
Konstantin Dikov
Telerik team
answered on 08 Jan 2024, 05:03 PM

Hello Noah,

Please try setting the validator as shown below:

 validator={(value) => lengthValidatorValidator(10, value)}

Here is an example with the above configuration;

 

Regards,
Konstantin Dikov
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Kendo family, check out our getting started resources!

Noah
Top achievements
Rank 1
commented on 09 Jan 2024, 09:44 PM

Hi Konstantin,

I'm not sure this will work.  In your example, if I add a console log to the Form component's render function like so:

<Form
  render={() => {
    console.log("Test");
    return(
      <FormComponent>
        ...
      </FormComponent>
    );
/>

The console log seems to print infinitely, suggesting that the form is re-rendering infinitely.  However, if I remove the field validator, the console log prints only twice, which is not unexpected.
Konstantin Dikov
Telerik team
commented on 10 Jan 2024, 06:31 AM

Hi Noah,

I have added the console.log and indeed, the Form was still re-rendering and it seems that it will not be possible to use inline validators in such a way. The only remaining options are to use some sort of locally defined validator that can call the main validator with another property or use React Context for passing additional data to the validators (if you need to use some value from the main component within the validator):

Noah
Top achievements
Rank 1
commented on 10 Jan 2024, 05:35 PM

Hi Konstantin,
Thank you for your responses and all of your assistance on this (and all of my previous requests for help).
Is there any plan to allow for more readily customizable validators (as in my original post) in the future, without having to establish each configuration in the same file as the form itself?
Konstantin Dikov
Telerik team
commented on 11 Jan 2024, 07:16 AM

Hi Noah,

As far as I am aware, this is a limitation of the framework in such scenarios, and using an "adaptor" with the customization (as in my last reply) would be the only available option.

0
Ronald
Top achievements
Rank 1
Iron
answered on 12 Jan 2024, 03:15 AM

Create a custom hook that manages the maxLength state and provides the configured validatorfunction:


import React, { useState } from 'react';

export const useLengthValidator = (initialMaxLength: number) => {
  const [maxLength, setMaxLength] = useState(initialMaxLength);

  const validator = (value: any) => {
    // ... your validation logic using maxLength ...
  };

  return { maxLength, validator, setMaxLength };
};

// In UserForm
const { maxLength, validator, setMaxLength } = useLengthValidator(10);

<Field
  name="test"
  component={FormInput}
  validator={validator}
/>

// Update maxLength later if needed
<button onClick={() => setMaxLength(20)}>Change Max Length</button>

Tags
Form
Asked by
Noah
Top achievements
Rank 1
Answers by
Konstantin Dikov
Telerik team
Ronald
Top achievements
Rank 1
Iron
Share this question
or