Testing if something is on screen with react - reactjs

I have an input field with a submit button and when someone enters something that text appears on the screen. how can I test that in react?
I know how to simulate the button click but what would the expectation be? or how would I actually be able to tell if the text is there?

You would need to use refs to check the values of input fields using React. The refs provide the hooking interface between virtual DOM element of input fields to access it values.

You scry for that input element by id or type or class. And you can access the text of that element by looking at .value

I'm not sure I understand the question... the first part of your question makes me think you want to detect when a user is typing some text in an input field, but the second part makes me think you want to automate a test, placing some text in the input and simulating click on a button, kinda confusing ...
In my last project I used that package instead of a classic input: react-contenteditable
You can hook your code to events that this component is firing:
render() {
const { selectedDbItem } = this.props
return (
<div>
<ContentEditable
onBlur={(e)=>this.onBlurField(e, 'supplier')}
className="field-value"
html={selectedDbItem ? selectedDbItem.supplier : ''}
disabled={false}
onChange={(e)=>this.onChangeField(e, 'supplier')}
onKeyDown={(e) => this.onKeyDown(e)}
/>
</div>
You can then implement the callbacks onBlur, onChange, onKeyDown (for input filtering for example ...) in the containing component.
Hope that helps

Related

How to change the value of hidden text input box when select menu option is changed

I want to change the existing value in a hidden text input box (automatically when the box is closed) to an empty string ('') when the user chooses one of the drop down menu selections. The problem is that I can close the component with the right menu selection, but the value does not change to an empty string until I click the button a second time. Then the value becomes an empty string and I get the correct information.
I originally based the approach to that of form data being passed to/from the parent and that does not seem to work for this component. I tried using a setState() function, however, this either didn't take or I did not implement correctly. All state has been set and all other components move data around as they're supposed to.
This is the parent component that sends/receives the information from the . The "cost={dailyTransportationCost}" is supposed to send the new value to the child.
<DailyTransportationCost
cost={dailyTransportationCost}
handleTransportationCost={e => setDailyTransportationCost(e.target.value)}
/>
This is the component that needs to change to an empty string when it's closed based on the menu option (separate component)
const DailyTransportationCost = ({ cost, handleTransportationCost }) => {
return (
<div className={`${styles.containerTransportationCost}`}>
<label className={`${styles.containerLabel}`} htmlFor='dailyTransportationCost'>Daily Cost</label>
<input className={`${styles.containerInput}`}
placeholder='0.00'
id='dailyTransportationCost'
type='number'
value={cost.dailyTransportationCost}
onChange={handleTransportationCost}
/>
</div>
);
};
Thank you for your help. I've been banging around on this for a couple of days. Any suggestions will be appreciated.
me again...
I figured it out. It was a simple useEffect() and everything worked remarkably well. Just want to thank anyone who might have stopped by.
Cheers!

Cannot type in input field when using value={}

I am using NextJS, and trying to build a form to update a supplier.
I have the following input:
<input type="text"
ref={nameDisplayedRef}
className='p-2 rounded'
name='nameDisplayed'
defaultValue={supplier.nameDisplayed}
value={supplier.nameDisplayed}
/>
When the input is like this, I cannot type in to it. I have read that I need an onChange function - but I dont need an onChange function. I dont care when its changed, I care when the form is submitted.
The data provided to this input field comes from an API call made by useSWR. When I update the database, the field only updates if I have the value={} in the input field. But with it I cannot change the input text.
I appreciate that i need an onChange function but what am I supposed to put in it? It wont let me leave it empty so I am not sure what to do.
edit:
Adding nameDisplayedRef.current.value = supplier.nameDisplayed solves the problem but typescript shows an error for it in PhpStorm. But the code works at least :\
The problem is controlled vs uncontrolled inputs.
An uncontrolled input is when an input handles value and change on its own.
A controlled input is when you control the input externally. What you want to do is use some kind of state to manage the value of the component (which handles the initial value) and the onChange handler will set the state that is placed in the value.
Here's an example with useState:
const [stateValue, setStateValue] = useState(initialVal)
<input
type="text"
value={stateValue}
onChange={(e)=>setState(e.target.value)}
/>

React Select Keep Input Value After Selection

I am currently working with react-select with single selection. After selecting a particular value, I would like the user to be able to edit the typed in text (not necessarily the same as the rendered option (formatOptionLabel).
https://codesandbox.io/s/react-select-course-dfmn2?file=/src/Selector.tsx
For example, if I typed in PHYS101, and then select the option PHYS101 ... joe, and then proceed to edit the text, for backspace the form would be come PHYS10 and if I type A then it would be PHYS101A.
I attempted to use the onInputChange and onChange props, but I cannot get it to work consistently. I would appreciate any suggestions or snippets of code I could use.
There is a similar issue. Maybe that could help.
Here is a link to the issue. react-select custom tag edit feature
OR
If you wanna switch over to some other library for your specific purpose.
You could use react-selectize.
You can provide props to edit the selected option.
I solved it like this.
I pulled a reference to the internals via ref
<Select
ref={selectRef}
onChange={onOptionSelect}
/>
and in the useEffect.
useEffect(() => {
const selectObj = selectRef?.current
if (selectedOption?.value && selectObj) {
selectObj.state.inputValue = selectedOption?.value
}
}, [selectedOption])

Add an additional component as soon as user types on input

I know how to add an item based on state. When user type something on input, It generates list items based on state(mapping) like below code.
return (
<div className="App">
<input name="name" value={name} onChange={handleInput} />
<button onClick={() => handleBtn(names)}>Click Me</button>
{names.map((item) => (
<div>{item}</div>
))}
</div>
);
But I want to add one more additional component automatically as soon as user type something on input.
To add an additional component easily right after finish typing like below image (+ List Item)
Here is an example
(Additional question)
I write a function which adding a listItem component onChange event. But it adds a component every time user type text as you know.. So I guess, To add an additional component successfully, I need to know when user starts and finishes typing not to add it multiple times(like user stops for a wile and typing again). Do you guys have any idea?
You could use onBlur so when the user finishes typing and loses the focus from the input you could add the additional component.
onBlur will be called every time the field loses the focus so if you want to add the additional component only if the value of the input has been changed, then you need to check if the value was changed after the blur, and then add the new component.

Fire same bootstrap tooltip for all disabled inputs / ReactJS

What's the best way to intialize Tooltip in a react component and have it fire on all disabled inputs, like a global single call.
i.e. "This cannot be edited" any time you hover over ANY disabled input.
My goal is to NOT have to wrap each of hundreds of inputs individually like this:
<Tooltip>
<input/>
</Tooltip>
Make an Input component, pass in a bool prop, something like showValidationMessageAsTooltip, and, inside Input comp., if showValidationMessageAsTooltip is true, wrap the Input comp. with Tooltip.
Code example:
return (
showValidationMessageAsTooltip ? <Tooltip><input {...props}/></Tooltip> : <input {...props} />
);
This way, you'll only have to pass in an extra bool prop.
P.S.: There are other, even more efficient ways, especially if you have a form config where each form field has a component defined for it and each form field can have multiple HOC (higher-order comps.) defined in the form config (an array of objects, basically) as well.
But, for now, until you dive deeper into things like redux-form, etc., I suggest to stick to the simpler solution.

Resources