I am trying the following code
import React, { Component } from 'react'
import ReactSearchBox from 'react-search-box'
export default class App extends Component {
data = [
{
key: 'john',
value: 'John Doe',
},
{
key: 'jane',
value: 'Jane Doe',
},
{
key: 'mary',
value: 'Mary Phillips',
},
{
key: 'robert',
value: 'Robert',
},
{
key: 'karius',
value: 'Karius',
},
]
render() {
return (
<ReactSearchBox
placeholder="Placeholder"
value="Doe"
data={this.data}
callback={record => console.log(record)}
/>
)
}
}
and it works really. However the search options only show when I start typing in the searchbox. What I am trying to do is when the user clicks in the search, show them some options, Can you help with understanding how to achieve that.
there is a method called
onFocus - A function which acts as a callback when the input is focussed.
which does get called when I click in the search box, but I am not able to work out how to display the options in the dropdown.
import React, { Component } from 'react'
import Select from 'react-select'
export default class App extends Component {
state = {
selectedValue:null
}
data = [
{
label: 'john',
value: 'John Doe',
},
{
label: 'jane',
value: 'Jane Doe',
},
{
label: 'mary',
value: 'Mary Phillips',
},
{
label: 'robert',
value: 'Robert',
},
{
label: 'karius',
value: 'Karius',
},
]
render() {
return (
<Select
options={this.data}
isSearchable
value={this.state.selectedValue}
onChange={this.handleChange}
/>
)
}
}
If you want to display a dropdown with search option I would recommend using react-select library. However your data should be in the form of an object like this {label:' ',value:' '}. This component takes an isSearchable prop that allows us to search the dropdown as well as select an option manually. Hope this helps!
Related
I implemented an MUI-DATABLE and I would like to style it but I don't know-how.
What I want to style is the bubbles that appear when you use filters and on top of the table
as per the screenshot are gray and I would like to have the power to style them with my design
Alter the color of the filter chip
If you are only looking to alter the color, according to the MUI Datatables docs, one can accomplish this by using theme overrides. To do this, you can follow the example on the MUI Datatables docs or you can view this Code Sandbox for a live example. The code can be set up like this:
import React from "react";
import MUIDataTable from "mui-datatables";
import { createMuiTheme, MuiThemeProvider } from "#material-ui/core/styles";
export default function App() {
// Here, we use createMUITheme to apply the custom styles to
// the filter chip with an override on the MuiChip-root class:
const getMuiTheme = () =>
createMuiTheme({
overrides: {
MuiChip: {
root: {
backgroundColor: "lightgrey"
}
}
}
});
const columns = [
{
name: "name",
label: "Name",
options: {
filter: true,
sort: true
}
},
{
name: "company",
label: "Company",
options: {
filter: true,
sort: false
}
},
{
name: "city",
label: "City",
options: {
filter: true,
sort: false
}
},
{
name: "state",
label: "State",
options: {
filter: true,
sort: false
}
}
];
const data = [
{ name: "Joe James", company: "Test Corp", city: "Yonkers", state: "NY" },
{ name: "John Walsh", company: "Test Corp", city: "Hartford", state: "CT" },
{ name: "Bob Herm", company: "Test Corp", city: "Tampa", state: "FL" },
{ name: "James Houston", company: "Test Corp", city: "Dallas", state: "TX" }
];
const options = {
filterType: "checkbox"
};
// Now, we wrap the MUI Datatable in the MUIThemeProvider to apply
// the styles:
return (
<MuiThemeProvider theme={getMuiTheme()}>
<MUIDataTable columns={columns} data={data} options={options} />
</MuiThemeProvider>
);
}
Custom Filter Chip
If what you want to do is to use a custom filter chip component rather than the default grey filter chips, you can pass a custom filter chip component to a custom filter list component. Then, you would pass that filter list component to the table's components prop like so:
import React from "react";
import "./styles.css";
// Import the chip component frfom Material UI or a
// custom component of your choosing:
import Chip from '#material-ui/core/Chip';
// Import the TableFilterList from mui-datatables:
import MUIDataTable, { TableFilterList } from "mui-datatables";
// Here is the custom chip component. For this example, we are
// using the outlined chip from Material UI:
const CustomChip = ({ label, onDelete }) => {
return (
<Chip
variant="outlined"
color="secondary"
label={label}
onDelete={onDelete}
/>
);
};
// Here is the custom filter list component that will display
// the custom filter chips:
const CustomFilterList = (props) => {
return <TableFilterList {...props} ItemComponent={CustomChip} />;
};
export default function App() {
const columns = [
{
name: "name",
label: "Name",
options: {
filter: true,
sort: true
}
},
{
name: "company",
label: "Company",
options: {
filter: true,
sort: false
}
},
{
name: "city",
label: "City",
options: {
filter: true,
sort: false
}
},
{
name: "state",
label: "State",
options: {
filter: true,
sort: false
}
}
];
const data = [
{ name: "Joe James", company: "Test Corp", city: "Yonkers", state: "NY" },
{ name: "John Walsh", company: "Test Corp", city: "Hartford", state: "CT" },
{ name: "Bob Herm", company: "Test Corp", city: "Tampa", state: "FL" },
{ name: "James Houston", company: "Test Corp", city: "Dallas", state: "TX" }
];
const options = {
filterType: "checkbox"
};
// Finally, we pass the CustomFilterList to the table's components
// prop:
return (
<div className="App">
<MUIDataTable
title={"Employee List"}
data={data}
columns={columns}
options={options}
components={{
TableFilterList: CustomFilterList,
}}
/>
</div>
);
}
Again, this example is taken from the MUI Datatables docs and I have a live example in this Code Sandbox.
A solution could be to be very specific with your selectors in your CSS. This would be something like:
mui-datatable > header > bubbles > .someClassMadeByMuiDatatable {}
As a tip, you can use the inspector in Google Chrome, select the bubbles in the tree structure (HTML), and copy the selector.
General reading about specificity in CSS can be found in https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
It looks like there is a built in option in the table config to do this.
From this example in the docs.
https://github.com/gregnb/mui-datatables/blob/master/examples/customize-filter/index.js
setFilterChipProps: (colIndex, colName, data) => {
//console.log(colIndex, colName, data);
return {
color: 'primary',
variant: 'outlined',
className: 'testClass123',
};
}
I'm trying to implement multilevel nested drop-down. I have made use of "react-dropdown". A new dropdown that appears so be displayed just below. But I'm unable to implement nested dropdown.
what to achieve something like this
this is my output
import React from "react";
import Dropdown from "react-dropdown";
import 'react-dropdown/style.css';
const object = [
{value: 'course',
lable: "course" ,
submenu: [
{ value: "PCF8883US/7EA/1Y", lable: "PCF8883US/7EA/1Y"},
{ value: "AT42QT1050-UUR", lable: "AT42QT1050-UUR" },
{ value: "PCF8883", lable: "PCF8883"}
]
},
{value: "code",
lable:"code",
submenu: [
{ value: "MC3672", lable: "MC3672"},
{ value: "MXC400XXC", lable: "MXC400XXC"}
]
}
]
const course = [
{ value: "PCF8883US/7EA/1Y", lable: "PCF8883US/7EA/1Y"},
{ value: "AT42QT1050-UUR", lable: "AT42QT1050-UUR" },
{ value: "PCF8883", lable: "PCF8883"}
]
const code = [
{ value: "MC3672", lable: "MC3672"},
{ value: "MXC400XXC", lable: "MXC400XXC"}
]
export class WorkSpace extends React.Component {
render() {
return (
<div className="base_container">
<div className="left">
<h3>Select Component</h3>
<div>
<Dropdown options={object} placeholder="Name">
<Dropdown options={course} onChange={this._onSelect} placeholder="course" />
<Dropdown options={code} onChange={this._onSelect} placeholder="code"/>
</Dropdown>
</div>
</div>
</div>
);
}
}
You could try the library React Treebeard. It gives a UI almost exactly like your example.
I am using Ant design in my react project and and want to add the string to the render attribute for the column structure.
Here is a usual code.
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Divider, Tag } from 'antd';
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a>{text}</a> // <<<< Want to pass string here
}
];
const data = [
{
key: '1',
name: 'John Brown',
},
{
key: '2',
name: 'Jim Green',
},
{
key: '3',
name: 'Joe Black',
},
];
ReactDOM.render(<Table columns={columns} dataSource={data} />, document.getElementById('container'));
Now in the above code I am passing JSX code in a string to render in column. But I am having string that I want to render.
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Divider, Tag } from 'antd';
const fun = "text => <a>{text}</a>" // this string I want to render
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: fun // <<<< no passing string here I do know I need to covert this string into something
}
];
const data = [
{
key: '1',
name: 'John Brown',
},
{
key: '2',
name: 'Jim Green',
},
{
key: '3',
name: 'Joe Black',
},
];
ReactDOM.render(<Table columns={columns} dataSource={data} />, document.getElementById('container'));
What approach do I need to follow to run and execute the code which will give me same result as above.
NOTE: I am getting this string from the Back-end
Any help to solve this issue will be appreciated.
You can use the same pattern instead of using as a string like instead of
const fun = "text => <a>{text}</a>"
You can write as:
const fun = text => <a>{text}</a>
Please check the demo at:
.
I solve the issue using the templating language. I have used the squirrelly templating language.
As you see in the below code.
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Table, Divider, Tag } from 'antd';
import * as sqrl from "squirrelly";
const render = "<a>{{data}}</a>"
const htmlNode = (text) =>{
/**
*we are formating a data in the particular format so that
*we can use it along with squirrelly templating
*/
const data = {data : text}
/**
* In the below code we are ,merging the html string and data together
*/
const __html = sqrl.Render(render, data || []);
return <div dangerouslySetInnerHTML={{__html}}/>
}
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => htmlNode(text)
}
];
const data = [
{
key: '1',
name: 'John Brown',
},
{
key: '2',
name: 'Jim Green',
},
{
key: '3',
name: 'Joe Black',
},
];
ReactDOM.render(<Table columns={columns} dataSource={data} />, document.getElementById('container'));
I am trying to dismiss an item from my array which I have mapped out. I made the onclick button, binded it, and defined the function. However, when I press the dismiss button, the items are still there
I tried to change my object id to different name, change some of the code. I even console.log to see whether my button was working. It was. Just it wasnt deleting the intended item.
import React from "react";
import "./App.css";
const animals = [
{ id: 1, species: "Bear", habitat: "Mountains" },
{ id: 2, species: "Lion", habitat: "Sahari" },
{ id: 3, species: "Hippo", habitat: "Sahari" },
{ id: 4, species: "Eagle", habitat: "Trees" },
{ id: 5, species: "Fish", habitat: "River" },
{ id: 6, species: "Snake", habitat: "Desert" },
{ id: 7, species: "Alligator", habitat: "Everglades" },
];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
animals: animals
}
this.onDismiss = this.onDismiss.bind(this);
}
onDismiss(id) {
const isNotID = animal => animal.id !== id;
const updatedList = this.state.animals.filter(isNotID);
this.setState({animals: updatedList});
console.log(this.state.animals)
}
render() {
return(
<div className="App">
{
animals.map((animal)=> {
return (
<div key={animal.id}>
<div>{animal.species}</div>
<div>{animal.habitat}</div>
<span>
<button onClick={()=>this.onDismiss(animal.id)}>Dismiss</button>
</span>
</div>
)
})
}
</div>
);
}
}
export default App;
I want the item to be deleted once i press the dismiss button. And bring back the updated list which will be brought about from the setState
Your render method is using animals (your initial data) instead of this.state.animals.
so I have the following component that is a dropdown list created using react-select.
import React from 'react'
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
];
class MealsFilters extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedOption: null,
};
}
handleChange = (selectedOption) => {
this.setState({ selectedOption });
console.log(`Option selected:`, selectedOption);
}
render() {
const { selectedOption } = this.state;
return (
<div className="container my-3">
<div className="row">
<div className="col-lg-4 col-md-6 col-sm-8">
<Select
isMulti
isSearchable
placeholder={"catégories"}
value={selectedOption}
onChange={this.handleChange}
options={options}
/>
</div>
</div>
</div>
)
}
}
export default MealsFilters;
the options variable is the default one from the docs. I actually need to replace its values by each meal category available.
To do so, as you can see, I need to create an array of objects with a value and a label.
this component accesses meal categories through props called meals that are like so:
console.log(this.props.meals);
=> [{
id: 0,
name: spaghettis,
category: italian,
price: 5.99},
{
id: 1,
name: hamburger,
category: american,
price: 7.99},
{
etc.
}, {}]
How can I take advantage of this.props.meals to get my options array of objects ?
EDIT: multiple meals can have the same category, and I need each category to only appear once in the options.
Map over your this.props.meals array, and create the needed options array,
<Select
isMulti
isSearchable
placeholder={"catégories"}
value={selectedOption}
onChange={this.handleChange}
options={this.props.meal.map(item=>({value: item.id, label: item.name}))}
/>
You could do something like this:
options={this.props.meals.map(
({id, name})=>({value:id,label:name})
)}
You could also use redux connect to create a container that will map the data to dropdown values for you
You can merge the data by category in the following way:
var items = [
{
id: 0,
name: 'spaghettis',
category: 'italian',
price: 5.99,
},
{
id: 1,
name: 'hamburger',
category: 'american',
price: 7.99,
},
{
id: 2,
name: 'other hamburger',
category: 'american',
price: 7.99,
},
];
console.log(
[
...items.reduce(
(result, item) => (
result.get(item.category)
? result.get(item.category).push(item.id)
: result.set(item.category, [item.id]),
result
),
new Map(),
),
].map(([label, value]) => ({ label, value })),
);
In the component it'll look like this:
options={[
...this.props.meals.reduce(
(result, item) => (
result.get(item.category)
? result.get(item.category).push(item.id)
: result.set(item.category, [item.id]),
result
),
new Map(),
),
].map(([label, value]) => ({ label, value }))}
You only need the "name" property so when you map through meals, simply retrieve it. Then upper case the first letter.
const meals = [{
id: 0,
name: "spaghettis",
category: "italian",
price: 5.99
},
{
id: 1,
name: "hamburger",
category: "american",
price: 7.99
}
]
const result = meals.map(({name}) => ({
label: `${name[0].toUpperCase()}${name.slice(1)}`,
value: name
}))
console.log(result);
You can use getOptionLabel and getOptionValue props.
<Select
options={this.props.meals},
getOptionLabel={m => m.name}
getOptionValue={m => m.id} />
https://react-select.com/props
getOptionLabel generic = (option) => string
Resolves option data to a string to be displayed as the label by components
getOptionValue generic = (option) => string
Resolves option data to a string to compare options and specify value attributes