[//lasso
	/*
	============================================================================
	Simple Web 2.0 with Lasso and jQuery - My Stocks Module
	============================================================================
	Author: Jason Huck/Core Five Creative
	Lasso Summit 2007
	----------------------------------------------------------------------------
	
	This module displays a symbols, prices, and change amounts for a list of
	stocks. Users can enter a comma separated list of stock symbols. Data is 
	retrieved from Yahoo! Finance every 15 minutes. The list of stock symbols is
	stored in a session.
	*/

	// start/refresh user session with 'symbols' var
	session_start( -name='jquerydemo', -expires=(60 * 24 * 365));
	session_addvar('symbols', -name='jquerydemo');

	// retrieve current set of stock symbols
	// if no symbols are stored, use defaults
	!var_defined('symbols') ? var('symbols') = 'AAPL,MSFT,GOOG,YHOO';
	
	// define a tag to create a stock quote object with the supplied symbols
	// and generate output for our specific layout
	// (see http://tagswap.net/yahoo_stockquote for usage)
	define_tag('quoterows', -req='symbols');
		local('quotes') = yahoo_stockquote(#symbols);
	
		local(
			'out' = string,
			'symbolkeys' = #quotes->symbols->keys
		);	
	
		#symbolkeys->sort;
	
		iterate(#symbolkeys, local('i'));
			local('change') = decimal(#quotes->getsymbol(#i)->find('change')->split(' - ')->first)->setformat( -precision=2)&;
			!string(#change)->beginswith('-') ? #change = '+' + #change;
		
			#out += '\
			<tr id="sym' + loop_count + 'row">
				<td><a class="remsymbtn" id="sym' + loop_count + '" href="#"><img src="lib/images/delete.gif" width="14" height="14" align="absmiddle" /></a></td>
				<td><a id="sym' + loop_count + 'id" href="http://finance.yahoo.com/q?s=' + #i + '" target="_blank">' + #i + '</a></td>
				<td>' + #quotes->getsymbol(#i)->find('price')->setformat( -precision=2)& + '</td>
				<td>' + #change + '</td>
			</tr>\
			';
		/iterate;
		
		#out->trim;
		
		return(@#out);
	/define_tag;

	// ajax functions
	if(request_isajax);	
		protect;
			var('resp' = string);
			
			select(action_param('function'));			
				// add new symbols to the session var
				case('add');
					// split the lists into arrays
					var('newsymbols') = action_param('symbols')->split(',');
					$newsymbols->foreach({params->first->trim; return(true);});
					var('oldsymbols') = $symbols->split(',');
					
					// only add them if they are not duplicates
					iterate($newsymbols, local('i'));
						$oldsymbols !>> #i ? $oldsymbols->insert(encode_sql(string_uppercase(#i)));
					/iterate;
				
					// join the updated list back into a string
					$symbols = $oldsymbols->join(',');
					
					// generate output for the response
					$resp += quoterows($symbols);
				
				// remove a symbol
				case('remove');				
					var('removeme') = string(action_param('symbol'))->trim&;
					$symbols = $symbols->split(',')->removeall(action_param('symbol'))&join(',');
				
				// just update data with existing symbols
				case('refresh');				
					$resp += quoterows($symbols);

			/select;

			// set the response and abort
			content_body = @$resp;
			abort;
			
			handle_error;
				content_body = error_msg;
				error_reset;
			/handle_error;
		/protect;
	/if;


	// create the initial display
	var('display') = quoterows($symbols);
]
<script type="text/javascript">	
	// plain javascript function returns the time of the last update
	lastUpdate = function(){
		var ampm = '';
		var d = new Date();
		var hr = d.getHours();
		hr < 12 ? ampm = 'AM' : ampm = 'PM';
		if(hr == 0) hr = 12;
		if(hr > 12) hr = hr - 12;
		var mins = d.getMinutes();
		if(mins < 10) mins = '0' + mins;
		return('Last Update: ' + hr + ':' + mins + ' ' + ampm);							
	}

	$(function(){
		// this makes our nice little rounded corners
		$('.modtitle').corner('round tr 10px');

		// finds all the links of class "remsymbtn" within the "stocks" table
		// and binds a click event to them
		bindDeleteButtons = function(){
			$('tbody#stocks').find('a.remsymbtn').click(function(){
				// determine the ID of the table row based on the ID of the link
				var symid = 'a#' + this.id + 'id';	
				// the linked text is the stock symbol
				var symname = $(symid).html();
				// hide the table row
				$(('tr#' + this.id + 'row')).css({display:'none'});
				// send a GET request back to the module to remove the selected 
				// symbol from the list
				$.get('./?mode=mystocks&function=remove&symbol=' + symname); // ,function(){void(null);});
				// prevent the original link from clicking through
				return false;
			});
		}
	
		// bind a submit event to the "addsymbolform"
		$('#addsymbolform').submit(function(){
			// grab the value of the "newsymbol" input and then clear it
			var newSymbols = $('#newsymbol').val();
			$('#newsymbol').val('');
			
			// if it had content...
			if(newSymbols.length > 0) {
				// this works in firefox and safari, but not opera and IE
				// $('tbody#stocks').load('./?mode=mystocks&function=add&symbols=' + newSymbols, bindDeleteButtons);
				// using $.get instead of .load() as workaround for IE per this post:
				// http://www.nabble.com/Bug--tf2099071.html#a5786036
				
				// send a GET request to add the new symbols
				$.get('./?mode=mystocks&function=add&symbols=' + newSymbols, function(thehtml){
					// empty the "stocks" table and add the response
					$('tbody#stocks').empty().append(thehtml);
					// bind the newly added delete buttons
					bindDeleteButtons();				
				});	
			}
			
			// prevent the normal submit
			return false;
		});
		
		// refresh every 15 minutes
		var stocktimer = setInterval(function(){
			/* this works in firefox and safari, but not opera and IE
			$('tbody#stocks').load('./?mode=mystocks&function=refresh', function(){
				bindDeleteButtons();
				$('span#lastupdate').html(lastUpdate());
			});
			*/
		
			// send a GET request with the refresh function
			$.get('./?mode=mystocks&function=refresh', function(thehtml){
				// empty the "stocks" table and add the response
				$('tbody#stocks').empty().append(thehtml);
				// bind the newly added delete buttons
				bindDeleteButtons();
				// update the timestamp
				$('span#lastupdate').html(lastUpdate());
			});
		}, 900000);
		
		// bind the delete buttons on initial display
		bindDeleteButtons();
		// create the initial timestamp
		$('span#lastupdate').html(lastUpdate());
	});
</script>

<h2 class="modtitle grey" id="mystocks">My Stocks</h2>
<div class="mod lightgrey">										
	<table width="100%" border="0" cellspacing="0" cellpadding="0">
		<tbody id="stocks">
[$display]
		</tbody>
	</table>
	<br />
	<span id="lastupdate"></span><br />
	<form id="addsymbolform" action="[response_filepath]" class="add" name="addsymbol" method="post">
		<input name="addme" type="image" src="lib/images/add.gif" width="14" height="14" align="absmiddle" />
		<input id="newsymbol" class="boxGreen" type="text" name="newsymbol" />
	</form>
</div>
