How to Automate ACF Data Entry in the Browser Console

How to Automate ACF Data Entry in the Browser Console

Codeable.io

Filling 12 question-and-answer fields by hand across dozens of products is slow and error-prone. For small or medium batches, WP All Import, CSV pipelines and WP-CLI scripts are overkill. A short JavaScript function pasted into the browser console does the job in seconds.

This guide shows a reusable pattern for filling ACF text fields and WYSIWYG editors directly in the WordPress admin.

When this approach makes sense

  • Per-post content such as FAQs, spec tables or short descriptions
  • One-off or occasional batches, not recurring imports
  • Content you’ve already drafted (or generated) in a structured format
  • Situations where you want to review the result before clicking Update

For thousands of records or scheduled syncs, use a proper importer or update_field() via WP-CLI instead.

The pattern

Assume an ACF field group with fields named question_1 to question_12 (text) and answer_1 to answer_12 (WYSIWYG). ACF renders each field in a wrapper with a data-name attribute, which makes it easy to target.

function fillFaqs(pairs){
  const setInput=(el,v)=>{
    const s=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set;
    s.call(el,v);
    el.dispatchEvent(new Event('input',{bubbles:true}));
    el.dispatchEvent(new Event('change',{bubbles:true}));
  };
  const setEditor=(ta,html)=>{
    const ed=window.tinymce&&tinymce.get(ta.id);
    if(ed){ed.setContent(html);ed.save();}
    ta.value=html;
  };
  const esc=t=>t.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  const log=[];
  for(let i=1;i<=12;i++){
    const q=document.querySelector(`.acf-field[data-name="question_${i}"] input`);
    const a=document.querySelector(`.acf-field[data-name="answer_${i}"] textarea`);
    if(!q||!a){log.push(`slot ${i}: FIELD NOT FOUND`);continue;}
    const p=pairs[i-1];
    setInput(q,p?p[0]:'');
    setEditor(a,p?`<p>${esc(p[1])}</p>`:'');
    log.push(`slot ${i}: ${p?'set':'cleared'}`);
  }
  console.log(log.join('\n'));
}

Then call it with an array of [question, answer] pairs:

fillFaqs([
  ["What is this product used for?", "It provides a safe connection point for..."],
  ["What are the ratings?", "Nominal current 250 A, maximum test voltage 2 kV."]
]);

How it works

1. Target fields by data-name. Selectors like .acf-field[data-name="question_1"] input are stable across ACF versions and don’t depend on generated IDs.

2. Use the native value setter. Assigning el.value = ... can bypass listeners that track value changes. Calling the prototype’s setter directly and then dispatching input and change events makes ACF and any conditional-logic scripts see the change as if you had typed it.

3. Handle TinyMCE separately. WYSIWYG fields are a hidden <textarea> plus a TinyMCE instance. Setting only the textarea leaves the visual editor stale, and it can overwrite your value on save. The function calls tinymce.get(id).setContent() and save() when the editor is initialised, and always sets the textarea value as a fallback (for example when the editor is on the Text tab).

4. Escape your content. The esc() helper stops stray <, > and & in your text from breaking the markup. If you want links or lists in answers, remove it and pass trusted HTML instead.

5. Clear unused slots. If you pass 6 pairs to a 12-slot field group, slots 7 to 12 are emptied. That prevents stale content from a previous run and keeps re-runs idempotent.

6. Log the result. The per-slot log tells you immediately if a field name didn’t match, which is the most common failure.

Step-by-step workflow

  1. Open the post or product edit screen in the WordPress admin.
  2. Open DevTools (F12), go to the Console tab, and paste the function definition.
  3. Call fillFaqs([...]) with your data.
  4. Check the log, and skim the fields on screen.
  5. Click Update.

If you generate the content elsewhere (a spreadsheet, a script, an AI draft), have that step output the ready-to-paste fillFaqs([...]) call. Then each post takes about ten seconds.

Adapting it to your fields

  • Different field names: change the question_${i} and answer_${i} selectors and the loop length.
  • Other field types: for <select>, set the value and dispatch change. For true/false, set checked and dispatch change.
  • Repeater fields: click Add Row programmatically (acf.getField(...).add()), or use fixed numbered fields as above. They are simpler for a known, capped number of items.
  • Gutenberg: ACF blocks re-render in React, so target the inputs after the block is open, or use wp.data.dispatch('core/editor').editPost({meta: {...}}) for meta-backed fields.

Caveats

  • Don’t paste untrusted data. Console code runs with your admin session’s privileges.
  • Nothing is saved until you click Update. That is a feature, since it gives you a review step.
  • Lazy-loaded editors: if a field is inside a collapsed tab or accordion, TinyMCE may not be initialised yet. Open the tab first, or rely on the textarea fallback.
  • Keep a backup of the data. The console is ephemeral, so store your pairs in a file.

Conclusion

A 25-line function replaces a lot of repetitive clicking. It uses standard DOM APIs, requires no plugin, and works with any ACF field group once you swap in the right selectors. For one-off content batches, it is often the fastest route from draft to published.

Leave a Reply

Your email address will not be published. Required fields are marked *