How do I validate a radio input in Yup/Formik? - formik

I'm using Yup to validate my Formik form, but I have no idea how to validate a radio input in Yup/Formik.

You validate the radio group. The only validation failure that is possible, is if you don't have a default button selected, and the user doesn't select any of the radio buttons.
Given:
<RadioButtonGroup
id="radioGroup"
label="One of these please"
value={values.radioGroup}
error={errors.radioGroup}
touched={touched.radioGroup}
>
<Field
component={RadioButton}
name="radioGroup"
id="radioOption1"
label="Choose this option"
/>
<Field
component={RadioButton}
name="radioGroup"
id="radioOption2"
label="Or choose this one"
/>
</RadioButtonGroup>
Validation code:
radioGroup: Yup.string().required("A radio option is required")
As used in context:
<Formik
...
validationSchema={Yup.object().shape({
radioGroup: Yup.string().required("A radio option is required"),
...
})}
Copied from this larger validation example:
https://gist.github.com/mrtony/c1ba5f8ec4122d2866b292fc36152d34

your radioInputGroup values:
state = {
gender: [
{
id: 0,
type: "woman",
text: interpreter("ImFemale")
}, {
id: 1,
type: "man",
text: interpreter("ImMale")
}
]
}
and your yup validationSchema:
ValidationSchema = Yup.object().shape({
gender: Yup.boolean().required().oneOf([0 , 1]),
});
note: you should to use gender values in .onOf() function.
if you want to show some msg for error message, use this code for yup validationSchema:
ValidationSchema = Yup.object().shape({
gender: Yup.boolean().required().oneOf([0 , 1], 'Selecting the gender field is required'),
});

