How can I handle multiple custom validations on a single field?

0 Answers 79 Views
NumericTextBox
Bruno71
Top achievements
Rank 2
Bruno71 asked on 13 Jun 2023, 07:27 PM

Hi,

Our internal app is very data intensive - lots of forms and/or grids with dozens of fields.  Each field can need different validations, such as specific min/max values and whether or not it is required.  I currently use Vuelidate for data validations.  But as I evaluate Kendo UI, it would be nice to replace Vuelidate with the native tools.

How can I use the native Kendo UI components, such as the NumericTextBox, to do complex custom validations?  The documentation examples are falling a little short for me.  For example, can I pass each field the spec data (such as min/max values) and then specify what should be validated (such as "between min & max", "allow zero", or "at least greater than min", etc.)?

Thanks.

Petar
Telerik team
commented on 14 Jun 2023, 07:51 AM

Hi, Bruno71.

I am happy to hear that you are considering the usage of the Kendo UI for Vue Native components in the project you are working on.

Based on the shared details about the application you have, I want to ask you if you've checked the documentation about the Kendo UI for Vue Native Form component and more specifically the main Form Guidelines demo.

In the second demo above, you will see that the validation of each Form field is controlled by a function defined in the validators.js file. Talking specifically for the NumericTextbox, the validation method used for it is the following:

export const nightsValidator = (value) =>
  value ? "" : "Number of Nights is required.";

The above is used in the following definition inside the FormContent.vue file:

<field
  :id="'nightsCount'"
  :name="'nightsCount'"
  :label="'Number of Nights'"
  :format="'n0'"
  :component="'myTemplate'"
  :validator="nightsValidator"
>
  <template v-slot:myTemplate="{ props }">
    <formnumerictextbox
      v-bind="props"
      @change="props.onChange"
      @blur="props.onBlur"
      @focus="props.onFocus"
    ></formnumerictextbox>
  </template>
</field>

As you can see the shared definition of the nightsValidator method is not that complex but it can be re-defined based on the requirement of the application you are working on.

As you shared that you need to control the min/max value of the NumericText box, here is a StackBlitz example in which we have the following nightValidator method:

nightsValidator(fieldName, min, max) {
  const numericValue =
    this.kendoForm &&
    this.kendoForm.values &&
    this.kendoForm.values[fieldName];
  console.log(numericValue);
  return numericValue
    ? numericValue >= min && numericValue <= max
      ? ''
      : `Number of Nights is should be bigger than ${min} and less thatn ${max}.`
    : 'Number of Nights is required.';
}

Please check the above details and let me know if the shared information helps you implement what you need in your scenario. 

Last but not least, I can see that you have a Trial license activated for your account. With the trial license, you can directly submit a support ticket that will be handled with priority by our team.

Bruno71
Top achievements
Rank 2
commented on 14 Jun 2023, 03:56 PM

Thanks Petar.  Your example helped.  I was trying to use the NumericTextBox component by itself.  I did not have all the layers of nesting with the form elements.  It's kind of working now.  But I'm still having a few issues with the validator function, and understanding how to get it to work inside my Grid component for inline editing. 

I'll open a support ticket for these specific issues.

Basically, this is what I ended up with on my main page...

<KForm>
	<KFormElement>
		<KField
			:id="'raw_vinyl_length'"
			:name="'rawVinylLength'"
			:label="'Raw Vinyl Length'"
			:format="'n2'"
			:component="'myField'"
			:validator="() => vinylLengthValidator('raw_vinyl_length', 5, 10)"
		>
			<template v-slot:myField="{ props }">
				<VNumericInput
					v-bind="props"
					@change="props.onChange"
					@blur="props.onBlur"
					@focus="props.onFocus"
				></VNumericInput>
			</template>
		</KField>
	</KFormElement>
</KForm>

 

...and this is what is in the "VNumericInput" component...

<template>
	<KFieldWrapper>
		<KLabel :editor-id="id" :editor-valid="valid">
			{{ label }}
		</KLabel>
		<div class="k-form-field-wrap">
			<KNumericTextBox
				ref="numericInput"
				:id="id"
				:value="value"
				:valid="valid"
				@change="onChange"
				@blur="onBlur"
				@focus="onFocus"
			/>
			<KError v-if="showValidationMessage">
				{{ validationMessage }}
			</KError>
			<KHint v-else>{{ hint }}</KHint>
		</div>
	</KFieldWrapper>
