React bootstrap Typeahead error on backspace - react-bootstrap-typeahead

Im using react Bootstrap Typeahead in my code, problem is whenever I use backspace to remove my selection and when I reach a point where there is no letter, my code breaks and I get below error.
**Uncaught Invariant Violation: One or more options does not have a valid label string. Check the labelKey prop to ensure that it matches the correct option key and provides a string for filtering and display.
My Typeahead Code :
<Typeahead
id="empName"
options={this.state.EmployeeNameOptions}
selected={[this.state.EmployeeName]}
placeholder="Enter Employee Name"
style={{ zIndex: 9999999 }}
onInputChange={text => {
this.setState({
EmployeeName: text,
})
}}
onChange={(e, val) => {
this.handleChange(e, val);
}}
/>

You're using onInputChange and onChange incorrectly. Every time you type inside the input, onInputChange is updating your state and changing the value for selected, leading to unexpected results. Meanwhile, onChange provides an array of the selected values its argument, not an event and value. Try the following instead:
<Typeahead
...
options={this.state.EmployeeNameOptions}
selected={this.state.selectedEmployee}
onChange={(selected) => {
this.setState({ selectedEmployee: selected });
}}
/>

Related

building a basic search bar Material-UI

I want to build a really basic search bar with a search icon (similar to the one on Material-UI ) & invoke a function with the current value of the search field whenever the user hits enter or click on the search enter. I am new to Material-UI & I'm struggling to find my way through the different text fields elements.
I currently have this code
import Input from '#material-ui/core/Input';
class ...somecode
...somecode
constructor(props) {
super(props);
this.state = {
resources: [],
value: '',
};
}
handleChange(event) {
console.log(event.target.value);
this.setState({ value: event.target.value });
}
search(/* access value upons enter/ search icon click */) { <--------------------------
}
...some code
return (
<form id="search">
<Input type="text" value={value} onChange={(event) => { this.handleChange(event); }} placeholder="Search..." autoFocus fullWidth />
</form>
);
p.s: I had a really hard time fiddling around with all the APIs and options available in the input suite (I highly suggest an explanation of how they are related in the docs)

Identify which [SelectField] [DropDownMenu] fired onChange

