0

I'm preparing plugin and I have trouble to call (and return) javascript from each (same) shortcode in one wp page/post. Javascript returns values only to last shortcode in page.

PHP code here:

add_shortcode( 'ada_chart', 'ada_chart_stranka' ); 
function ada_chart_stranka ($atts) {            
    $a = shortcode_atts( array(
        'cid' => '',
    ), $atts );     
    $cislo_chart = $a['cid'];                
    wp_register_script( 'ada_chart_handle', plugins_url().'/ada-chart/js/ada-chart1.js' );
    $ada_sheet_params = array(
        'ada_ch_cislo'      =>  $cislo_chart,
    );  
    wp_localize_script( 'ada_chart_handle', 'ada_ch', $ada_sheet_params );
    wp_enqueue_script( 'ada_chart_handle');     
    return 'atribut: '.$cislo_chart;        
}

and JS script here:

    var cisloChart = ada_ch.ada_ch_cislo;
document.getElementById('chart_div'+cisloChart).innerHTML = 'Cislo: ' + cisloChart;

Can anybody hepl me? Thanks

2 Answers 2

0

A script should be enqueued and localized only one time per page; so, what you describe is the correct behaviour. I think you are confusing localizing a script with printing inline JavaScript. Also, enqueuing and localizing should be done in wp_enqueue_scripts action.

You need to think in a different approach.

For example (just a example), you could use dataset API:

First, enqueue the script:

add_action( 'wp_enqueue_scripts', 'cyb_enqueue_scripts' );
function cyb_enqueue_scripts() {
    wp_enqueue_script( 'ada_chart_handle', plugins_url().'/ada-chart/js/ada-chart1.js' );
}

Second, use the data atribute to include the cid value:

add_shortcode( 'ada_chart', 'ada_chart_stranka' ); 
function ada_chart_stranka ($atts) {            
    $a = shortcode_atts( array(
        'cid' => '',
    ), $atts );     

    $cislo_chart = $a['cid'];                

    return '<div data-cid="' . $cislo_chart . '"></div>';        
}

Third, write JavaScript that use dataset API to read the data-cid attribute and perform the desired action:

// Get all elements with data-cid attribute
var a = document.querySelectorAll('[data-cid]');

// Loop over all selected elements
for (var i in a) if (a.hasOwnProperty(i)) {

    // Get the value of data-cid attribute for current element in the loop
    var cid = a[i].getAttribute('data-cid');

    // Do something with the cid value

}
2
  • Technically, there's nothing really limiting you to enqueueing and localizing scripts only within wp_enqueue_scripts. If you're outputting on wp_footer, calling those anywhere in between is still valid.
    – Milo
    Commented Dec 23, 2016 at 19:12
  • Right, that is why I said "should be" and not "have to be"; but really, in almost every case you want to enqueue in wp_enqueue_scripts, specially if the scripts have dependencies, even if you want to output on footer.
    – cybmeta
    Commented Dec 23, 2016 at 20:14
0

Cybmeta,

thanks a lot for your answer. Your idea saved me a lot of sleepless nights )

I tried to use your solution but there was some trouble. The browser has showed empty divs, without signalisation any error in Javascript.

But finally I have combined your and my solution that working very well. Seems that wp_enqueue_scripts is better to use inside the shortcode.

Final solution:

PHP script:

    add_shortcode( 'ada_chart', 'ada_chart_stranka' ); 

function ada_chart_stranka ($atts) {            
    $a = shortcode_atts( array(
        'cid' => '',
    ), $atts );   

    $cislo_chart = $a['cid'];                
   wp_enqueue_script( 'ada_chart_handle', plugins_url().'/ada-chart/js/ada-chart.js');        
    return 'atribut: '.$cislo_chart.'<br><div id="chart_div'.$cislo_chart.'" data-cid="' . $cislo_chart . '" style="height: 150px; background: #d5d5d5"></div>';       
}

Javascript:

    var a = document.querySelectorAll('[data-cid]');
    for (var i in a) if (a.hasOwnProperty(i)) {

      // Get the value of data-cid attribute for current element in the loop
      var cid = a[i].getAttribute('data-cid');

      'Cislo: ' + cid;

      // Do something with the cid value
      document.getElementById('chart_div'+cid).innerHTML = 'Cislo: ' + cid;
    }
1
  • "wp_enqueue_script() is better to use inside the shortcode": definitely not. The issue must be some where else, very probably related with the JavaScript code (as I sais in the answer, I write jsut a proof of concept example). I don't know, maybe it needs to wait until DOM is ready before it tries to find elements. But that is a very different issue. Anyway, glad you found a working code.
    – cybmeta
    Commented Dec 26, 2016 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.