Multi Level drop-down in ReactJS - javascript

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.

Related

Hover on an option element?

Can I hover an option element to show more options?
I want to have a dropdown nested component like the following screenshot
I have this array of objects and pass it to the DropDown component, if the first object has a field called modules and it has an array of two objects how can I display it as a nested dropdown?
index.js
import React from "react";
import ReactDOM from "react-dom";
import DropDown from "./DropDown";
const availableModules = [
{
text: "environment",
value: "Environment",
modules: [{ key: "greenhouse" }, { key: "protected species" }],
},
{
text: "mobility",
value: "Mobility",
modules: [
{ key: "walk accessibility" },
{ key: "transit accessibility" },
{ key: "travel patterns" },
],
},
{
text: "resiliency",
value: "Resiliency",
modules: [{ key: "flood" }, { key: "fire" }, { key: "earthquake" }],
},
];
ReactDOM.render(
<DropDown availableModules={availableModules} />,
document.getElementById("root")
);
Dropdown.js
const DropDown = ({availableModules}) => {
return (
<div>
<p>Select Option </p>
<select >
{availableModules.map((item, index) => (
<option
value={item.text}
key={index}
>
{item.text}
</option>
))}
</select>
</div>
)
}
Yes, you can. Just render the entire div structure, with all ULs and LIs, and use css to show/hide the menus and submenus.
There is no need to use state for this - showing/hiding via css and detecting hover via css - css alone can handle the job.
On desired LI items, add your click handler as per normal.
<li
onClick={handleDoThisParticularThing}
>
This particular item
</li>
There are many examples online. Just google something like create a nested menu system css
https://css-tricks.com/solved-with-css-dropdown-menus/
https://www.smashingmagazine.com/2017/11/building-accessible-menu-systems/

How to run a method using v-for in Vue.js?

I want to get the following output for the following data.
・3
・1
and sample data :
export const dummyData = [
{
id: "1",
name: "a",
sub: [
{
id: "1#1",
name: "b",
sub_sub: [
{ id: "1#1#1", name: "b-a" },
{ id: "1#1#2", name: "b-b" },
]
},
{
id: "1#2",
name: "c",
sub_sub: [
{ id: "1#2#1", name: "c-a" },
]
},
]
},
{
id: "2",
name: "d",
sub: [
{
id: "2#1",
name: "e",
sub_sub: [
{ id: "1#2#1", name: "e-a" },
]
}
]
},
]
I want to count how many elements of sub_sub are includes in object "a" and "d".
So, I made the following code.
<template>
<div>
<ul>
<li v-for="item in items" :key="item.i">{{rowSpanCalc(item.id)}}</li>
</ul>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import { dummyData } from '~/store/dummy'
#Component({})
export default class extends Vue {
items: any = []
created() {
this.items = dummyData
}
rowSpanCalc(item: any) {
const count = item.sub.reduce(
(total: any, curr: any) => total + curr.sub_sub.length,
0
)
return count;
}
}
</script>
I ran my code and got an error in console like
  
  item.sub.reduce is not a function
Could anyone please advise me how to fix this errors?
Methods in the template are used as events handler not for rendering, try to use that method inside a computed property then use that property for render your items :
#Component({})
export default class extends Vue {
items: any = []
created() {
this.items = dummyData
}
get customItems(){
return this.items.map(item=>({...item,count:this.rowSpanCalc(item.id)}))
}
rowSpanCalc(item: any) {
const count = item.sub.reduce(
(total: any, curr: any) => total + curr.sub_sub.length,
0
)
return count;
}
}
template :
...
<li v-for="item in customItems" :key="item.id">{{item.count}}</li>
...

display options in react search box when clicking on the box

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!

Attempting to show array element of react select in list item

I am using react-select to store multiple elements and am using the map function to display elements which is working fine. But when I am using the same element in another class to display in a list element it shows a blank.
Here is the code where I am displaying the multiple options.
const Departments = [
{ label: "OneIT", value: "OneIT" },
{ label: "HR", value: "HR" },
{ label: "Vigilance", value: "Vigilance" },
{ label: "Ethics", value: "Ethics" },
{ label: "Corporate Services", value: "Corporate Services" },
{ label: "Legal", value: "Legal" },
{ label: "Sports", value: "Sports" },
{ label: "TQM", value: "TQM" },
{ label: "Iron Making", value: "Iron Making" },
{ label: "TMH", value: "TMH" }
];
class MultiSelect2 extends Component {
state = {
selectedOptions: []
};
handleChangeField = selectedOptions => {
this.setState({ selectedOptions });
};
render() {
const { selectedOption } = this.state;
return (
<div className="container">
<div className="row">
<div className="col-md-2"></div>
<div className="col-md-8">
<span>Select Department</span>
<Select
value={selectedOption}
options={Departments}
onChange={this.handleChangeField}
isMulti
/>
{this.state.selectedOptions.map(o => (
<p>{o.value}</p>
))}
</div>
<div className="col-md-4"></div>
</div>
</div>
);
}
}
I am trying to display this in another class in the list item but it is not showing.
export class Confirm extends Component {
state = {
selectedOptions: []
};
render() {
const {
values: {selectedOptions
}
} = this.props;
return (
<List>
<ListItemText primary="Departments" secondary={selectedOptions} />
</List>

Allow to type values that are not in options

Basically, I have not find a way to setup select component to allow values that are not in the option set. I know that select suggests that it must be a selection. But I am looking to make it act more like an autocomplete. Any knowledge on that?
Try This:
import react-select
$ yarn add react-select#next
# or, using npm:
$ npm install react-select#next
The dropdown is searchable.
import React from 'react';
import Select from 'react-select';
const tools = [
{ label: "Hammer", value: 1 },
{ label: "Hand Drill", value: 2 },
{ label: "Tape Rule", value: 3 },
{ label: "Saw", value: 4 },
{ label: "Ruler", value: 5 },
{ label: "Soldering Iron", value: 6 },
];
const App = () => (
<div className="app">
<div className="container">
<Select options={tools} />
</div>
</div>
);

Categories

Resources