Skip navigation

mStocks

Overview

mFinance is a mashup of the Stock Quote XML Web Service used by the Apple Stock Widget, Historical Charts from Google, and Financial News feeds from Yahoo! news.

Resources

The following XML API are used in creating this Moblet:

Name
Description
Documentation
Apple Stock Quotes
A feed pulled from the source code of the Apple Stock Widget
n/a
Google Historical Charts
Charts "scraped" from the Google Finance site
n/a
Yahoo! Financial News
News from Yahoo! RSS finance
n/a

Download

Visit http://moblets.sf.net on your mobile web browser.

Source Code

All the source code below is available for download from Sourceforge.net https://moblets.svn.sourceforge.net/svnroot/moblets/trunk/mStocks.

index.mjx

<moblet default="splashScreen" name="mStocks" icon="images/mjxlogo_32x32.png" onError="errorHandler(event)">

  <style src="mStocks.mcss"/> 
  
  <!-- Preload and cache the images -->
  <resource url="images/loading_animation.gif" persist="true"/>
  <resource url="images/yahoo_finance.png" persist="true"/>
  <resource url="images/house.png" persist="true"/>
  <resource url="images/feed.png" persist="true"/>
  <resource url="images/chart_bar.png" persist="true"/>
  <resource url="images/text_list_bullets.png" persist="true"/>
  
  <script><![CDATA[
    var detail;               // Stock detail
    var news;                 // Stock news
    var quotes = null;        // Stock quotes
    var currentSymbol;        // Current stock symbol active
    var currentScreen;        // The current screen displayed
    var resetScreen = true;   // Force rebuild of screen
    var resetNewsScreen;      // Force rebuild of the news screen
    var quoteList;            // Quote list entered in rightmost tab (user configured)
    var msg;                  // Messages displayed to user
    var loadingMsg;           // Message when loading data
    
    // URL for information
 //   var quotesURL = "http://wu.apple.com/fq/applewidgets/quote.asp?key=tHisIsApplewidgeTs&symbols=";
    var quotesURL = "http://finance.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgnprj1v&s=";
    var newsURL = "http://finance.yahoo.com/rss/headline?s=";
    var chartURL = "http://www.google.com/pfetch/dchart?s=";
  
    // Default symbols
    var defaultSymbols = "AAPL GOOG YHOO CSCO CPT DOW LBC";
    
    var symbolidx = 0;
    var lasttradeidx = 1;
    var changeidx = 4;
    var openidx = 5;
    var companynameidx = 8;
    var prevtradeidx = 9;
    var ratioidx = 10;
    var capidx = 11;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *  Save stock symbols on the device                     
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    if (!Cache.symbols) 
    {
      Cache.symbols = defaultSymbols;
    }
    
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *  Set style sheet class for stock details
    *   (red == stock down  green == stock up)                   
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function getChangeClass() 
    {
      var myClass = "greenDetail";
      var value = detail[changeidx];
      if (value.indexOf("-") > -1) 
      {
        myClass = "redDetail";
      }
      return myClass;
    }
    
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *  Download quotes                     
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function getQuotes(refresh) 
    {
      // If a data refresh is needed, so progress   
      if (refresh)
      {
        resetScreen = true;       // Force screen rebuild
        loadingMsg = "Requesting stock quotes...";
        show(loadingScreen, 1);   // Show progress
      }
      downloadQuotes();           // Download the stock details
    }
    
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *  Set quotes from the csv                     
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function setQuotes(quoteString) 
    {
      var newQuotes = new Array();
      var csvLines = quoteString.split("\n");
      
      for (line in csvLines)
      {
          var values = line.split(",");
          for (i=0; i < values.length; i++)
          {
              var start = 0;
              var end = values[i].length;
              if (values[i].charAt(0) == "\"")
              {
                  start = 1;
              }  
              if (values[i].charAt(values[i].length - 1) == "\"")
              {
                  end = values[i].length - 1;
              }
              values[i] = values[i].substring(start, end);
          }
          newQuotes.push(values);
      }
      return newQuotes;
    }
    
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *   Get detail (high, low, chart, etc)                     
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function getDetails(symbol, refresh) 
    {   
      // If user has selected a different stock from the main tab
      // or if the user has requested that the main tab be refreshed 
      if (currentSymbol != symbol || refresh == true) 
      {
        currentSymbol = symbol;   // Set new current symbol
        loadingMsg = "Requesting " + currentSymbol + " data...";
        show(loadingScreen, 1);   // Show progress
        resetScreen = true;       // Force screen rebuild
        resetNewsScreen = true;   // Force news screen rebuild
        downloadDetails();        // Download stock details
        downloadNews();           // Download Rss news as well
      }
      else
        displayScreen();          // No changes, simply display screen
    }

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *   Get news (Rss tab)            
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function refreshNews() 
    {      
      // This method will only be called if the news screen
      // was requested to be refreshed
      loadingMsg = "Requesting " + currentSymbol + " news...";
      show(loadingScreen, 1);     // Show progress
      resetScreen = true;         // Force screen rebuild
      downloadNews();             // Download news
    }
  
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *   Update the display                     
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function displayScreen()
    {
      // The news screen info is downloaded the same time
      // as the detail screen info, so a special check is
      // needed to know when to rebuild the news screen
      // when something changes on the details screen
      if (currentScreen == newsScreen && resetNewsScreen) 
      {
        currentScreen.reset();    // Force screen rebuild
        resetNewsScreen = false;  // Reset news screen flag        
      }                           
      else
      {
        // If reset/refresh is requested (on any screen)
        if (resetScreen)
        {
          currentScreen.reset();  // Force screen rebuild
          resetScreen = false;    // Reset flag
        }
      }
      hide(loadingScreen);        // Hide the loading screen
      show(currentScreen);        // Show screen
    }  
    
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    *  Retry a failed data request
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function retryDataRequest() 
    {
      // Depending on which screen was active when data reqeust failed...
      if (currentScreen == mainScreen)
        getQuotes(true);
      else
        getDetails(currentSymbol, true);
    }
    
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    * Moblet error handler                     
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    function errorHandler(e) 
    {
      msg = e.label;
      show(errorScreen, 1);
    }
      
  ]]></script>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Tabrow prototype                        -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <prototype name="tabrow" layout="none" extends="Box" width="100%">
    <attribute name="active">
      this.children[0].children[this.active].class = "onstate";
    </attribute>
    <box layout="horizontal" width="100%" y="7">
      <imagebox class="offstate" height="100%" width="100%" halign="center" 
        layout="vertical" valign="center" url="images/house.png"/>
      <imagebox class="offstate" height="100%" width="100%" halign="center" 
        layout="vertical" valign="center" url="images/chart_bar.png"/>
      <imagebox class="offstate" height="100%" width="100%" halign="center" 
        layout="vertical" valign="center" url="images/feed.png"/>
      <imagebox class="offstate" height="100%" width="100%" halign="center" 
        layout="vertical" valign="center" url="images/text_list_bullets.png"/>
    </box> 
  </prototype>
      
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Quote prototype                         -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->          
  <prototype name="quote" extends="Box" layout="horizontal" width="100%" focusable="true">
    <attribute name="symbol">this.children[0].value = this.symbol;</attribute>
    <attribute name="lasttrade">this.children[1].value = this.lasttrade;</attribute>
    <attribute name="change">
      // Set color based on stock up/down
      if (this.change.indexOf("-") &lt; 0)
        this.children[2].class = 'green';
      else
        this.children[2].class = 'red';
      this.children[2].value = this.change;
    </attribute>
    <attribute name="position">
      // Alternate current row color
      if (this.position % 2) 
        this.class = "even";
      else 
        this.class = "odd";
    </attribute>
    <method name="onClick">
      // On click, move to next (details screen)
      currentScreen = detailsScreen; 
      getDetails(this.symbol, false);
    </method>
    <textbox class="symbol" width="100%"/>
    <textbox class="lasttrade" width="100%" halign="right"/>
    <textbox class="green" width="100%" halign="right"/>
  </prototype>

  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Companyname prototype                   -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <prototype name="companyname" layout="vertical" extends="TextBox" width="100%" 
    halign="center" valign="center"/>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Stockdetail prototype                   -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <prototype name="stockdetail" layout="vertical" extends="Box" width="100%">
    <gridbox cols="4" rows="3" height="100%" width="100%" layout="horizontal" valign="top">
      <textbox width="100%" class="quoteslabel" maxLines="1">Last:</textbox>
      <textbox width="100%" class="quotesvalue" maxLines="1">bind{detail[lasttradeidx]}</textbox>
      <textbox width="100%" class="quoteslabel" maxLines="1">Change:</textbox>
      <textbox width="100%" class="bind{getChangeClass()}" maxLines="1">bind{detail[changeidx]}</textbox>
      
      <textbox width="100%" class="quoteslabel" maxLines="1">Open:</textbox>
      <textbox width="100%" class="quotesvalue" maxLines="1">bind{detail[openidx]}</textbox>
      <textbox width="100%" class="quoteslabel" maxLines="1">Prev Close:</textbox>
      <textbox width="100%" class="quotesvalue" maxLines="1">bind{detail[prevtradeidx]}</textbox>
       
      <textbox width="100%" class="quoteslabel" maxLines="1">Cap:</textbox>
      <textbox width="100%" class="quotesvalue" maxLines="1">bind{detail[capidx]}</textbox>
      <textbox width="100%" class="quoteslabel" maxLines="1">P/E:</textbox>
      <textbox width="100%" class="quotesvalue" maxLines="1">bind{detail[ratioidx]}</textbox>
    </gridbox>
  </prototype>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Newsitem prototype                      -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <prototype name="newsitem" extends="Box" layout="vertical" focusable="true" width="100%">
    <attribute name="title">
      this.children[0].value = this.title;
    </attribute>
    <attribute name="link"/>
    <attribute name="description"/>
    <attribute name="pubdate"/>
    <textbox class="newstitle" width="100%"/>
  </prototype>
            
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Chart prototype                         -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->                
  <prototype name="chart" class="chart" extends="ImageBox" layout="vertical" width="100%" halign="center" valign="center" focusable="false" transform="stretch">
    <attribute name="symbol">
      this.url = chartURL + this.symbol;
    </attribute>
  </prototype> 
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Inputitem prototype                     -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <prototype name="inputitem" width="100%" layout="vertical" focusable="false" extends="Box">
    <attribute name="label">
      this.children[0].value = this.label;
    </attribute>
    <attribute name="value">
      this.children[1].value = this.value;
    </attribute>
  
    <textbox class="label"/>
    <textbox class="textentry" height="100%" width="100%" focusable="true" maxLines="1"/>
    
    <!-- When user selects the textinput box... -->
    <method name="onClick">
      this.getInput();
    </method>
    
    <script><![CDATA[
      
      // Save the current list coming in
      quoteList = Cache.symbols;
    
      // Get input from user
      this.getInput = function() 
      {
        // Use native textinput
        var textInput = new NativeTextInput();  
       
        textInput.source = this;
        textInput.title = this.label;
        textInput.value = this.value;
        textInput.length = 50;
        
        // When done entering data
        textInput.onDone = function()
        {  
          // If no data entered...
          if (this.value.length == 0)
          {
            msg = "You must enter at least one stock symbol. The list will be reset.";       
            show(errorScreen, 1);
            return;
          }
        
          // Force upper case, set current list of quotes and show prefs screen
          this.source.value = this.value.toUpperCase();
          
          // Save the result into a global variable
          quoteList = this.source.value;
          
          // Return to the preferences screen
          show(prefsScreen);
            
        };
        
        // When user cancelled entering data
        textInput.onCancel = function() 
        {
          // Return to the preferences screen
          show(prefsScreen);
        };
        
        // Show the textinput box
        show(textInput);  
      };
      
      // User selected 'Reset' from the preferences screen
      this.setValue = function(value)
      {
        this.value = value;
        quoteList = Cache.symbols;
      };
    ]]></script>
    
  </prototype>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Softkeys prototype                      -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <prototype name="softkeys" extends="Box" layout="horizontal" width="100%">
    <attribute name="left">
      this.children[0].value = this.left;
      this.children[0].visible = true;
    </attribute>
    <attribute name="right">
      this.children[1].value = this.right;
      this.children[1].visible = true;
    </attribute>
    <textbox width="100%" halign="left" visible="false"/>
    <textbox width="100%" halign="right" visible="false"/>
  </prototype>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- HTTP requests                           -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <httprequest id="downloadQuotes" url="bind{quotesURL + escape(Cache.symbols)}" mimeType="text/plain" async="true"> 
    <method name="onLoaded">
      quotes = setQuotes(this.responseText);
      displayScreen();                  // Display main screen
    </method>

    <method name="onLoaded">
      var response = this.responseText;
      quotes = setQuotes(response);
      if (quotes.length == 0)                 // No stock quotes returned 
      {
        msg = "Unable to download the list of stock quotes.\r\n\r\nClick Ok to retry.";
        show(dataError, 1);        
      }
      else
        displayScreen();                // Display main screen
    </method>

  </httprequest>
  
  <httprequest id="downloadDetails" url="bind{quotesURL + currentSymbol}" mimeType= "text/plain" async="true">
    <method name="onLoaded">
      var allQuotes = setQuotes(this.responseText);
      if (allQuotes.length == 0)    // No details returned
      {
        msg = "Unable to download the detail information for the stock symbol: \r\n\r\n" + currentSymbol + "\r\n\r\n  Click Ok to retry.";
        show(dataError, 1);
      }
      else
      {
        detail = allQuotes[0];
        displayScreen();                // Display details screen
      }
    </method>
  </httprequest>    

  <httprequest id="downloadNews" url="bind{newsURL + currentSymbol}" filter="stockFilter.xsl" async="true">
    <method name="onLoaded">
      news = this.responseXML;          // Save results
      if (currentScreen == newsScreen)  // If refresh was requested from the news screen, display it
        displayScreen();
     </method>
   </httprequest>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Main screen                             -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <screen id="mainScreen" layout="vertical" autoReset="false" 
      onLeftSoftkey="exit()" 
      onRightSoftkey="getQuotes(true)"
      onRightKey="currentScreen = detailsScreen; getDetails(this.focus.symbol, false);">
    <imagebox url="images/yahoo_finance.png" width="100%" halign="center"/>
    <tabrow id="home_tab" active="0"/>
    <scrollbox id="mainScroll" width="100%" height="100%" focusable="false" scrollbar="true" >
      <script>
        var ndx = 0;
      </script>      
      <foreach var="q" items="quotes" if="quotes">
 <!--       <quote symbol="once{q.symbol}" lasttrade="once{q.lasttrade}" change="once{q.change}" position="once{ndx++}"/> -->
       <quote symbol="once{q[symbolidx]}" lasttrade="once{q[lasttradeidx]}" change="once{q[changeidx]}" position="once{ndx++}"/> 
      </foreach>
    </scrollbox>
    <softkeys left="Exit" right="Refresh"/>
  </screen> 
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Details screen                          -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->      
  <screen id="detailsScreen" layout="vertical" autoReset="false" 
      onRightSoftkey="getDetails(currentSymbol, true)"
      onLeftKey="currentScreen = mainScreen; displayScreen()"
      onRightKey="currentScreen = newsScreen; displayScreen()">
    <imagebox url="images/yahoo_finance.png" width="100%" halign="center"/>
    <tabrow id="quotes_tab" active="1"/>
    <scrollbox width="100%" height="100%" focusable="true" scrollbar="true"  >
      <companyname value="bind{ detail[companynameidx] + '(' + detail[symbolidx] + ')'; }"/>
      <stockdetail/>
      <chart symbol="bind{currentSymbol}" height="100%"/>
    </scrollbox>
    <softkeys left="" right="Refresh"/> 
  </screen> 
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- News screen                             -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->      
  <screen id="newsScreen" layout="vertical" autoReset="false"
      onRightSoftkey="refreshNews()"
      onLeftKey="currentScreen = detailsScreen; displayScreen()"
      onRightKey="currentScreen = prefsScreen; displayScreen()">
    <imagebox url="images/yahoo_finance.png" width="100%" halign="center"/>
    <tabrow id="news_tab" active="2"/>
    <scrollbox width="100%" height="100%" focusable="false" scrollbar="true" >
      <companyname value="bind{ detail[companynameidx] + '(' + detail[symbolidx] + ')'; }"/>
      <foreach var="i" items="news.item" if="news">
        <newsitem title="once{i.title}"/>
      </foreach>
    </scrollbox>
    <softkeys left="" right="Refresh"/> 
  </screen> 

  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Preferences screen                      -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <screen id="prefsScreen" layout="vertical" autoReset="false" 
    onLeftKey="currentScreen = newsScreen; displayScreen()">
    <imagebox url="images/yahoo_finance.png" width="100%" halign="center"/>
    <tabrow id="prefs_tab" active="3"/>
    <box layout="horizontal" height="100%" width="100%">
      <inputitem id="symbols" label="Enter quotes for home page:" value="bind{Cache.symbols}"/>
    </box>
    <method name="onLeftSoftkey">
      // Reset the textbox contents to current cache value
      this.children[2].children[0].setValue(Cache.symbols);
      
      // With list reset, show the screen again (refresh)
      displayScreen();
    </method> 
    <method name="onRightSoftkey">      
      // Update the cached list
      Cache.symbols = quoteList;    

      // Set the current screen to 'main' and get new quotes
      currentScreen = mainScreen; 
      resetScreen = true;
      getQuotes(true);                   
    </method> 
    <softkeys left="Reset" right="Save"/>
  </screen> 
    
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Loading (data) screen                   -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <screen id="loadingScreen" layout="vertical" halign="center" valign="center">
    <textbox class="loadingtext" value="bind{loadingMsg}"/>
    <imagebox id="loading" focusable="false" url="images/loading_animation.gif">  
      <method name="onShow">
        this.animate(true);             // Start animation
      </method> 
      <method name="onHide">     
        this.animate(false);            // Stop animation
      </method> 
    </imagebox>
  </screen>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Splash screen (app startup)             -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->      
  <screen id="splashScreen" layout="vertical" halign="center" valign="center">
    <imagebox url="images/yahoo_finance.png" width="100%" halign="center"/>
    <box height="100%" width="100%" layout="vertical" halign="center" valign="center">
      <textbox class="splashtext" width="100%" halign="center" valign="center">
        Loading, please wait ...
      </textbox>
      <imagebox id="splashloading" focusable="false" url="images/loading_animation.gif">  
        <method name="onShow">
          currentScreen = mainScreen;   // Start with the 'main' screen     
          this.animate(true);           // Start animation
          getQuotes(false);             // Get app data
        </method> 
        <method name="onHide">     
          this.animate(false);          // Stop animation
        </method>
      </imagebox> 
    </box>
  </screen>
  
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Data loading error screen               -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->     
  <screen id="dataError" layout="vertical" valign="center" halign="center" onLeftSoftkey="exit()">
    <method name="onRightSoftkey">
      hide(this);
      retryDataRequest();
    </method> 
    <imagebox url="images/yahoo_finance.png" width="100%" halign="center"/>
    <box class="errorbox" valign="center" halign="center" layout="vertical"> 
      <textbox valign="center" halign="center" width="100%" >
        bind{msg}
      </textbox>        
    </box>     
    <softkeys left="Exit" right="Ok"/> 
  </screen>

  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
  <!-- Moblet error screen                     -->
  <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->    
  <screen id="errorScreen" layout="vertical" focusable="false" onLeftSoftkey="displayScreen();">
    <imagebox url="images/yahoo_finance.png" width="100%" halign="center"/>
    <textbox width="100%" height="100%" halign="center" valign="center">bind{msg}</textbox> 
    <softkeys left="Back"/>  
  </screen>
    
