Twitter widget changes

Below is the source code for my twitter widget as you see on the top of the page.  This makes a simple JSONP call to Twitter with JQuery.

The change I made today was to read Mentions, Lists, and URLs and convert them to respective URLs. 

 

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    var last_tweet;
    var twitterAccount = "dannygnj";
    var divClass = "twitterStatus"
    
    $(function() {
        $.getScript("http://twitter.com/statuses/user_timeline/"+twitterAccount+".json?callback=twitterCallback2&amp;;count=1");
    });
    
    function twitterCallback2(data) {    
        last_tweet = twitterize(data[0].text);
        $("." + divClass).html("<img src='/dannyg/pics/twitter_icon.png' style='vertical-align:text-top;'><a href='http://twitter.com/dannygnj' target='_blank'>Last Tweet:</a> " + last_tweet);            
    }
    
    function twitterize(str) {
        var final = str;
        var re = /http:\/\/[A-Za-z0-9_\.\/]*/g;
        var result = final.match(re);    
        if (result != null) {
            for (var i = 0; i < result.length; i++) {
                final = final.replace(result[i], "<a href='" + result[i] + "' target='_blank'>" + result[i] + "</a>");                        
            }
        }
        var re = /@[A-Za-z0-9_]*/g;
        var result = final.match(re);
        if (result != null) {
            for (var i = 0; i < result.length; i++) {
                var xword = result[i].replace("@","");
                final = final.replace(result[i], "@<a href='http://twitter.com/" + xword + "' target='_blank'>" + xword + "</a>");                        
            }
        }
        var re = /#[A-Za-z0-9_]*/g;
        var result = final.match(re);    
        if (result != null) {
            for (var i = 0; i < result.length; i++) {
                var xword = result[i].replace("#","");
                final = final.replace(result[i], "#<a href='http://twitter.com/#search?q=%23" + xword + "' target='_blank'>" + xword + "</a>");                        
            }    
        }
        return final;    
    }    
    </script>     
8. August 2010 10:39 by Danny Gershman | Comments (0) | Permalink

Supressing “…navigate... page?” message in Internet Explorer (IE)

Whenever there is a download going on and the page changes you’ll get a similar alert popup.

“Are you sure you want to navigate away from this page?  There is currently a download in progress.  If you leave now, the download will pause shortly.  Press OK to continue, or Cancel to stay on the current page.”

image

<body onBeforeUnload=”return false;”>

Technorati Tags: ,
24. May 2010 08:56 by Danny Gershman | Comments (0) | Permalink

Observer pattern in Javascript

The observer pattern is extremely powerful in many cases where you want to have a Javascript class “listen” to another object.  The class or object attaches to a Subject and waits an update command and then notifies all Observers.    Another key concept here is the idea of inheritance in Javascript. 

I have a simple Javascript function that handles inheritance:

function inherits(base, extension)
{
    for (var property in base)
    {
        try
        {
            extension[property] = base[property];
        }
        catch(warning)
        {
        
        }
    }
}

 

Using this concept in mind I can now extend any additional functionalities of any Javascript class or object on the DOM.  Now let’s take a look at the Observer and Subject classes.

function Observer()
{
    this.Update = function(data)
    {
        alert(this.id + " Update() function has not been implemented");
    }
}
 
function Subject() {
    this.observers = new ArrayList();
}
 
Subject.prototype.Notify = function( context ) {
    var m_count = this.observers.Count();
            
    for( var i = 0; i < m_count; i++ )
        this.observers.GetAt(i).Update( context );
}
 
Subject.prototype.AddObserver = function( observer ) {
    if( !observer.Update )
        throw 'Wrong parameter';
 
    this.observers.Add( observer );
}
 
Subject.prototype.RemoveObserver = function( observer ) {
    if( !observer.Update )
        throw 'Wrong parameter';
   
    this.observers.RemoveAt(this.observers.IndexOf( observer, 0 ));
}

 

We can now go forward and actually implement the code on our HTML page.  Let say we have a series of form fields and we want to set that data equal to the value of another text box.  We could easily subscribe or unsubscribe to listen for updates.  We’ll then use a simple HTML button to send updates to the listening controls.

Our page looks like this in the browser

image

And now for the underlying HTML code.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>    
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script type="text/javascript" src="../Resources/Javascripts/library.js"></script>
    <title>Observer Pattern Example</title>
</head>
<body>
    <form>
        <br />textbox1: <input type="text" id="textbox1" />
        <br />button2: <input type="button" id="button2" />
        <br />notify data: <input type="text" id="textbox3" />
        <input type="button" id="button1" value="Notify" onclick="NotifyObservers(this)" />
    </form>
