Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optgroups #59

Closed
kopancek opened this issue Feb 6, 2015 · 95 comments
Closed

optgroups #59

kopancek opened this issue Feb 6, 2015 · 95 comments

Comments

@kopancek
Copy link

kopancek commented Feb 6, 2015

Is there a way of having option groups, like the standard optgroup element in html select?

@jossmac jossmac self-assigned this Feb 15, 2015
@piecyk
Copy link
Contributor

piecyk commented Mar 25, 2015

I want to help with this future... i was thinking going with simple structure

var options = [{
            label: "Group 1",
            children: [{
                value: "one",
                lable: "One"
            }, {
                value: "two",
                lable: "Two"
            }];

is someone started to work on that?

@acthp
Copy link

acthp commented Mar 31, 2015

I also need this, immediately. Is there work in progress, or should I fork?

@Venkatrao727
Copy link

+1

@TSMMark
Copy link

TSMMark commented Apr 2, 2015

+1

Anyone working on this?

@whather
Copy link

whather commented Apr 15, 2015

I also would love this. Planning on switching from Selectize.js (which has optgroup support) to this, but would need this functionality first.

@rick-li
Copy link

rick-li commented Apr 27, 2015

+1

1 similar comment
@guillaumepiot
Copy link

+1

@dcousens
Copy link
Collaborator

dcousens commented May 7, 2015

We're accepting PRs, so don't feel bad if you beat @jossmac to it. It currently isn't on the hit list.

@jossmac jossmac assigned dcousens and unassigned jossmac May 7, 2015
@jossmac
Copy link
Collaborator

jossmac commented May 7, 2015

I'm working almost exclusively on http://elemental-ui.com for the foreseeable future, so I won't be of much help I'm afraid. Incidentally I've implemented a dropdown over there that may be of interest using the following pattern:

var selectOptions = [
  { type: 'option', value: 'option', label: 'Option' },
  { type: 'option', value: 'another-option', label: 'Another option' },
  { type: 'option', value: 'something-else-here', label: 'Something else here' },
  { type: 'divider' },
  { type: 'label', label: 'Select label' },
  { type: 'option', value: 'separated-option', label: 'Separated option' },
];

More here: https://github.com/elementalui/elemental/blob/master/src/components/Dropdown.js

Ping @JedWatson for preferences on implementation details

@rorykoehein
Copy link

+1

@zenjyn
Copy link

zenjyn commented Jun 15, 2015

@JedWatson I'm currently working on this for a project. How would you like this implemented? The interface we need is a variation on the selectize structure, but I can handle that in a wrapper class if you prefer something different:

options: [
    {optgroup: 'Things', value: "thing1", label: "Thing 1" },
    {optgroup: 'Things', value: "thing2", label: "Thing 2" },
    {optgroup: 'Things', value: "thing3", label: "Thing 3" },
    {optgroup: 'Stuffs', value: "stuff1", label: "Stuff 1" },
    {optgroup: 'Piles', value: "pile1", label: "Pile 1" },
    {value: "pile1", label: "Pile 1" }
],
optgroups: [
    {position: 1, label: 'Things'},
    {position: 2: label: 'Stuffs'}
],

Options with an optgroup not in the optgroup set are ignored. Options without an optgroup are listed last.

@piecyk
Copy link
Contributor

piecyk commented Jun 15, 2015

@zenjyn 👍 great if you working on public branch i can help with something ( would love to see this merged... and kill select2 at my project

what do you think about something like this ? then you can sort the whole options array by label (if we have values the render it as optgroup )

options: [
  {
    label: "Thing 1a",
    //value: "allThings1a" then in future we can also add selecting the whole group
    values: [
      {
        value: "thing1a", label: "Thing 1a"
      },
      {
        value: "thing2a", label: "Thing 2a" 
      }
    ]
  },
  {
    label: "Thing 2b",
    values: [
      {
        value: "thing1b", label: "Thing 1b"
      },
      {
        value: "thing2b", label: "Thing 2b" 
      }
    ]
  },
  {
    label: "Thing 3c",
    value: "thing3c"    
  }
];

@zenjyn
Copy link

zenjyn commented Jun 16, 2015

@piecyk I started with something like that on our end but determined that being able to add, remove, reorder the optgroups in their own array was slightly more flexible for our purposes. I'm still open to something more like your nested structure for the PR, however.

As far as group selecting goes, I wasn't planning on getting into that just yet, but we could make a group select flag then just enable a toggleGroup callback to the onClick event for optgroup divs. Thoughts?

@grydstedt
Copy link

+1

@banderson
Copy link
Contributor

@zenjyn @piecyk any progress on a public branch? I'd be willing to help out too, I need this for a project very soon.

/cc @colbyr

@zenjyn
Copy link

zenjyn commented Sep 24, 2015

@banderson the optgroup issue for my project was pushed to the backlog almost immediately after I posted on here. I probably won't get to it unless it's still unimplemented by the time the task comes up again. For my project I believe it's on the roadmap 6 months out or so.

@agrass
Copy link

agrass commented Oct 22, 2015

+1

2 similar comments
@tineo
Copy link

tineo commented Oct 23, 2015

+1

@lanceschi
Copy link

👍

@thataustin
Copy link

Trying to kick this thing up again...

@piecyk - I like your proposed API, but I would rename values to children. I think it's a bit more obvious what the purpose is, and a bit easier to read (ie, easier to distinguish between the value and the children). Anyone else fine with that API? If we get some more feedback on that API, it will be easier to start in on it.

@piecyk
Copy link
Contributor

piecyk commented Dec 9, 2015

@thataustin i agree the children is a better name... maybe @JedWatson can share his point of view on this... if this is on road map... there are so many issues and pull request now it's getting hard to follow 👍

for now we can make simple crazy and naive wrapper, but should work as expected ;)

const MyOptions = [
  {
    text: "Group 1",
    children: [{
      id: "one1",
      text: "One1"
    }, {
      id: "two2",
      text: "Two2"
    }]
  },{
    text: "Group 2",
    children: [{
      id: "one2",
      text: "One2"
    }, {
      id: "two2",
      text: "Two22"
    }]
  }
];

function option(value, label, render, disabled = false) {
  return {value, label, render, disabled};
}
const transformOptions = options => _.reduce(options, (res, el) => {
  const parent = option(el.text, el.text, (<strong>{el.text}</strong>), true);
  const children = _.map(el.children, child => _.assign(
    {}, option(child.id, child.text, (<span style={{paddingLeft: 10}}>{child.text}</span>)), {parent: el.text}
  ));

  return res.concat(parent).concat(children);
}, []);

const SelectGroups = React.createClass({
  getInitialState() {
    return {
      value: this.props.value,
      options: transformOptions(this.props.options)
    };
  },
  optionRenderer(option) {
    return option.render;
  },
  onChange(value) {
    this.setState({value});
    this.props.onChange(value);
  },
  filterOptions(options, term, currentValues) {
    if (term === this.prevTerm) {
      return this.prevOptions;
    } else {
      const almostReadyOptions = this.props.filterOptions ? this.props.filterOptions(options, term, currentValues)
      // very naive filter, maybe ref form react-select and re-use the filterOptions ;)
            : _.filter(options, o => o.parent ? _.includes(o.label.toLowerCase(), term.toLowerCase()) : true);
      const optionsGroupByParent = _.groupBy(almostReadyOptions, 'parent');
      // filter empty parents
      const readyOptions = _.filter(almostReadyOptions,
                                    option => option.parent ? option : _.size(optionsGroupByParent[option.value]) > 0);
      this.prevTerm = term;
      this.prevOptions = readyOptions;
      return readyOptions;
    }
  },
  render() {
    return (
      <Select
        {...this.props}
        value={this.state.value}
        onChange={this.onChange}
        optionRenderer={this.optionRenderer}
        options={this.state.options}
        filterOptions={this.filterOptions}
      />
    );
  }
});

// use it 
//<SelectGroups
//  options={MyOptions}
//  onChange={val => console.log(val)}
///>

@mqklin
Copy link

mqklin commented Dec 26, 2015

Guys, i have a workaround:

//react-select-groups.scss
.Select-menu-outer {
  .Select-option {
    padding-left: 2em;
  }
  .Select-option.is-disabled {
    cursor: default;
    padding-left: 1em;
    font-weight: bold;
  }
}

Then you have to just push disabled values into options with labels that are group names:

//my-component.js
...
let options = [];
options.push({
  label: "Пользователи",
  value: "someUniqueValue",
  disabled: true
});
users.map((user) => {
  options.push({
    label: user.name,
    value: user.id,
  });
});
...

Result:
123

@FrankRenyu-zz
Copy link

If we only wan to implement "optgroup" on top of "option", we can do something like this. It works for me.

return <option>{props.data}</option>;
};
 var options = [];
 $.each(this.props.options, function(key, item) {
       options.push(<optgroup label={key}>{item.map((data) => <Item data={data}/>)}</optgroup>);
 });

@proton1k
Copy link

@FrankRenyu it does not solve the problem with scrolling-off from the top as far as I understand ?

@sundriver
Copy link

+1

1 similar comment
@jainamit333
Copy link

+1

@drakoniprincessa
Copy link

+1

1 similar comment
@dannyvassallo
Copy link

+1

@Geczy
Copy link

Geczy commented Sep 12, 2017

unsubscribes

bkoltai pushed a commit to bkoltai/react-select that referenced this issue Sep 20, 2017
…ld-trigger-close-menu

Trigger closeMenu when isOpen changes from true to false
@zhilinstas
Copy link

+1

2 similar comments
@arumpuspa
Copy link

+1

@graphical-iain
Copy link

+1

@lucasff
Copy link

lucasff commented Oct 12, 2017

please stop (spam-)posting +1, just react with the thumbs up!

@chhuang
Copy link

chhuang commented Oct 25, 2017

+$50

@renanborgez
Copy link

+1

2 similar comments
@moguelor
Copy link

+1

@NicholasKuchiniski
Copy link

+1

@JedWatson
Copy link
Owner

I am really happy to say that groups are implemented in my new v2 branch 🎉

Everyone who has +1'd this will be happy to know this was one of the first things we implemented in the new version, and I'm quite happy with how they turned out.

v2 is currently in alpha: see #2208 and the PR #2289

If you want an early preview, it's available here: https://deploy-preview-2289--react-select.netlify.com

Expect it to hit final release sometime towards the end of February.

Now, with great relief, I'm going to close this issue 🙂

@guillaume86
Copy link

@JedWatson brilliant thanks!

Is there a lot of API changes in v2? Do you expect easy migrations or will it be a bit involved?

@JedWatson
Copy link
Owner

I'm not sure yet - I need to finalise the new API before I can know, and then I'll publish an upgrade guide.

Depends on how much you've customised it. I'm removing a lot of the edge-case props in favour of a more powerful architecture, but I'll try to make the upgrade as simple as possible.

@jossmac
Copy link
Collaborator

jossmac commented Jan 25, 2018

An end to the +1 emails 🎉

But seriously, I think everyone will be stoked with v2 -- we've really sweated the details.

@s-dezign
Copy link

s-dezign commented Mar 5, 2018

v2 is really great. One question ... How to get group label/object for selected option? for example in onChange method.

Thanks

@JedWatson
Copy link
Owner

Answer in #2417

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests