Thursday, November 12, 2009

Cookies With Silverlight 2.0


I was looking to set and retrieve cookies with Silverlight 2.0 and came across the following article by Nikola. Unfortunately, it did not work out of the box for me, so I modified it.  Here is my updated version:


using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;

/* www.datawinconsulting.com */

namespace Datawin
{

    /* 
    Thanks to Nikola  -  http://blogs.msdn.com/nikola
    http://blogs.msdn.com/nikola/archive/2008/04/14/setting-cookies-through-    silverlight.aspx
    */

    public class Cookie
    {
     

        /// 
        /// sets a persistent cookie with huge expiration date
        /// 
        /// the cookie key
        /// the cookie value
        public static void SetCookie(string key, string value)
        {
           
            string oldCookie = HtmlPage.Document.GetProperty("cookie") as String;
            DateTime expiration = DateTime.UtcNow + TimeSpan.FromDays(2000);
            string cookie = String.Format("{0}={1};expires={2}", key, value, expiration.ToString("R"));
            HtmlPage.Document.SetProperty("cookie", cookie);
        }

        /// 
        /// Retrieves an existing cookie
        /// 
        /// cookie key
        /// null if the cookie does not exist, otherwise the cookie value
        public static string GetCookie(string key)
        {
            string[] cookies = HtmlPage.Document.Cookies.Split(';');
            key += '=';
            foreach (string cookie in cookies)
            {
                string cookieStr = cookie.Trim();
                if (cookieStr.StartsWith(key, StringComparison.OrdinalIgnoreCase))
                {
                    string[] vals = cookieStr.Split('=');

                    if (vals.Length >= 2)
                    {
                        return vals[1];
                    }

                    return string.Empty;
                }
            }

            return null;
        }

        /// 
        /// Deletes a specified cookie by setting its value to empty and expiration to -1 days
        /// 
        /// the cookie key to delete
        public static void DeleteCookie(string key)
        {
            string oldCookie = HtmlPage.Document.GetProperty("cookie") as String;
            DateTime expiration = DateTime.UtcNow - TimeSpan.FromDays(1);
            string cookie = String.Format("{0}=;expires={1}", key, expiration.ToString("R"));
            HtmlPage.Document.SetProperty("cookie", cookie);
        }


    }
}

Here is how I call the Cookie Code:

private void SetCookie_Click(object sender, RoutedEventArgs e)
        {
            Datawin.Cookie.SetCookie("FoodName", txtBox1.Text);
            

        }

        private void GetCookie_Click(object sender, RoutedEventArgs e)
        {
            txtBox2.Text = Datawin.Cookie.GetCookie("FoodName");

        }

Hope that helps some of you out there. It sure helps me.

Thursday, October 8, 2009

Update Your Latitude and Longitude using Google

Untitled Page
My client had a "Entity Locator" on their site and needed additional data imported into the database. The data they gave me had the Entities' addresses but no Latitude and Longitude, which were essential for the program to work. In the past, I've had to use purchased data that gave zip code lat and long, but no more! With Google Maps API, I was not only able to get a more accurate Lat and Long (based on the full address, not just the zip code), but it was free!
First of all, you need to sign up for a developer key: http://code.google.com/apis/maps/signup.html
Here is a function that I wrote to get the Latitude and Longitude for a given address using the Google API. It's quite simple. You build the URL along with the query string parameters, make a request to Google's API, when the response comes back you process the results.
The parameters that you send to Google's API are:
key - the App key you got from Google when you signed up for the service.
output - the format of your results. For ease and size, I choose cvs.
q - the address you are looking for.
using System.Net;

