Skip to content

Instantly share code, notes, and snippets.

@carlows
Created October 5, 2016 23:24
Show Gist options
  • Save carlows/e9a9c1122b3648fbf9a81d2acb43eb98 to your computer and use it in GitHub Desktop.
Save carlows/e9a9c1122b3648fbf9a81d2acb43eb98 to your computer and use it in GitHub Desktop.

Disclaimer

WIP

Author

Carlos Martinez

Problem Overview

The textareas for commenting in the app allow users to mention other users. To enhance the user experience, it is required to implement an autocomplete menu to select the user to mention.

gif

Constraints

  • The dropdown should popup in the cursor position

Background

There are a couple of solutions to this problem available:

React mentions is pretty cool, and being a react component would be nice to use. However, they dropped bower support in version v0.3.0. Because we're using rails-assets and no npm we can't get to use this component.

At-js is a jquery component that works nice for our use case too, I selected this component because It will be easy to create a wrapper with react and it allows for customization.

Theory of operation

What's needed to implement this feature is the following:

  1. Refactor out the textarea components in the comments components to a TextArea component.
  2. Within the TextArea component, use componentDidMount to configure At-Js.
  3. Expose methods to set and get the value of the textarea

We have to add these methods to get/set the value of the textarea because we can't use a controlled component as the value of the textarea would get out of sync with the plugin.

Goals

  • Having an autocomplete dropdown component that triggers within the textarea of the comments component when a user types @.

Functional Specification

The component is wrapped as a gem and can be fetch for the app adding:

Gemfile

gem 'jquery-atwho-rails'

./components/textarea.js.jsx

class TextArea {
  componentDidMount() {
    // these would be get through props
    const names = [
      { id: '1', name: 'Carlos Martinez', email: '[email protected]' },
      { id: '2', name: 'Luis Jose', email: '[email protected]' }
    ];

    const config = {
      at: '@',
      data: names,
      // the template to use for each of the items in the dropdown
      displayTpl: '<li>${name} <small>${email}</small></li>'
    };

    let component = this.refs.textarea;

    $(component).atwho(config);
  }

  getValue() {
    return this.refs.textarea.value;
  }

  setValue(value) {
    this.refs.textarea.value = value;
  }

  render() {
    return (
      <textarea ref='component'></textarea>
    );
  }
}

Open Issues

N/A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment