ux icon indicating copy to clipboard operation
ux copied to clipboard

[Autocomplete] group_by option from EntityType does not work on Ajax auto-complete field

Open jvancoillie opened this issue 2 years ago • 3 comments

Description

EntityType's group_by option does not work on auto-complete field. The ajax return does not allow us to make a groupment we lose the optgroup information

Do you think that with a custom tom-select extension and a custom AJAX autocomplete endpoint, could have the expected behavior?

In this case we would lose all the magic of the bundle ;(

jvancoillie avatar Sep 22 '22 15:09 jvancoillie

Hi!

Hmm, indeed! I see TomSelect supports optgroup - https://tom-select.js.org/examples/optgroups/.

I would welcome a PR for this :). What's not clear to me is:

(A) exactly how the JSON structure should change to support the group_by (here is where the JSON structure is created - https://github.com/symfony/ux/blob/2.x/src/Autocomplete/src/AutocompleteResultsExecutor.php#L50-L57 )

(B) Exactly how the JavaScript controller code would need to change (I couldn't find any examples of opt group + remote) - the last example here https://tom-select.js.org/examples/optgroups/ shows how you can set optgroups as a separate option then refer to them by each option via class (or whatever optgroupField: 'class', is set to). I wonder if we could set this optGroups programmatically inside here: https://github.com/symfony/ux/blob/2.x/src/Autocomplete/assets/src/controller.ts#L142

Cheers!

weaverryan avatar Sep 23 '22 14:09 weaverryan

Hi @weaverryan :wave:

Thanks for your reply.

I will try to see what it is possible to do thanks to your leads.

I'll submit a pull request if I can find a solution.

jvancoillie avatar Sep 24 '22 09:09 jvancoillie

After some research I think it is possible to modify the return json with the following format

{
  "results": {
    "options": [
      {
        "class": "mammal",
        "value": "dog",
        "text": "Dog"
      },
      {
        "class": "bird",
        "value": "duck",
        "text": "Duck"
      },
      {
        "class": "reptile",
        "value": "turtle",
        "text": "Turtle"
      }
    ],
    "optgroups": [
      {
        "value": "mammal",
        "label": "Mammal",
        "label_scientific": "Mammalia"
      },
      {
        "value": "bird",
        "label": "Bird",
        "label_scientific": "Aves"
      },
      {
        "value": "reptile",
        "label": "Reptile",
        "label_scientific": "Reptilia"
      }
    ]
  }
}

The callback of tom-select can take two parameters options and optgroups

that can be done like this

load: function (query, callback) {

    const url = this.getUrl(query);
    fetch(url)
        .then(response => response.json())
        .then(json => { this.setNextUrl(query, json.next_page); callback(json.results.options, json.results.optgroups); })
        .catch(() => callback());
},

on the other hand it is necessary to add the tom-select configuration for optgroupField

jvancoillie avatar Sep 24 '22 10:09 jvancoillie