</moblet>

mStocks.mcss

screen {
	background-color: #FFFFFF;
	padding: 2px;
	font-size: small;
}

tabrow {
  border-bottom-width: 10px;
  border-bottom-color: #445681;
  font-size: small;
}
	
.offstate {
	margin: 1px 1px 0px 1px;
	border-style: rounded;
	border-width: 2px;
	border-color: #445681;
	background-color: #FFFFFF;
	padding: 5px 5px 8px 5px;
	color: #445681;
}

.onstate {
	margin: 1px 1px 0px 1px;
	border-style: rounded;
	border-width: 2px;
	border-color: #445681;
	background-color: #445681;
	padding: 5px 5px 8px 5px;
	color: #FFFFFF;
}

stockquotes {
	background-color: #DAE4F6;
}

stockdetail {
	background-color: #F1F5FB;
	padding: 2px;
	border-color: #DAE4F6;
	border-width: 2px;
}

stocknews {
	padding: 2px;
	color: #445681;

}

newsitem {
	color: #445681;
	margin: 2px;
}

newsitem:focus {
	margin: 2px;
	background-color: #DAE4F6;
}	
	
.newstitle {
	font-weight: bold;
	margin: 2px;
}

.newsdescription {
	margin: 2px;
}

.quoteslabel {
	background-color: #DAE4F6;
	padding: 2px;
	color: #445681;
	border-bottom-width: 1px;
	border-bottom-color: #445681;
}	

.quotesvalue {
	background-color: #F1F5FB;
	padding: 2px;
	color: #445681;
	border-bottom-width: 1px;
	border-bottom-color: #445681;
}
	
chart {
	padding: 5px;
	border-style: rounded;
	border-color: #DAE4F6;
	border-width: 5px;
	background-color: #FFFFFF;	
}

.even:focus, .odd:focus {
	background-color: #C0C0C0;
}

.even {
	background-color: #F1F5FB;
	padding: 2px;
	color: #445681;	
}

.odd {
	background-color: #DAE4F6;
	padding: 2px;
	color: #445681;
}

.red {
	color: #CC0000;
	padding: 2px;
}

.green {
	color: #00CC00;
	padding: 2px;
}

.redDetail {
	color: #CC0000;
	padding: 2px;
	border-bottom-width: 1px;
	border-bottom-color: #445681;
}

.greenDetail {
	color: #00CC00;
	padding: 2px;
	border-bottom-width: 1px;
	border-bottom-color: #445681;
}

.lasttrade {
	padding: 2px;
}

.symbol {
	padding: 2px;
}

inputitem {
	background-color: #FFFFFF;
	color: #445681;
	margin: 10px;
}

inputitem:focus {
	background-color: #FFFFFF;
	color: #445681;
	margin: 10px;
	border-color: #FF0000;
}

