I need to set and send value of slider after onChange - javascript

I am using material PrettoSlider I need to set on change properly so if any value gets change I am able to submit that value but what happening right now if I change something means if I click one time I will get value null if I click two times in same value then value get the print I need to set onChnage using formik and need to set field value properly so if I submit then that change value gets submitted whatever value get to change it storing in event.target.ariaValueNow
how can I set Field values properly
export default function CustomizedSlider() {
const classes = useStyles();
const ruleForm = useFormik({
initialValues: {
partialNameMatchThreshold: 40
},
enableReinitialize: true,
onSubmit: (values) => {
alert(JSON.stringify(values, null, 2));
}
});
return (
<div className={classes.root}>
<Typography gutterBottom>pretto.fr</Typography>
<PrettoSlider
onChange={(event) => {
console.log("Number change ", event.target.ariaValueNow);
ruleForm.setFieldValue(event.target.ariaValueNow);
}}
valueLabelDisplay="on"
aria-label="pretto slider"
defaultValue={ruleForm.values.partialNameMatchThreshold}
marks={marks}
name="partialNameMatchThreshold"
/>
<Button
onSubmit={ruleForm.handleSubmit}
variant="contained"
color="primary"
type="submit"
>
Commit Changes
</Button>
</div>
);
}
CodeSandBox Link

