Multiple Dynamic DataTables on a Page Via WordPress Plugin
Multiple Dynamic DataTables on a Page Via WordPress Plugin
Hi all, I have a weird situation. I am writing a WordPress plugin that relies on DataTables for the creation of some nice looking dynamic tables. My current implementation works great with rendering a single table on a page, but when trying to load multiple, only the last call creates an actual DataTable. The other calls just render the $container.
I cannot provide the full code as it is making a call to a server with our credentials, so I will redact that, but it should be applicable to any output, really. I am suspecting it is because the following is called multiple times when there are multiple shortcodes:
var fieldTable = $('#stField_' + props.tournament).DataTable({
"info": false,
"paging": false,
"processing": true,
"responsive": {
details: false
},
"searching": false
});
However, I am unsure of how to change this because I rely on table.row.add
to add data to the table. I've seen examples that use a single selector to select all the tables on the page to convert them to a DataTable, but this wouldn't work in my case because I am creating them dynamically. Any suggestions are appreciated.
leaderboard-plugin:
add_action('wp_enqueue_scripts', 'my_register_scripts');
add_action('init','my_register_shortcodes');
function my_register_scripts() {
wp_register_style('datatables_css', plugins_url('/css/datatables.min.css', __FILE__));
wp_register_script('datatables_js', plugins_url('/js/datatables.min.js', __FILE__));
wp_register_script('xmlToJson', plugins_url('/js/xmlToJson.js', __FILE__));
wp_enqueue_script('jquery');
wp_enqueue_style('datatables_css');
wp_enqueue_script('datatables_js');
wp_enqueue_script('xmlToJson');
wp_register_script('my_gen_table', plugins_url('/js/generate.js', __FILE__), array('jquery'));
}
function my_register_shortcodes() {
add_shortcode('player-fields', 'my_gen_table');
}
function my_gen_table($args, $content) {
$username = $args['username'];
$password = $args['password'];
$tournament = $args['tour_id'];
$results = "REDACTED";
$container = "<table id='stField_{$tournament}' class='display responsive nowrap' width='100%'><thead><tr style='background: repeating-linear-gradient(45deg, #77d56a, #117ac9); font-weight: bold; color: white'><td>Player</td><td>City</td><td>State</td><td>Seed</td></tr></thead></table>";
$props = array('uri' => $results, 'username' => $username, 'password' => $password, 'tournament' => $tournament);
wp_enqueue_script('my_gen_table');
wp_localize_script('my_gen_table', 'props', $props);
return $container;
}
generate.js:
jQuery(document).ready(function($) {
function generate() {
$.ajax({
url: props.uri,
type: 'GET',
dataType: 'xml',
success: function (data) {
// xmlToJson converts the raw xml data to an easy to use JSON object
var jsonData = xmlToJson(data);
// Table ID is set in st_generatePlayerField
var fieldTable = $('#stField_' + props.tournament).DataTable({
"info": false,
"paging": false,
"processing": true,
"responsive": {
details: false
},
"searching": false
});
// For-each loop with Player fields
for (var i = 0; i < jsonData.Field.Player.length; i++) {
var currentPlayer = jsonData.Field.Player[i];
var _name = currentPlayer['@attributes'].player_name;
var _city = currentPlayer['@attributes'].city;
var _state = currentPlayer['@attributes'].state_cd;
var _seed = currentPlayer['@attributes'].player_seed;
fieldTable.row.add([_name, _city, _state, _seed]);
}
try {
fieldTable.draw();
} catch (error) {
console.log(error);
}
},
error: function (error) {
console.debug(error);
}
});
}
generate();
});
Answers
Let me add onto this: When I say things break, I mean that only the table created by the last my_gen_table is a DataTable table with data. None of the other calls have any data added to them, they are just the $container.
And another node, the shortcode calls are remnants of my current codebase, forgot to modify for here:
Without being able to debug the code it would be difficult to say. Are you calling the
generate()
generate function multiple times? Since ajax is synchronous you might have multiple outstanding ajax requests and when the are processed theprops.tournament
variable value is the last one generated. I'm not familiar with your environment but I would look t setting a var local to the function scope to theprops.tournament
value. Something like this:Not sure that will work but debug your page to see if the props.tournament value is what you expect it to be in the success function. Maybe pass
props
in as a parameter to generate().Kevin
Yes, I am invoking it multiple times as such:
[player-fields username="random" password="password" tour_id="1015"]
[player-fields username="random" password="password" tour_id="1016"]
I added some prints to the beginning, and it seems it's not even entering jQuery(document).ready(function($) twice, which is weirder.
That event fires once when the page is loaded and ready.
Kevin