Support

Account

Home Forums Backend Issues (wp-admin) ACF Javascript API – Dynamically Update select2 Field Options

Solving

ACF Javascript API – Dynamically Update select2 Field Options

  • How can I use the ACF Javascript API to dynamically update a select2 field’s options after the edit page has already loaded? I have effectively updated the options on the select2_args filter, (ie, making certain options disabled). But when I try to do the same thing on the ‘load’ or a ‘show_field’ action by looping through a getFields array, I don’t see the live effect on the select options.

  • I don’t think you can do that directly with the ACF API. You need to target the .select2() object of the field…. and I don’t know how to do that.

    I found this which indicates that this is not technically possible in Select2 itself but there appears to be several work-a-rounds https://github.com/select2/select2/issues/2830

  • Yeah, that seems pretty messy. I don’t know that it’s a requirement, however, that this is a select2 select field. I just started from that angle. Assuming I just have a normal select field (ie, didn’t toggle ‘Stylized UI’ on the field), could I use the ACF JS API to dynamically change/add/delete options?

  • Actually, no, there’s nothing in the API that I’m aware of that will let you update the options in the select field. You’d still need to do it manually. The only way I’ve found to do this is to destroy all of the existing options and rebuild them every time. You can see an example of this here https://github.com/Hube2/acf-dynamic-ajax-select-example/blob/master/dynamic-select-example/dynamic-select-on-select.js in the “update_cities_on_state_change” function

  • I can give this a go. Thanks for the link. For as much as the ACF API can handle, I’m kind of surprised it doesn’t have built in field option editing. Seems like an instinctual use, especially since the conditional logic parts are philosophically the same.

  • Honestly, it does, but if it’s in there I can’t find it.

  • Did this in my tiny lib where I can dynamicaly populate ACF select list with the content of other ACF selected items.

    Feel free to check the code at https://github.com/chdenat/acf-xtend !

    The idea is to get the select associated to any select field and manage its content accordingly.

  • If anyone is interested in a simple fix to this other than @christian-denatorange-fr ‘s, I found a useful hook in the ACF JS API:

    https://www.advancedcustomfields.com/resources/javascript-api/#actions-select2_init

    Here, the configuration args that were passed to select2() in the initialization process are passed to the hook. This allows you to store them in order to re-use them when you need to re-initialize the field.

    Here’s how I modify the html of dropdown items for example:

    acf.addAction('select2_init', function( $select, args, settings, field ){
                    console.log("Select2 initialized with args: ", args);
                    args['templateResult'] = function (state) {
                        if (!state.id) {
                            return state.text;
                        } else {
                            //Note that this html will not be escaped further on. If you need to escape, do it here!
                            let $state = "<div class='item'>" + state.text + "<span class='label'>Add</span></div>";
                            return jQuery($state);
                        }
                    };
                    //Reinit
                    $select.select2(args);
                });
  • The hook acf.addAction('select2_init', function( $select, args, settings, field ){ is perfect and it would allow me to assign the correct language settings to all fields by using args['language'] = 'xx'; and by integrating this

    $.fn.select2.amd.define('select2/i18n/xx',[],function () {
      return {
        errorLoading: function () {
          return acf.__('the results could not be loaded.');
        },
        inputTooLong: function (args) {
          var overChars = args.input.length - args.maximum;
    
          var message = acf.__('please delete') + ' ' + overChars + ' ' + acf.__('character');
    
          if (overChars != 1) {
            message += 's';
          }
    
          return message;
        },
        inputTooShort: function (args) {
          var remainingChars = args.minimum - args.input.length;
    
          var message = acf.__('please enter') + ' ' + remainingChars + ' ' + acf.__('or more characters');
    
          return message;
        },
        loadingMore: function () {
          return acf.__('loading more results…');
        },
        maximumSelected: function (args) {
          var message = acf.__('you can only select') + ' ' + args.maximum + ' ' + acf.__('item');
    
          if (args.maximum != 1) {
            message += 's';
          }
    
          return message;
        },
        noResults: function () {
          return acf.__('no results found');
        },
        searching: function () {
          return acf.__('searching...');
        },
        removeAllItems: function () {
          return acf.__('remove all items');
        },
        removeItem: function () {
          return acf.__('remove item');
        },
        search: function() {
          return acf.__('search');
        }
      };
    });

    but the new problem is that now all select2 fields have more hight than before – it seems that they lost the styling…….

  • I found a “more easy” solution for the translation problem of select 2 without using acf.addAction('select2_init'.

    I changed:

    $.fn.select2.amd.define('select2/i18n/xx',[],function () {

    to this:

    $.fn.select2.amd.define('select2/i18n/' + your-var-array.your-locale-2-char-languange,[],function () {

    and now it works perfect by using the acf.__('no results found');-function and pulling the right translations direct from my plugin mo/po files.

  • I forgot that you have to define the associated translations via normal PHP with:

    		acf_localize_text(array(
    			'the results could not be loaded.'	=> _x( 'The results could not be loaded.', 'Select2', 'picture-frame' ),
    			'please delete'						=> _x( 'Please delete', 'Select2', 'picture-frame' ),
    			'character'							=> _x( 'character', 'Select2', 'picture-frame' ),
    			'please enter'						=> _x( 'Please enter', 'Select2', 'picture-frame' ),
    			'or more characters'				=> _x( 'or more characters', 'Select2', 'picture-frame' ),
    			'loading more results…'				=> _x( 'Loading more results…', 'Select2', 'picture-frame' ),
    			'you can only select'				=> _x( 'You can only select', 'Select2', 'picture-frame' ),
    			'item'								=> _x( 'item', 'Select2', 'picture-frame' ),
    			'no results found'					=> _x( 'No results found', 'Select2', 'picture-frame' ),
    			'searching...'						=> _x( 'Searching...', 'Select2', 'picture-frame' ),
    			'remove all items'					=> _x( 'Remove all items', 'Select2', 'picture-frame' ),
    			'remove item'						=> _x( 'Remove item', 'Select2', 'picture-frame' ),
    			'search'							=> _x( 'Search', 'Select2', 'picture-frame' ),
    		));
Viewing 11 posts - 1 through 11 (of 11 total)

The topic ‘ACF Javascript API – Dynamically Update select2 Field Options’ is closed to new replies.