Skip to content

Instantly share code, notes, and snippets.

@vapvarun
Created August 29, 2025 19:41
Show Gist options
  • Select an option

  • Save vapvarun/358f093fccacd06e124ed5ef413ba688 to your computer and use it in GitHub Desktop.

Select an option

Save vapvarun/358f093fccacd06e124ed5ef413ba688 to your computer and use it in GitHub Desktop.

Dokan Downloadable File Picker Fix

This snippet fixes a long-standing issue in Dokan Pro vendor dashboards where clicking “Choose file” for downloadable products fails on the first attempt (the media modal opens but does not populate _wc_file_urls[] and _wc_file_names[] inputs).

✅ Problem

  • Vendors go to Products → Add/Edit → Downloadable files.
  • Clicking Choose file opens the WordPress Media Library.
  • On the first attempt, the chosen file does not populate the input fields.
  • On the second attempt, it suddenly works.

🔧 Solution

This snippet:

  • Creates a fresh wp.media frame every click (prevents stale state).
  • Uses stopPropagation to stop Dokan’s internal click handler from interfering.
  • Writes values twice (immediately and after 150ms) to beat race conditions with other scripts.
  • Removes all debug logs for production use.

🛠 Usage

  • Add wbcom-dokan-download-picker-clean.php via the Code Snippets plugin (front-end)
    or include it in a small site plugin.
  • No configuration required.

⚠️ Notes

  • Requires WordPress media modal (wp_enqueue_media).
  • If inputs still get cleared after saving, check for Dokan/WooCommerce sanitizers that strip URLs.
  • If your site uses a strict Content-Security-Policy, enqueue this as an external .js file instead of inline.

Author: Wbcom Designs
License: GPLv2 or later

<?php
/**
* WBCom — Dokan Downloadable File Picker (Clean, Race-proof)
*
* Fixes the vendor front-end “Choose file” button not populating
* `_wc_file_urls[]` / `_wc_file_names[]` on first attempt.
*
* - Creates a fresh wp.media frame on every click (avoids stale state)
* - Stops propagation to beat conflicting handlers
* - Double-sets value (immediate + slight delay) to win race conditions
* - No console logs (production clean)
*
* Usage: Add via Code Snippets (front-end) or a site plugin.
*/
if (!defined('ABSPATH')) exit;
function wbcom_dokan_download_picker_clean() {
if ( is_admin() ) return;
if ( function_exists('wp_enqueue_media') ) {
wp_enqueue_media();
}
$lines = array(
'(function(){',
' function fillInput(el, val){',
' if(!el) return;',
' el.value = val || "";',
' el.dispatchEvent(new Event("input",{bubbles:true}));',
' el.dispatchEvent(new Event("change",{bubbles:true}));',
' if (window.jQuery) { jQuery(el).trigger("input").trigger("change"); }',
' }',
'',
' function handleClick(e){',
' var a = e.target;',
' while(a && a.nodeType===1 && a.tagName!=="A"){ a = a.parentNode; }',
' if(!a || a.tagName!=="A" || !a.classList.contains("upload_file_button")) return;',
' e.preventDefault();',
' e.stopPropagation();',
' if (e.stopImmediatePropagation) e.stopImmediatePropagation();',
'',
' if (typeof wp==="undefined" || !wp.media){',
' alert("Media Library not available (wp.media missing).");',
' return;',
' }',
'',
' var row = a.closest("tr") || document;',
' var url = row.querySelector(\'input.wc_file_url[name="_wc_file_urls[]"]\');',
' var name = row.querySelector(\'input[name="_wc_file_names[]"]\');',
'',
' var frame = wp.media({',
' title: a.getAttribute("data-choose") || "Choose file",',
' button: { text: a.getAttribute("data-update") || "Insert file URL" },',
' multiple: false',
' });',
'',
' frame.on("open", function(){',
' try {',
' var st = frame.state && frame.state();',
' if(st && st.get && st.get("selection")) st.get("selection").reset();',
' } catch(_){}',
' });',
'',
' frame.on("select", function(){',
' var sel = frame.state().get("selection");',
' var file = sel && sel.first ? sel.first().toJSON() : null;',
' if(!file) return;',
' fillInput(url, file.url || "");',
' if (name && !name.value) fillInput(name, file.title || file.filename || "");',
' setTimeout(function(){',
' fillInput(url, file.url || "");',
' if (name && !name.value) fillInput(name, file.title || file.filename || "");',
' }, 150);',
' });',
'',
' frame.open();',
' }',
'',
' document.addEventListener("click", handleClick, true);',
'})();'
);
$js = implode("\n", $lines);
wp_enqueue_script('jquery');
wp_add_inline_script('jquery', $js, 'after');
}
add_action('wp_enqueue_scripts', 'wbcom_dokan_download_picker_clean', 5);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment