Wednesday, November 4, 2009
Microsoft SQL Server's Database Publishing Wizard BatchParser error
Tuesday, November 3, 2009
<VisualStudioUNCWeb>
<Web URLPath = "http://localhost/Folder/fred.csproj" />
</VisualStudioUNCWeb>
Sunday, November 1, 2009
Free Subversion Book by O'Reilly
Friday, August 28, 2009
Python 3.0 handles Dictionary differently
Python 2.5.x (pg 112 from MIT's reading material): >>> letterCounts = {} >>> for letter in "Mississippi": letterCounts[letter] = letterCounts.get (letter, 0) + 1 >>> letterCounts {’M’: 1, ’s’: 4, ’p’: 2, ’i’: 4} >>> letterItems = letterCounts.items() >>> letterItems.sort() >>> print letterItems [(’M’, 1), (’i’, 4), (’p’, 2), (’s’, 4)] Python 3.1.x: >>> letterCounts = {} >>> for letter in "Mississippi": letterCounts[letter] = letterCounts.get (letter, 0) + 1 >>> letterCounts {'i': 4, 'p': 2, 's': 4, 'M': 1} >>> letterItems = list(letterCounts.items()) >>> letterItems.sort() >>> letterItems [('M', 1), ('i', 4), ('p', 2), ('s', 4)]
Friday, August 14, 2009
Ruby and Python in your script tags!
Wednesday, August 5, 2009
Keeping busy with ASP.NET MVC
I'm looking for a job in "the worst recession since the great depression" blah blah blah. It really sucks.
To keep busy, I've been doing some 'freelance' work. I've been trying to expand more into MVC products by deploying a RadiantCMS site in Ruby on Rails and an e-business site I'm developing in ASP.NET MVC.
I'm liking the entire MVC mantra of keeping it DRY, or Don't Repeat Yourself. I don't know if it's because I've always hated repeating myself and this idea really hits home with me, or if it's just because it's a huge change from what I've encountered professionally and academically. Whatever it is, I love it.
One thing I love about ASP.NET MVC is it's heavy use of extension methods as "Helpers". It's easy to go overboard with helpers, but I like them anyway. One nice thing about them is that if you are like me, and sometimes forget to close some HTML tags, helpers can fix that.
1: /// <summary>
2: /// Returns a DIV with specified attributes
3: /// </summary>
4: /// <param name="helper">HtmlHelper class to extend</param>
5: /// <param name="contents">Contents of the DIV element</param>
6: /// <param name="htmlAttributes">Attributes to apply to the DIV element</param>
7: /// <returns>string</returns>
8: public static string Div(this HtmlHelper helper, string contents, object htmlAttributes)
9: {
10: return Div(helper, contents, new RouteValueDictionary(htmlAttributes));
11: }
12:
13: /// <summary>
14: /// Returns a DIV with specified attributes
15: /// </summary>
16: /// <param name="helper">HtmlHelper class to extend</param>
17: /// <param name="contents">Contents of the DIV elemtn</param>
18: /// <returns>string</returns>
19: public static string Div(this HtmlHelper helper, string contents,
20: IDictionary<string, object> htmlAttributes)
21: {
22: TagBuilder tagBuilder = new TagBuilder("div")
23: {
24: InnerHtml = contents.NewlineToHtmlBreak() ?? string.Empty
25: };
26:
27: if(htmlAttributes != null)
28: {
29: tagBuilder.MergeAttributes(htmlAttributes);
30: }
31:
32: return tagBuilder.ToString();
33: }
1: <%= Html.Div("<p>This is content in left_box and helper method</p>", new {@class="left_box"}) %>
You could, of course, call the methods Tag and pass in the string value of the tag to create, eg. a, div, p, em, etc. Then, you would have a fairly generic helper to standardize all of your tags!
Even the NewlineToHtmlBreak method on String class is an extension method which calls String.Replace(Environment.Newline, "<br />") on the string input. I've done this because it's easier/faster to rely on Intellisense to hit .n+TAB than to type out the entire method. Like I said, it is very easy to go overboard with Helpers!
Wednesday, July 8, 2009
Job Hunting
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/)
<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.
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: });
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: };
- 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
Tuesday, June 16, 2009
JavaScript & CSS Modal Loading DIV
- Prototype Javascript (http://prototypejs.org/)
- Loading image (http://www.ajaxload.info/)
- Script & CSS
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.