Support

Account

Home Forums General Issues Does ACF have a JS API? Reply To: Does ACF have a JS API?

  • You’d have to look in the ACF js files, and I have looked. I could not find any way, for example to re-render an image field. If you look specifically at this file https://github.com/Hube2/acf-dynamic-ajax-select-example/blob/master/dynamic-fields-on-relationship/dynamic-fields-on-relationship.js you see that in order to get the image field to render I had to basically do the same thing that ACF does when an image is added to the field, here’s the bit of code that does that from that file.

    
    if (json['image']) {
    	// data-key == field key of image field
    	// put the id value into the hidden field
    	$('[data-key="field_57d9e92159b78"] input[type="hidden"]').val(json['image']['id']);
    	// put the url into the img element
    	$('[data-key="field_57d9e92159b78"] img').attr('src', json['image']['url']);
    	// set the image field to show 
    	$('[data-key="field_57d9e92159b78"]').find('.acf-image-uploader').addClass('has-value');
    }
    

    As I said, I’m working on a JS api form myself that will let me pass in an ACF field object to get and set values. Image is one of the field types that I’ve completed and this is the image field setting code from that work. If you look at the place where the image is set, it’s basically doing the same thing, because I could not figure out how to trigger ACF to re-render the image field. ACF does the same thing that I’m doing here from the value returned by the WP Media Modal. More information on what ACF is doing below.

    
    setImage: function(object, value, args) {
      // setting images are a little more work
      if (typeof(value) == 'object' && typeof(value.id) != 'undefined') {
        value = value.id;
      }
      value = parseInt(value);
      var uploader = object.closest('.acf-image-uploader');
      if (!value) {
        // clear the image
        this.setInput(object, '', args);
        object.closest('.acf-input').find('img').attr('src', '');
        if (uploader.hasClass('has-value')) {
          uploader.removeClass('has-value');
        }
        object.trigger('change');
        return;
      }
      // ajax request
      var self = this,
          data = this.o;
      data.action= 'acfField_load_image';
      data.attachment = value;
      data.size = uploader.data('preview_size');
      data.exists = [];
      
      this.request = $.ajax({
        url: acf.get('ajaxurl'),
        data: acf.prepare_for_ajax(data),
        type: 'get',
        dataType: "json",
        async: true,
        success: function(json) {
          if (!json) {
            self.setInput(object, '', args);
            object.closest('.acf-input').find('img').attr('src', '');
            if (uploader.hasClass('has-value')) {
              uploader.removeClass('has-value');
            }
            object.trigger('change');
            return;
          }
          self.setInput(object, json.id, args);
          object.closest('.acf-input').find('img').attr('src', json.src);
          if (!uploader.hasClass('has-value')) {
            uploader.addClass('has-value');
          }
          object.trigger('change');
        },
        error: function(jqXHR, textStatus, error) {
          console.log(jqXHR+' : '+textStatus+' : '+error);
        }
      });
      
      //this.setInput(object, value, args);
      //object.trigger('initialize');
    }, // end setImage
    

    If you want to see what ACF is doing, look in /advanced-custom-fields-pro/assets/js/acf-input.js

    On line ~6418 is the function add, in this function the WP media modal is opened.

    When the modal is closed ACF sets the values of the image field and the src of the image element if they are returned and then calls the render function on line ~6361, and this function basically toggles the ‘has-value’ class on the image container.

    As you can see, there isn’t any “re-rendering”. For the image field, if the field already has an image all of the needed values for the image field are set when the field is output by PHP.

    TL;DR
    If you find a better way of doing this I would really like to hear about it.