Theoretically it shouldn't be different from any other value. You're tracking the radio value (or Formik's tracking it for you) somewhere in your state as a string most likely, and you simply need to apply the rules to the value that you're storing.
If you want to make sure the value matches only the presented radio options, you can use oneOf to accomplish that, but otherwise it's no different than any other scalar value.

Related

populate cards and modals via same json file using react(-bootstrap)?

The data from workData fills <Card></Card> correctly.
The <Modal></Modal> only fills with the last entry of workData (e.g. Test4, Modal4, test text 4...)
my goal is to generate cards and respective modals (for each card) using the data from the json, in the same file.
why is the modal only being filled by the last properties in the json? how do i get it to populate with the entire array? if possible please explain why this does not work the way it is.
if it's not obvious im super new, i am, any responses would be super appreciated. ty
cards good
after clicking "Read1" bad, should say Test1, test text 1
in App.js: import { Works } from "./Works";
in Works.js: import { workData } from "./data";
also in Work.js:
export const Works = () => {
const [show, setShow] = React.useState(false);
const onClick = () => setShow(true);
return (
<>
<div className="work-container">
<Row xs={1} md={2} lg={4} className="g-4">
{workData.map((data, key) => {
return (
<div key={key}>
<Col>
<Card>
<Card.Img variant="top" src={data.projectImage} />
<Card.Body>
<Card.Title>{data.projectTitle}</Card.Title>
<Card.Text>with {data.projectTeam}</Card.Text>
<Button variant="link" onClick={onClick}>
{data.readMore}
</Button>
</Card.Body>
<Card.Footer>{data.tags}</Card.Footer>
</Card>
</Col>
<Modal
show={show}
onHide={() => setShow(false)}
dialogClassName="modal-95w"
>
<Modal.Header closeButton>
<Modal.Title>{data.projectTitle}</Modal.Title>
</Modal.Header>
<Modal.Body>
<Image src={data.projectImage}></Image>
<p>
{data.modalText}
</p>
<Image src={data.modalImage}></Image>
</Modal.Body>
</Modal>
</div>
);
})}
</Row>
</div>
</>
);
}
in data.js:
export const workData = [
{
projectTitle: "Test1",
modalTitle: "Modal1",
modalText: "test text 1",
modalImage: "image",
readMore: "Read1",
projectImage: "image",
projectTeam: "Test1",
year: "2022",
link1: "link",
link2: "link2",
tags: [
"#tag1 ",
"#tag2 "
]
},
...
The data from workData fills <Card></Card> correctly.
The <Modal></Modal> only fills with the last entry of workData (e.g. Test4, Modal4, test text 4...)
my goal is to generate cards and respective modals (for each card) using the data from the json, in the same file.
why is the modal only being filled by the last properties in the json? how do i get it to populate with the entire array? if possible please explain why this does not work the way it is.
cards good
after clicking "Read1" bad, should say Test1, test text 1
You iterate over workData for Cards and Modals, but you use only one single state for everything. What you need to do, is to also create a state for every Modal. Usually you create an array with unique id as key and boolean value. I assumed projectTitle is unique:
{
Test1: false,
Test2: false,
Test3: false
}
Because you don't know the length of your data, you just iterate over the array, as you have done for Cards und Modals:
const initialShowState = Object.fromEntries(
workData.map((data) => [data.projectTitle, false])
);
const [show, setShow] = React.useState(initialShowState);
Then you need to create a generic callback function, which takes the id of the Card and shows the appropriate Modal. I simplified the logic and created a toggle function:
const toggleShow = (id) =>
setShow((prev) => {
return { ...prev, [id]: !prev[id] };
});
Finally, when you render UI and iterate over workData, you need to apply the callback function to Button onClick and Modal onHide event handlers and set the show property of Modal:
<Button variant="link" onClick={() => toggleShow(data.projectTitle)}>
...
<Modal
show={show[data.projectTitle]}
onHide={() => toggleShow(data.projectTitle)}
dialogClassName="modal-95w"
>
That's it. Here is the working sandbox: https://codesandbox.io/s/hungry-sunset-t865t3
Some general tips:
You don't need the outer Fragment in Works as you only have one upper most element
If you use JSX syntax in your file, your extension should be .jsx and not.js (Works.jsx)
Using index as key in the list is bad practice. Find some unique id in your data

Admin-on-rest: Input validation based on field value

In a SimpleForm of an Edit view I would like to set the minimum value of the group size based on the current number of members inside.
The entity is:
group = {members: 3, size: 10}
What I'm trying to achieve looks like:
export const UserCreate = (props) => (
<Edit {...props}>
<SimpleForm>
<DisabledInput label="Members number"
source="members" />
<NumberInput label="Group size"
source="size"
validation={{min: members, required: true}} />
</SimpleForm>
</Edit>
);
This is explained in the documentation, in the Per Field Validation: Function Validator part.
In a nutshell, you define a function which will take 2 parameters: the value to validate and values which contains all the form values

Kendo UI DropdownList dataSource

Is there any way I can set a kendo ui dropdowns data source to a property of an object? Example.
If I have following object
Person:{
FirstName: 'Nilesh',
Gender: 'Male',
GenderList:['Male','Female']
}
If I have a form in which I show a text box for the first name and a dropdownlist for the gender, I want to bind the kendo ui dropdownlist to the GenderList Property of the object.
I want to do this in angularjs
Is this even possible? If yes how can we get this to work?
I used following html to render the kendodropdown list.
<input kendo-drop-down-list k-data-source="Person['GenderList']" />
but this does not work.
Any help appreciated.
I have tested your code and this works for me:
In your controller:
$scope.Person = {
FirstName: 'Nilesh',
Gender: 'Male',
GenderList: ['Male', 'Female']
}
In your html:
<input kendo-drop-down-list k-data-source="Person['GenderList']" />
The only difference is var Person is declarate into $scope. This is necessary for angular data-binding.

Validation in knockout js input fields

I created some input fields using KnockoutJS, and now I want to validate them.
http://jsfiddle.net/sohimohit/43zkoszu/12/
I tried it using validation plugin but it doesn't work.
I added that plugin and used it as mentioned but didn't get the solution. When you click on "add field" a form appears; I want to make the name field required and branch id as numeric. However, when I click on "add fields" it doesn't get added until the form is validated.
How can I achieve this?
You are not doing validation properly. I recommend this method
Set some settings
ko.validation.configure({
insertMessages: false,
decorateElement: true,
errorElementClass: 'error-element',
errorClass: 'error-element',
errorsAsTitle: true,
parseInputAttributes: false,
messagesOnModified: true,
decorateElementOnModified: true,
decorateInputElement: true
});
Make inputs bind with validationElement
<input type="text" placeholder="Name" data-bind="value:name,validationElement:name">
<input type="text" placeholder="Branch" data-bind="value:branch,validationElement:branch">
Extend observables
self.name = ko.observable().extend({required:true})
self.branch = ko.observable().extend({required:true,digit: true})
Now apply the rule. I prefer group
var data = [
self.name,
self.branch
]
self.Errors = ko.validation.group(data);
Now on add button wrap your code
self.Add = function(){
if(self.Errors.length == 0){
.
.
.
//Your code here
}else{
self.Errors.showAllMessages()
}
}
Hope it helps

Set tag attribute based on variable value with kendo binding

I create a variable list of input elements which are bound to a kendo MVVM.
I have a kendo validation running over all my input elements (this is standard functionality), checking if the input is empty.
The objects in my MVVM have an attribute IsMandatory, like this:
{ Name: "test", ID: 12, ... , IsMandatory: false }
The validation must not try to validate elements with an IsMandatory value of false. How can I achieve this?
I know I can bind attributes to MVVM values like this:
<input data-bind="attr: { name: Name }" />
Which results in an actual output like this for the object above:
<input name="test" />
However, the required attribute used for the standard required validation is value-less, like this.
<input name="test" required />
So basically I need to create elements with a required attribute if the IsMandatory attribute in my MVVM object is set to true, and without the required attribute if it is set to false.
{ Name: "test1", ID: 1, ... , IsMandatory: true }
{ Name: "test2", ID: 2, ... , IsMandatory: false }
{ Name: "test3", ID: 3, ... , IsMandatory: true }
<input name="test1" required />
<input name="test2" />
<input name="test3" required />
Is there an elegant solution to this problem? Other than putting an if-else around the creation of each element. Or is there a different solution of excluding/including elements in my validation?
One option I could imagine would be to create a custom required validation, checking if the IsMandatory attribute for the input is set to true and only then validate the element. However, I could not find any possibility to get my hands on the MVVM object of the current element.
...
validation: {
required: function (input) {
var observable = // Get the kendo observable from input here !!!!!
if (observable.IsMandatory) {
return input.val() != "";
}
return true;
}
},
...
This can be implemented as a custom binding:
kendo.data.binders.required = kendo.data.Binder.extend({
refresh: function() {
var required = this.bindings.required.get();
if (required) {
this.element.setAttribute("required", "required");
} else {
this.element.removeAttribute("required");
}
}
});
Here is a live demo: http://jsbin.com/atozib/1/edit

Resources