</template>
Petar
Telerik team
commented on 15 Jun 2023, 02:19 PM

Hello, Mike.

To be able to provide more precise feedback we will need more context of what is happening in your application.

Here is a StackBlitz example that demonstrated how we can add validation inside the Grid using a custom template. In this specific solution, the component that is used is the DropDownList but the same approach can be applied when we use NumericTextbox. 

If the above example doesn't help you implement what you need in your project, may I ask you to edit the shared StackBlitz in a way we can replicate the mentioned specific issues? When you are ready, please send us the edited project back and we will be happy to help you furhter.

Looking forward to your reply.

Bruno71
Top achievements
Rank 2
commented on 15 Jun 2023, 05:43 PM

You're example with the DropDownList is similar to what I was trying before with just the NumericTextbox.  This is what lead to my original post about defining the specs and validation methods external to the component and passing them in dynamically.

I will edit the StackBlitz example to replicate what I'm doing.  I'll post it here hopefully by tomorrow.

Petar
Telerik team
commented on 16 Jun 2023, 05:02 AM

Hi,

Take your time to prepare the example and if you want, you can submit a support ticket about it or continue the current discussion.

Bruno71
Top achievements
Rank 2
commented on 16 Jun 2023, 01:39 PM

OK...I was able to piece together a StackBlitz example that reproduces what is happening for me.  This is how I have things setup based on all the previous examples and documentation that I've looked at.  (Please note that I am using Vue 2, but I wasn't able to get that version to work in StackBlitz.)

Here is what happens...
After clicking the Edit button and changing the value of the Length field, you have to press TAB or click out of the field to activate the validation message.  And then it only shows the "field is required" message.  It does not check that the value is between the min/max.

Also, I'm not sure how to pre-populate the NumericTextbox with the current value when clicking the Edit button?

Petar
Telerik team
commented on 20 Jun 2023, 11:30 AM

Hi,

Thank you for the shared example. In the context of the Grid, I would recommend you use an approach like the one in this StackBlitz example.

The approach in the example is much more simple than the implementation in the StackBlitz you sent us. I want to apologize that probably I mislead you to use the Form component inside the Grid, while it is not needed to do it.

In the above example, you will see how we can control the value of the valid property and also how we can control the validation message based on the value of a specific dataItem property. 

In the shared example we have the following computed properties:

getValidationMessage() {
  const min = 5;
  const max = 12;
  const numericValue = this.dataItem.raw_vinyl_length;
  return numericValue >= min && numericValue <= max
    ? ''
    : numericValue !== null
    ? `Vinyl Length should be between ${min} and ${max}.`
    : 'Vinyl Length is required.';
},
vinylLengthValidator() {
  const min = 5;
  const max = 12;
  const numericValue = this.dataItem.raw_vinyl_length;
  return numericValue >= min && numericValue <= max;
}

The above properties are then used in the following template:

 

<template>
  <td v-if="dataItem.inEdit">
    <KNumericTextBox
      ref="numericInput"
      :id="id"
      :value="dataItem.raw_vinyl_length"
      :valid="vinylLengthValidator"
      @change="onChange"
      @blur="onBlur"
      @focus="onFocus"
    />
    <KError v-if="!vinylLengthValidator">
      {{ getValidationMessage }}
    </KError>
  </td>
  <td v-else>{{ dataItem.raw_vinyl_length }}</td>
</template>

Please check the above details and let me know if they help you implement the desired functionality in your application.

Bruno71
Top achievements
Rank 2
commented on 20 Jun 2023, 02:38 PM

Thanks Petar.  This is getting me closer to what I was looking for.  I was able to get your latest example working in my code.  I will use this method and continue from here.  Thank you for all your help!
Petar
Telerik team
commented on 20 Jun 2023, 02:50 PM

Hi, Mike.

I am happy to hear that the latest example helps you achieve the desired functionality. If you have additional questions related to the Kendo UI for Vue library, please submit a support ticket and we will be happy to help you.

No answers yet. Maybe you can help?

Tags
NumericTextBox
Asked by
Bruno71
Top achievements
Rank 2
Share this question
or