Add support for OPTGROUPs? #58

Closed
choxnox opened this Issue May 17, 2012 · 38 comments

Projects

None yet
@choxnox
choxnox commented May 17, 2012

I'm currently using Chosen on my website, but I find Select2 better because it allows loading of remote data via AJAX which I must have (for Location field in users' profiles - 60.000+ locations). However, I've noticed Select2 doesn't support OPTGROUPs which I also need (let's say for separating locations by countries).

Is there anyway to throw is support for OPTGROUP elements?

@natwallbank

I've just switched to Select2 from Chosen for a project I'm working on and must admit that this is the one feature I'm missing...

@balexand

+1 I'd like to see optgroup support as demoed on the Chosen site. For now I'm probably going to end up using both Select2 and Chosen.

I love Select 2 (especially the tagging support). Thanks for the hard work!

@ianlandsman

+1 on this

@ivaynberg
Contributor

how do you guys envision the json response looking in order to support optgroups since it only contains a partial dataset?

@ianlandsman

You can't select the optgroup label in a normal select so you'd still keep that concept. It would just be a visual separator. Nothing needs to change in any json response.

@ivaynberg
Contributor

i understand that, but what would the json look like?

now its {results: [{choice1},{choice2}]}...

as in, where do we define the optgroups, and their nesting, and which choices go with which optgroup

@ivaynberg
Contributor

we also have to take into account lazy loading, and what happens when new optgroups are introduced in page 2 that were not available in page 1. how would that render and if the rendering would jitter the list in an unpleasant way...

paging of hierarchical structures is usually not done, but paging is crucial to select2

@natwallbank

I guess it'd be something like the following?

[results: [{group: "Group 1", options: [{ id: 1, text: "choice 1" }, { id: 2, text: "choice 2" }]}, {group: "Group 2", options: [{ id: 3, text: "choice 3" }, { id: 4, text: "choice 4" }]}] ]

(crosses fingers and hopes that actually looks right after typing it in...)

@natwallbank

Interesting point on paging / lazy loading - it's not something I've used or even looked at so far, as I've only been using Select2 for a few days (great work btw!).

@ivaynberg
Contributor

[results:
[{group: "Group 1", options: [{ id: 1, text: "choice 1" }, { id: 2, text: "choice 2" }]},
{group: "Group 2", options: [{ id: 3, text: "choice 3" }, { id: 4, text: "choice 4" }]}]
]

that wont work, optgroups can be nested, so the format needs to be recursive...

@natwallbank

Really? Is that new in HTML5? I'm pretty sure you never used to be able to nest optgroups, but haven't used them for a while.

@ivaynberg
Contributor

oh man. i was 100% sure they added that in html 5. but looks like they havent: http://www.w3.org/TR/html5/the-optgroup-element.html#the-optgroup-element

@performancewanted

+1 for this feature. Except if I type in part or all of the optgroup name, I expect to see all entries in that optgroup to show up. Something that 'Chosen' doesn't do but I suppose this could just be implemented via the AJAX callback in select2.

As to what JSON to expect, it should be something like:

{results: { group1: [{choice1}, {choice2}], group2: [{choice3}, {choice4}] }}

If the key is a string and maps to an array/object, it is an 'optgroup', otherwise it is a regular entry.

As to nested optgroups, I'm not even sure how that would work in a browser environment. Such a feature would, at the very least, be ripe for abuse by people with no design taste. You can be pretty sure it won't happen - mobile devices barely support basic optgroups.

@ProLoser
Contributor
ProLoser commented Jun 5, 2012

Too bad you can't use an object literal to retain order or @performancewanted would actually suffice. Although I suppose you could ALSO support that approach for slightly less overhead yet easier formatting if order didn't matter.

In all honesty, thinking about all the different variations, I can't think of 1 clean consistent solution, so instead I propose this:

We support a callback function where people can decide for themself how to format their data. It would actually just detect if it's an optGroup or not, but no more. Or alternatively it could just be the value formatter enhanced in a way that it can call itself recursively with the subset of options.

In addition we could try and setup a default callback that is as understandable as possible by default. Unfortunately with setups like this it's really hard to make it consistent (when order matters). By default we can check for some clean convention (such as a children and label key) but still let people declare their own callback functions instead.

<select>
      <option>First</option>
      <option>First</option>
      <option>First</option>
      <optgroup label="test">
        <option>First</option>
        <option>First</option>
        <option>First</option>
      </optgroup>
      <option>First</option>
      <option>First</option>
</select>
@sundorf
sundorf commented Jun 7, 2012

+1 for a callback to format the data. This would allow for various indentation levels and also for the group title (optgroup label) be selectable.

@ivaynberg
Contributor

i dont mind providing the callback. however, this is a power-user type feature. i dont see an average dev wanting to mess with it, so we should probably provide some kind of baked in support for optgroups.

@ProLoser
Contributor
ProLoser commented Jun 7, 2012

Step 1: Add custom callback support
Step 2: Provide a default callback for quick-use
Step 3: ???
Step 4: Profit!

We don't have to do everything at once. First lets get callback support working. After that we can continue to argue about how to format the data by default.

@fjsj
fjsj commented Jun 8, 2012

A nice implementation of optgroups using jQuery UI is: http://www.erichynds.com/examples/jquery-ui-multiselect-widget/demos/

It would be great to have jquery-ui-multiselect-widget features with select2 infinite scrolling and ajax.

@ProLoser
Contributor
ProLoser commented Jun 8, 2012

Step 1: add support for custom callbacks
Step 2: provide a default callback
Step 3:???
Step 4: profit!

We don't have to do it all at once

Sent from my Android phone with K-9 Mail. Please excuse my brevity.

sun reply@reply.github.com wrote:

+1 for a callback to format the data. This would allow for various indentation levels and also for the group title (optgroup label) be selectable.


Reply to this email directly or view it on GitHub:
#58 (comment)

@ivaynberg ivaynberg added a commit that referenced this issue Jun 14, 2012
@chroder @ivaynberg chroder + ivaynberg Add support for hierarchies and unselectable items. issue #58
Signed-off-by: Igor Vaynberg <igor.vaynberg@gmail.com>
6151ddb
@ivaynberg ivaynberg added a commit that closed this issue Jun 14, 2012
@ivaynberg ivaynberg simplify optgroup querying and rendering code. provide a more powerfu…
…l populateResults() function fixes #58. fixes #105. fixes #84
55fd001
@ivaynberg ivaynberg closed this in 55fd001 Jun 14, 2012
@dominikwilkowski

Hey there...

I am trying to get optgroup working from a json feed ...
What did the syntax ended up to be?
I tried:
data: [{group:"group1", options:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}, {group:"group2", options:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}]
data: [{group1:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}, {group2:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}]
data: [{group:"group1", text:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}, {group:"group2", text:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}]
data: [{id:0, text:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}, {id:1, text:[{id:0, text:"option 1"}, {id:1, text:"option 2"}]}]

all of which fail...
data: [{id:0, text:"option 1"}, {id:1, text:"option 2"}]
that of course works just to show that the rest of the implementation is correct...

@ivaynberg
Contributor
{results:[{id:1,text:'optgroup',children:[{id:2,text:'child1'},{id:3,text:'nested optgroup', children:[...]}]}]}
@dominikwilkowski

Oh man thanks for the quick answer!
This should really be somewhere in the docs.....
at least it's in here now

@armstnp
armstnp commented May 9, 2013

Agreed, it took quite a while to track this down. Thanks for the info!

@zippo445

I'm using the optgroup format for the query and it works fine. only problem I have is that the opt group line are now selectable items. Although this may be useful when group selection is desired, in my case I only want child items to be selectable. any way to prevent group header selection? thanks!

@ivaynberg
Contributor

@zippo445 dont give the optgroup elements an id attribute and they wont be selectable.

@zippo445

thanks @ivaynberg! that was a fast answer! did I miss that in the documentation? if so it might be a nice addition...

@ivaynberg
Contributor

@zippo445 pull requests to gh-pages branch are most welcome

@zippo445

@ivaynberg I will try to do my homeworks when I have a bit of time :)

@jayant29

Hey,

i am trying to use optgroup with Ajax call in my code.But there is some problem with formatting of result. Anybody can help me out here to show the Hierarchical Data exactly in the same format as it is given in documentation.

results: [
{ text: "Western", children: [
{ id: "CA", text: "California" },
{ id: "AZ", text: "Arizona" }
] },
{ text: "Eastern", children: [
{ id: "FL", text: "Florida" }
] }
]

I am getting the same formatted json data from ajax call but when i am calling formatResult,formatSelection then i am getting issue.
So, it would be great help to get a code for formatResult, formatSelection callback.

Thanks in Advance.

@hemantthorat

For ajax data loading with group and data work for me using,
$arrFinal = array(array("name"=>"My shiny group 1",
"children"=>array(array("id"=>1,"name"=>"My shiny item 11"),array("id"=>2,"name"=>"My shiny item 12"))
),array("name"=>"My shiny group 2",
"children"=>array(array("id"=>1,"name"=>"My shiny item 21"),array("id"=>2,"name"=>"My shiny item 22"))
)
);
die(json_encode(array("result" => $arrFinal)));

if formatResult: ratioFormatResult then,
function ratioFormatResult(row) {
// Here, you will get both group ("My shiny group 1") as well as data("My shiny item11") as row .
}