I am programmatically rendering multiple SelectField and DropDownMenu components. I am trying to work with a single onChange handler functions, but I'm have not found a way to reference specific SelectField / DropDownMenu that triggered the event so I can update state accordingly.
The params passed for the onChange event seem not to contain any helpful information to identify the firing components. Any ideas?
Here's an example of how this can be done
https://jsfiddle.net/davidebarros/k9ng7bk9/
This is assuming you are familiar with the es6 arrow function syntax.
state = {
dropDown1: 1,
dropDown2: 4,
selectfield1: null,
selectfield2: null
}
onChange = (type) => (event, index, value) => {
this.setState({
[type]: value
})
//In your render method
<SelectField
floatingLabelText="Select Field 1"
value={this.state.selectfield1}
onChange={this.onChange("selectfield1")}>
<MenuItem value={1} primaryText="Select 1, value 1" />
<MenuItem value={2} primaryText="Select 1, value 2" />
</SelectField>

Find the hidden checkboxes in Coypu

I'm try to create test for my Bootstrap project. I'm use Coypu. But I ran into a some problem. I can't check my check-boxes. The problem is that I changed style form my check-box. And now standard Bootstraps check-boxes is hidden. The new check-box is hidden inside standard pattern:
<label>
<input type="checkbox" data-bind="checkedValue: key, checked: $parent.selectedCatchments, attr: { id: key }" class="catchment-checkbox" />
<span data-bind=" text: value, attr: { for: key }" class="lbl padding-8 openSans-Text catchment-checkbox-span"></span>
</label>
The problem is that Coypu can't to find the hidden element on browser. And now I can't to check selected check-box or not.
This is standard check-box:
I turned off: opacity: 0 in CSS style.
And this is new checkbox with the new style.
How can I check the number of checked items in Coypu?
I can add ConsideringInvisibleElements = true inside SetUp method, but this option will be works always for all Tests. How I can change value of ConsideringInvisibleElements option on true or false when I need inside test code?
I'm find this variant:
var catchmentsCheckboxes = Browser.FindAllXPath("id('catchmentsColumn')/div[1]/div/label/input", null, new Coypu.Options { ConsiderInvisibleElements = true });
The first parameter: xPath to element;
The second parameter is can be null;
The third parameter is ConsideringInvisibleElements. And we can change value of this parameter on true or false.

In Reactjs how do I update the correct value in the parent state with a callback that's been passed to a nested child component?

I've been on this one for days, and all my reading hasn't helped me find a clean solution for this particular case.
Issue
I can send a parent state value and callback down to a nested component, but once the callback is triggered in the child I don't know how I can send the updated value back to the parent so it can update the correct value.
For instance
Parent Component (Has values and the callback)
Child Component (Values and callback is passed here)
Grand Child Component (Values Updated here and callback triggered)
What is SEEMS to cause the Issue
It seems the issue is I need the original key name in order for "setState" to update the correct value in the parent component(or at least it seems that way), but the child component only has original value and new updated value and has no access to the key associated with original value in the parent component.
Important Notes on Best Practice Surrounding this question
-From what I understand it is bad practice to use refs to handle nested situations like this.
-It seems like there is a cleaner solution than sending a prop for the key and another for the value.
-I'm assuming also that flux might provide a solution to this issue but I feel that there is a basic component to component communication technique or principle that I'm missing here.
Here is a bare bones example of what I'm dealing with.
/*All the values need to be updated here so that the inputs can used for calculation and then sent to a component that displays the output*/
var Calculator =
React.createClass({
getInitialState:function(){
return {
value1: "Enter value 1", /*These values are passed to a nested child component, can't figure how to update the right one*/
value2: "Enter value 2",
}
},
update: function(update){
this.setState(
update
);
},
render: function () {
return (
<div>
<h2>Input</h2>
<Input onClick={this.handleClick} update={this.update} value1={this.state.value1} value2={this.state.value2} /> //pass the values here
<h2>Output</h2>
<Output />
</div>
);
},
handleClick: function () {
//want to update the state for the correct value here
}
});
/* A compenent that is a middle layer between the parent and nested child component I'm working with*/
var Input =
React.createClass({
update: function(){
this.props.update();
},
render:function(){
return (
<div>
<p><InputComponent update={this.update} value={this.props.value1} /> / <InputComponent value={this.props.value2}/></p>//passing down values again
<p><ButtonComponent onClick={this.props.onClick} /></p>
</div>
)
}
});
/*This is the child component that gets the value and call back from the top level component. It will get updates to the values and send them back to change state of the parent component.*/
var InputComponent =
React.createClass({
handleChange: function(event) {
this.props.update();
},
render: function() {
return <input type="text" value={this.props.value} onChange={this.handleChange} />; //this props value has no key associated with it. Cant't make update object ie {originalkey:newValue}
}
});
/* This component is triggered to carry out calculations in the parent class.*/
var ButtonComponent =
React.createClass({
render:function(){
return <button onClick={this.handleClick}> {this.props.txt} </button>
},
handleClick: function(){
this.props.onClick();
}
});
/*The inputs will be calculated and turned to outputs that will displayed here.This component doesn't matter for the question so I left it empty*/
var Output =
React.createClass({
});
Here's an example I just put together on jsfiddle.
Instead of putting update in setState, we pass a value to update from the child component and let the parent set its state.
In the parent, we have:
_update: function(val){
this.setState({
msg: val
});
},
render: function() {
return (
<div>
<p>Message: {this.state.msg}</p>
<Child _update={this._update} />
</div>
);
}
And in the child, we have a _handleClick function that calls the parent _update function with values:
_handleClick: function(){
this.props._update(React.findDOMNode(this.refs.text).value);
},
render: function(){
return (
<div>
<input type="text" ref="text" />
<button onClick={this._handleClick}>Update</button>
</div>
);
}

With jquery autocomplete widget, how to populate the input value after a selection with my own data

In my form text input bar, the json returned by the autocomplete widget will be, [{id = 1,lable="lable1"},......]
[{id = 1,label="label1"},{id = 2, label="label2"},......]
and I want the input box display value to be "label" which works as default, but I want to the input value to be "id" when I submit the form..
Many thanks!
I usually keep a <input type='hidden'> right next to the autocomplete input, and then on the select event of the complete I populate that with the ID:
$("#autocomplete-input").autocomplete({
minLength: 2,
select: function (event, ui) {
$("#autocomplete-input-id").val(ui.item.id);
}
});