0

This is a bit tricky to explain, I'll try my best.

I have a website based on Spring that uses static HTML pages with AJAX and jQuery. I want to present some info in an HTML page that will always vary in size.

I have a table such as this: (don't mind the terrible design)

test table

So, depending on the number of countries and users returned from the API, I want to have different number of rows.

I'm currently using a jQuery function to inject the HTML code after submitting this form: enter image description here

Such as this:

$('#stats').submit((event) => {
  event.preventDefault();
  $.ajax({
      url: '/api/stats/' + $(event.currentTarget).serialize(),
      type: 'GET',
      success(msg) {
          // language=HTML
          $('#result').html(`
            <div class="container">
                <h2>Country stats:</h2>
                <div class="panel panel-group">
                    <table>
                        <thead>
                            <tr> 
                                <th>Country</th>
                                <th>Users</th>
                            </tr>
                         </thead>
                         <tbody>
                            <tr> <!-- I want to generate here the right amount of rows -->
                                <td>Test</td>
                                <td>2</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>`);
      },
      error() {
          $('#result').html("<div class='alert alert-danger lead'>ERROR</div>");
      },
  });

The response received from the API looks like this:

{
"countries":
    [{"data":xx,"users":xx},
    {"data":xx,"users":xx}],
"other data":
    [whatever]
}

And so on.

How can I render N rows if N is the size of the countries array?

Sync
  • 3,571
  • 23
  • 30
dari1495
  • 289
  • 1
  • 5
  • 18
  • 2
    Build the html? `var rows = ''; msg.countries.forEach((country) => rows += "" + country.data + "");` and then concat `rows` to your `$result`? – Blue Dec 13 '17 at 17:26
  • Okay that was easy, huh. Please post as an answer so I can accept it! – dari1495 Dec 13 '17 at 17:33

2 Answers2

3

One solution could be to build your "html" content in 3 part : the begin of your bloc, a loop for each rows according to the size of the countries array, then the end of the bloc :

$('#stats').submit((event) => {
  event.preventDefault();
  $.ajax({
  url: '/api/stats/' + $(event.currentTarget).serialize(),
  type: 'GET',
  success(msg) {
      // language=HTML

      // The begin of your html bloc
      var result = `
            <div class="container">
                <h2>Country stats:</h2>
                <div class="panel panel-group">
                    <table>
                        <thead>
                            <tr> 
                                <th>Country</th>
                                <th>Users</th>
                            </tr>
                         </thead>
                         <tbody>
                   `;

      // Just get your countries array here and loop, this can be wrong
      $.each(response.countries, function() {
          // build each row as you need
          result += '<tr>' + 
                        '<td>' + this.data + '</td>' +
                        '<td>' + this.users + '</td>' +
                     '</tr>';
      });

      // The end of your html bloc
      result += `              
                    </tbody>
                </table>
            </div>
        </div>
                `;

      $('#result').html(result);
  },
  error() {
      $('#result').html("<div class='alert alert-danger lead'>ERROR</div>");
  },
 });

Is it what your are looking for?

Mickaël Leger
  • 3,426
  • 2
  • 17
  • 36
  • Don't forget to remove the `Test2` from the end of the html bloc! – Luke Dec 13 '17 at 17:50
  • 1
    Yeah sorry I started to write it before you post your anwser but you were faster ! And ty I edited my post ;) – Mickaël Leger Dec 13 '17 at 17:51
  • 1
    I like your use of `$.each`. You might flesh out the `// your data` part to really complete the answer. – showdev Dec 13 '17 at 18:00
  • Thanks, I appreciate your edits. I tried running the code and there seem to be a couple of errors. I'd suggest using [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) to build the strings, since only quoting multiline strings throws an error in JavaScript. Also, there seems to be a missing parenthesis after the `each`. [Example here](https://jsfiddle.net/7mra6qtq/). Nice work! – showdev Dec 13 '17 at 18:35
  • @showdev : thanks for the feedback, I add the missing ");" and change the " by ' to avoid conflict with other "..." for the class name. I don't really see your point using "template literals", can you explain me a little please? (sorry I have flu, my brain is kinda slow tonight !) – Mickaël Leger Dec 13 '17 at 18:43
  • It's just that JavaScript doesn't understand strings that span multiple lines. See [Creating multiline strings in JavaScript](https://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript). Again, thanks for responding to feedback. Hope you feel better. – showdev Dec 13 '17 at 18:55
2

I would assign the rest of my HTML to a variable like so:

var html = `<div class="container">
            <h2>Country stats:</h2>
            <div class="panel panel-group">
                <table>
                    <thead>
                        <tr> 
                            <th>Country</th>
                            <th>Users</th>
                        </tr>
                     </thead>
                     <tbody>`;

Then, add your rows:

for(var i = 0; i < msg.countries.length; i++){
    html += "<tr><td>" + msg.countries[i].data + "</td><td>" + msg.countries[i].users + "</td></tr>";
}

Finally, add the end of the HTML and set it to the element:

html += `</tbody>
                </table>
            </div>
        </div>`;
$('#result').html(html);

Hope this helps!

Luke
  • 1,060
  • 8
  • 19