How can i force validation on the initial values in a formik form, when it mounts - formik

I am in React 16+, using withFormik for the form.
Its a single field form which on initial use will have an empty string value. I want the initial value to be validated so the user knows they must fill a value.
So blank string "" initial value, i want the error to say "please enter a value" without the user touching or anything. onload.
formik docs claim it can do this thru the built in tools, but the library/docs dont add up.
validateOnMount:
https://formik.org/docs/api/withFormik#validateonmount-boolean
this value does nothing when set to true in my form. There are lots of logged issues of others having the same problems. It seems formik depreciated an old property that used to do this well. i cant find anything to do this without building some type of hack.
how can i have formik run the validation as ssoon as the from mounts.
in case your answer is to disable the "enableReinitialize" property, ive tried this in conjunction with validateOnMount: true and still get nothing.

Related

Kendo UI ComboBox for Angular: how to prevent Expected value of type Object error?

I am trying to make a Kendo ComboBox for Angular not crash with error "Prevent Expected value of type Object":
<kendo-combobox
formControlName="gender"
[data]="genders"
[textField]="'text'"
[valueField]="'value'"
[valuePrimitive]="false"
[filterable]="true"
[allowCustom]="true"
required
>
</kendo-combobox>
StackBlitz
The error can be obtained if the value is deleted and Tab is pressed (combo blur). In fact, by leaving an invalid value in the box, this error will occur.
I will explain below why I am using some settings:
textField and valueField - in my application I request complex objects and the selected value will provide some information to other form fields
[valuePrimitive]="false" - the selected value is a complex object
[allowCustom]="false" - I used this to allow the control to receive an initial value that is not among the list. In my application I am using server-side filtering with an empty initial list
When using in the application (server-side filtering) I also receive this error when pushing the arrow button, but I can get rid of this by either ensuring that initial value is within the list of values (ugly) or simply by removing the button.
Any idea about how to make this work?
According to Kendo UI for Angular you have to use a valueNormalizer function to convert what the user actually types into a valid object.
public valueNormalizer = (text: Observable<string>) => text.pipe(map((text: string) => {
return {
value: this.genders[this.genders.length - 1].value + 1, //whatever value
text: text
};
}));
Please check the updated Stackblitz and let me know if it is helpful.
valueNormalizer didn't work for me at all.
I went for a different solution (I can't post the code here because of security limitations in my company).
We want to allow an initial value and have to allow [allowCustomer]="true" because that initial value is not initially a part of the [data] array since we fetch it from the server.
I simply pushed the initial value to the [data] array and that fixes it. no need for [allowCustome]="true"

##redux-form/UPDATE_SYNC_ERRORS is unintentionally clearing my _error state

I'm setting up form-wide errors pretty much exactly like the Submit Validation Example from the docs.
But unlike the example, my _error object is removed as soon as I do any change in any other form field on my page. On the example page the _error is always shown until the button is pressed again.
Using the Redux dev tools extension in Chrome I see that the action ##redux-form/UPDATE_SYNC_ERRORS is dispatched on the first change I do on any other form field after _error has been set and this action is clearing my _error object in the form state.
How can I control when this action is dispatched?
Can I make it not clear my _error object?
Your form-wide (_error) error is from a failed form submission? i.e. something other than sync validation?
The code as it is now will definitely clear that error. The reason being that once the user has modified something in the form, it seems reasonable to remove the complaint about their past behavior.
However, this seems like a reasonable thing that someone might want to configure. Please submit a feature request referencing this question.

How do clear words/images upon form validation? (AngularJS)

Just to be clear, in the subject line, it says "words/images". The "words" part is not about clearing the words in the form, but rather the word "required". As for images, these are validation images, like the green checkmark.
I just realized that I had no clue how to clear words/images upon form completion in AngularJS. Basically, the checkmark stays, and the word "required" appears after submitting the validated form. It does so, because now the form is empty. I tried using the $setPristine in the script page,
$scope.imgHolderComments.$setPristine(true);
knowing that it would probably not work. I looked for a workaround, so I checked out this impressive thread (but realized this was more for the validation itself and not added words/images).
Reset form to pristine state (AngularJS 1.0.x)
Then I tried using this code which I had used prior to today for the pre-validation. Or if you will, for the live validation, before submitting the form. I thought I could recycle this, but no.
$scope.checkUrl = 'images/validation/y_square_trans.png';
$scope.loadUrl = 'images/validation/loading.gif';
$scope.crossUrl = 'images/validation/loading_wrong.gif';
$scope.imgHolderComments = '';
$scope.comments = "";
$scope.timeout = null;
$scope.imgHolderComments = ($scope.reviewForm.comments.$invalid) ? $scope.crossUrl : $scope.crossUrl;
That looked so dirty, but thought it could work after pushing the data in. But the image stayed there (as you can see, I tried replacing the checkmark with a cross instead, as I did not want to create a blank pic).
I also googled it, but everything I could find had to do with two things: clearing the form AND removing the coloured frame (red/green). of course, my form already does that. So, I'm still trying to find a way to remove the word "required" and the gif image in my form upon successful validation.
In any case, I created a plunker. You'll have to click on the word "Reviews" to show the form.
http://embed.plnkr.co/QZT1Jzgg9elMMRHwhYel/preview
Have a look at the directives ng-show and ng-hide.
You can set $scope.allGood = true; somewhere in your controller (after validation) and use this directive: <span ng-hide="allGood">Required</span>
Edit:
You might also want to look at the ng-class directive. Example:
<span ng-class="{green: allGood == 1}">Name:</span> and obviously style the class green to your needs.

AngularJS ng-value boolean validation

To be specific: I have two radio buttons and their ng-model value must be boolean. Since this is not possible with normal html value property I found useful Angularjs ng-value. Problem is when I want to do some validation, when radio button ng-value="false" is selected it recognizes it as an empty ng-model and we have validation error.
Example: http://plnkr.co/edit/lvdNHZoSSN1nM6uLyc0Q?p=preview
Any clue how to tackle this?
This is a bug.
value="true/false" won't work because your radio inputs won't be initialized and checked correctly when your model is loaded, but ng-value="true/false" won't work because "false" selections will cause the form to be invalid.
I was having the same problem and reported it as an issue, but since there's no telling when it will be resolved, I also came up with a workaround: ng-boolean-radio
It basically converts your model's boolean true / false values into string "true" / "false" values, which match your form's string value="true/false" attributes. This will allow the corresponding radio inputs to be checked by default when the model loads. It will also allow you to save "false" values because "false" != false.
Finally, it preserves the boolean datatype by converting the string "true" / "false" values back to boolean true / false before saving them in the model.
I hope that helps!
http://plnkr.co/edit/Y5vDuTug0kvS3Ut58Lz9?p=preview
Problem is in the required attribute.
I believe using ng-required="!user.gender" is what you're looking for.
Edit: it seems that ng-required, while slightly better, still doesn't work fully.
My recommendation is to omit require completely and initialize your model with a default value:
{gender: true} (false will work too).
I had this problem, too. Michael Moussa's directive was very good for debugging what the checkboxe's/radio button's actual modelValue is. As it turned out, a modelValue of false arrived undefined at the checkbox/radio button. Updating (from 1.2.0) to angular 1.2.5 fixed the problem for me.

How can I validate my Firefox extension's preferences?

What is a generally accepted way to validate preference values in a Firefox extension, specifically when using the prefwindow mechanism in XUL?
I am introducing some new preferences in one of my extensions that I would like to validate before the preferences window is closed. If there's an error, the user should be allowed to correct the issue, and then proceed. I see that the prefwindow element has two potentially useful functions to help in this regard:
onbeforeaccept
ondialogaccept
The former seems to have an associated bug (Bug 474527) that prevents the prefwindow from remaining open when returning false from that function. This is bad in that it doesn't give the user an opportunity to immediately correct their mistake.
The latter appears to have the problem that the preferences get saved prior to exiting, which leaves the preferences in a bad state internally.
In addition, the prefwindow mechanism supports the browser.preferences.instantApply option, in which preference values are written immediately upon updating the associated control. This makes validation extra tricky. Is there a clean way to validate custom preferences in a Firefox extension, allowing the user to correct any potential mistakes?
Normally you would want to validate the preferences when they are changed. That's something that onchange attribute (and the corresponding change event) is good for:
<preference name="preference.name" onchange="validate(this);"/>
The event is fired after the preference value changes. There are two drawbacks:
In case of instantApply the new preference value is already saved, too late to validate and decline.
For text fields the preferences are saved every time a new character is typed. This becomes ugly if you report validation failure while the user is still typing.
You can solve the first issue by intercepting the change events for the actual input fields. For example, for a text field you would do:
<input preference="preference.name"
oninput="if (!validate(this)) event.stopPropagation();"
onchange="if (!validate(this)) { event.stopPropagation(); this.focus(); }"/>
So changes that don't validate correctly don't bubble up to the <prefpane> element and don't get saved. The events to listen to are: input and change for text fields, command for buttons and checkboxes, select for the <colorpicker> element.
The second issue is tricky. You still want to validate the input when it happens, showing the message immediately would be bad UI however. I think that the best solution is to assume for each input field initially that it is still "in progress". You would only set a flag that the value is complete when you first see a blur event on the field. That's when you can show a validation message if necessary (ideally red text showing up in your preference page, not a modal prompt).
So to indicate what the final solution might look like (untested code but I used something like that in the past):
<description id="error" hidden="true">Invalid preference value</description>
<input preference="preference.name"
_errorText="error"
onblur="validate(event);"
oninput="validate(event);"
onchange="validate(event);/>
<script>
function validate(event)
{
// Perform actual validation
var field = event.target;
var valid = isValid(field);
// If this is the blur event then the element is no longer "in progress"
if (event.type == "blur")
{
field._inputDone = true;
if (!valid)
field.focus();
}
// Prevent preferences changing to invalid value
if (!valid)
event.stopPropagation();
// Show or hide error text
var errorText = document.getElementById(field.getAttribute("_errorText"));
errorText.hidden = valid || !field._inputDone;
}
</script>
If you want to validate values as soon as the field is changed so you can handle the instantApply case, you could hook into the change events for the individual fields (e.g. oninput for a textbox). Display an error message and force the focus back to the field if the value is invalid. You can either set it back to a valid value automatically or block the user from closing the dialog until it is fixed.

Resources