private void GetLatAndLongGoogle(string address, string city, string state,
                                string zip, ref string inLat, ref string inLong)
        {
            /* 
             * Pass in the paramters: address, city, state, zip
             * 
             * The Longitude and Latitude will be passed back out through: inLat, inLong
             * (don't forget to pass these last two as "ref")
             */


            /* appID is the API Key you get from Google */
            string appID = "YOUrKraZYKey1w";
            
            /* Here we build the URL with the query string parameters*/
            StringBuilder url = new StringBuilder("http://maps.google.com/maps/geo?");
            url.Append("output=csv&key=");
            url.Append(appID);
            url.Append("&q=");
            url.Append(CleanForURL(address));
            url.Append(",");
            url.Append(CleanForURL(city));
            url.Append(",");
            url.Append(CleanForURL(state));
            url.Append(",");
            url.Append(CleanForURL(zip));

            /*Create HttpWebRequest object*/
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url.ToString());
            myReq.Credentials = CredentialCache.DefaultCredentials;

            try
            {
                HttpWebResponse response = (HttpWebResponse)myReq.GetResponse();
                Stream receiveStream = response.GetResponseStream();
                StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                string httpString = readStream.ReadToEnd();
                if (httpString.StartsWith(@"200,"))
                {
                   
                    string[] AddressArray = httpString.Split(',');
                    inLat = AddressArray[2];
                    inLong = AddressArray[3];
                }
                else
                {
                    inLat = "0.0";
                    inLong = "0.0";
                }
            }
            catch (Exception e)
            {
                inLat = "0.0";
                inLong = "0.0";
            }
        }



        private string CleanForURL(string inStr)
        {
            inStr = inStr.Replace(@"&", "");
            inStr = inStr.Replace(@"/", "");
            inStr = inStr.Replace(@"\", "");
            inStr = inStr.Replace(@"?", "");
            return inStr;
        }
Here is a sample of how you would call the function:
int myAddressKey = 1234;
            string myAddress = "401 Main St";
            string myCity = "Huntington Beach";
            string myState = "CA";
            string myZip = "92648";
            string myLatitude = "";
            string myLongitude = "";
 
            GetLatAndLongGoogle(myAddress, myCity, myState, myZip, 
            ref myLatitude, ref myLongitude);
 
            MyProcedureThatUpdatesDBWithLatAndLong(myAddressKey, myLatitude, myLongitude);

Thursday, August 13, 2009

Automatic LightWindow Popup

Do you need LightWindow to pop up as soon as the page loads? The following hack to LightWindow will help you do that...
The LightWindow library allows the developer to launch a LightWindow programmatically. When the lightwindow.js library loads, it automatically instantiates a LightWindow object called myLightWindow. You can then use the activeWindow method to open a url in a LightWindow:
myLightWindow.activateWindow({
    href: 'http://www.google.com', 
    title: 'Google', 
    author: 'Datawin Consulting', 
    caption: 'This is Google's Home Page.', 
    width:995, 
    height:610
    });
You can easily execute this code from a button or link on your web page. So if you wanted the LightWindow to pop up as soon as the user lands on the page, you would think that all you have to do is call myLightWindow.activateWindow(…) in the main page’s onLoad event. Unfortunately, this doesn’t work. The onLoad event fires before the LightWindow library can load and instantiate the myLightWindow object so all you get is a javascript error and no LightWindow.
So what do we do? Well, our solution is to hack the LightWindow library (lightwindow.js) and add our own “pseudo-event” to fire right after the myLightWindow object gets instantiated. Here is the code in the lightwindow.js file (hint: it is at the very bottom of the file).
Original code:
var myLightWindow = null;
function lightwindowInit() {
 myLightWindow = new lightwindow();
 }
Our changes to the code:
var myLightWindow = null;
function lightwindowInit() {
 myLightWindow = new lightwindow();
 
 // The following was added to run code immediately 
 // after this library loads and instantiates the 
    // myLightWindow object.  
    // ***********************
    // In the code on the main page we’ll need to create a 
 // lightWindow_DoneLoading() function that catches 
 // the the pseudo-event.
 // ***********************
 // Not elegant. 
    // Tightly coupled. 
 // But at least we check for the existence of
 // the lightWindow_DoneLoading() function before 
    // we try calling it.
 if(('function' == typeof window.lightWindow_DoneLoading)){
     lightWindow_DoneLoading();
 }
}
In the main code we need to create a function called lightWindow_DoneLoading(). This is our pseudo-event handler that will handle the pseudo event that we raised. The code in our main page (including the loading of the necessary libraries) will look like this.
<link rel="stylesheet" type="text/css" href="css/lightwindow.css" />
 <script type="text/javascript" src="/dnn/Portals/0/javascript/prototype.js"></script>
 <script type="text/javascript" src="/dnn/Portals/0/javascript/effects.js"></script>
 <script type="text/javascript" src="/dnn/Portals/0/javascript/lightwindow.js"></script>
 <script type="text/javascript"> 
     function lightWindow_DoneLoading() {
         myLightWindow.activateWindow({
             href: 'http://www.google.com',
             title: 'Google',
             author: 'Datawin Consulting',
             caption: 'This is the Google Homepage.',
             width: 995,
             height: 610,
             top: 10,
             left: 200
         });
     }   
 </script>
To modify the appearance of the LightWindow you would change the following values in the “activeWindow” method above:
  • href – the url of the site you want in your LightWindow.
  • title – the text for the Title that shows on the left, directly above the LightWindow.
  • author - the text for the Author that shows in the bottom, right hand side of the LightWindow.
  • caption – the text for the Caption that show in the bottom, left hand side of the LightWindow.
  • width – the width of the LightWindow in pixels.
  • height – the height of the LightWindow in pixels.
  • top – the top position of the LightWindow relative to the browser window.
  • left – the left position of the LightWindow relative to the browser window.
That’s it! The LightWindow should now pop up as soon as the page loads.
p.s. You will note that since our hack to the LightWindow.js checks for the existence of the function before trying to call it, it will not throw an error if the function does not exist in your main page. That means you can use the hacked version even on your pages where you don’t necessarily want an automatic LightWindow pop up.)

Saturday, August 1, 2009

Changing The Background Opacity for LightWindows


When the LightWindow pops up, it darkens the original page underneath it. This has the cool effect of drawing your attention to the newly popped window, while reminding you that you are still on the same site. LightWindow makes the original page pretty dark, though, and our clients wanted it lighter than that.

Behind the scenes, LightWindow creates the "page goes dark" effect by stretching a transparent black squared completely over the browser window. IE and Firefox use different methods to make this square transparent, though. In IE, you load a black opaque image and then set the opacity to a decimal between 0 and 1. The lower the number, the more transparent it becomes. For instance, .7 would make the image 70% opaque or in other words, 30% transparent, .2 would make it 80% transparent. In Firefox, on the other hand, you create an already transparent .png file and just stretch that over the browser window. That means for Firefox, we’ll have to modify the .png file with a graphics editor like Fireworks. Since LightWindow seeks compatibility with both (and so do we), you will have to make a few steps to make the change.

For our project, we want to lighten the page from 70% opacity to 20%.

First we will create the transparent image that Firefox uses, adjusting the opacity to 20% and saving it as "black-20.png":

  • Open "black.png" (in "images" directory) with Fireworks.
  • Select the Black bitmap object.
  • In the Properties window (probably at the bottom) you should see two dropdown boxes, one has "100%" in the box and the other has "Normal".
  • Click on the down arrow by the "100%" box and move the slider down to "20%".
  • Click somewhere else in the program. You will see the bitmap become more transparent.
  • From the menu: File-->Save as "black-20.png

Next we will modify the code in "lightwindow.js"

  • Open "lightwindow.js" (in the "javascript" directory) with your favorite text editor or Visual Studio.
  • Search for "opacity" to locate the following block of code:

overlay : {
    opacity : 0.7,
    image : 'images/black.png',
    presetImage : 'images/black-70.png'
   }
  • Change "opacity : 0.7" to "opacity : 0.2" (For IE).
  • Change the "presetImage" value to "black-20.png" (For FireFox).
  • Save.

overlay : {
    opacity : 0.2,
    image : 'images/black.png',
    presetImage : 'images/black-20.png'
   }
That should do it! Reload the page and verify that it works.