HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Append table cells to select boxes in indexed order

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
boxesordercellsindexedappendselecttable

Problem

I am having a huge brain fart with efficiency right now.

The idea here is if I have a static table (unfortunately formatted this way with the data I've received), how would I appropriately append a select option dropdown with every value from the table categorized easily?

I currently have it working, but it seems as if I could make it more efficient than my current statement. I have the feeling with all the DOM manipulation I have going on, if I tried to use this on a table with thousands of items it would lag the browser. Let's get to the code.

JS Fiddle: http://jsfiddle.net/z2V2p/1/

HTML:


    
      Item 1
      Value 1
      Prop 1
    
    
      Item 2
      Value 2
      Prop 2
    
    
      Item 3
      Value 3
      Prop 3
    


Javascript/jQuery:

$('tr td').each(function() {
    var $this = $(this);
    var text = $this.text();
    var select = ''+text+'';
    switch($this.index()){
        case 0:
          $('#item').append(select);
          break;
        case 1:
          $('#value').append(select);
          break;
        case 2:
          $('#prop').append(select);
          break;
        default:
          alert('Unexpected Error.');
     }
});


So, I suppose the questions are:

  • Is there any easy way to make this more efficient?



  • Perhaps utilizing an array to cache the values, and append them


from that?

  • Or is there an easier method of using index of the items instead of


my switch case that would render quicker and be more expandable for further tds if they were implemented?

I appreciate all of the help.

I've considered just ultimately converting the darn table to a json object, but I figured I'd reach out here first. (this will deploy thousands of times per week, and I don't want anything hard coded.)

Looking for a way to add every TD in its index of its TR to be appended to an existing select option based on the index value.

Basically re-categorize columns of td elements.

Solution

First little thing: var names are important. So

var option = ''+text+'';


Second and main. When we are making webapps with JS, the main perfomance rule is:

Reduce access to DOM

I tried you code with 15000 tr's in Firefox and Chrome. I wrapped you code with

console.time('DOM');
...
console.timeEnd('DOM');


Results was:

  • Chrome - about 5000ms



  • Firefox - about 20000ms



Then i replaced $.append() with just strings concatenation

console.time('String');
var itemOptions = '', valueOptions = '', propOptions = '';
$('tr td').each(function() {
    var $this = $(this);
    var text = $this.text();
    var option = ''+text+'';
    switch($this.index()){
        case 0:
            itemOptions += option;
          break;
        case 1:
            valueOptions += option;
          break;
        case 2:
            propOptions += option;
          break;
        default:
          alert('Unexpected Error.');
     }
});
$('#item').append(itemOptions);
$('#value').append(valueOptions);
$('#prop').append(propOptions);
console.timeEnd('String');


Results:

  • Chrome - about 1100ms (bravo, Chrome :))



  • Firefox - about 4000ms



If you will change your data source to a JSON or something, next optimisation will not need, but you can set first argument of .each() method (index of all td elements) to avoid using .index(). I noticed about 300-500ms of speed increase. So the last version is

console.time('String');
var itemOptions = '', valueOptions = '', propOptions = '';
$('tr td').each(function(index) {
    var $this = $(this);
    var text = $this.text();
    var option = ''+text+'';
    var modulo = index % 3;
    switch(modulo){
        case 0 :
            itemOptions += option;
          break;
        case 1:
            valueOptions += option;
          break;
        case 2:
            propOptions += option;
          break;
        default:
          alert('Unexpected Error.');
     }
});
$('#item').append(itemOptions);
$('#value').append(valueOptions);
$('#prop').append(propOptions);
console.timeEnd('String');


Results:

  • Chrome - about 850ms



  • Firefox - about 3500ms

Code Snippets

var option = '<option value="'+text+'">'+text+'</option>';
console.time('DOM');
...
console.timeEnd('DOM');
console.time('String');
var itemOptions = '', valueOptions = '', propOptions = '';
$('tr td').each(function() {
    var $this = $(this);
    var text = $this.text();
    var option = '<option value="'+text+'">'+text+'</option>';
    switch($this.index()){
        case 0:
            itemOptions += option;
          break;
        case 1:
            valueOptions += option;
          break;
        case 2:
            propOptions += option;
          break;
        default:
          alert('Unexpected Error.');
     }
});
$('#item').append(itemOptions);
$('#value').append(valueOptions);
$('#prop').append(propOptions);
console.timeEnd('String');
console.time('String');
var itemOptions = '', valueOptions = '', propOptions = '';
$('tr td').each(function(index) {
    var $this = $(this);
    var text = $this.text();
    var option = '<option value="'+text+'">'+text+'</option>';
    var modulo = index % 3;
    switch(modulo){
        case 0 :
            itemOptions += option;
          break;
        case 1:
            valueOptions += option;
          break;
        case 2:
            propOptions += option;
          break;
        default:
          alert('Unexpected Error.');
     }
});
$('#item').append(itemOptions);
$('#value').append(valueOptions);
$('#prop').append(propOptions);
console.timeEnd('String');

Context

StackExchange Code Review Q#41028, answer score: 3

Revisions (0)

No revisions yet.