.input {
	background-color: #FFFFFF;
	border: 1px solid #F1F5FB;
}

.input:focus {
	background-color: #FFFFFF;
	border: 1px solid #DAE4F6;
}

#loadingScreen {
	color: #FFFFFF;
	background-color: #000000;
	opacity: 75%;
}

.loadingtext {
	color: #FFFFFF;
	font-size: large;
	font-weight: bold;
	font-family: system;
	width: 100%;
	halign: center;
	
}

.splashtext {
  color: #00008B;
  background-color: #FFFFFF;
  font-size: large;
  font-weight: bold;
  font-family: system;
}

.textentry { 
  background-color: #FFFFFF;
  border: 1px solid #DAE4F6;
  padding: 2px;
  color: #000000;
}

.textentry:focus {
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
  background-color: #FFFFFF;
  valign: center;
}

softkeys {
  color: #00008B;
  font-weight: bold;
  background-color: #ffffff;
  padding: 2px;
}

.errorbox {
  background-color: #FFFFFF; 
  border-color: #00008B; 
  border-width: 1px; 
  border-style: rounded; 
  padding: 8px 15px 8px 15px; 
  width: 80%;
  height: 100%; 
}

stockFilter.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>

    <xsl:template match="/INDEXSET">
        <quotes>
            <xsl:apply-templates select="QUOTE"/>
        </quotes>
    </xsl:template>
    
    <xsl:template match="QUOTE">
        <xsl:element name="quote">
            <xsl:attribute name="companyname"><xsl:value-of select="COMPANYNAME/text()"/></xsl:attribute>
            <xsl:attribute name="exchange"><xsl:value-of select="EXCHANGE/text()"/></xsl:attribute>
            <xsl:attribute name="symbol"><xsl:value-of select="SYMBOL/text()"/></xsl:attribute>
            <xsl:attribute name="lasttrade"><xsl:value-of select="LASTTRADE/text()"/></xsl:attribute>
            <xsl:attribute name="change"><xsl:value-of select="CHANGE/text()"/></xsl:attribute>
            <xsl:attribute name="pctchange"><xsl:value-of select="PCTCHANGE/text()"/></xsl:attribute>
            <xsl:attribute name="daylow"><xsl:value-of select="DAYLOW/text()"/></xsl:attribute>
            <xsl:attribute name="dayhigh"><xsl:value-of select="DAYHIGH/text()"/></xsl:attribute>
            <xsl:attribute name="volume"><xsl:value-of select="VOLUME/text()"/></xsl:attribute>
            <xsl:attribute name="mktstatus"><xsl:value-of select="MKT_STATUS/text()"/></xsl:attribute>
        </xsl:element>
    </xsl:template>
    
    <xsl:template match="/rss">
    	<items>
            <xsl:apply-templates select="channel/item"/>
        </items> 
    </xsl:template>
 
     <xsl:template match="channel/item">
        <xsl:element name="item">
            <xsl:attribute name="title"><xsl:value-of select="title/text()"/></xsl:attribute>
            <xsl:attribute name="link"><xsl:value-of select="link/text()"/></xsl:attribute>
            <xsl:attribute name="description"><xsl:value-of select="description/text()"/></xsl:attribute>
            <xsl:attribute name="guid"><xsl:value-of select="guid/text()"/></xsl:attribute>
            <xsl:attribute name="pubdate"><xsl:value-of select="pubDate/text()"/></xsl:attribute>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Adaptavist Theme Builder Powered by Atlassian Confluence