how can i solve a key value select input problem - javascript

im just testing this reactjs npm but when i use the select input it just show up de value pair insted of the label pair
this is the piece of the code:
import "./styles.css";
import React, { useState, useEffect } from "react";
import { FormField } from "react-form-input-fields";
import "react-form-input-fields/dist/index.css";
export default function App() {
let [type, setType] = useState("All");
const types = [
{ label: "All", value: "All" },
{ label: "Skins", value: "outfit" },
{ label: "Banners", value: "banner" },
{ label: "Wraps", value: "wrap" },
{ label: "Sprays", value: "spray" },
{ label: "Emoji", value: "emoji" },
{ label: "Pickaxe", value: "pickaxe" },
{ label: "Gliders", value: "glider" },
{ label: "Loading screens", value: "loadingscreen" },
{ label: "Emotes", value: "emote" }
];
function handletype(e) {
setType(e);
}
return (
<div className="App">
{/* <h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2> */}
<FormField
type="select"
value={type}
option={types}
label={"Select your type"}
keys={"country"}
handleOnChange={(value) => handletype(value)}
/>
</div>
);
}
here is the link from codesanbox
https://codesandbox.io/s/select-problem-ykplcm
i have trid using map and filter functions on value property component and i still dont get what i want.

Store the whole selected type in the state.
Then use type.label as the value.
import "./styles.css";
import React, { useState, useEffect } from "react";
import { FormField } from "react-form-input-fields";
import "react-form-input-fields/dist/index.css";
export default function App() {
let [type, setType] = useState({ label: "All", value: "All" }); // The state contains an object.
const types = [
{ label: "All", value: "All" },
{ label: "Skins", value: "outfit" },
{ label: "Banners", value: "banner" },
{ label: "Wraps", value: "wrap" },
{ label: "Sprays", value: "spray" },
{ label: "Emoji", value: "emoji" },
{ label: "Pickaxe", value: "pickaxe" },
{ label: "Gliders", value: "glider" },
{ label: "Loading screens", value: "loadingscreen" },
{ label: "Emotes", value: "emote" }
];
function handletype(e) {
// Find the selected object based on the returned value
const selected = types.filter((type) => type.value === e)[0]
console.log(selected)
// Set state with it.
setType(selected);
}
return (
<div className="App">
{/* <h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2> */}
<FormField
type="select"
value={type.label} // The label property of the stored state is used here
option={types}
label={"Select your type"}
keys={"country"}
handleOnChange={(value) => handletype(value)}
/>
</div>
);
}

Related

using react-awesome-query-builder npm package in next.js Unable to add multiple fields as shown in demo

I am trying to make a same query builder as the demo using the docs provided ... after adding more fields in the config I get new options in the dropdown .. and to create more fields used multiple Builder components and even tried different config files for each of them .. but they all change simultaneously. How can I create more fields and also have handlers for them
Link to package https://www.npmjs.com/package/react-awesome-query-builder
Link to the demo https://ukrbublik.github.io/react-awesome-query-builder/
what am I doing wrong ... How can I add more sections.. here is my component with the config file.
import React, {Component} from 'react';
import {Query, Builder, BasicConfig, Utils as QbUtils} from 'react-awesome-query-builder';
//import AntdConfig from 'react-awesome-query-builder/lib/config/antd/index';
//import loadedInitValue from "./init_value";
const InitialConfig = BasicConfig; // or BasicConfig
// You need to provide your own config. See below 'Config format'
let config = {
...InitialConfig,
fields: {
qty: {
label: 'Qty',
type: 'number',
fieldSettings: {
min: 0,
},
valueSources: ['value'],
preferWidgets: ['number'],
},
price: {
label: 'Price',
type: 'number',
valueSources: ['value'],
fieldSettings: {
min: 10,
max: 100,
},
preferWidgets: ['slider', 'rangeslider'],
},
color: {
label: 'Color',
type: 'select',
valueSources: ['value'],
fieldSettings: {
listValues: [
{ value: 'yellow', title: 'Yellow' },
{ value: 'green', title: 'Green' },
{ value: 'orange', title: 'Orange' }
],
}
},
is_promotion: {
label: 'Promo?',
type: 'boolean',
operators: ['equal'],
valueSources: ['value'],
},
}
},
};
const queryValue = {"id": QbUtils.uuid(), "type": "group"};
class QueryBuilder extends Component {
state = {
tree: QbUtils.checkTree(QbUtils.loadTree(queryValue), config),
config: config
};
render = () => (
<div>
<Query
{...config}
value={this.state.tree}
onChange={this.onChange}
renderBuilder={this.renderBuilder}
/>
{this.renderResult(this.state)}
</div>
)
renderBuilder = (props) => (
<div className="query-builder-container" style={{padding: '10px'}}>
<div className="query-builder qb-lite">
<Builder {...props} className="my-4" />
<Builder {...props} className="my-4" />
<Builder {...props} className="my-4" />
</div>
</div>
)
renderResult = ({tree: immutableTree, config}) => (
<div className="query-builder-result">
<div>Query string: <pre>{JSON.stringify(QbUtils.queryString(immutableTree, config))}</pre></div>
<div>MongoDb query: <pre>{JSON.stringify(QbUtils.mongodbFormat(immutableTree, config))}</pre></div>
)
onChange = (immutableTree, config, idx) => {
// Tip: for better performance you can apply `throttle` - see `examples/demo`
this.setState({tree: immutableTree, config: config});
const jsonTree = QbUtils.getTree(immutableTree);
console.log(jsonTree);
// `jsonTree` can be saved to backend, and later loaded to `queryValue`
}
}
export default QueryBuilder;
Add this inside your fields config
results: {
label: "Results",
type: "!group",
subfields: {
product: {
type: "select",
fieldSettings: {
listValues: ["abc", "def", "xyz"],
},
valueSources: ["value"],
},
score: {
type: "number",
fieldSettings: {
min: 0,
max: 100,
},
valueSources: ["value"],
}
}
},
The issue was with the config and init_value files ... the fields were not properly mapped ... you need to use same name, type etc in the init_value file for the fields you define in config

