Home | PicNet Information Technology Services

How to prevent 'Stop running this script' message in browsers

DiggThis
clock March 4, 2010 07:23 by author guido

Avoiding the 'Script taking too long' (all browsers have some form or another of this) message in browsers is relatively simple. You just have to make sure the browser knows you have not created an endless loop or recursion. And the easiest way to do is is to just give the browser a breather in between long running tasks.

So how would we go about this.  Well the simplest solution is to just break up your task into mutliple smaller tasks with a setTimeout in between these tasks.  The utility class below does just this:

Utility Class


RepeatingOperation = function(op, yieldEveryIteration) {
var count = 0;
var instance = this;
this.step = function(args) { 
if (++count >= yieldEveryIteration) { 
count = 0;
setTimeout(function() { op(args); }, 1, [])
return;
}
op(args); 
}; 
};

So how do we use this class, lets say we have the following code which is giving us a jerky browser and occasionally displaying those horrible 'Stop running this script' message:


// initdata is just an array of numbers (a very very large array)
var test1 = new Array(initdata.length);
for (var i = 0; i < initdata.length; i++) { test1[i]  = initdata[i] * 2; } // Double each item in the initdata array
continueOperations();

To use the utility class above we would change the code to this:


var test2 = new Array(initdata.length);
var i = 0;
var ro = new RepeatingOperation(function() {
test2[i] = initdata[i] * 2;
if (++i < initdata.length) { ro.step(); }
else { continueOperations(); }
}, 100);
ro.step(); 

That's it, a little bit more code, an extra closure, so not pretty but I think a relativelly stylish solution to a nasty problem.  Note: Remember this will also give you a much more responsive browser during execution of this expensive code also.

Note: This solution is used in the Mouse Eye Tracking system.  So it is production ready (at your own risk tho).

Thanks

Guido Tapia

Manager - Custom Software Development

PicNet Pty Ltd

 



Game of Life in JQuery

clock November 10, 2009 10:56 by author guido

Hi All,

I've just done a tutorial video on JQuery, I chose to hack together a quick version of the Game of Life.  This tutorial aims to show how JQuery can help you modify the DOM on the fly and do some nifty manipulations.  I hope you enjoy.

Please let me know if there are other JQuery topics you would like to see covered in a 'practical' style video.

Demo


Part 1

Part 2

Part 3

Guido Tapia

Manager - Custom Software Development

PicNet Pty Ltd



JQuery Table Filter Plugin

clock June 29, 2009 07:32 by author guido


This project has moved. New Home Page


Update 1/Mar/2010

The home page for this project is now at http://www.picnet.com.au/picnet_table_filter.html
Thanks

Update 11/Feb/2010

I will be moving this project to its own page with the source code at codeplex very shortly. This is because this project has taken on a life of its own and I personally don't want to be the only mantainer (having very limited time). So I'm sending a call out to anyone that wants to participate on the ongoing development of this project. Please email me (guido.tapia@picnet.com.au) if you would like to be a developer of this project. Note: I assume very little time will be required.

Once the new site is ready this blog post will be sanitized (links removed and comments closed) as everything will live on the new site.

Thanks

Introduction

This plugin adds column filtering capabilities to a regular <table> by adding a row to the <thead> section of a table and adding filters that allows real time filtering of tabular data.  Download this demo bundle for a quick start.

Note: We use this library in the production of many of our custom software development projects so it is production ready.

Demo

A simple demo page.

Getting Started

This plugin uses several other popular plugins so you will need to download these plugins before starting.

You can also use this packed version of the scripts. These plugins will then need to be referenced in the <head> section of your page.


 
<script type="text/javascript" src="Scripts/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="Scripts/jquery.cookie.js"></script>   
<script type="text/javascript" src="Scripts/picnet.jquery.tablefilter.js"></script>
 

Or (For Production Code)

 


 
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>    
<script type="text/javascript" src="Scripts/scripts-pack.js"></script>  
 

 

 

This plugin will then create the filters in a row in the THEAD element of the table so add this if it is not already there.


 
<table id='demotable'>        
    <thead>
        <tr><th>Col1</th><th>Col2</th><th>Col3</th></tr>        
    </thead>
    <tbody>
        <tr><td>Value 1</th><th>Value 2</th><th>Value 3</th></tr>        
        ....
    </tbody>
</table>
 

Hook in your table when the document is loaded.

 


 
$(document).ready(function() {
    $('#demotable).tableFilter();
});
 

Filter Types

Currently the picnet.jquery.tablefilter.js only supports two kinds of filters.  The first and default is 'text' which just produces a text box for context sensitive text matches.  The second is 'ddl', this produces a drop down list that allows the selection of a single item in that list.  To specify the filter type simply add "filter-type='ddl'" in the header cell of the required column.  I.e.


 
<table id='demotable'>        
    <thead>
        <tr><th>Col1</th><th>Col2</th><th filter-type='ddl'>Col3</th></tr>        
    </thead>
    <tbody>
        <tr><td>Value 1</th><th>Value 2</th><th>Value 3</th></tr>        
        ....
    </tbody>
</table>
 

Options

We can also pass an options object to control some basic behaviours of the tableFilter. The current supported options are.

 

  • additionalFilterTriggers: These are additional input controls that will be hooked in to the filter code. Currently only type='text' and type='checkbox' controls are supported.
  • clearFiltersControls: Controls that onclick will clear all of the filter values (including additionalFilterTriggers).
  • matchingRow: function(state, tr, textTokens) { ... } These event will allow you to determine wether a matching row is actually correctly matching. This event will be called when a row is considered to have matched the filter, returning false will override this assumtion and hide the row from the results.
  • matchingCell: function(state, td, textTokens) { ... } This event behaves the same as the one above but allows more granular overriding capabilities. Returning false will again override the default match logic.

 

Example 1: Adding an additional whole row filter

Lets suppose that appart from having column filters we also want to have a quick find style filter that matches any cell in a row. To do this simply add the textbox to the additionalFilterTriggers array. TODO

 


 
<head>
    ...
    <script type="text/javascript">  
    $(document).ready(function() {
        // Initialise Plugin
        var options = {
            additionalFilterTriggers: [$('#quickfind')]
        };
        $('#demotable).tableFilter(options);
    });
    </script>
</head>
<body>
    Quick Find: <input type="text" id="quickfind"/>
    <table id='demotable'>        
        <thead>
            <tr><th>Col1</th><th>Col2</th><th>Col3</th></tr>        
        </thead>
        <tbody>
            <tr><td>Value 1</th><th>Value 2</th><th>Value 3</th></tr>        
            ...
        </tbody>
    </table>
    ...
 

 

Example 2: Adding an additional checkbox filter

Let’s suppose that we have a Boolean column that we want to filter. The best way to do this will be to add a checkbox filter so let’s do this. We will keep the quick find filter to show how to have multiple additional filters. 

 


 
<head>
    ...
    <script type="text/javascript">
    $(document).ready(function() {
         // Initialise Plugin
        var options = {
            additionalFilterTriggers: [$('#onlyyes'), $('#quickfind')],
            matchingRow: function(state, tr, textTokens) {
                if (!state || state.id != 'onlyyes') { return true; }
                return state.value != true || tr.children('td:eq(2)').text() == 'yes';
            }
        };
         $('#demotable').tableFilter(options);
    });
<

p>    </script>
 
</head>
<body>    
    Only Show Yes: <input type="checkbox" id="onlyyes"/>
    <br/>
    Quick Find: <input type="text" id="quickfind"/>
    <table id='demotable'>        
        <thead>
            <tr><th>Col1</th><th>Col2</th><th>Boolean Col3</th></tr>        
        </thead>
        <tbody>
            <tr><td>Value 1</th><th>Value 2</th><th>yes</th></tr>        
            ...
        </tbody>
    </table>
    ...
 

 

Example 3: Clear Filters

Having a clear filters button comes in very handy, especially when you have a table with a larger number of columns. To add this functionality simply add your clickable control to the clearFiltersControls array. 

 


 
<head>
    ...
    <script type="text/javascript">
        $(document).ready(function() {        
            // Initialise Plugin
            var options = {
                clearFiltersControls: [$('#cleanfilters')],            
            };
            $('#demotable').tableFilter(options);
        });
    </script>
</head>
<body>
    <a id="cleanfilters" href="#">Clear Filters</a>
    <br/>    
    <table id='demotable'>        
        <thead>
            <tr><th>Col1</th><th>Col2</th><th>Col3</th></tr>        
        </thead>
        <tbody>
            <tr><td>Value 1</th><th>Value 2</th><th>Value 3</th></tr>        
            ...
        </tbody>
    </table>
...
 

 

Known Limitations

  • More custom filter types needed (such as multi select lists, radio lists, etc)
  • No support for custom additional filters other than checkbox.

Guido Tapia

Manager - Custom Software Development

PicNet Pty Ltd