Moving data in pieces to avoid timing out

I’m working on a WordPress plugin for building special financial tables. Screenshots are attached for reference.

CSV Data is uploaded and converted into an HTML table in a popup window. (The uploader and processor is in an iframe).

When clicking the “add group” button the table is moved to the main preview window and to a hidden input.
Any time a change is made to the table in the preview window, it is copied to the hidden input as well.

Sometimes with longer tables, the browser times out and only moves part of the data which causes big problems. Because when it doesn’t close the table it breaks the WP admin. Other times, it produces an unresponsive script error.

Is there a way to stagger the operation to prevent timing out? I attempted to use .each() with no effect. It would be great if it counted the rows and displayed a processing bar as it was going down the list.

Here is the code that moves the table:

jQuery('#data_group_btn').click(function(){
				
		var TableTop="<table>"+
					"<tr>"+	
						"<th class='w1'>Issuer Name</th>"+
						"<th class='w2'>Maturity</th>"+
						"<th class='w3'>Industry</th>"+
						"<th class='w4'>Current Coupon</th>"+
						"<th class='w5'>Basis Points Above Index <sup>(1)</sup></th>"+
						"<th class='w6'>Par/Shares</th>"+
						"<th class='w7'>Cost</th>"+
						"<th class='w8'>Fair Value <sup>(2)</sup></th>"+
					"</tr>";
			var TableLegs =	"</table>";
			
			jQuery('#table_constructor #preview_window').html(TableTop);
			
			var c=0;
			jQuery('#table_import table tr').each(function(){
				jQuery(this).clone().appendTo('#table_constructor #preview_window');	
			});
			
			jQuery('#table_constructor #preview_window').append(TableLegs);
		
		addAlternating_color();//adds alt class to odd rows
		tb_remove(); //removes the popup
		set_content(); // copies data from the preview window to the hidden input
	});
 

Thank you E

There’s a technique called “chunking” that splits the data being uploaded into “chunks”.

I haven’t actually needed to use it myself, but there seems to be a number of different solutions available: https://www.google.com/search?q=javascript+data+chunking

Thanks for this tip. I found that using a timer worked. I tried speeding up the processing by using :gt():lt() selectors to move more than one row over at a time, but that timed out no matter how it was configured. The method below is a little slow, but with the addition of the progress bar, the speed is acceptable. Hiding the preview table until the data transfer is complete also speeds things up a lot.

jQuery('#data_group_btn').click(function(){
		
		//var table_data=jQuery('#table_import table').html();
		
		var TableTop="<table>"+
					"<tr>"+	
						"<th class='w1'>Issuer Name</th>"+
						"<th class='w2'>Maturity</th>"+
						"<th class='w3'>Industry</th>"+
						"<th class='w4'>Current Coupon</th>"+
						"<th class='w5'>Basis Points Above Index <sup>(1)</sup></th>"+
						"<th class='w6'>Par/Shares</th>"+
						"<th class='w7'>Cost</th>"+
						"<th class='w8'>Fair Value <sup>(2)</sup></th>"+
					"</tr>";
			var TableLegs =	"</table>";
			
			//hide preview window until transfer is complete
			jQuery('#table_constructor #preview_window').hide();
			
			//add top
			jQuery('#table_constructor #preview_window').html(TableTop);
			
			//use timer to progressively transfer rows
			var c=0;
			var num=jQuery('#table_import table tr').length;
			
			var addRowIntval = setInterval(function(){add_table_rows()}, 2);
			jQuery('#loading_bar').remove();
			jQuery('#table_constructor').prepend('<div id="loading_bar"><h1>Importing Data</h1><div id="bar"><div id="meter" style="width:0"></div></div>');
			
			function add_table_rows(){
				//adjust progress bar
				jQuery('#loading_bar span').text(c);
				var per=c/num*100;
				jQuery('#meter').width(per+'%');
				
				//append table
				jQuery('#table_import table tr:eq('+c+')').clone().appendTo('#table_constructor #preview_window');	
				c++;
				
				//finish
				if(c>=num){
					clearInterval(addRowIntval);
					jQuery('#table_constructor #preview_window').append(TableLegs);
					jQuery('#table_constructor #preview_window').fadeIn('slow');
					jQuery('#loading_bar').remove();
				}
			}		
		
		addAlternating_color();
		tb_remove(); 
		set_content();
	});