Click here to Skip to main content
11,631,710 members (71,492 online)
Click here to Skip to main content
Add your own
alternative version

Observer Design Pattern Using JavaScript

, 26 Apr 2006 227.9K 1.1K 150
Ensuring a crisp boundary exists between objects, enabling greater reuse and system maintainability.
observerdp.zip
<html>
	<head>
		<script language="javascript">
		
		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;
		}
		
		function Observer()
		{
			this.Update = function()
			{
				return;
			}
		}


		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 ));
		}
		
		</script>
	</head>
	<body bgcolor="#ff9900">
		<table width="100%" border="0">
			<tr>
				<td align="center"><INPUT style="color: #ff9900" id="BtnAdd" onclick="AddObserver()" type="button" value='Insert a new "Observer" checkbox'>
				</td>
			</tr>
			<tr>
				<td align="center" width="100%">Observable/Subject<INPUT id="MainCheckBox" type="checkbox" name="MainCheckBox">Checkbox</td>
			</tr>
			<tr>
				<td align="center">
					<div id="MainContainer"></div>
				</td>
			</tr>
		</table>
		<script language="javascript">
		
		function inherits(base, extension)
		{
			for (var property in base)
			{
				try
				{
					extension[property] = base[property];
				}
				catch(warning)
				{
				}
			}
		}	
		
		var cont = document.getElementById('MainContainer');
		
		var mainCheck  = document.getElementById('MainCheckBox');
	
		inherits(new Subject(), mainCheck);
		
		mainCheck["onclick"] = new Function("mainCheck.Notify(mainCheck.checked)");
		
		
		function AddObserver()
		{
			var check  = document.createElement("INPUT");
			check.type = 'checkbox';
			
			inherits(new Observer(), check)
			
			check.Update = function(value)
			{
				this.checked = value;
			}
			
			mainCheck.AddObserver(check);
			
			cont.appendChild(check);
		}
		
		</script>
	</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Salvatore Vetro
Web Developer
Italy Italy
Salvo is a software architect working in Milan, Italy.

He enjoys design infrastructures based on object oriented paradigm.
At the moment he is managing the integration of “ERP Business Processes” with other applications developing designing business services that are service-oriented architecture compliant.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150723.1 | Last Updated 26 Apr 2006
Article Copyright 2006 by Salvatore Vetro
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid