0

I am a beginner in JQuery/Javascript, so I appreciate any help in advance.

I have two scripts/tasks. Using JQuery. the first script parses a file and report its contents in table form. The goal of the second script is to run an analysis and display results in a separate table. The first task is successful, however, for the second task, instead of populating the second table, the data appends to the first table. What am I missing here?

file.html

<section id='results'>
  <p><span id='program'>no</span> program used.</p>
  <p><span id='match_count'>0</span> match(es) found.</p>
  <button name="resubmit" id="resubmit" type="submit">Save selected results</button>
  <table>
    <thead>
      <tr>
        <td>Save?</td>
        <td>DB</td>
        <td>Accession</td>
        <td>Description</td>
        <td>Score</td>
        <td>E-value</td>
        <td>Start</td>
        <td>Stop</td>
      </tr>
    </thead>
    <tbody>
      <!-- this will be filled in by javascript when there are results -->
    </tbody>
  </table>
</section>

<section id='dbresults'>
  <p><span id='db_count'>0</span> match(es) found.</p>
  <table>
    <thead>
      <tr>
        <td>Accession</td>
        <td>Description</td>
        <td>Structural</td>
      </tr>
    </thead>
    <tbody>
      <!-- this will be filled in by javascript when there are results -->
    </tbody>
  </table>

file.js

function processJSON( data ) {
// set the span that lists the match count
$('#match_count').text( data.match_count );
// set the span that lists the program used
$('#program').text( data.program );
var next_row_num = 1;
// iterate over each match and add a row to the result table for each
$.each( data.matches, function(i, item) {
        var this_row_id = 'result_row_' + next_row_num++;
        $('<tr/>', { "id" : this_row_id } ).appendTo('tbody');
        $('<td/>', { "text" : item.database } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.accession } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.description } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.score } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.evalue } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.start } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.stop } ).appendTo('#' + this_row_id);
    });
$('#results').show();
}

function processJSON_db( data ) {
$('#db_count').text( data.db_count );
var next_row_num = 1;
$.each( data.dbmatches, function(i, item) {
        var this_row_id = 'result_row_' + next_row_num++;
        $('<tr/>', { "id" : this_row_id } ).appendTo('tbody');
        $('<td/>', { "text" : item.accession } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.description } ).appendTo('#' + this_row_id);
        $('<td/>', { "text" : item.structural } ).appendTo('#' + this_row_id);
    });
$('#dbresults').show();
}
3
  • 2
    If you create your html as strings and append everything at once (after the loop) you can improve speed by like 1000%. Commented May 6, 2013 at 23:49
  • I would totally do that if it wasn't for several AJAX calls for several for data analysis. Using JQuery makes it so much more organized for me. Commented May 6, 2013 at 23:50
  • 1
    I'm not saying to get rid of jQuery, just to append all at once as a big string. It doesn't seem like you really need to create 8 jQuery objects on each iteration, you can do this as well and it's totally readable: html += '<td>'+ item.database +'</td>' Commented May 6, 2013 at 23:53

3 Answers 3

1

You can fix this by using a more specific selector in your appendTo calls, with your current html this would suffice...

For the first task:

$('<tr/>', { "id" : this_row_id } ).appendTo('#results tbody');

and for the second task:

$('<tr/>', { "id" : this_row_id } ).appendTo('#dbresults tbody');

There are a lot of improvements you could make to this but those simple changes should fix your immediate problem.

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

3 Comments

Ah, thought I had to append it together #dbresults.tbody ; appreciate the clarification.
#dbresults.tbody means "elements with an id of dbresults and a class of tbody". You need a space to select descendants and if you want to select tag names you don't use a dot, that's used for classes.
Ah gotcha. Coming from scripting in Perl, this is quite a learning experience. Thanks for the clarification.
1

IDs have to be unique. But both of your functions are creating rows with IDs result_row_<row_number>. In the second function, change it to:

var this_row_id = 'dbresult_row_' + next_row_num++;

The other problem is that you're not specifying which table to append the table to.

.appendTo('tbody')

selects the first table in the DOM, you need to identify it:

.appendTo('#dbresults tbody')

Even better, don't bother assigning IDs to the rows. You can do:

$('<tr/>').append('<td/>', { text: item.accession } )
          .append('<td/>', { text: item.description } )
          .append('<td/>', { text: item.structural } )
          .appendTo('#dbresults tbody');

3 Comments

Ah, I missed the space. Thought I had to append it #dbresults.tbody; appreciate the short hand alternative.
You don't have #dbresults.tbody in your code, you just have tbody. I think you need to go reread a tutorial on CSS selectors.
I took it out because it didn't work. But yea, I have a lot of learning to do.
0

You have ambiguous row ids. IDs always have to be unique. If you must use common name between rows of two tables use class or else you have use a different row id.

Here are the illustration of both methods.

Using Unique ID:

var this_row_id = 'table_2_result_row_' + next_row_num++;

Differentiate your row id like above

Class:

$.each( data.dbmatches, function(i, item) {
    var this_row_id = 'result_row_' + next_row_num++;
    $('<tr/>', { "class" : this_row_id } ).appendTo('tbody');
    $('<td/>', { "text" : item.accession } ).appendTo('#tableid .' + this_row_id);
    $('<td/>', { "text" : item.description } ).appendTo('#tableid .' + this_row_id);
    $('<td/>', { "text" : item.structural } ).appendTo('#tableid .' + this_row_id);
});

or Choose to use class names instead

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.