</body>
</html>
    <script type="text/javascript">
        $(function() {
            inherits(new Observer(), $("#textbox1")[0]);
            inherits(new Observer(), $("#button2")[0]);
            inherits(new Subject(), $("#button1")[0]);
 
            $("#button1")[0].AddObserver($("#textbox1")[0]);
            $("#button1")[0].AddObserver($("#button2")[0]);
 
            $("#textbox1")[0].Update = function(data) {
                this.value = data;
            }
 
            $("#button2")[0].Update = function(data) {
                this.value = data;
            }
        });
 
        function NotifyObservers(subject) {
            subject.Notify($("#textbox3")[0].value);
        }
    </script>

 

As you can see the DOM objects themselves inherit the respective Javascript class functions and properties.  I’m using jQuery to directly call the functions on the objects.  When I fill in some value on the textbox3 that data gets passed through the individual implementations of the Update() method on each object that had been attached to the Subject.

image

The attached objects have decided to update their own values, but in theory I can do anything with that data.  A very powerful design pattern.

This also uses an ArrayList a feature not included in Javascript.  The ArrayList class is seen below.

function ArrayList() {
    this.aList = []; //initialize with an empty array
}
        
ArrayList.prototype.Count = function() {
    return this.aList.length;
}
        
ArrayList.prototype.Add = function( object ) {
    return this.aList.push( object ); //Object are placed at the end of the array
}
 
ArrayList.prototype.GetAt = function( index ) //Index must be a number {
    if( index > -1 && index < this.aList.length )
        return this.aList[index];
    else
        return undefined; //Out of bound array, return undefined
}
        
ArrayList.prototype.Clear = function() {
    this.aList = [];
}
 
ArrayList.prototype.RemoveAt = function ( index ) // index must be a number {
    var m_count = this.aList.length;
            
    if ( m_count > 0 && index > -1 && index < this.aList.length ) 
    {
        switch( index )
        {
            case 0:
                this.aList.shift();
                break;
            case m_count - 1:
                this.aList.pop();
                break;
            default:
                var head   = this.aList.slice( 0, index );
                var tail   = this.aList.slice( index + 1 );
                this.aList = head.concat( tail );
                break;
        }
    }
}
 
ArrayList.prototype.Insert = function ( object, index ) {
    var m_count       = this.aList.length;
    var m_returnValue = -1;
                
    if ( index > -1 && index <= m_count ) 
    {
        switch(index)
        {
            case 0:
                this.aList.unshift(object);
                m_returnValue = 0;
                break;
            case m_count:
                this.aList.push(object);
                m_returnValue = m_count;
                break;
            default:
                var head      = this.aList.slice(0, index - 1);
                var tail      = this.aList.slice(index);
                this.aList    = this.aList.concat(tail.unshift(object));
                m_returnValue = index;
                break;
        }
    }
                
    return m_returnValue;
}
 
ArrayList.prototype.IndexOf = function( object, startIndex ) {
    var m_count       = this.aList.length;
    var m_returnValue = - 1;
                
    if ( startIndex > -1 && startIndex < m_count ) 
    {
        var i = startIndex;
                    
        while( i < m_count )
        {
            if ( this.aList[i] == object )
            {
                m_returnValue = i;
                break;
            }
                        
            i++;
        }
    }
                
    return m_returnValue;
}
        
        
ArrayList.prototype.LastIndexOf = function( object, startIndex ) {
    var m_count       = this.aList.length;
    var m_returnValue = - 1;
                
    if ( startIndex > -1 && startIndex < m_count ) 
    {
        var i = m_count - 1;
                    
        while( i >= startIndex )
        {
            if ( this.aList[i] == object )
            {
                m_returnValue = i;
                break;
            }
                        
            i--;
        }
    }
                
    return m_returnValue;
}

 

Enjoy!  Tweet me if you have any questions @dannygnj

18. February 2010 07:07 by Danny Gershman | Comments (0) | Permalink

JQuery & JSONP

8. February 2010 18:58 by Danny Gershman | Comments (0) | Permalink

Poison Cookies

I thought I coined the term, but it exists already

http://www.testingreflections.com/node/view/3701

18. September 2009 03:55 by Danny Gershman | Comments (2) | Permalink

About dannyg

dannyg has been writing software for the last 12+ years and worked with various languages and programs.  He specializes business process automation, versatile solutions and R&D.