React Hook Form reset Controller (value) to default - reactjs

Here is an example of my component, wrapped into Controller
<div className="mt-1">
<Controller
control={control}
name="selectedBirthMonth"
defaultValue={selectedMonth}
render={({ field }) => (
< SelectBirthMonth
field={field}
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
reducedMonths={reducedMonths}
onChange={useEffect(() => monthSelect(field.value)), [selectedMonth]}/>
)}
/>
</div>
For now I am just trying to reset it with a button. Later I'd love to conditionally reset, depending on the value in a sibling component. Would be great to get it work with the button in the first place:
<input
style={{ display: "block", marginTop: 20 }}
type="button"
onClick={() =>
reset(selectedBirthMonth)
}
value="Reset with values"
/>
I get en error: selectedBirthMonth is not defined. Bassicaly, what I am aming for,on click, the whole component goes to default / a state it had when first rendered. What am I missing?

reset didn't do the job somehow, but setValue did. However I am setting to a value, not to the original state after first render, but in my case it's same.
<input
style={{ display: "block", marginTop: 20 }}
type="button"
onClick={() =>
etValue('selectedBirthMonth', lastAvaliableMonth)
}
value="Reset with values"
/>

Related

Non-MUI component as renderInput prop of TimePicker (#mui/x-date-pickers)

I have the following implementation of MUI's TimePicker:
<TimePicker
value={time}
inputFormat="HH:mm"
views={["hours", "minutes"]}
onChange={(newValue) => {
newValue && setResultTime(newValue);
}}
renderInput={(props) => {
console.log(props);
return (
<InputWrapper>
<Input ref={props.inputRef} tw="w-16" />
<FontAwesomeIcon
icon={faAngleDown}
tw="text-company-light-1 opacity-80 text-sm px-2 cursor-pointer"
/>
</InputWrapper>
);
}}
/>
I am unable to use a controlled version of this by specifying isOpen because the outside click handler appears to fire when I click on the component and that causes it to close. That is, wrapping it in:
<OutsideClickHandler onOutsideClick={() => setTimePickerOpen(false)}>
...
</OutsideClickHandler>
causes it to close, even when clicking on the component itself.
The props to renderInput do not appear to contain an onClick and so I have no idea how to cause my component to respond to clicks. How can this be achieved?

Autoclose bootstrap 5 Dropdown without toggle in React

I have a search field that shows data as dropdown.item when user is typing. The library is React Bootstrap (bootstrap 5). This is working great. The dropdown is showing. The problem is that the dropdown persist when clicking outside or navigating to a new link. The dropdown is in a header that does not get rerendered with the rest of the page. Using NextJS. Any tips on how to close a dropdown that has no toggle?
<form className="d-none d-sm-inline-block" style={{ zIndex: "1000" }}>
<div className="input-group input-group-navbar">
<input
type="text"
className="form-control"
placeholder="Søk"
aria-label="Search"
onChange={(event) => {
setSearchTerm(event.target.value);
}}
/>
<button className="btn" type="button">
<Icon.Search className="align-middle" />
</button>
</div>
{searchData.length >= 1 && (
<Dropdown style={{ position: "absolute", background: "white" }} autoClose="outside">
{searchData.slice(0, 10).map((element, index) => {
return (
<Link key={element.agressoResourceId} href={`employees/69918`} passHref replace={true}>
<Dropdown.Item>
{element.firstname} - {element.lastname}
</Dropdown.Item>
</Link>
);
})}
</Dropdown>
)}
</form>
The solution was to use onBlur event and hide the dropdown. The problem comes with the onblure is triggered before you press the item. The solution here was to use a setTimeout of 200ms.

CSSTransition not working with stripe elements React

I have a CSSTransition that works until I add the CardElement from "#stripe/react-stripe-js";
<CSSTransition
classNames="method"
in={radio === 'add-card'}
exit={!(radio === 'add-card')}
timeout={500}
unmountOnExit>
<form id="payment-form" onSubmit={handleSubmit} className="stripe-ad">
<input
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter Email Address (Optional)"
/>
<CardElement id="card-element" options={cardStyle} onChange={handleChange} />
{error && (
<div className="card-error" role="alert">
{error}
</div>
)}
<p className={succeeded ? "result-message" : "result-message hidden"}>
Payment succeeded, see the result in your
<a
href={`https://dashboard.stripe.com/test/payments`}
>
{" "}
Stripe dashboard.
</a> Refresh the page to pay again.
</p>
</form>
</CSSTransition>
When I comment out the , the transition will work properly over the 500ms time interval. When I leave the Card element in, it will refuse to adhere to the transition rules.
I'm using the base cardstyle
const cardStyle = {
style: {
base: {
color: "#32325d",
fontFamily: 'Arial, sans-serif',
fontSmoothing: "antialiased",
fontSize: "16px",
"::placeholder": {
color: "#32325d"
}
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a"
}
}
};
The problem is that the CardElement either has its own transition on mount, or the style needs to be changed. Has anyone ever had this issue with the stripe element on transition?
I suspect that this will not work as the Elements exist within a Stripe-hosted iframe. Only certain styles are supported on Elements:
https://stripe.com/docs/js/appendix/style
I suggest opening an issue on github with a minimal example of this, for example forked from the codesandbox demo.
https://github.com/stripe/react-stripe-js/issues

React-select options shows default blue background

I have created a select component using react-select. I need to append a badge to the option who's available value is false. I have achieved it using -
const formatOptionLabel = ({ code, name, available }) => (
<div className="ds-select-distibutor-step-container format-option" style={{ display: "flex", cursor:"none" }}>
<div>{name}</div>
{!available ?
<div className="format-label" style={{ borderRadius: "12px" ,marginLeft: "auto", color: "#fff" , backgroundColor: "#aaa", padding: "2px 10px", fontSize:"12px"}}>
<span>Coming Soon</span>
</div>
: ''}
</div>
);
Following json comes at run time, which I map and use as options-
const options= [
{code:"abc",name:"abc",rank:0,available:true},
{code:"xyz",name:"xyz",rank:0,available:false},
{code:"pqr",name:"pqr",rank:0,available:true}]
And following is my custom select component
<Field
id="selectedDistributor"
name="selectedDistributor"
component={customSelect}
options={sortBy(options, 'name').map(({ code, name, available}) => ({ code, name, available }))}
formatOptionLabel={formatOptionLabel}
className="select-step"
placeholder="abc"
touched={false}
defaultValue="abc"
requiredField
>
</Field>
<FieldWrapper
label={label}
requiredField={requiredField}
touched={touched}
forId={inputId}
>
<Select
{...input}
id={inputId}
disabled={isEditMode || disabled}
onChange={value => input.onChange(value.code)}
formatOptionLabel={formatOptionLabel}
options={options}
placeholder={placeholder}
value={input.code}
className={`input-components-select ${className}`}
>
</Select>
</FieldWrapper>
enter code here
Everything is almost working but when I select the option, the background of all the options turns into blue, I tried making changes and found that if I pass the 'value' as a key of JSON instead of 'name' in the option this error goes away. But I can't use it since the json is coming from the backend and its dynamic.
Could anybody please suggest what should be done so that the background doesn't change? I have attached images for reference
first time
after selecting
I faced the same problem and I found that you need to declare a function getOptionValue as the Select's props. In your example, it should be like this
<Select
{...input}
id={inputId}
disabled={isEditMode || disabled}
onChange={value => input.onChange(value.code)}
formatOptionLabel={formatOptionLabel}
options={options}
placeholder={placeholder}
value={input.code}
getOptionValue={(option) => option.code} // changes here!!!
className={`input-components-select ${className}`}
>
</Select>
This function is used for comparison to highlight the currently selected option in the list. You can check more details in the discussion here
https://github.com/JedWatson/react-select/issues/3388

Display correct components on change with selected value from dropdown?

I have a component called DropDown Single and that has an options param Object and Database. If the Object is selected then I want to show the Autocomplete component for the name Table. If Database is selected I want it to show the autocomplete named database. I have tried to cut down the code with only the components I need to be using. The onclick itself doesn't actually do anything yet but I am assuming I will need it when I want it to show the right component.
<div className='Main UnitTestsAutoCompleteWrapper' style={{display: 'flex', justifyContent: 'space-between'}}>
<div>
<DropdownSingle
options={['Object', 'Database']}
value='Object'
name='Search for unit tests'
onclick={onChange}
/>
</div>
<div style={{marginRIght: '10px'}} >
<AutoCompleteSingle
name='Table'
label='Table'
options={autoComplete.tablesAutoComplete}
onChange={autoComplete.onTableAutoCompleteFieldUpdate}
onSelect={onSelect}
uniqueIdentifier={0}
initialValue={targetObject}
/>
</div>
<div>
<AutoCompleteSingle
name='Database'
label='Database'
options={autoComplete.databasesAutoComplete}
onChange={(e) => onFieldUpdate(e, 'database')}
onSelect={onDatabaseSelect}
uniqueIdentifier={1}
triggerOnSelectOnBackspace
/>
</div>
</div>
Use this as a simple example to guide you, you should really read the documentation. This is all covered under Conditional Rendering:
import React, { useState } from "react";
export default function App() {
const [selectValue, setSelectValue] = useState("cow");
return (
<div>
<select onChange={(e) => setSelectValue(e.target.value)}>
<option value="cow">Cow</option>
<option value="sheep">Sheep</option>
</select>
{selectValue === "cow" ? <p>Cow</p> : <p>Sheep</p>}
</div>
);
}

Resources