To make group selectable use id field along with name in group.

I Hope most of you will find this useful.

@canercak

Could anyone please help me?. I'm almost done with it but stuck with this thing I've stated on stackoverflow.

http://stackoverflow.com/questions/18209630/rails-mongoid-solr-grouping-remote-ajax-data-in-select2-optgroup-appearing-mult

@canercak

It works now. Please check the stackoverflow link.

@seanbischoff

Hi guys, where are we with lazy loading and optgroups? Am I correct in assuming lazy-appending does not work with optgroups? Please say I'm wrong, with an example ;)

@armstnp
armstnp commented Oct 16, 2013

Lazy loading really doesn't make sense with optgroups, I think. Consider this: you're scrolling down, and it stops for a second to lazy-load a new set of items. It then proceeds to add those items to groups above your current position. That would lead to a couple issues:

  • The new additions may not be visible to the user at all.
  • If no new groups or items are inserted, you would probably end up triggering the next lazy-load since you're already at the bottom of the list.

No examples, but I suspect that these would be problematic. Generally, lazy-load has an implicit assumption that the items are appended to the end of the list. The only case I could see this working is if the items that come back are always grouped hierarchically, as additional items would simply fall into the correct optgroup naturally.

@seanbischoff

My UX guy clarified, he wants the first N options in optgroup 1 displayed, then as we scroll down more of optgroup1 displays, and eventually optgroup 2 comes into view, then optgroup 3, etc etc. Perhaps a custom paging function could achieve this.

@xc8tlik
xc8tlik commented Jan 1, 2014

@ivaynberg: "dont give the optgroup elements an id attribute and they wont be selectable."

Is it possible to retain the ID for the optgroup but prevent the optgroup from being selectable at the same time?

I have a dependent select which requires that I can access the optgroup ID, but also I need to retain access to the selected option value.

Many thanks for your fantastic work!

@ivaynberg
Contributor

you can specify your own id option that will return null ids for optgroup elements.

@Jeloi
Jeloi commented Feb 9, 2014

Does anyone know if it is possible to show results in an optgroup based off an optgroup's text hit in search? This is the default behavior with Chosen http://harvesthq.github.io/chosen/. For example, searching "nfc east" will display all the options in that group. This is not the case by default with Select, and its the one thing keeping me from moving over. Thanks

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