0

Context

I'm building a WordPress Theme Template and am trying to pass an array of data from a Advanced Custom Fields > Repeater Field, using PHP and core WordPress functions, to a JavaScript / HTML5 pie chart.

The Problem

I don't know how to pass the PHP data to JS in a format JS understands.

The Questions

I'm not confident I'm asking the questions correctly, or thinking about the problem correctly. For example, I believe I can use JS to communicate directly with the database. But here's what I think the questions are:

  • How do you pass a PHP array outside of a loop and into a format readable in JS?
  • What are some links to training materials or courses on the subject?

Code

Here is my code:

<?php
if( have_rows('tpc_psmr_referrer') ):
  while ( have_rows('tpc_psmr_referrer') ) : the_row();
        $tpc_psmr_referrer_type = get_sub_field('tpc_psmr_referrer_type');
        $tpc_psmr_referrer_platform = get_sub_field('tpc_psmr_referrer_type_platform'); // This needs to get passed as an array to the JS below.
  endwhile;
endif;
?>

<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);

function drawChart() {

  var data1 = google.visualization.arrayToDataTable([
    ['Task', 'Hours per Day'],
    ['Work',     11],
    ['Eat',      2], // This is where the PHP array needs to be output.
    ['Commute',  2],
    ['Watch TV', 2],
    ['Sleep',    7]
  ]);

  var options = {
    title: 'Revenue'
  };

  var chart1 = new google.visualization.PieChart(document.getElementById('piechart1'));

  chart1.draw(data1, options);

  var data2 = google.visualization.arrayToDataTable([
    ['Task', 'Hours per Day'],
    ['Work',     11],
    ['Eat',      2],
    ['Commute',  2],
    ['Watch TV', 2],
    ['Sleep',    7]
  ]);

  var options = {
    title: 'Budget'
  };

  var chart2 = new google.visualization.PieChart(document.getElementById('piechart2'));

  chart2.draw(data2, options);
}
</script>
7
  • Are you going to make an ajax request to your php from javascript? Commented May 7, 2018 at 21:56
  • use data-attributes and output the PHP variable to it (and json_encode it - php.net/manual/en/function.json-encode.php). You can then retrieve from JS. developer.mozilla.org/en-US/docs/Learn/HTML/Howto/… Commented May 7, 2018 at 21:57
  • 1
    @BenDubuisson That's one way to do it, but I'd argue to rather put the JSON in an invisible element to avoid any chance of XSS ( owasp.org/index.php/… ) Commented May 7, 2018 at 22:11
  • @JakubJudas an invisible element does not prevent from XSS Commented May 7, 2018 at 22:13
  • @BenDubuisson true, but it does make escaping more foolproof (example: a beginner could use single quotes in html but escape using htmlentities with default settings). But maybe I'm paranoid and I'm definitely off topic so I'll stop now. Commented May 7, 2018 at 22:28

4 Answers 4

0

WordPress has a function called wp_localize_script. It allows you to pass an array to your script and then access it in your JS as an object.
For example:

wp_localize_script( 'your_script', 'your_script_data',
    array( 
        'ajax_url' => admin_url( 'admin-ajax.php' ),
        'var_1' => 'value 1',
        'var_2' => 'value 2',
    )
);

Then somewhere in your JS

alert(your_script_data.var_1)

will display value 1

P.S. ajax_url contains and URL to make your AJAX calls in case you need that too. Here is some explanation on that.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this seems like it could work but a couple clarifying questions: The docs state the model for wp_localize_script are wp_localize_script( string $handle, string $object_name, array $l10n ) but your model suggests handle to become my script path? And localization be my array. So it seems like that would output an error.
@SpencerHill that's exactly how it works. There won't be any error. Handle is the name you gave your script when you enqueued it (1st parameter of wp_enqueue_script) and yes, localization is in fact your array.
0

I think you need something like this:

<?php
$php_var = [['Task', 'Hours per Day'],
    ['Work',     11],
    ['Eat',      2], 
    ['Commute',  2],
    ['Watch TV', 2],
    ['Sleep',    7]];
?>


<script type="text/javascript">
    var data = <?= json_encode($php_var, JSON_HEX_TAG) . ';' ?>   
</script>

See this PHPFiddle.

Other usefull links:

how-to-pass-variables-and-data-from-php-to-javascript

pass-a-php-array-to-a-javascript-function

2 Comments

Why did you use JSON_HEX_TAG? The docs on that state that's for replacing < and > with their unicode value.
Yes, I used JSON_HEX_TAG for security issues, because passing in a raw string to JSON encode can lead to XSS attacks. See stackoverflow.com/questions/6816787/… .
0

Look at json_encode()'ing the values in your while loop, and echoing the data structure that holds them, in the PHP script. $.ajax() request the script, and parse/appropriate the JSON returned on the front end in the success callback.

More specifically, for links to more information on the mechanisms involved in the process, look at json_encode at php.net (Example 1 is straightforward):

http://php.net/manual/en/function.json-encode.php

and the jQuery API documentation on $.ajax:

http://api.jquery.com/jquery.ajax/

SCRIPT.PHP

<?php 

  header("Content-type: application/json");

  $data_array = ['one','two','three'];
  $json = json_encode($data_array);
  echo $json;

?>

JS

$('document').ready(function() {
    $.ajax({
        type:'POST',
        url:'/the/path/to/script.php',
        dataType:'JSON',
        data:{
        },
        success:function(data){
            $.each(data,function(x,y) {
                console.log(data[x]);
            });  
        },
        error:function(jqXHR,textStatus,errorThrown){
            console.log('Could not retrieve JSON');
        }

    });
});

Comments

0
<?php $data_array = [1,2,3...]; ?>

<html>
  <div id='yellowstone' hidden>
     <?php echo json_encode($data_array); ?>
  </div>
</html>


<script>
     var array = JSON.parse(document.getElementById('yellowstone').innerHTML);
</script>

4 Comments

If you're doing that, might as well output it straight as a Javascript variable. <script> var array = <?php echo json_encode($data_array); ?>; </script>
Unnecessarily commingling the markup, js, and php using this sort of approach. It's cleaner to request the data from a dedicated php script.
@mdlanglais example?
@Frank See my answer above, I added a basic working example. You can do what you want with the values returned in the callback at that point. This way your concerns are kept separate, js in a js file, server-side code in its own script.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.