Reputation: 21846
I am using the Dropdown component in MaterializeCSS.
The following HTML works alright:
<a class='dropdown-button btn' href='#' data-activates='dropdown1'>Drop Me!</a>
<ul id='dropdown1' class='dropdown-content'>
<li><a href="#!">one</a></li>
<li><a href="#!">two</a></li>
<li class="divider"></li>
<li><a href="#!">three</a></li>
<li><a href="#!"><i class="material-icons">view_module</i>four</a></li>
<li><a href="#!"><i class="material-icons">cloud</i>five</a></li>
</ul>
When the option is selected, it navigates to a link. But what I want to happen is, when the option is selected, the "Drop Me!" text is replaced by the text of the selected option. In this case, the text should be one, two, etc.
How do I do that? Thanks.
Upvotes: 0
Views: 1945
Reputation: 21846
A custom Dropdown solution using pure React as requested by @Alex
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import DropdownArrow from '../icons/DropdownArrow';
import { Animate } from 'react-move';
import Animation from '../constants/Animation';
import { easeQuadInOut } from 'd3-ease';
export default class Dropdown extends Component {
state = { isOpen: false };
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
window.addEventListener('mousedown', this.handleClickOutside);
window.addEventListener('keydown', this.handleKeyDown, true);
this.scrollTop =
window.pageYOffset || document.documentElement.scrollTop;
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
window.removeEventListener('mousedown', this.handleClickOutside);
window.removeEventListener('keydown', this.handleKeyDown);
}
componentDidUpdate(prevProps, prevState) {
if (this.state.isOpen && !prevState.isOpen) {
this.menuComp.scrollTop = this.menuScrollTop || 0;
}
}
handleKeyDown = e => {
if (e.keyCode == 27) {
if (this.state.isOpen) {
e.stopPropagation();
this.setState({ isOpen: false });
}
}
};
handleClickOutside = e => {
if (this.state.isOpen) {
if (this.comp && !this.comp.contains(e.target)) {
e.stopPropagation();
this.setState({ isOpen: false });
}
}
};
handleScroll = () => {
const scrollTop =
window.pageYOffset || document.documentElement.scrollTop;
if (Math.abs(scrollTop - this.scrollTop) > 2) {
this.setState({ isOpen: false });
}
this.scrollTop = scrollTop;
};
handleClick() {
if (this.props.disabled) return;
let { isOpen } = this.state;
isOpen = !isOpen;
this.setState({ isOpen });
}
handleItemClick(value, e) {
e.preventDefault();
this.menuScrollTop = this.menuComp.scrollTop;
this.props.onClick(value);
this.setState({ isOpen: false });
}
getOptionValue(option) {
return typeof option === 'undefined'
? ''
: typeof option === 'string' ? option : option.value;
}
getOptionLabel(option) {
return typeof option === 'undefined'
? this.props.placeholder
: typeof option === 'string' ? option : option.label;
}
renderMenu() {
const { isOpen } = this.state;
const { options, selectedOption, height, marginLeft } = this.props;
return (
<Animate
show={isOpen}
start={() => ({
opacity: 0.01,
scale: 0.8
})}
enter={() => ({
opacity: [1],
scale: [1],
timing: {
duration: Animation.DropdownDuration,
ease: easeQuadInOut
}
})}
leave={{
opacity: [0.01],
scale: [0.8],
timing: {
duration: Animation.DropdownDuration,
ease: easeQuadInOut
}
}}
>
{({ opacity, scale }) => {
return (
<div
className="menu-outer"
style={{
marginLeft,
opacity
}}
>
<div
className="menu"
style={{
maxHeight: height || 368,
overflowY: opacity == 1 ? 'auto' : 'hidden',
opacity,
transform: `scale(${scale})`
}}
ref={c => {
this.menuComp = c;
}}
>
{options.map(option => (
<div
className={
this.getOptionValue(option) ===
this.getOptionValue(selectedOption)
? 'menu-item selected'
: 'menu-item'
}
key={this.getOptionValue(option)}
>
<a
href="#"
onClick={this.handleItemClick.bind(
this,
this.getOptionValue(option)
)}
className={
this.getOptionLabel(option)
.length === 1
? 'circle'
: ''
}
>
{this.getOptionLabel(option)}
</a>
</div>
))}
</div>
<div className="cover-bar" />
</div>
);
}}
</Animate>
);
}
render() {
const { options, selectedOption, disabled } = this.props;
return options.length ? (
<div
className={disabled ? 'dropdown disabled' : 'dropdown'}
ref={c => {
this.comp = c;
}}
>
<div className="label" onClick={this.handleClick.bind(this)}>
<span>{this.getOptionLabel(selectedOption)}</span>
<DropdownArrow width={18} height={18} />
</div>
{this.renderMenu()}
</div>
) : null;
}
}
Dropdown.propTypes = {
placeholder: PropTypes.string,
options: PropTypes.array,
selectedOption: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
onClick: PropTypes.func,
height: PropTypes.number,
marginLeft: PropTypes.number,
disabled: PropTypes.bool
};
Dropdown.defaultProps = {
marginLeft: 0
};
And the style for it is:
.dropdown {
position: relative;
&.disabled .label {
color: $color-grey-56;
cursor: not-allowed;
}
.label {
display: inline-flex;
align-items: center;
color: $color-black;
cursor: pointer;
&>span {
font-family: Axiforma;
font-size: 12px;
line-height: 16px;
padding-top: 2px;
}
}
.menu-outer {
position: absolute;
z-index: 1500;
width: 24rem;
margin-top: 0.8rem;
border-radius: $border-radius;
box-shadow: 0 1rem 3rem $color-grey-32;
transform-origin: 20% 20%;
.cover-bar {
width: 20px;
}
&:hover .cover-bar {
opacity: 0;
transition: opacity 100ms;
}
}
.menu {
padding: 0.8rem 0;
background-color: $color-white;
.menu-item {
height: 4rem;
display: flex;
align-items: center;
padding-left: 2.4rem;
a {
font-family: Axiforma;
color: $color-grey-56;
margin-left: -0.8rem;
padding: 0.8rem;
border-radius: 1.8rem;
line-height: 1;
&.circle {
border-radius: 50%;
padding: 0;
display: inline-flex;
width: 30px;
height: 30px;
justify-content: center;
align-items: center;
}
&:hover {
background-color: $color-yellow-hover;
}
&:active {
background-color: $color-yellow-active;
}
}
&.selected {
a {
font-family: 'Axiforma SemiBold';
color: $color-black;
background-color: $color-yellow;
}
}
}
}
}
Upvotes: 1
Reputation: 1109
You can do this through jquery on click event trigger. Just find the value of li and set text of drop me to the value of clicked li. Below is the code snippet. I hope this helps..
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
</head>
<body>
<!-- Dropdown Trigger -->
<a class='dropdown-button btn dropdownBtn' href='#' data-activates='dropdown1'>Drop Me!</a>
<!-- Dropdown Structure -->
<ul id='dropdown1' class='dropdown-content'>
<li><a href="#!">one</a></li>
<li><a href="#!">two</a></li>
<li class="divider"></li>
<li><a href="#!">three</a></li>
<li><a href="#!"><i class="material-icons">view_module</i>four</a></li>
<li><a href="#!"><i class="material-icons">cloud</i>five</a></li>
</ul>
<script type="text/javascript">
$(document).ready(function(){
$('.dropdown-button').dropdown('open');
})
$('#dropdown1 li').click(function(){
a = $(this).text()
$('.dropdownBtn').text(a)
})
</script>
</body>
</html>
Upvotes: 1