XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Seattle Movie Finder: An AJAX- and REST-Powered Virtual Earth Mashup
by Dare Obasanjo | Pages: 1, 2, 3, 4, 5

Putting It All Together

There are two primary dynamic components of the Seattle Movie Finder page; the list of movies currently showing in the Seattle area and the locations of movie theaters on the map. The list of available movies is toggled by clicking the hyperlinked text that alternatively reads "Show Available Movies" and "Hide Available Movies" depending on whether the list of available movies is being shown or not. The locations of movie theaters are displayed on the map based on the last movie that was searched for by clicking the Locate Theaters button.

The function that toggles the list of movies is named ToggleMovies() and is referenced in the HTML for the hyperlink that toggles the list of movies, as shown below.

<a id="avail_movies_link" href="javascript:ToggleMovies()"
  oncontextmenu="return false">Show Available Movies</a>

The ToggleMovies() function is pretty straightforward; it changes the hyperlink text and attempts to download the list of available movies asynchronously. 

  function ToggleMovies(){
    var availmovies = document.getElementById("avail_movies_link");    

    if (availmovies.innerHTML == "Show Available Movies") {
           availmovies.innerHTML = "Hide Available Movies";
           if (movies != null) {
             document.getElementById("avail_movies").innerHTML = movies;
               } else {   
                   loadXMLDoc("http://www.25hoursaday.com/moviefinder/MovieFinder.aspx?showall=true");
               }
            } else {
               availmovies.innerHTML = "Show Available Movies";
               document.getElementById("avail_movies").innerHTML = "";
            }
     }

Once the movie list has been downloaded, it is inserted into the page by the ProcessMovies() method.

 function ProcessMovies(xmlDoc){
      var m = xmlDoc.selectNodes("//movie");
      var newContent = '';
      movies = document.createElement('temp');
      for (var i=0; i < m.length; i++) {
          newContent += (i + 1) + '. <a href=javascript:ShowMovieLocations("' + escape(GetTextValue(m[i]))
                + '")>' + GetTextValue(m[i]) + "</a><br>";
      }
     movies = newContent;
     var availmovies = document.getElementById("avail_movies");
     availmovies.innerHTML = newContent;    
  }

When the user selects a movie to search for, either by clicking on a movie name in the list of available movies or by typing a movie title into the search box, the ShowMovieLocations() function is invoked. The function is shown below.

  function ShowMovieLocations(movieName){
     map.ClearPushpins();
     htm();
     document.getElementById("moviename").value = movieName;        
     loadXMLDoc("http://www.25hoursaday.com/moviefinder/MovieFinder.aspx?movie=" + movieName);                  
  }

Once the list of movie theater locations and showtimes for the specified movie have been downloaded, they are processed by the ProcessTheaters() method, which iterates over each movie theater in the returned XML document and adds it to the map as a pushpin. The ProcessTheaters() function is shown below.

  function ProcessTheaters(xmlDoc){
      var theaters = xmlDoc.selectNodes("//theater");
      theaterInfo = new Array(theaters.length);

      for (var i=0; i < theaters.length; i++) {
          var t = theaters[i];
          var name = GetTextValue(t.firstChild) + " ";
          var address = GetTextValue(t.firstChild.nextSibling);
          var lat = GetTextValue(t.firstChild.nextSibling.nextSibling);
          var lon = GetTextValue(t.firstChild.nextSibling.nextSibling.nextSibling);
          var addressNtimes = "<br>Address: " + address + "<br>Showtimes: ";
          var times = t.getElementsByTagName("time");

          for (var j=0; j < times.length; j++) {
              addressNtimes += GetTextValue(times[j]) + " " ;
          }

          theaterInfo[i] = new Array(2);
          theaterInfo[i][0] = "Theater: " + name;
          theaterInfo[i][1] = addressNtimes;   
          //stm([ theaterInfo[i][0], theaterInfo[i][1]  ], TooltipStyle);
          //stm(theaterInfo[i], TooltipStyle);

          var markup = "<div class='pin' onMouseOver='showMovieInfo(theaterInfo[" + 
          i + "])' onMouseOut='clearMovieInfo()'>" + ( i + 1) + "</div>";  
          map.AddPushpin(
             'pushpin' + i, // id
             lat,        // latitude
             lon,     // longitude
             2,          // width
             2,          // height
             'bluepin',   // className
             markup,         // innerHtml
              3);
      }
  }

For completeness, the code for the helper functions loadXMLDoc() and ProcessReqChange(), which are used in the aforementioned JavaScript functions, is shown below.

var req;
  function loadXMLDoc(url) {
     req = false;
     if(window.XMLHttpRequest) {
        try {
               req = new XMLHttpRequest();
          } catch(e) {
           req = false;
          }
      // branch for IE/Windows ActiveX version
      } else if(window.ActiveXObject) {
           try {
                  req = newActiveXObject("MSXML2.XMLHTTP.3.0");
           } catch(e) {
           try {
                  req = newActiveXObject("Microsoft.XMLHTTP");
           } catch(e) {
                 req = false;
          }
        }
      }
      if(req) {
              req.onreadystatechange = ProcessReqChange;
                 req.open("GET", url, true);
                 req.send(null);
      }
  }

  function ProcessReqChange() {
      // only if req shows "loaded"

      if (req.readyState == 4) {
          // only if "OK"
          if (req.status == 200) {
             var doc  = req.responseXML;        
             if(doc.documentElement.nodeName == "movies"){
               ProcessMovies(doc);
             }else if(doc.documentElement.nodeName == "theaters"){
               ProcessTheaters(doc);
             }
              } else {
              alert("There was a problem retrieving the XML data:\n" +
              req.statusText);
          }
      }
  }

Conclusion

This is my first article on building mashups with Windows Live services and I had quite a lot of fun doing it. As I've shown, it doesn't take much more than moderate knowledge of using JavaScript and building RESTful web services to create an interesting mashup. Thanks to Steve Lombardi and Chandu Thota for their ideas and feedback while writing this article.



1 to 2 of 2
  1. code
    2007-10-31 05:22:37 red91.com
  2. Copyrights? using this code
    2006-06-01 10:10:49 Acts7
1 to 2 of 2