React-select how to filter out already chosen values?

I have a select component defined like this:
this.state.list = [{label: "test1", value:1}, {label:"test2", value:2}, {label:"test3", value:3}]
this.state.selected = [{label:"test2", value:2}]
let listMap = this.state.list
let list = this.state.list
{listMap.length !== 0 ? listMap.map((item: any, key: number) => (
<div>
<Select
id="list for data"
options={list}
onChange={value => selectList(value)}
placeholder="Select Your Option"
/>
<div/>
))
I want is after test2 is selected, I want the other two drop downs to show test1, and test3.
What I have done so far:
let y = this.state.selected.map(itemY => { return itemY.value })
let x = list.filter(itemX => !yFilter.includes(itemX.value)) // [{value: 1, label:"test1"},{value: 3, label: "test3"}]
And then replacing options property as x.
The filters are working but,
The place holder is not updating the selected values.
What I want to achieve:
And for the next drop down [1], be only able to select those which aren't selected:
You have to separate the three react selects. As you are applying filter on one it will be applicable to all react select.The filtering will also remove in all react select. You can checkout following example.
https://codesandbox.io/s/react-select-5u3rh
import React from "react";
import {
render
} from "react-dom";
import ReactDOM from "react-dom";
import Select from "react-select";
import "react-select/dist/react-select.css";
class ReactSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
itemtitle: "",
multi: true,
multiValue: "eeee...",
options: [{
value: "Color",
label: "Yellow"
},
{
value: "Fruit",
label: "Apple"
},
{
value: "Tool",
label: "Spanner"
}
],
options2: [{
value: "Color",
label: "Yellow"
},
{
value: "Fruit",
label: "Apple"
},
{
value: "Tool",
label: "Spanner"
}
]
};
}
onTitleChange(e, value) {
this.setState({
[e.target.name]: e.target.value
});
this.setState({
multiValue: e.target.value
});
}
handleOnChange(obj) {
this.setState({
multiValue: obj
});
this.setState({
options2: this.state.options2.filter(v => v.value !== obj.value)
})
}
handleOnChange2(obj) {
this.setState({
multiValue2: obj
});
}
render() {
return ( <
div >
<
Select
// multi={this.state.multi}
options = {
this.state.options
}
onChange = {
this.handleOnChange.bind(this)
}
value = {
this.state.multiValue
}
isSearchable = {
false
}
placeholder = "eee" /
>
<
Select
// multi={this.state.multi}
options = {
this.state.options2
}
onChange = {
this.handleOnChange2.bind(this)
}
value = {
this.state.multiValue2
}
isSearchable = {
false
}
placeholder = "eee" /
>
<
/div>
);
}
}
ReactDOM.render( < ReactSelect / > , document.body);
your state should look like this
state = { items : [{value: 1, label:"test1", selected:false},{value: 1, label:"test2", selected:false},{value: 3, label: "test3", selected:false}]
Then when an option is clicked, it sets the key "selected" to true. Afterward, only map the objects with selected false as dropdown items. Remember to use setState.

select input field always return undefined

when ever i try to select an option in input field it must set the state value to the selected option but it return undefined
I am using Semantic ui react Form to take input but when ever i select the option and submit it gives me undefined
import React from 'react'
import { Form, Input, TextArea, Button, Select, Container } from
'semantic-ui-react'
const RankOptions = [
{ key: 'lg', text: 'Lt-Gen', value: 'Lt-Gen' },
{ key: 'mg', text: 'Mj-Gen', value: 'Mj-Gen' },
{ key: 'b', text: 'Brig', value: 'Brig' },
{ key: 'col', text: 'Col', value: 'Col' },
{ key: 'lc', text: 'Lt-Col', value: 'Lt-Col' },
{ key: 'm', text: 'Major', value: 'Mj' },
{ key: 'capt', text: 'Capt', value: 'Capt' },
{ key: 'lt', text: 'Lt', value: 'Lt' },
{ key: '2lt', text: '2-Lt', value: 'Lt-2' },
]
export default class Employee extends React.Component{
state={}
handleSubmit = () => {
console.log(this.state)
}
handlerankChange = (e) => {
const value = e.target.value
this.setState({
rank : value
})
}
render() {
return (
<Container>
<Form size='huge'>
<Form.Group widths='equal'>
<Form.Field
name = 'rank'
control = {Select}
label = 'Rank'
options = {RankOptions}
placeholder = 'Rank'
value = {this.state.value}
onChange = {this.handlerankChange}
/>
<Button primary onClick=
{this.handleSubmit}>Submit</Button>
</Form>
</Container>
)
}
}
the state must be any option from ranks
A working code will help you out:
import React from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import {
Button,
Form,
Grid,
Header,
Image,
Message,
Segment,
Label,
Dropdown
} from "semantic-ui-react";
import Select from "react-select";
import "./index.css";
const styles = {
fontFamily: "sans-serif",
textAlign: "center"
};
class App extends React.Component {
state = {
selectedOption: ""
};
handleChange = selectedOption => {
this.setState({ selectedOption });
};
render() {
const { selectedOption } = this.state;
const value = selectedOption && selectedOption.value;
return (
<div className="login-form">
<Grid
textAlign="center"
style={{ height: "100%" }}
verticalAlign="middle"
>
<Grid.Column style={{ maxWidth: 450 }} textAlign="left">
<Form size="large">
<Segment>
<div>
<Select
name="form-field-name"
value={value}
onChange={this.handleChange}
options={[
{ value: "one", label: "One" },
{ value: "two", label: "Two" }
]}
/>
</div>
</Segment>
</Form>
</Grid.Column>
</Grid>
</div>
);
}
}
render(<App />, document.getElementById("root"));
Source of the code on the codesandbox
Set initial value for rank in state as
state = {
rank:''
}
and change
<Form.Field
name = 'rank'
control = {Select}
label = 'Rank'
options = {RankOptions}
placeholder = 'Rank'
value = {this.state.rank}
onChange = {this.handlerankChange}
/>
you need not access the value by e.target.value, the callback provides object with key 'value';
eg:
import React from 'react'
import { Form, Input, TextArea, Button, Select, Container } from
'semantic-ui-react'
const RankOptions = [
{ key: 'lg', text: 'Lt-Gen', value: 'Lt-Gen' },
{ key: 'mg', text: 'Mj-Gen', value: 'Mj-Gen' },
{ key: 'b', text: 'Brig', value: 'Brig' },
{ key: 'col', text: 'Col', value: 'Col' },
{ key: 'lc', text: 'Lt-Col', value: 'Lt-Col' },
{ key: 'm', text: 'Major', value: 'Mj' },
{ key: 'capt', text: 'Capt', value: 'Capt' },
{ key: 'lt', text: 'Lt', value: 'Lt' },
{ key: '2lt', text: '2-Lt', value: 'Lt-2' },
]
export default class Employee extends React.Component{
state={}
handleSubmit = () => {
console.log(this.state)
}
handlerankChange = ({ value }) => {
this.setState({
rank : value
})
}
render() {
return (
<Container>
<Form size='huge'>
<Form.Group widths='equal'>
<Form.Field
name = 'rank'
control = {Select}
label = 'Rank'
options = {RankOptions}
placeholder = 'Rank'
value = {this.state.rank} // this should be rank
onChange = {this.handlerankChange}
/>
</Form.Group>.
<Button primary onClick=
{this.handleSubmit}>Submit</Button>
</Form>
</Container>
)
}
}
Hope this helps!!

How can I store the selected semantic UI dropdown option in state?

I have a dropdown list with 5 options. I need to save the selected option to my state as listValue.
My list of options and the state
const options = [
{ key: 1, text: 'OK', value: 1 },
{ key: 2, text: 'Avvikelse', value: 2 },
{ key: 3, text: 'Ej Relevant', value: 3 },
{ key: 4, text: 'Observation', value: 4 },
{ key: 5, text: 'Saknas', value: 5 },
]
export default class ConfirmationModal extends React.Component {
state = {
listValue: 'Status'
}
My list (from semantic-ui)
dropDownList = () => (
<Dropdown
placeholder={this.state.listValue}
clearable
options={options}
selection
/>
)
How can I store the selected option in my state?
You can add an onChange handler and put the value given to the handler in your component state.
Example
const options = [
{ key: 1, text: "OK", value: 1 },
{ key: 2, text: "Avvikelse", value: 2 },
{ key: 3, text: "Ej Relevant", value: 3 },
{ key: 4, text: "Observation", value: 4 },
{ key: 5, text: "Saknas", value: 5 }
];
class DropdownExampleControlled extends React.Component {
state = {
options,
value: options[0].value
};
handleChange = (_e, { value }) => this.setState({ value });
render() {
const { value, options } = this.state;
const currentOption = options.find(o => o.value === value);
return (
<Grid columns={2}>
<Grid.Column>
<Dropdown
onChange={this.handleChange}
options={options}
placeholder="Choose an option"
selection
value={value}
/>
</Grid.Column>
<Grid.Column>
<Segment secondary>
<pre>Current value: {currentOption.text}</pre>
</Segment>
</Grid.Column>
</Grid>
);
}
}
As I understood you, you need to save in the state the values, which user selected?
If yes, You need have an event for example onChange, which means that user seelct that particular option from list. and set it in state
onChange(selectedValue) {
this.setState({listValue: selectedValue});
}
add this function to your component:
handleChange = (_p, { value }) => {
this.setState({ listValue: value});
};
add it as prop to your Dropdown:
<Dropdown onChange={this.handleChange} placeholder={this.state.listValue} clearable options={options} selection />
Handle state management using setState. Simple example:
Example Sandbox
const options = [
{ key: 1, text: 'OK', value: 1 },
{ key: 2, text: 'Avvikelse', value: 2 },
{ key: 3, text: 'Ej Relevant', value: 3 },
{ key: 4, text: 'Observation', value: 4 },
{ key: 5, text: 'Saknas', value: 5 },
]
class App extends Component {
constructor(props){
super(props)
this.state = {
listValue: ''
}
}
componentWillMount() //before render
{
this.setState({
listValue: options[1].text //storing text from second line
})
}
render() {
return (
<div>
{this.state.listValue}
</div>
);
}
}
This displays: Avvikelse

How do I create new option if there are no left while searching in React-Select v2?

I need to create new option with label "Ostatni" while filtering if there are no options left. I tried to do it by customising MenuList and NoOptionsMessage, but nothing works. Is there any way?
NoOptionsMessage = props => (
<components.NoOptionsMessage
{...props}
children={<components.Option {...components.Option.defaultProps} data={{ value: 37, label: 'Ostatni' }} />}
/>
)
You can achieve your goal using filterOption function like the following code:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
hasExtraValue: false,
options: [
{ label: "Label 1", value: 1 },
{ label: "Label 2", value: 2 },
{ label: "Label 3", value: 3 },
{ label: "Label 4", value: 4 },
{ label: "Label 5", value: 5 },
{ label: "Label 6", value: 6 },
{ label: "Label 7", value: 7 },
{ label: "Label 8", value: 8 },
{label: 'Ostatni', value: 'other'}
]
};
}
filterOption = (option, inputValue) => {
// tweak the filterOption to render Ostatni only if there's no other option matching + set hasExtraValue to true in case you want to display an message
if (option.label === "Ostatni"){
const {options} = this.state
const result = options.filter(opt => opt.label.includes(inputValue))
this.setState({ hasExtraValue: !result.length})
return !result.length
};
return option.label.includes(inputValue);
};
render() {
return (
<div>
<Select
isMulti
filterOption={this.filterOption}
noOptionsMessage={() => "No more options"}
options={this.state.options}
/>
// Displays a user friendly message to explain the situation
{this.state.hasExtraValue && <p>Please select 'Ostatni' option if you don't find your option !</p>}
</div>
);
}
}
The idea is to trigger when the user is typing something. If there's no options available you add a new one the desired label to offer the user a new option.
In filterOption you set this special option to be always true so it will always displayed if it exists.
Here a live example.
This now seems possible through a built-in component.
https://react-select.com/creatable
import React, { Component } from 'react';
import CreatableSelect from 'react-select/creatable';
import { colourOptions } from '../data';
export default class CreatableSingle extends Component<*, State> {
handleChange = (newValue: any, actionMeta: any) => {
console.group('Value Changed');
console.log(newValue);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
};
handleInputChange = (inputValue: any, actionMeta: any) => {
console.group('Input Changed');
console.log(inputValue);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
};
render() {
return (
<CreatableSelect
isClearable
onChange={this.handleChange}
onInputChange={this.handleInputChange}
options={colourOptions}
/>
);
}
}

Categories