问题
I am using jQuery to insert rows into a table after a database insert. When the page loads the table is ordered alphabetically on a particular cell (see below). When I insert a new row using jQuery I would like to be able to insert it alphabetically also.
So for example I have a table with <tbody>
elements similar to this:
<tbody>
<tr class="docRow" bgcolor="#EFE5D3" style="font-weight: bold; font-size: 1.1em;">
<td width="25px"><a class="docEditLink docAdminFormSubmit" name="38" href="#">Edit</a></td>
<td width="20px"><input type="checkbox" class="chkDeleteDocs" name="removeDocs[]" value="38" /></td>
<td>Document A</td>
<td>Description of Document A</td>
</tr>
<tr class="docClassesRow noClasses">
<td colspan="4">
<strong>No classes are currently associated with this document.</strong>
</td>
</tr>
</tbody>
<tbody>
<tr class="docRow" bgcolor="#EFE5D3" style="font-weight: bold; font-size: 1.1em;">
<td width="25px"><a class="docEditLink docAdminFormSubmit" name="35" href="#">Edit</a></td>
<td width="20px"><input type="checkbox" class="chkDeleteDocs" name="removeDocs[]" value="35" /></td>
<td>Document B</td>
<td>Description of Document B</td>
</tr>
<tr class="docClassesRow">
<td></td>
<td width="100px" align="right"><input type="checkbox" class="chkRemoveClasses" name="removeClasses[]" value="33-35" /></td>
<td width="200px">CLASS111</td>
<td width="600px">Description of CLASS101</td>
</tr>
<tr class="docClassesRow">
<td></td>
<td width="100px" align="right"><input type="checkbox" class="chkRemoveClasses" name="removeClasses[]" value="45-35" /></td>
<td width="200px">CLASS333</td>
<td width="600px">Description of CLASS333</td>
</tr>
</tbody>
<tbody>
<tr class="docRow" bgcolor="#EFE5D3" style="font-weight: bold; font-size: 1.1em;">
<td width="25px"><a class="docEditLink docAdminFormSubmit" name="46" href="#">Edit</a></td>
<td width="20px"><input type="checkbox" class="chkDeleteDocs" name="removeDocs[]" value="46" /></td>
<td>Document D</td>
<td>Description of Document D</td>
</tr>
<tr class="docClassesRow noClasses">
<td colspan="4">
<strong>No classes are currently associated with this document.</strong>
</td>
</tr>
</tbody>
Currently, when inserting a new class row to a given document's <tbody>
I use the .append()
function, and when inserting a new document I use .after()
.
Using jQuery I want to be able to insert a class or document in alphabetical order on class number or document name (as appropriate for what's being inserted).
So for instance I want to be able to insert a new <tbody>
for Document C, or add a new class to Document B with a class number of CLASS222.
How can I do this?
UPDATE: Here's the code I currently use to insert a new class for one of the documents:
newClassesRows += $('#docsTable a[name="' + docID + '"]').closest('tr').after('<tr class="docClassesRow">' +
'<td></td>' +
'<td width="100px" align="right"><input type="checkbox" class="chkRemoveClasses" name="removeClasses[]" value="' + classID + '-' + docID + '" /></td>' +
'<td width="200px">' + classNumber + '</td>' +
'<td width="600px">' + className + '</td>' +
'</tr>');
As you can see, the correct document is found with $('#docsTable a[name="' + docID + '"]').closest('tr')
, so I would need to look through the selected row's third td element, check the text and somehow determine where the variable classNumber fits alphabetically in with the other classNumbers.
回答1:
Here's an approach that might work for you (untested and off the top of my head). This applies only to the main header "document" rows, but if it works for you, I'm sure you can adapt the idea to the inner rows as well.
First, a convenience function to build a "document" row fitting your pattern above. Presumably you have something already to generate these rows:
var makeDocRow = function(name, description) {
return $('<tbody><tr class="docRow" bgcolor="#EFE5D3" style="font-weight: bold; font-size: 1.1em;">\
<td width="25px"><a class="docEditLink docAdminFormSubmit" name="whatever" href="#">Edit</a></td>\
<td width="20px"><input type="checkbox" class="chkDeleteDocs" name="removeDocs[]" value="whatever" /></td>\
<td>' + name + '</td>\
<td>' + description + '</td>\
</tr></tbody>');
};
Next, a function to add a new document row:
var addDocRow = function(name, description) {
var counter = 0; // so we know when we've reached the end
// assumes it's already sorted
$('#main').find('tr.docRow').each(function() {
counter++;
if ($(this).find('td:eq(2)').html() >= name) {
/* Have we found the right slot for the new document by name?
td:eq(2) refers to the table cell containing the name for comparison
Assumes the table is always sorted to start */
$(this).parent().before(makeDocRow(name, description)); // build/add row
return false; // break out of each() since we're done
}
// Handle case where we've reached the end, but we're still in the loop.
// This means the new row is alphabetically last, so insert after
if ($(this).closest('table').find('tr.docRow').length === counter ) {
$(this).parent().after(makeDocRow(name, description));
}
});
};
And in your code, when you want to insert a new row:
addDocRow('Document C','Document C Description');
addDocRow('Document Z','Document Z Description');
This can surely be made better, is untested, and off the top of my head, but perhaps it will be helpful.
Edit: Threw it into a Fiddle. Seems to work. http://jsfiddle.net/redler/fhkWT/
回答2:
Here is one approach which I had done in one of previous projects.
Just append the row to tbody. Give index to each row as a data attribute. Grab the data values of the column on which you want to sort the able in the form of any array of object as shown below.
var trs = [['data', 0], ['data', 1]];//0, 1 are the row indexes before sort.
Sort this array by providing a custom sort method. After sorting you can loop through this array and append the rows to the same table.
var tbody = $('tbody', fromYourTable);
$.each(trs, function(index, tr){
//find the row by using tr[1] which contains the index in the unsorted table
tbody.append(tbody.find('tr[index="'+tr[1]+'"]'));
});
来源:https://stackoverflow.com/questions/6429220/insert-row-into-table-alphabetically-on-a-certain-cell