If anyone hears of any openings for an Application Developer/System Engineer, send the info my way.
Wednesday, July 8, 2009
Job Hunting
Now that I've graduated from VCU, it's time to find a job. My wife and I started this year with plans to move out of state, but things came up and we've decided to stay in the area. That decision came a little too late, and I passed up on a couple of really good opportunities. I currently have a few prospects.
Wednesday, June 17, 2009
Quake Tracker using Google Maps API v3 and XML/Atom feed
- Google Maps API v3 (http://code.google.com/apis/maps/documentation/v3/)
- jQuery v1.3.2 (http://jquery.com/)
First, you will need to include the google maps api in your header:
<script src="http://maps.google.com/maps/api/js?sensor=true" type="text/javascript">This line of code is slightly different from the v2 API because an API key isn't needed. This will probably change in the near future. It is also necessary to load jQuery, which can be done by downloading it from the above link, or loading it via Google's AJAX API.
When the document is ready:
1: // init map
2: var map;
3: $(document).ready(function(){
4: var latlng = new google.maps.LatLng(35.6802, -121.1165);
5: var myOptions = {
6: zoom: 3,
7: center: latlng,
8: mapTypeControl: true,
9: mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
10: navigationControl: true,
11: navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
12: mapTypeId: google.maps.MapTypeId.SATELLITE
13: };
14:
15: map = new google.maps.Map(document.getElementById("map"), myOptions);
16:
17: });
When the map is ready:
1: // SEE : http://www.xml.com/pub/a/2007/10/10/jquery-and-xml.html
2:
3: $('#map').ready(function(){
4: $.ajax({
5: type: "GET",
6: url: "getxml.php?q=http://www.earthquake.usgs.gov/eqcenter/catalogs/7day-M2.5.xml",
7: dataType: "xml",
8: success: function(xml){
9: $(xml).find('entry').each(function(){
10: // Retrieve all needed values from XML
11: var title = $(this).find('title').text();
12: var updated = $(this).find('updated').text();
13: var link = $(this).find('link').text();
14: var summary = $(this).find('summary').text();
15: var coord = $(this).find('georss\\:point').eq(0).text();
16: if(!coord){var coord = $(this).find('point').text();};
17: var points = coord.split(' ');
18: var latitude = parseFloat(points[0]);
19: var longitude = parseFloat(points[1]);
20: var elev = $(this).find('georss\\:elev').eq(0).text();
21: if(!elev){var elev = $(this).find('elev').text();};
22: var htmlString = "<b>" + title + "</b>" + "<p>" + summary + "<br>";
23: // create a marker
24: var myLatlng = new google.maps.LatLng(latitude,longitude);
25: var marker = new google.maps.Marker(
26: {
27: position: myLatlng,
28: map: map,
29: title: title
30: });
31:
32: addMarkerBubble(marker, map, htmlString);
33: // Show output below map
34: $('<li></li>')
35: .html(title + ' (updated: ' + updated + ') at ' + points[0] + ', ' + points[1])
36: .appendTo('#output');
37: });// end each
38: }
39: }); // end $.ajax
40: });// end function
41:
42: function addMarkerBubble(marker, map, message){
43: // set balloon
44: var infowindow = new google.maps.InfoWindow(
45: {
46: content: message,
47: size: new google.maps.Size(400,200)
48: });
49:
50: // add listener to marker
51: google.maps.event.addListener(marker, 'click' ,function(){
52: infowindow.open(map,marker);
53: });
54: };
Explanations:
First of all, I create a global variable called map, so I can use it in each function.
Then, when the document is ready, I get a geographic coordinate which Google Maps builds from maps.LatLng. This coordinate is in California, because I know there are quakes there.
Next, I've set a number of options (lines 6-12) for the map including:
- zoom level
- map center
- a control to allow user to change the look of the map
- a control to allow user to change zoom
- default map type of "SATELLITE", which shows tectonic regions
The Google Maps API v3 makes it very easy to supply these options to the Map constuctor, as you can see on line 15 of the first code snippet. The map is loaded into the DOM object supplied as the first parameter in the constructor.
The next snippet is the AJAX call to retrieve the feed and build the markers and info windows when the GET succeeds.
Inside the function call, I've used jQuery's simplified DOM access for the returned XML. On line 9 of this snippet, I find each 'entry' node and then iterate over each of these nodes to find the text of each node value.
On lines 15-16 and 20-21, I check the variables because some browsers properly process namespaced nodes and some don't. This simple check allows the application to display properly in Chrome, Safari, Firefox, and Internet Explorer.
Next, I create a marker on the map at the given coordinate and give it a title (tooltip).
On line 32, I call the function 'addMarkerBubble' to create an info window and add the event to the map. After this, I add the title and updated date to a div element below the map.
Tuesday, June 16, 2009
JavaScript & CSS Modal Loading DIV
Things I've used in this:
Here is the script necessary to make a request and build/show/remove the DIV.
Here is the stylesheet needed to make the dialog "modal".
In order to use this code, you'll have to give your body tag an id of 'bodyDocument', and the div tag to receive your ajax request should be called 'content'.
I've also included an image error detecting script, which replaces broken images with a default image. Unfortunately, if you're trying to produce 100% compliant HTML documents, this won't be compliant unless you're using HTML5. In order to use this, you'll have to do something like <img src='asdf.gif' onerror='javascript:onImgError(this)' alt='image'>
I've left some code commented out, which will help in debugging your efforts. And, in the stylesheet, you have the option of using a flat background instead of a PNG with transparency.
- Prototype Javascript (http://prototypejs.org/)
- Loading image (http://www.ajaxload.info/)
- Script & CSS
What I do here is build a DIV element and show it on the page while Prototype's Ajax Request object is loading. Then, when the Request is finished, the DIV is removed from the document.
Here is the script necessary to make a request and build/show/remove the DIV.
1: /** Main.js
2: * @author Jim Schubert
3: * (c) 2009
4: */
5:
6: function showContent(file){
7: var content = new Ajax.Request(file,
8: {
9: method:'get',
10: onLoading: showLoading(),
11: onSuccess: function(request)
12: {
13: var contentDIV = document.getElementById('content');
14: contentDIV.innerHTML = "";
15: contentDIV.innerHTML = request.responseText;
16:
17: closeLoading();
18: },
19: onFailure: function(){ alert('Cannot process your request.');}
20: // onComplete: closeLoading()
21: });
22: };
23:
24: function onImgError(source) {
25: source.src = "img/img_error.png";
26: // disable onerror to prevent endless loop
27: source.onerror = "";
28: return true;
29: };
30:
31: function showLoading() {
32: // create div element
33: var overlayDIV = document.createElement('div');
34: var loadingDIV = document.createElement('div');
35: overlayDIV.setAttribute('id', 'overlay');
36: overlayDIV.setAttribute('class', 'overlay');
37: overlayDIV.style.visibility = 'visible';
38:
39: loadingDIV.setAttribute('id', 'loading');
40: loadingDIV.setAttribute('class', 'modalPopup');
41: loadingDIV.innerHTML = '<center><img src="img/ajax-loader.gif"><br>Loading...</center>';
42:
43: overlayDIV.appendChild(loadingDIV);
44: var content = document.getElementById('bodyDocument');
45: if (content) {
46: content.appendChild(overlayDIV);
47: var overlay = document.getElementById('overlay');
48: if (overlay) {
49: overlay.style.visibility = 'visible';
50: overlay.style.height = '100%';
51: }
52: }
53:
54: return true;
55: };
56:
57: function closeLoading(){
58: var overlayDIV = document.getElementById('overlay');
59: var loadingDIV = document.getElementById('loading');
60:
61: if (overlayDIV) {
62: if (loadingDIV) {
63: overlayDIV.removeChild(loadingDIV);
64: document.getElementById('bodyDocument').removeChild(overlayDIV);
65: }
66: // else {alert("can't find loadingDIV")}
67: }
68: // else{ alert("Can't find overlay.");}
69:
70: return true;
71: };
Here is the stylesheet needed to make the dialog "modal".
1: .overlay {
2: visibility: hidden;
3: position: absolute;
4: left: 0px;
5: top: 0px;
6: width:100%;
7: height:100%;
8: text-align:center;
9: z-index: 1000;
10: filter:alpha(opacity=70) !important;
11: opacity:0.8 !important;
12: elevation:above !important;
13: /* background-color:Gray !important; */
14: background-image: url(../img/overlay.png);
15: }
16:
17: .modalPopup
18: {
19: display: block;
20: margin-left: auto;
21: margin-right: auto;
22: width:180px;
23: margin: 100px auto;
24: background-color:#F1F1F1 !important;
25: border:1px solid #000;
26: padding:15px;
27: text-align:center;
28: elevation:above !important;
29: }
In order to use this code, you'll have to give your body tag an id of 'bodyDocument', and the div tag to receive your ajax request should be called 'content'.
I've also included an image error detecting script, which replaces broken images with a default image. Unfortunately, if you're trying to produce 100% compliant HTML documents, this won't be compliant unless you're using HTML5. In order to use this, you'll have to do something like <img src='asdf.gif' onerror='javascript:onImgError(this)' alt='image'>
I've left some code commented out, which will help in debugging your efforts. And, in the stylesheet, you have the option of using a flat background instead of a PNG with transparency.
Monday, May 18, 2009
Example Ruby code
I decided to do some of those Facebook puzzles in Ruby. I won't post everything I do, because I would consider that cheating (after all, you can win prizes!).
However, considering this is a very simple script, and I'm doing it more for learning Ruby than to enter into Facebook's puzzles, I will post this one.
This is the first puzzle, called Hoppity Hop:
private @file_exists = false def get_integer(filename) if File::exists?(filename) file = File.open(filename) line = file.gets.strip! file.close @file_exists = true return line.to_i else @file_exists = false return 0 #zero files present end end def get_string(num) if(num%3 == 0 && num%5 == 0) print "Hop\n" elsif num%3 == 0 print "Hoppity\n" elsif num%5 == 0 print "Hophop\n" else return #nothing end end def hip_hop(arg) num = get_integer(arg) if(num > 0 && @file_exists) for i in 1..num.to_i get_string(i) end else puts "File not found" end end public arg = ARGV[0].to_s # this is the name of the file if(/\D/ =~ arg) puts "Please enter a positive integer as the filename." else unless arg == nil hip_hop(arg) end end
Saturday, May 9, 2009
Ruby on Rails, Aptana Studio
This weekend, I decided to give Ruby on Rails a go, considering I just finished school and I'll have plenty of free time to explore.
I downloaded Aptana Studio and installed Ruby, Rails, PHP, and a few extra ruby gems for fun. Then, I went over to the Rails Guide to follow along and do some learnin'. At the end of the guide, I ran the completed blog application and received errors. A little googling helped me find the solution.
Apparently, Aptana doesn't install the latest build of gems from its repositories, and the guide was written for the newest version.
As noodlygod writes on the forum linked above:
Hello, I just thought I'd post something as I had the same problem on Windows.
I tried running the command "gem install rails --source http://gem.rubyonrails.org" but I received the error: "actionpack requires rack (>= 0.9.0, runtime)"
So I ran "gem install rack" which installed something And then "gem install rails --source http://gem.rubyonrails.org" and it installed 2.3.0 just fine.
Based on this post: http://railsforum.com/viewtopic.php?pid=89050 I also changed my rails version in environment.rb to "2.3.0" and renamed "application.rb" to "application_controller.rb" and everything is working. Thanks a bunch for the info!
Thursday, April 30, 2009
Useful Serialization Methods of LINQ to SQL objects
I am just going through a project for my senior "Projects in Information Systems" class, commenting most of the complex logic. I came across these two methods I wrote to serialze LINQ to SQL objects. They came in pretty handy, so I thought I'd share even though they don't have error-handling. I'm not too embarrassed.
The way I used them was pretty ghetto, I was having troubles getting the objects I needed to serialize to be used in a Session object (I thnk it had something to do with an Order_Details table having two foreign keys to the same table, Ledger, for an IN and OUT field). Anyway, I serialed the object to XML and just stored the whole string into a listBox's value. I know that's begging for poor performance, and overriding the data validation checks is opening the ASP.NET page up for security issues, but the only people who are going to use this are me and my instructor. So, it was a quick work around. I could have stored it in a Session Object as a string, but then I would have had to call some funky work around for the listBox. Anyway, enough about that.
1:
2: /// <summary>
3: /// Serializes a LINQ object to an XML string
4: /// </summary>
5: /// <typeparam name="T">Type of the Object</typeparam>
6: /// <param name="linqObject">The LINQ object to convert</param>
7: /// <returns>string</returns>
8: public static string SerializeLINQtoXML<T>(T linqObject)
9: {
10: // see http://msdn.microsoft.com/en-us/library/bb546184.aspx
11: DataContractSerializer dcs = new DataContractSerializer(linqObject.GetType());
12:
13: StringBuilder sb = new StringBuilder();
14: XmlWriter writer = XmlWriter.Create(sb);
15: dcs.WriteObject(writer, linqObject);
16: writer.Close();
17:
18: return sb.ToString();
19: }
20:
21: /// <summary>
22: /// Deserializes an XML string to a LINQ object
23: /// </summary>
24: /// <typeparam name="T">The type of the LINQ Object</typeparam>
25: /// <param name="input">XML input</param>
26: /// <returns>Type of the LINQ Object</returns>
27: public static T DeserializeLINQfromXML<T>(string input)
28: {
29: DataContractSerializer dcs = new DataContractSerializer(typeof(T));
30:
31: TextReader treader = new StringReader(input);
32: XmlReader reader = XmlReader.Create(treader);
33: T linqObject = (T)dcs.ReadObject(reader, true);
34: reader.Close();
35:
36: return linqObject;
37: }
38:
Saturday, April 25, 2009
Storing Generics in ASP.NET Profile object
Sometimes, I'll come across a problem that I research for an hour or two. When I find the solution, I think "Wow, that should have been the first thing I tried!"
This is one of those occasions.
I decided to use the ASP.NET profile instead of Session objects to store a list of products. So, in web.config, I tried a number of "work-arounds" that I found online, including:
1: <profile>
2: ...
3: <properties>
4: <add name="RecentlyViewed" allowAnonymous="false" type="System.Collections.Generic.List`1[Model.Product]" serializeAs="Xml"/>
5: </properties>
6: </profile>
The problem I was having, and it seems a lot of people are having, is that System.Collections.Generic.List`1[Model.Product] throws an error. For some people, it seems to work. Well, I tried changing the lt and gt in the generic list so the XML would parse it as it is written in the code-behind. That didnt work.
The solution: Create a class which inherits from List<Model.Product>
For instance:
1: using System;
2: using System.Collections.Generic;
3:
4: namespace Model
5: {
6: /// <summary>
7: /// This class wraps the Generic List into a class to serialize in Profile provider
8: /// </summary>
9: [Serializable]
10: public class RecentlyViewed : List<Model.Product>
11: {
12: public RecentlyViewed()
13: {
14: }
15: }
16: }
This works beautifully! Now, in web.config, you can do the following:
1: <profile>
2: ...
3: <properties>
4: <add name="RecentlyViewed" allowAnonymous="false" type="Model.RecentlyViewed" serializeAs="Xml"/>
5: </properties>
6: </profile>
Tuesday, April 14, 2009
Displaying multiple fields in a Dropdownlist's DataTextField
I've encountered this problem on occasion, where I want to display more than one field in a dropdownlist's DataTextField property. In the past, I've overcome this problem by rewriting a SQL statement, or adding another column in the database itself to accomodate my needs.
This takes the List of Business Entity objects and uses the LINQ select statement to generate an implicit/anonymous object from that. The only downfall to this method is that the new object only has local scope. But, since I'm only using this in a dropdown, it's a pretty nifty trick.
In one of my classes (INFO 465: Projects in Information Systems @ VCU), we're working from a database which we're not allowed to change. The reason we can't change it is because the instructor uses the same database for his examples. I could just write another method into my business logic layer, but it would get cluttered pretty quickly.
So, I decided to make use of LINQ and found the following solution:
1: ddlUsers.DataSource = BLL.Employee.GetEmployees()
2: .Select(be =>
3: new {
4: ID = be.Id,
5: FullName = String.Format("{0}{1}{2}",
6: be.LastName,
7: (!string.IsNullOrEmpty(be.FirstName) ? ", " : string.Empty),
8: be.FirstName)
9: }).AsEnumerable();
This takes the List of Business Entity objects and uses the LINQ select statement to generate an implicit/anonymous object from that. The only downfall to this method is that the new object only has local scope. But, since I'm only using this in a dropdown, it's a pretty nifty trick.
Wednesday, April 1, 2009
T-SQL Multi-Table Delete
I was trying to run a DELETE query on multiple tables and I kept getting this error:
The DELETE statement conflicted with the REFERENCE constraint
I'm not that great with SQL, but I can get by. DELETEs have always been somethng that have given me trouble. So, I thought I'd share this simple fix.
DELETE FROM PRODUCT FROM BOOK WHERE BOOK.ID = PRODUCT.BOOK_ID AND BOOK.ID = @BOOK_IDYou just have to make sure you put the table with the FK as the first table in the query.
I guess I should have paid a little more attention in Database class. We learned Oracle, which is different from Microsoft's SQL in many ways.
Subscribe to:
Posts (Atom)