-1

I am trying to implement a search feature which enables the user to search through this table which is being populated from a JSON from a public api.

My table:

<input type="text" id="myInput" onkeyup="searchPlayers()" placeholder="Search for player">
<table id ="player_info">
<tr>
<th>ID</th>
<th>Full Name</th>
<th>Team</th>
<th>Position</th>
<th>Current Price</th>
<th>Value Season</th>
<th>Cost Change from Start</th>
<th>Percentage selected by</th>
<th>Transfers In</th>
<th>Transfers Out</th>
<th>Total Points</th> 
<th>Points Per Game</th>
<th>Minutes</th>
<th>Goals Scored</th>
<th>Assists</th>
</tr>

Populating the table from the JSON. Iterating through the JSON file and create a new table cell for each of the keys.

request.onload = function() {
// Begin accessing JSON data here
var data = JSON.parse(this.response);

if (request.status >= 200 && request.status < 400) {

    var table = document.getElementById('player_info');

    data.elements.forEach(elements => {

    var tr = document.createElement('tr');
    tr.innerHTML = '<td>' + elements.id + '</td>' + 
        '<td>' + elements.first_name + '<p>' + '</p>' + elements.second_name + '</td>' + 
        '<td>' + elements.team_code + '</td>' + 
        '<td>' + elements.element_type + '</td>' + 
        '<td>' + elements.now_cost + '</td>' + 
        '<td>' + elements.value_season+ '</td>' + 
        '<td>' + elements.cost_change_start + '</td>' + 
        '<td>' + elements.selected_by_percent + '</td>' + 
        '<td>' + elements.transfers_in + '</td>' + 
        '<td>' + elements.transfers_out + '</td>' + 
        '<td>' + elements.total_points + '</td>' + 
        '<td>' + elements.points_per_game + '</td>' + 
        '<td>' + elements.minutes + '</td>' + 
        '<td>' + elements.goals_scored + '</td>' + 
        '<td>' + elements.assists + '</td>';

    table.appendChild(tr);
    });
}
//append_json(data);
console.log(data);
}

Search for players function

function searchPlayers() {
  // Declare variables
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("player_info");
  tr = table.getElementsByTagName("tr");

  // Loop through all table rows, and hide those who don't match the search query
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[0];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }
  }
}

Does anybody know why this is not working?

  • 1
    Is this for use with the Fantasy Premier League API? – DAustin Feb 20 '20 at 14:31
  • Yes. It is indeed – anil naraindas Feb 20 '20 at 14:33
  • 1
    I don't have my code to hand at work but if you don't get an answer by this evening I'll dig out my old script for parsing the player data. Are you doing it on the main array or on individual player jsons? It's hard to see what's going wrong by looking at the code, can you edit it with "drf" url and I can run a quick test for you – DAustin Feb 20 '20 at 14:35
  • the "drf" url does not work anymore, the new URL is https://fantasy.premierleague.com/api/bootstrap-static/ – anil naraindas Feb 20 '20 at 14:37
  • 1
    Unrelated to the issue, but related to your app. Take a look into using chart.js, its very useful for visually comparing more than 1 player's data side by side. Pie chart for Mins played with 3 sections (No. of 0 Mins played, < 60 Mins played & 60-90 mins played) was very useful for quickly comparing if a player was a regular starter or not. – DAustin Feb 20 '20 at 15:11
  • Thanks for this information. I had a quick look at chart.js and it does seem great. – anil naraindas Feb 20 '20 at 15:18

1 Answers1

0

Edit:

Using a locally downloaded copy of the data, I think your error is this line:

td = tr[i].getElementsByTagName("td")[0];

Which is targetting the PlayerId column, not the PlayerName column which should be this:

td = tr[i].getElementsByTagName("td")[1];

Seems like it works now, but your filter will need a bit of improvement to account for non-english characters like the Umlaut in Agüero. Have fun, the Fantasy API is a great way to learn a bunch of stuff for Front-End development.

Edit 2:

I changed your loop to this:

for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[1];
    if (td) {
      txtValue = td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "table-row";
      } else {
        tr[i].style.display = "none";
      }
    }
  }

I added a display type to the shown version to make sure they got updated, and also removed the || conditional from your txtValue var:

txtValue = td.innerText;

Original answer below:

Been a few seasons since I've played with the api obviously. There isn't necessarily an issue with your javascript (though your HTML table is missing thead and tbody elements), as I'm getting a CORS error:

CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

I don't have time to figure out the workaround you'll need to implement here, but this answer from a similar problem might help you get started:

No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API

You might be best off doing what my old app did, as this error is related to trying to get the data via an AJAX request from a remote resource that has the CORS No-Access thing is set by the website owners.

You can attempt to work around it with the above methods, but a better solution would be to use something like PHP or .NET (Or any other back-end language that supports CURL or some sort of HTTPGet) to download the json locally, then use AJAX to access the local .json files. Added bonus of faster response times too. I would have it cycle through the 600 or so player json files & download them to disk every hour on a timer.

DAustin
  • 371
  • 2
  • 10