Skip to content

Instantly share code, notes, and snippets.

@s4kh
Last active August 13, 2018 03:06
Show Gist options
  • Save s4kh/edf3fe1c9a99644b5a319140314e96d4 to your computer and use it in GitHub Desktop.
Save s4kh/edf3fe1c9a99644b5a319140314e96d4 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import SelectDropdown, {CHECK_MARK} from './SelectDropdown';
/**
* Uses render prop to reuse SelectDropdown functionalities
* @author skh
*/
export default class CountryFilter extends Component {
constructor(props) {
super(props);
const { items, context } = props;
this.urlCountries = context.map(countryCode => {
let item = items.find(item => item.slug === countryCode)
return {
title: item && item.title,
slug: countryCode
}
});
}
static propTypes = {
items: PropTypes.array.isRequired,
title: PropTypes.string,
applyFn: PropTypes.func,
context: PropTypes.array,
};
static defaultProps = {
title: '',
context: [],
applyFn: null,
};
render() {
const { title, items, applyFn } = this.props;
return (
<SelectDropdown title={title}
preSelectedItems={this.urlCountries}
applyFn={applyFn}
render={({selectedItems, multiItemCheck}) =>
items && items.map((item, idx) =>
<div key={idx}>
<a onClick={multiItemCheck(item)}
className="form-container decoration-none text-gray-darker">
<span
className={selectedItems.find(obj => obj.slug === item.slug) ? 'active' : ''}
>
{item.title}
</span>
<span className={CHECK_MARK}></span>
{item.count !== 0 && <span className="count">{item.count}</span>}
</a>
</div>
)
}/>
);
}
}
import React, { Component } from "react";
import PropTypes from "prop-types";
import Popover from "react-bootstrap/lib/Popover";
import Overlay from "react-bootstrap/lib/Overlay";
/**
* Render prop component
* @author skh
*/
export const RADIO_MARK = "radiomark";
export const CHECK_MARK = "checkmark";
export default class SelectDropdown extends Component {
static propTypes = {
preSelectedItems: PropTypes.array,
title: PropTypes.string.isRequired,
applyFn: PropTypes.func
};
static defaultProps = {
preSelectedItems: [],
applyFn: null,
description: ""
};
constructor(props) {
super(props);
const { preSelectedItems } = props;
this.state = {
showPopover: false,
selectedItems: preSelectedItems
};
}
setSelectedItems = items => {
this.setState({ selectedItems: items });
};
multiItemCheck = value => () => {
const values = this.state.selectedItems;
const index = values.findIndex(obj => obj.slug === value.slug);
if (index > -1) {
values.splice(index, 1);
} else {
values.push({ title: value.title, slug: value.slug });
}
this.setSelectedItems(values);
};
popoverTitle = () => {
const { selectedItems } = this.state;
let { title } = this.props;
if (selectedItems.length === 1) {
title = selectedItems[0].selectedTitle
? selectedItems[0].selectedTitle
: selectedItems[0].title;
} else if (selectedItems.length > 1) {
title += ` · ${selectedItems.length}`;
}
return title;
};
clearItems = () => {
this.setSelectedItems([]);
};
applyFn = () => {
this.props.applyFn && this.props.applyFn(this.state.selectedItems);
this.hide();
};
hide = () => {
this.setState({ showPopover: false });
};
open = () => {
this.setState({ showPopover: true });
};
showHide = () => {
this.setState(prevState => ({ showPopover: !prevState.showPopover }));
};
render() {
return (
<div className="dropdown-popover position-relative">
<Overlay
show={this.state.showPopover}
onHide={this.hide}
placement="bottom"
container={this}
rootClose
onExit={this.applyFn}
>
<Popover id="dropdown-popover">
<React.Fragment>
<div className="mb20">
<div className="row">
{this.props.render({
...this.state,
multiItemCheck: this.multiItemCheck,
setSelectedItems: this.setSelectedItems
})}
</div>
</div>
{this.props.applyFn && (
<div>
<a
onClick={this.clearItems}
className="text-gray-light cursor-pointer"
>
Clear
</a>
<a
onClick={this.hide}
className="text-success pull-right cursor-pointer"
>
Apply
</a>
</div>
)}
</React.Fragment>
</Popover>
</Overlay>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment