Commit 6cc84c53 authored by Florent Chehab's avatar Florent Chehab

Search Countries ok

parent 9a0cded3
Pipeline #26887 passed with stages
in 2 minutes and 25 seconds
// Inspired by : https://material-ui.com/demos/autocomplete/
import React from 'react';
import PropTypes from 'prop-types';
import deburr from 'lodash/deburr';
import keycode from 'keycode';
import Downshift from 'downshift';
import { withStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';
import Paper from '@material-ui/core/Paper';
import MenuItem from '@material-ui/core/MenuItem';
import Chip from '@material-ui/core/Chip';
import _ from 'underscore';
function renderInput(inputProps) {
const { InputProps, classes, ref, ...other } = inputProps;
return (
<TextField
InputProps={{
inputRef: ref,
classes: {
root: classes.inputRoot,
},
...InputProps,
}}
{...other}
/>
);
}
function renderSuggestion({ suggestion, index, itemProps, highlightedIndex, selectedItem }) {
const isHighlighted = highlightedIndex === index;
const isSelected = (selectedItem || '').indexOf(suggestion) > -1;
return (
<MenuItem
{...itemProps}
key={suggestion.label}
selected={isHighlighted}
component="div"
style={{
fontWeight: isSelected ? 500 : 400,
}}
>
{suggestion.label}
</MenuItem>
);
}
renderSuggestion.propTypes = {
highlightedIndex: PropTypes.number,
index: PropTypes.number,
itemProps: PropTypes.object,
selectedItem: PropTypes.string,
suggestion: PropTypes.shape({ label: PropTypes.string, id: PropTypes.number }).isRequired,
};
class DownshiftMultiple extends React.Component {
state = {
inputValue: '',
selectedItems: [],
};
componentDidUpdate(prevProps, prevState, snapshot) {
if (this.state.selectedItems != prevState.selectedItems) {
this.props.onChange(this.state.selectedItems);
}
}
getSuggestions(value) {
const { options } = this.props;
const { selectedItems } = this.state;
const inputValue = deburr(value.trim()).toLowerCase();
const inputLength = inputValue.length;
let count = 0;
if (inputLength === 0) {
return []
} else {
let out = _.difference(options, selectedItems).filter(suggestion => {
const keep =
count < 5 && suggestion.label.slice(0, inputLength).toLowerCase() === inputValue;
if (keep) {
count += 1;
}
return keep;
});
return out;
}
}
handleKeyDown = event => {
const { inputValue, selectedItems } = this.state;
if (selectedItems.length && !inputValue.length && keycode(event) === 'backspace') {
this.setState({
selectedItems: selectedItems.slice(0, selectedItems.length - 1),
});
}
};
handleInputChange = event => {
this.setState({ inputValue: event.target.value });
};
handleChange = item => {
const { options } = this.props;
let { selectedItems } = this.state;
if (selectedItems.indexOf(item) === -1) {
for (let ind in options) {
let el = options[ind]
if (el.id == item) {
selectedItems = [...selectedItems, el];
break;
}
}
}
this.setState({
inputValue: '',
selectedItems,
});
};
handleDelete = item => () => {
this.setState(state => {
const selectedItems = [...state.selectedItems];
selectedItems.splice(selectedItems.indexOf(item), 1);
return { selectedItems };
});
};
render() {
const { classes, field_label, field_placeholder } = this.props;
const { inputValue, selectedItems } = this.state;
return (
<div className={classes.root}>
<Downshift
id="downshift-multiple"
inputValue={inputValue}
onChange={this.handleChange}
selectedItem={selectedItems}
>
{({
getInputProps,
getItemProps,
isOpen,
inputValue: inputValue2,
selectedItem: selectedItem2,
highlightedIndex,
}) => (
<div className={classes.container}>
{renderInput({
fullWidth: true,
classes,
InputProps: getInputProps({
startAdornment: selectedItems.map(item => (
<Chip
key={item.id}
tabIndex={-1}
label={item.label}
className={classes.chip}
onDelete={this.handleDelete(item.id)}
variant="outlined"
color="primary"
/>
)),
onChange: this.handleInputChange,
onKeyDown: this.handleKeyDown,
placeholder: field_placeholder,
}),
label: field_label,
})}
{isOpen ? (
<Paper className={classes.paper} square>
{this.getSuggestions(inputValue2).map((suggestion, index) =>
renderSuggestion({
suggestion,
index,
itemProps: getItemProps({ item: suggestion.id }),
highlightedIndex,
selectedItem: selectedItem2,
}),
)}
</Paper>
) : null}
</div>
)}
</Downshift>
</div>
);
}
}
DownshiftMultiple.propTypes = {
classes: PropTypes.object.isRequired,
};
DownshiftMultiple.defaultProps = {
options: [
{ label: 'Item 1', id: 1 },
{ label: 'Item 2', id: 2 },
{ label: 'Item 3', id: 3 },
{ label: 'Item 4', id: 4 },
],
field_label: "label",
field_placeholder: "placeholder"
};
const styles = theme => ({
root: {
flexGrow: 1,
height: 250,
},
container: {
flexGrow: 1,
position: 'relative',
},
paper: {
position: 'absolute',
zIndex: 1,
marginTop: theme.spacing.unit,
left: 0,
right: 0,
},
chip: {
margin: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 4}px`,
},
inputRoot: {
flexWrap: 'wrap',
}
});
export default withStyles(styles)(DownshiftMultiple);
// Inspired by : https://material-ui.com/demos/autocomplete/
import React from 'react';
import PropTypes from 'prop-types';
import deburr from 'lodash/deburr';
import keycode from 'keycode';
import Downshift from 'downshift';
import { withStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';
import Paper from '@material-ui/core/Paper';
import MenuItem from '@material-ui/core/MenuItem';
import Chip from '@material-ui/core/Chip';
import _ from 'underscore'
function renderInput(inputProps) {
const { InputProps, classes, ref, ...other } = inputProps;
return (
<TextField
InputProps={{
inputRef: ref,
classes: {
root: classes.inputRoot,
},
...InputProps,
}}
{...other}
/>
);
}
function renderSuggestion({ suggestion, index, itemProps, highlightedIndex, selectedItem }) {
const isHighlighted = highlightedIndex === index;
const isSelected = (selectedItem || '').indexOf(suggestion) > -1;
return (
<MenuItem
{...itemProps}
key={suggestion.label}
selected={isHighlighted}
component="div"
style={{
fontWeight: isSelected ? 500 : 400,
}}
>
{suggestion.label}
</MenuItem>
);
}
renderSuggestion.propTypes = {
highlightedIndex: PropTypes.number,
index: PropTypes.number,
itemProps: PropTypes.object,
selectedItem: PropTypes.string,
suggestion: PropTypes.shape({ label: PropTypes.string, id: PropTypes.number }).isRequired,
};
class DownshiftMultiple extends React.Component {
state = {
inputValue: '',
selectedItems: [],
};
componentDidUpdate(prevProps, prevState, snapshot) {
if (this.state.selectedItems != prevState.selectedItems) {
this.props.onChange(this.state.selectedItems);
}
import DownshiftMultiple from './DownshiftMultiple';
import MyComponent from '../MyComponent'
import { connect } from "react-redux";
import _ from 'underscore';
import {
universitiesFetchData,
mainCampusesFetchData,
citiesFetchData,
countriesFetchData
} from '../../generated/actions';
class Search extends MyComponent {
constructor() {
super();
this.state = {
leaflet_instance: null
};
}
componentWillUnmount() {
getSuggestions(value) {
const { options } = this.props;
const { selectedItems } = this.state;
const inputValue = deburr(value.trim()).toLowerCase();
const inputLength = inputValue.length;
let count = 0;
if (inputLength === 0) {
return []
} else {
let out = _.difference(options, selectedItems).filter(suggestion => {
const keep =
count < 5 && suggestion.label.slice(0, inputLength).toLowerCase() === inputValue;
if (keep) {
count += 1;
}
return keep;
});
return out;
}
}
handleKeyDown = event => {
const { inputValue, selectedItems } = this.state;
if (selectedItems.length && !inputValue.length && keycode(event) === 'backspace') {
this.setState({
selectedItems: selectedItems.slice(0, selectedItems.length - 1),
});
}
};
handleInputChange = event => {
this.setState({ inputValue: event.target.value });
};
handleChange = item => {
const {options} = this.props;
let { selectedItems } = this.state;
if (selectedItems.indexOf(item) === -1) {
for (let ind in options) {
let el = options[ind]
if (el.id == item) {
selectedItems = [...selectedItems, el];
break;
}
getCountriesWhereThereAreUniversities() {
const { universities,
mainCampuses,
countries,
cities } = this.getAllFetchedData();
let res = [];
_.each(mainCampuses, (campus) => {
let univ = universities[campus.university]
if (univ && campus) {
let city = cities[campus.city]
let country = countries[city.country]
res.push(country)
}
}
this.setState({
inputValue: '',
selectedItems,
});
};
handleDelete = item => () => {
this.setState(state => {
const selectedItems = [...state.selectedItems];
selectedItems.splice(selectedItems.indexOf(item), 1);
return { selectedItems };
});
};
return _.uniq(res, false, _.iteratee((val) => { return val.iso_alpha2_code }));
}
render() {
const { classes } = this.props;
const { inputValue, selectedItems } = this.state;
myRender() {
let options = [];
this.getCountriesWhereThereAreUniversities().forEach(country => {
options.push({ id: country.iso_alpha2_code, label: country.name });
})
return (
<Downshift
id="downshift-multiple"
inputValue={inputValue}
onChange={this.handleChange}
selectedItem={selectedItems}
>
{({
getInputProps,
getItemProps,
isOpen,
inputValue: inputValue2,
selectedItem: selectedItem2,
highlightedIndex,
}) => (
<div className={classes.container}>
{renderInput({
fullWidth: true,
classes,
InputProps: getInputProps({
startAdornment: selectedItems.map(item => (
<Chip
key={item.id}
tabIndex={-1}
label={item.label}
className={classes.chip}
onDelete={this.handleDelete(item.id)}
variant="outlined"
color="primary"
/>
)),
onChange: this.handleInputChange,
onKeyDown: this.handleKeyDown,
placeholder: 'Select multiple countries',
}),
label: 'Label',
})}
{isOpen ? (
<Paper className={classes.paper} square>
{this.getSuggestions(inputValue2).map((suggestion, index) =>
renderSuggestion({
suggestion,
index,
itemProps: getItemProps({ item: suggestion.id }),
highlightedIndex,
selectedItem: selectedItem2,
}),
)}
</Paper>
) : null}
</div>
)}
</Downshift>
<DownshiftMultiple options={options} onChange={(selection) => console.log(selection)} />
);
}
}
DownshiftMultiple.propTypes = {
classes: PropTypes.object.isRequired,
};
DownshiftMultiple.defaultProps = {
options: [
{ label: 'Afghanistan', id: 1 },
{ label: 'Aland Islands', id: 2 },
{ label: 'Albania', id: 3 },
{ label: 'Algeria', id: 4 },
],
};
const styles = theme => ({
root: {
flexGrow: 1,
height: 250,
},
container: {
flexGrow: 1,
position: 'relative',
},
paper: {
position: 'absolute',
zIndex: 1,
marginTop: theme.spacing.unit,
left: 0,
right: 0,
},
chip: {
margin: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 4}px`,
},
inputRoot: {
flexWrap: 'wrap',
},
divider: {
height: theme.spacing.unit * 2,
},
});
function IntegrationDownshift(props) {
const { classes } = props;
return (
<div className={classes.root}>
<div className={classes.divider} />
<DownshiftMultiple classes={classes} onChange={(selection) => console.log(selection)} />
<div className={classes.divider} />
</div>
);
}
const mapStateToProps = (state) => {
return {
universities: state.universities,
mainCampuses: state.mainCampuses,
cities: state.cities,
countries: state.countries
};
};
IntegrationDownshift.propTypes = {
classes: PropTypes.object.isRequired,
const mapDispatchToProps = (dispatch) => {
return {
fetchData: {
universities: () => dispatch(universitiesFetchData()),
mainCampuses: () => dispatch(mainCampusesFetchData()),
cities: () => dispatch(citiesFetchData()),
countries: () => dispatch(countriesFetchData())
}
};
};
export default withStyles(styles)(IntegrationDownshift);
export default connect(mapStateToProps, mapDispatchToProps)(Search);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment