1

I'm struggling with configuration of Symfony UX Autocomplete component extension - My goal is to modify TomSelelct Instance - the way how its rendered and add options like https://tom-select.js.org/plugins/checkbox-options/

I have a working example of autocomplete defined like this:

EntityAutocompleteField.php

#[AsEntityAutocompleteField]
class EntityAutocompleteField extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'class' => Entity::class,
            'searchable_fields' => ['name'],
            'label' => 'entity',
            'choice_label' => 'name',
            'attr' => [
                'data-controller' => 'custom-autocomplete', //this should point me to custom controller - right?
            ],
            'multiple' => true,
        ]);
    }

    public function getParent(): string
    {
        // In 2.13 it will be replaced by BaseEntityAutocompleteType
        return ParentEntityAutocompleteType::class;
    }
}

In ./assets/controllers.json

{
    "controllers": {
        "@symfony/ux-autocomplete": {
            "autocomplete": {
                "enabled": true,
                "fetch": "eager",
                "autoimport": {
                    "tom-select/dist/css/tom-select.default.css": true,
                    "tom-select/dist/css/tom-select.bootstrap5.css": false
                }
            }
        }
    },
    "entrypoints": []
}

In ./assets/controllers/custom-autocomplete_controller.js:

import { Controller } from '@hotwired/stimulus';

/* stimulusFetch: 'lazy'*/ //I am not sure if this shoul dbe lazy - it does not work without this line anyway 
export default class extends Controller {

  initialize() {
//THIS IS NOT WORKING
    console.debug("Init");
    this._onPreConnect = this._onPreConnect.bind(this);
    this._onConnect = this._onConnect.bind(this);
  }

  connect() {
    console.debug("Connect");

    this.element.addEventListener('autocomplete:pre-connect', this._onPreConnect);
    this.element.addEventListener('autocomplete:connect', this._onConnect);
  }

  disconnect() {
    console.debug("Disconnect");

    // You should always remove listeners when the controller is disconnected to avoid side-effects
    this.element.removeEventListener('autocomplete:connect', this._onConnect);
    this.element.removeEventListener('autocomplete:pre-connect', this._onPreConnect);
  }

  _onPreConnect(event) {
    // TomSelect has not been initialized - options can be changed
    console.log(event.detail.options); // Options that will be used to initialize TomSelect
    event.detail.options.onChange = (value) => {
      // ...
    };
  }

  _onConnect(event) {
    console.log(event.detail.tomSelect); // TomSelect instance
    console.log(event.detail.options); // Options used to initialize TomSelect
  }
}

In my ./webpack.config.js I have only enabled stimulus bridge, and added main app.js:

Encore
 ...
    .addEntry('app', './assets/js/app.js')
    .enableStimulusBridge('./assets/controllers.json')

In my ./assets/js/app.js

import { startStimulusApp } from '@symfony/stimulus-bridge';

export const app = startStimulusApp(require.context(
  '@symfony/stimulus-bridge/lazy-controller-loader!./../controllers/',
  true,
  /\.[jt]sx?$/
));

The logic of autocomplete is working fine but I cant find a way to modify TomSelect instance - seems like the custom-autocomplete controllers is not loaded/found as there are no logs in the console.

I can see the controller in ./public/build directory after I made

bin/console assets:install
yarn install
yarn build
bin/console cache:clear
yarn watch 

In my composer json there are new lines;

    "@hotwired/stimulus": "^3.0.0",
    "@symfony/stimulus-bridge": "^3.2.0",
    "@symfony/stimulus-bundle": "file:vendor/symfony/stimulus-bundle/assets",
    "@symfony/ux-autocomplete": "file:vendor/symfony/ux-autocomplete/assets",
    "tom-select": "^2.2.2",

In yarn.lock :

"@symfony/stimulus-bridge@^3.2.0":
  version "3.2.2"
  resolved "https://registry.yarnpkg.com/@symfony/stimulus-bridge/-/stimulus-bridge-3.2.2.tgz#afc1918f82d78cb2b6e299285c54094aa7f53696"
  integrity sha512-kIaUEGPXW7g14zsHkIvQWw8cmfCdXSqsEQx18fuHPBb+R0h8nYPyY+e9uVtTuHlE2wHwAjrJoc6YBBK4a7CpKA==
  dependencies:
    "@hotwired/stimulus-webpack-helpers" "^1.0.1"
    "@types/webpack-env" "^1.16.4"
    acorn "^8.0.5"
    loader-utils "^2.0.0"
    schema-utils "^3.0.0"

"@symfony/stimulus-bundle@file:vendor/symfony/stimulus-bundle/assets":
  version "1.0.0"

"@symfony/ux-autocomplete@file:vendor/symfony/ux-autocomplete/assets":
  version "1.0.0"

"@hotwired/stimulus-webpack-helpers@^1.0.1":
  version "1.0.1"
  resolved "https://registry.yarnpkg.com/@hotwired/stimulus-webpack-helpers/-/stimulus-webpack-helpers-1.0.1.tgz#4cd74487adeca576c9865ac2b9fe5cb20cef16dd"
  integrity sha512-wa/zupVG0eWxRYJjC1IiPBdt3Lruv0RqGN+/DTMmUWUyMAEB27KXmVY6a8YpUVTM7QwVuaLNGW4EqDgrS2upXQ==

"@hotwired/stimulus@^3.0.0":
  version "3.2.2"
  resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.2.tgz#071aab59c600fed95b97939e605ff261a4251608"
  integrity sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==


tom-select@^2.2.2:
  version "2.3.1"
  resolved "https://registry.yarnpkg.com/tom-select/-/tom-select-2.3.1.tgz#df338d9082874cd0bceb3bee87ed0184447c47f1"
  integrity sha512-QS4vnOcB6StNGqX4sGboGXL2fkhBF2gIBB+8Hwv30FZXYPn0CyYO8kkdATRvwfCTThxiR4WcXwKJZ3cOmtI9eg==
  dependencies:
    "@orchidjs/sifter" "^1.0.3"
    "@orchidjs/unicode-variants" "^1.0.4"

3
  • 1
    I understand that you try to modify the options in the custom-autocomplete_controller and indeed, it should work this way. Anyway, the documentation suggest that you can modify the options from the Form field using tom_select_options ==> symfony.com/bundles/ux-autocomplete/current/… Can you give it a try ? Commented Dec 14, 2023 at 10:50
  • I am able to pass tom_select_options like 'tom_select_options' => [ 'maxItems' => 2, ], But as far as I see I could only trigger additional parameters like checkbox near every item from the custom controller.js But I need to modify tomSelect Render Templates Commented Dec 14, 2023 at 15:45
  • Also in rendered element there is data-controller="custom-autocomplete symfony--ux-autocomplete--autocomplete" But If i remove symfony--ux-autocomplete--autocomplete and leave just custom-autocomplete its not working - I believe I'm missing this controller from being loaded by stimulus Commented Dec 14, 2023 at 15:54

2 Answers 2

0

I have removed node-modules directory along with vendor - run composer install again.

I made sure that in composer.lock there were only 2 new items:

"name": "symfony/ux-autocomplete",
...
"name": "symfony/stimulus-bundle",

After this hard reset I could see the proper logs in the console coming from custom-autocomplete_controller.js

Then in _onPreConnect function I could modify TomSelect options

_onPreConnect(event) {
    // TomSelect has not been initialized - options can be changed
    let options = event.detail.options;

    options.render = {
      option: function(data, escape) {
        return '<div>' + escape(data.text) + '</div>';
      },
    };

    options.plugins.checkbox_options = {};
    options.plugins.clear_button = {};
    delete options.plugins.remove_button;
}

I still dont know if the styling I made was done in proper way but I have just added separate stylesheet for tomSelect that I later import in main style.scss

@import 'components/tomSelect';

Anyway - that works OK.

Sign up to request clarification or add additional context in comments.

Comments

0

According to documentation you should remove your/* stimulusFetch: 'lazy' */

The extending controller should be loaded eagerly (remove /* stimulusFetch: 'lazy' */), so it can listen to events dispatched by the original controller.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.