Skip to content

shouldSuggestionsRender wont display #612

Open
@gromstone

Description

@gromstone

For some reason the suggestion wont display. Also need a bit of help

combo box flow
Senario

  1. User clicks on combobox, suggestion are displayed (Working).

  2. User select a suggestion. Suggestion is displayed on combobox. (Working)

  3. If user clicks on combobox after making a selection, combobox will clear input, but previous selection will display as a highlighted first choice. Also updated suggestion display below first choice.
    ( Cant get the previous selection to be re selected, can only select from standard drop down )

(see image for reference)

Code

import React, { Component } from "react";
import ReactDOM, { findDOMNode } from "react-dom";
import PropTypes from "prop-types";
import classNames from "classnames";
import Autosuggest from "react-autosuggest";

import Icon from '../Components/Icons/Icons';

class Autocomplete extends Component {
  constructor() {
    super();

    this.state = {
      value: "",
      suggestions: [],
      isTouched: false,
      multi: false,
      selectedInput: ""
    };

    this.onChange = this.onChange.bind(this);
    this.onClick = this.onClick.bind(this);
    this.blurCallback = this.blurCallback.bind(this);
    this.triggerFocus = this.triggerFocus.bind(this);
    this.handleClear = this.handleClear.bind(this);
  }

  getSuggestionValue = suggestion => suggestion.text;

  renderSuggestion = suggestion => (<span>{suggestion.text}</span>)

  escapeRegexCharacters = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

  getSectionSuggestions = section => section && section.items;

  getSuggestions = (value, selected, reason) => {
    let suggestions = this.props.data;

    if (value !== undefined) {
      const escapedValue = this.escapeRegexCharacters(value.trim());
      const selectedInput = [];
      selectedInput.push(selected);
      const regex = new RegExp(escapedValue, "i");
      const filtered = suggestions.filter(language =>
        regex.test(language.text)
      );

      if (escapedValue === "") {
        return {
          suggestions: [
            { text: selectedInput[0], items: [] },
            { text: "", items: filtered }
          ],
          multi: true
        };
      }

      if (!filtered.length) {
        return {
          suggestions: selectedInput.length > 0 ? selectedInput : filtered,
          multi: false
        };
      }

      return {
        suggestions: [{
            text: selectedInput[0],
            items: selectedInput.length > 0 ? selectedInput : filtered
          },
          {
            text: "",
            items: reason === "focused" ? suggestions : filtered
          }],
        multi: true
      };
    } else return;
  };

  onSuggestionsFetchRequested = ({ value, reason }) => {
    if (reason === "input-focused") {
      this.setState({ value: "" });
      const { multi, suggestions } = this.getSuggestions(
        value,
        this.state.selectedInput ? this.state.selectedInput : "",
        "focused"
      );
      this.setState({
        suggestions,
        multi
      });
    } else {
      const { multi, suggestions } = this.getSuggestions(
        value,
        this.state.selectedInput ? this.state.selectedInput : "",
        "notfocused"
      );
      this.setState({
        suggestions,
        multi
      });
    }
  };

  onSuggestionsClearRequested = () => {
    this.setState({
      suggestions: [],
      multi: false
    });
  };

  onChange = (event, { newValue, method }) => {
    if (method === "enter") {
      this.setState({
        value: this.state.value
      });
    } else {
      this.setState({
        value: newValue
      });
    }

    if(this.props.search) {
      this.props.search(newValue, ReactDOM.findDOMNode(this).parentNode.parentNode.querySelectorAll('li'));
    };
  };

  onSuggestionSelected = (ev,
    { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }
  ) => {
    this.setState({
      selectedInput: suggestionValue
    });
  };

  blurCallback (ev) {
    this.setState({  isTouched: false });
  }

  handleClear() {
    this.setState({
      value: ''
    })
  }
  onClick(ev) {
    this.setState({ isTouched: true });
  }

  triggerFocus() {
    const input = document.getElementById(this.props.id);
    input.focus();
  }

