Support

Account

Home Forums Backend Issues (wp-admin) Setting Field values using the Javascript API

Solved

Setting Field values using the Javascript API

  • I’m using Javascript to add a layout to a Flexible Content field and set values on the fields therein. Here’s the relevant bit of code:

    
    /* 
    This isn't the real data, just giving you an idea of what it looks like. 
    That is not a spread operator at the end :) 
    */
    var l = { layout: 'my_layout', data: [ 'heading' => 'My Heading Content', 'text' => 'the text', ...]};
    
    /*
    fcField is the Flexible Content field. I know this part is working correctly.
    */
    var added = fcField.add({ layout: l.layout });
    
    for (var name in l.data) {
        var key = added.find(<code>[data-name=&quot;${name}&quot;]</code>).attr('data-key');
    
        /*
        This line feels pretty clunky but I didn't see a better way to do this.
        */
        var subField = acf.getField(acf.findField(key, added));
        var val = l.data[name];
    
        /*
        This notice is appearing on all of the fields I'm targeting, exactly like I would expect
        */
        subField.showNotice({
            text: 'Set field value to “' + val + '”',
            type: 'success',
            dismiss: true
        });
    
        console.log('Set %s to %s', name, val);
    
        /*
        This doesn't seem to do anything if subField is a WYSIWYG or Image (and probably other types too)
        */
        subField.val(val);
    }
    

    This is *kinda* working. I know the subField variable is the subfield in the newly generated layout clone like I want. The field *notices* are appearing on every field, and my logs are all looking like what I would expect, but for some reason the values aren’t getting set on my WYSIWYG and Image fields. My gut tells me some kind of JS initialization is getting skipped… but I’m at a loss as to what that could be.

    Any ideas?

  • After doing more digging it seems that there’s nothing built into the api for this. So instead I had to write a bunch of code to take care of it. It’s just a start, and might not work for some field configurations (like cases where an image field returns just an id instead of an object), I’m not sure I’d paste this straight into production, but it’s a decent starting point. At the very least it could use a refactor to not be a single big, ugly function.

    
    function setFieldValue(field, value) {
        switch (field.data.type) {
            case 'repeater':
                //Clean out any row there by default
                var rows = field.$rows();
                if (rows.length > 0) {
                    field.remove(field.$rows().eq(0));
                }
    
                for (var rowIndex in value) {
                    var row = value[rowIndex];
                    var rowEl = field.add();
    
                    for (var rowName in row) {
                        var rowVal = row[rowName];
                        var repeaterSubField = acf.getField(rowEl.find('[data-name="' + rowName + '"]'));
    
                        setFieldValue(repeaterSubField, rowVal);
                    }
                }
    
                break;
    
            case 'clone':
                for (var cloneKey in value) {
                    var cloneValue = value[cloneKey];
                    var cloneSubField = acf.getField(field.$el.find('[data-name="' + cloneKey + '"]'));
    
                    setFieldValue(cloneSubField, cloneValue);
                }
                break;
    
            case 'image':
            case 'file':
                var atts = {};
                for (var k in value) {
                    atts[k] = value[k];
                }
                value.attributes = atts;
                field.render(value);
                break;
    
            case 'wysiwyg':
                var $wrap = field.$control();
                if ($wrap.hasClass('delay')) {
                    $wrap.removeClass('delay');
                    $wrap.find('.acf-editor-toolbar').remove();
                    field.initializeEditor();
                }
    
                var editorWrap = field.$el.find('.wp-editor-wrap');
                if (editorWrap.length > 0) {
                    var editorID = editorWrap.eq(0).attr('id').replace(/^wp-/, '').replace(/-wrap$/, '')
                    window.tinyMCE.get(editorID).setContent(value);
                }
    
                break;
    
            case 'oembed':
                var url = $(value).attr('src').split('?').shift();
    
                field.$search().val(url);
                field.val(url);
                field.$el.find('.canvas-media').html(value);
    
                break;
    
            case 'gallery':
                for (var attIndex in value) {
                    var att = value[attIndex];
                    field.appendAttachment(att, attIndex);
                }
    
                break;
    
            case 'checkbox':
                field.$inputs().each(function (i, checkbox) {
                    if (value.indexOf(checkbox.value) >= 0) {
                        checkbox.setAttribute('checked', 'checked');
                    }
                });
                break;
    
            case 'radio':
                field.$control().find('[value="' + value + '"]').prop('checked', 'checked');
                break;
    
            case 'button_group':
                field.val(value);
                field.$el.find('input[value="' + value + '"]').prop('checked', 'checked').trigger('click');
                break;
    
            case 'true_false':
                if (value) {
                    field.$input().prop('checked', 'checked');
                }
                break;
    
            case 'post_object':
                setSelect2FieldValue(field, value.ID, value.post_title);
                break;
    
            case 'page_link':
                setSelect2FieldValue(field, value, value);
                break;
    
            case 'relationship':
                var loadCheck = setInterval(function () {
                    if (!field.get('loading')) {
                        clearInterval(loadCheck);
                        for (var relIndex in value) {
                            var post = value[relIndex];
                            field.$el.find('[data-id=' + post.ID + ']').trigger('click');
                        }
                    }
                }, 100);
    
                break;
    
            case 'taxonomy':
                for (var taxIndex in value) {
                    field.$el
                        .find('[value=' + value[taxIndex] + ']')
                        .prop('checked', 'checked');
                }
                break;
    
            case 'user':
                var userLabel = value.user_nicename + ' (' + value.nickname + ')';
                setSelect2FieldValue(field, value.ID, userLabel);
                break;
    
            case 'google_map':
                break;
    
            case 'date_picker':
            case 'date_time_picker':
            case 'time_picker':
                field.val(value);
                field.$el.find('[type=text]').val(value);
                break;
    
            default:
                field.val(value);
        }
    }
    
Viewing 2 posts - 1 through 2 (of 2 total)

The topic ‘Setting Field values using the Javascript API’ is closed to new replies.