We should not be using the event to capture the selected value . There is a second argument provided by the onChange method which holds the actual selected value.
onChange={(event, newValue) => {
we need to use the newValue instead of event.
Formik's setFieldValue takes 2 arguments , one is the field which you need to update and the other is the value to update .
ruleForm.setFieldValue("partialNameMatchThreshold", newValue);
Slider component needs to read the value from the Formik to keep the value in sync . So we need to make the slider as a controlled component . Add this new value prop to the slider
value={ruleForm.values.partialNameMatchThreshold}
Codesandbox

Related

Get a checkbox value on change of other checkbox in react

I have 2 checkboxes A and B. I want to check whether checkbox B is checked or not on change of checkbox A and vice versa. Also I want to change checkbox B on change of checkbox A. How can we achieve that in react.js.
You can create a state for both of them and change it accordingly.
This way you'll have access to it whenever needed.
Also, to avoid handling changes separately for every input, you can give each of them a name and then have a single dedicated function that changes the value of the checkbox based on it's name.
Example:
function App() {
const [state, setState] = useState({
firstCheckbox: false,
secondCheckbox: false,
})
const handleChange = (e) => {
setState(prev => ({
...prev,
[e.currentTarget.name]: e.currentTarget.checked,
}));
};
return (
<>
<input
name='firstCheckbox'
type='checkbox'
checked={state.firstCheckbox}
onChange={handleChange}
/>
<input
name='secondCheckbox'
type='checkbox'
checked={state.secondCheckbox}
onChange={handleChange}
/>
</>
)
}
Currently in this example, each checkbox relates to it's own state.
However, you can easily adjust the handleChange function based on your needs.

How to get custom number buttons to show on correct input field react.js

Having a hard time seeing how I could accomplish this. I created some custom number buttons from 0-9 that users can click on instead of using the keyboard. The problem I'm having is I have multiple dynamically created input fields depending on JSON Data so let's say there are 10 dynamically created input fields and a user starts with question one and the user then uses the custom number buttons I created and clicks numbers "145" to answer question one, but what happens is then all 10 inputs have the same number "145" not the problem the user was trying to solve. I'm using the context API to then save the values typed in on a function called getButtonValue that I then call to the parent component and save the values in a state array, so I know that my problem is that all the inputs share the same state array but how could I make sure the correct input the user clicks on is only receiving those values.
Thanks in advance.
My Custom Number Button Component:
import { FormContext } from "../../lib/FormContext";
function ActivityBar() {
const { getButtonValue } = useContext(FormContext);
return (
<div className={`${activity.activity__workSheet__numberButton}`}>
<button value={0} onFocus={(e) => getButtonValue(e)}>
<img
className={`${activity.activity__workSheet__img0}`}
src={"/assets/activityNumber-btn.png"}
alt="activity number button"
/>
.... more code
Parent Component:
const [numberButtonClicked, setNumberButtonClicked] = useState([]);
const getButtonValue = (e) => {
setNumberButtonClicked((prevButtonClicked) => [
...prevButtonClicked,
e?.target?.attributes[0].value
]);
};
return (
<Carousel>
<div ref={imageRef} style={{ height: "100%" }}>
{Object.entries(elements).map((element, i) => {
const { fields } = element[1];
if (fields) {
return (
<Element
key={i}
field={fields[0]}
id={i}
useReff={`answer${i}`}
currentValue={
numberButtonClicked === "" ? null : numberButtonClicked.join("")
}
/>
);
} else {
return;
}
})}
</div>
</Carousel>
Got a good working version figured out for this scenario, what I did was.
I have a onFocus method on my input tags that then takes in the event and calls a handleChange(e) function. Within that function I then save the currentInputId in a variable by using e?.target?.attributes[0]?.value and the previous InputId in a state variable and just check if the previous InputId is equal to the currentId user just focused on. If so then we'll add the next number user clicks into the same field, else if previousInputId !== currentInputId then make my user value state array empty, setNumberButtonClicked([]).

How to create a submit button in react-admin which changes appearance and behaviour depending on form data and validation

In a complex tabbed form in react-admin I need to have two submit buttons, one is the regular save button and one for altering the "status" field (advancing one workflow step) and saving the form.
The save butten should only become active if all required fields are filled by the user.
The other button changes its text depending on a "status" field in the record which contains the current workflow step, and is only active when the form validation for the current workflow step passes.
So either I need a dynamic button or several buttons which show and hide depending on the "status" field.
I think the dynamic button would be the more elegant solution.
Below you see the code I currently have, it is more or less copied from the react-admin documentation. I need to add a custom save button as well, but it is just a subset, easy to do when the AdvanceWorkflowButton works at the end.
const AdvanceWorkflowButton= ({ handleSubmitWithRedirect, ...props }) => {
const [create] = useCreate('posts');
const redirectTo = useRedirect();
const notify = useNotify();
const { basePath, redirect } = props;
const form = useForm();
// I need to set the label dynamically ... how?
// I also need sth like:
// if (validationSucceeds()) enable=true
const handleClick = useCallback(() => {
// here I need to check the current content of the "status" field.... how?
form.change('status', { "id": 2, "name": "Vorbereitung begonnen" });
handleSubmitWithRedirect('list');
}, [form]);
return <SaveButton {...props} handleSubmitWithRedirect={handleClick} />;
};
const CustomToolbar = props => (
<Toolbar {...props} >
<SaveButton
label="Speichern"
redirect="list"
submitOnEnter={true}
variant="text"
/>
<AdvanceWorkflowButton />
</Toolbar>
);
I had the exact same trouble.
Needed a button to save the form without validation, and another to save and change status with validation in place.
The code above helped me get to the answer, here are my configuration of the components necessary to achieve the desired outcome.
Set a new truthy value up in the form data as follows when the user clicks the save and next. Check the new property ('goNextStep' in our example) on the server to move the process forward.
<SaveButton
label="Save and next step"
handleSubmitWithRedirect={() => {
form.change('goNextStep', 1); // or true
props.handleSubmitWithRedirect('list');
}}
</SaveButton>
<SaveButton
label="Save only"
handleSubmitWithRedirect={() => {
form.change('validateCustom', 0); // or false
props.handleSubmitWithRedirect('list');
}}
/>
Use the validate prop on react-admin form. I could not make it work with field level validations. I had to remove every field level validation props, and implement all those in validateFunction.
Altough, you could still use the validators in your custom validation function.
const validateFunction = (values) =>{
// using our previously set custom value, which tells us which button the user clicked
let shouldValidate = values.goNextStep === 1;
// return undefined if you dont want any validation error
if (!shouldValidate) return undefined;
let errors = {};
// use built in validations something like this
var someTextFieldErrorText = required()(values.someTextField, values);
if (someTextFieldErrorText) {
errors.someTextFieldErrorText = someTextFieldErrorText;
}
// OR write plain simple validation yourself
if(!values.someTextField) {
errors.someTextField = 'Invalid property!';
}
return Object.keys(errors) ? errors : undefined;
}
Than set up tabbed form to use the previous function for validation.
<TabbedForm
validate={validateFunction}
>
...
</TabbedForm
React-admin version: 3.10.1

How to get the value from the react fabric ui checkbox

This is the JSX tag. I'm getting the status of the checkbox but not the value or the label name.
<Checkbox label="Innovation" value="Innovation" onChange={this._onChange} />
Below is the code that shows the status
public _onChange(ev: React.FormEvent<HTMLElement>, isChecked: boolean) {
console.log(`The option has been changed to ${isChecked}.`);
I tried to pass the value but it didn't work.
You should use Checkbox tag inside Stack tag like this
<Stack>
<Checkbox label="Innovation" onChange={_onChange} />
</Stack>
function _onChange(ev: React.FormEvent<HTMLElement>, isChecked: boolean) {
console.log(`The option has been changed to ${isChecked}.`);
}
For more reference you can go through this link
You can consider using the inputProps attribute to set the value and id of the element.
After you set the value and id of the element, then in the onChangeEvent, you can read these values from event object
<FabricCheckbox ...props inputProps={{value:myVal, id:myId}} onChange={(e, checked) => this.handleOnChange}/>
...
handleOnChange(event, checked) {
const selectedVal = event.target.value; //This will return the value you set
}

How to access/reference component values inside a component

Trying to build a react component where I need to control checked status of checboxes and select options when change event occurs. But I don't know how it is possible to get value of the checked checkbox(es) and set the state.
We're using custom data-binding. On page load, we're assigning selected value of the select, with jQuery.
Programmatically changing value of the select must update matching check-boxes.
When user checks/unchecks a checkbox, corresponding value must be toggled on the select.
With jQuery I would loop trough check-boxes and build array with checked values then assign this value to the select on checkbox change. And when select change event is triggered, I would uncheck all check-boxes and check the ones matching selected items.
This is my simplified code.
state = {
items: [
{Key: 1, Value: "A"},
{Key: 29, Value: "Z"}
],
selected: [1, 29]
}
function onSelectChange(){
// Update checked checkboxes
}
function onCheckboxChange(){
// Update selected options
}
<div>
<select multiple onChange={onSelectChange} className="hidden">
{this.state.items.map((item, i) =>
<option value={item.Key}>{item.Value}</option>
)}
</select>
<div className="checkboxes">
{this.state.items.map((item, i) =>
<input
type="checkbox"
key={i}
checked={this.state.selected.indexOf(item.Key) >= 0}
onChange={onCheckboxChange} />
)}
</div>
</div>
You would use this.setState({}) inside the event handler to update the state of a component in React. This triggers a rerender in React which allows you to query the the updated state (this.state.selected).
Be advised that this.setState() expects an immutable object, so you should never change the previous, but always set a new state object!
Answer to comment:
For selectItem:
onSelectChange = event => this.setState({selected:event.target.value})
and for checkboxes (note the prevState):
onCheckboxChange = item => event => this.setState(({selected,...prevState})=> ({
...prevState,
selected: event.target.checked? selected.concat(item): selected.filter(it=> it!== item)
}))
and usage:
{this.state.items.map((item, i) =>
<input
type="checkbox"
key={i}
checked={this.state.selected.indexOf(item.Key) >= 0}
onChange={onCheckboxChange(item)} />
)}
This has the downside that it will create a new function on each rerender, so it's better to create a custom CheckboxItem and pass the item to it and use a handleClick.
onChange function give event where you could check whether the select box is being checked or not using this you can update your state accordingly.
function onCheckboxChange(e){
console.log("checked", e.target.checked);
// Then, on the basis of boolean you can update your state
}

Categories