  render() {

    const theme = {
      container: "el-form",
      containerOpen: "react-autosuggest__container--open",
      input: "autocomplete form-control",
      inputOpen: "react-autosuggest__input--open",
      inputFocused: "react-autosuggest__input--focused",
      suggestionsContainer: "react-autosuggest__suggestions-container",
      suggestionsContainerOpen:
        "react-autosuggest__suggestions-container--open",
      suggestionsList: "autocomplete-wrap",
      suggestion: "react-autosuggest__suggestion",
      suggestionFirst: "react-autosuggest__suggestion--first",
      suggestionHighlighted: "react-autosuggest__suggestion--highlighted",
      sectionContainer: "react-autosuggest__section-container",
      sectionContainerFirst: "react-autosuggest__section-container--first",
      sectionTitle: "react-autosuggest__section-title"
    };

    const {
      className,
      placeholder,
      data,
      disabled,
      label,
      labelClass,
      icon,
      iconSize,
      iconClass,
      clear,
      clearClass,
      id,
      search,
      ...attributes
    } = this.props;

    const labelClassFix = classNames(
      isNotEmpty && "active",
      disabled && "disabled",
      labelClass
    );
    const iconClassFix = classNames(
      "prefix",
      this.state.isTouched && "active",
      iconClass
    );
    const clearClassFix = classNames(
      clearClass
    )

    const isclearVisible = () => {
      let hiddenOrNot = "hidden"
      if (this.state.value) {
        hiddenOrNot = "visible";
      }
      return hiddenOrNot;
    }
    const clearStyleFix = {
      position: "absolute",
      zIndex: 2,
      top: "2.5rem",
      right: "10px",
      border: "none",
      background: "0 0",
      visibility: isclearVisible(),
    }

    let isNotEmpty =
      Boolean(this.state.value) || placeholder || this.state.isTouched;

    const { value, suggestions, multi } = this.state;

    const inputProps = {
      placeholder: placeholder,
      value,
      onChange: this.onChange,
      onBlur: this.blurCallback,
      onClick: this.onClick,
      onFocus: this.onFocus,
      id: this.props.id,
      name: this.props.name
    };

    const renderInputComponent = inputProps => (
      <div>
        { icon && <Icon icon={icon} className={iconClassFix}/> }
        <input
          type="text"
          id={id}
          name={name}
          className="form-control"
          {...inputProps}
          onFocus={(ev, val) => {
            this.onClick();
            inputProps.onFocus(ev, val);
          }}
        />
        <label
          htmlFor={id}
          id={`label for ${id}`}
          onClick={this.triggerFocus}
          className={labelClassFix}
        >
          { label }
        </label>
        { clear &&
          <Icon icon="close" onClick={this.handleClear} style={clearStyleFix}
          className={clearClassFix}/>
        }
      </div>
    );

    return (
        <Autosuggest
          multiSection={multi}
          renderSectionTitle={this.renderSuggestion}
          getSectionSuggestions={this.getSectionSuggestions}
          suggestions={suggestions}
          highlightFirstSuggestion={true}
          focusInputOnSuggestionClick={false}
          onSuggestionsClearRequested={this.onSuggestionsClearRequested}
          onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
          getSuggestionValue={this.getSuggestionValue}
          renderSuggestion={this.renderSuggestion}
          inputProps={inputProps}
          theme={theme}
          renderInputComponent={renderInputComponent}
          shouldRenderSuggestions={ () => true }
          onSuggestionSelected={this.onSuggestionSelected}
        />
    );
  }
}

Autocomplete.propTypes = {
  className: PropTypes.string,
  icon: PropTypes.string,
  id: PropTypes.string,
  name: PropTypes.string,
};

Autocomplete.defaultProps = {
  id: 'autocomplete-1',
  name: '',
  clear: true
};

export default Autocomplete;

Component

const states = [ "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illnois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming" ];

<Autocomplete
  data={states}
  label="Choose your state"
  icon="lightbulb"
  clear
  clearClass="grey-text" id="combobox-states" name="state-selection"
  className="mx-auto"
/>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions