April 24, 2007

New Blog Address

Alrighty, plain and simple: New blog address!

Update your links and bookmark the new feed.

http://www.dennydotnet.com/

Old posts will remain here until I can import them to the new blog.

kick it on DotNetKicks.com

April 13, 2007

SubSonic 2.0 Beta 3

SubSonic 2.0 Beta 3 is available for download: http://www.codeplex.com/actionpack/Release/ProjectReleases.aspx?ReleaseId=1387

Not a ton of info but you can see what was fixed. Keep yourself updated here, since CodePlex "seems to have an issue with updating RSS feeds in a timely fashion.": http://monk.thelonio.us/category/1.aspx

kick it on DotNetKicks.com

March 21, 2007

JavaScript: Adding/Removing Elements from thin air

JavaScript

Some of the key items we'll be going over:

1. How to create an element from thin air.
2. How to remove an element that we created from thin air.
3. How to set properties of an element created from thin air.
4. How to create a toggle feature for our element.
5. How to toggle only one element at a time.

Ok first off, why did I need this? I'm using a DataList to display item information. Each line is one item and contains a few action buttons. These action buttons pop up new windows and allow you to configure whatever it is you need. Anywho, it was decided that there should be no pop-ups and that the information should appear below the row. In an effort to reduce code the information below the row would be in an IFRAME so we could just point to the URL of the old pop-up window. I didn't want to throw in an IFRAME with each row so I decided to use JavaScript to create the IFRAME on the fly.

So first we need to know how to create an element from thin air. No problem,

var s2div = document.createElement('div');
s2div.setAttribute('id', 's2info');


Tada! All good to go. We have a DIV element with an id of s2info. But where is it? Well it's not displayed yet because we need to let it know who its parent is. Luckily within each row is a DIV element which contains all the information. This is going to be our parent element. Let's add our newly created DIV to our content DIV and give it some style.

s2div.height = '300px';
s2div.width = '90%';
s2div.style.backgroundColor = 'red';
s2div.style.display = 'inline';
s2div.innerHTML = '<iframe src="http://www.example.com" width="100%"></iframe>';

var par = document.getElementById('parentDiv');
par.appendChild(s2div);


Great now our new DIV appears and it contains our IFRAME pointing to our example.com. Since this code needs to be called from our button clicks lets throw it in a function and then each button can just call it directly.

function showWin(el) {
// Create our DIV container
var s2div = document.createElement('div');
s2div.setAttribute('id', 's2info');
s2div.height = '300px';
s2div.width = '90%';
s2div.style.backgroundColor = 'red';
s2div.style.display = 'inline';
s2div.innerHTML = '<iframe src="http://www.example.com" width="100%"></iframe>';
el.parentNode.appendChild(s2div);
return false;
}


Note that el is passed from the calling button. Also note that we append the new DIV with el.parentNode.appendChild(...). This is because we pass the button as el and its parentNode is the DIV we want to append to. So we're basically just pointing to the DIV but getting there through the button. Here is our button:

<input type="button" onclick="showWin(this);" id="iRox0rzB0xorz" value="Display" />


So now every time we click the button we append a new DIV with the iframe on the same row. Gravy right? Well what if we keep clicking the button? We're going to keep appending a new DIV! Well we only want one DIV visible per button click. If another button is clicked we want to close the currently open DIV (if one is open) and then open the one we clicked.

We'll need to set a global variable to keep an eye on which one is open. Here's the whole package:

<script language="javascript" type="text/javascript">
var old = '';
function showWin(el) {
var s = document.getElementById('s2info');
if (s) {
if (old != '') old.removeChild(s);
if (old == el.parentNode) {old=''; return false;}
}

// Create our DIV container
var s2div = document.createElement('div');
s2div.setAttribute('id', 's2info');
s2div.height = '300px';
s2div.width = '90%';
s2div.style.backgroundColor = 'red';
s2div.style.display = 'inline';
s2div.innerHTML = '<iframe src="http://www.example.com" width="100%"></iframe>';
el.parentNode.appendChild(s2div);
old = el.parentNode;

return false;
}
</script>


You can see our old variable keeps track of which element is showing the DIV. We also check to make sure a new button was clicked. If the same button was clicked twice we just remove the element but do not continue to add the new element.

And there you go. Cross-browser compatible? Not sure.

kick it on DotNetKicks.com

March 07, 2007

Integrating Google Maps

Google Maps + Your web app = Simple

Working on a feature for my project and wanted to share how easily you can get Long + Lat using the Google Maps API.

First we need to get the presentation down. We'll be creating a popup div where you can type an address and a button that displays the location on the Google Map.

    <div id="selectgeo" runat="server" style="background-color: GreenYellow; border: solid 1px darkgreen;
position: absolute; left: 10px; top: 5px;">
Address:
<input id="txtAddr" type="text" />
<input id="btnfindgeo" type="button" value="Go" onclick="showAddress(document.getElementById('txtAddr').value); return false;" />
<input id="btndonegeo" type="button" value="Done" onclick="document.getElementById('selectgeo').style.display='none';" />
<div id="mappp" style="width: 270px; height: 175px">
</div>
</div>

<script src="http://maps.google.com/maps?file=api&v=2&key=yourkey"
type="text/javascript"></script>


REMEMBER to replace "yourkey" with your Google Maps API key. Get one here.

So we've got our Div: selectgeo, our Address box: txtAddr, our Button to find the location: btnfindgeo, our Done button: btndonegeo and finally our div which contains the map: mappp.

You can see btnfindgeo is wired up with a javascript function: showAddress. This is where the goods come from :) Onto the JavaScript!

var map;
var geocoder = new GClientGeocoder();

function loadGMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("mappp"));
map.addControl(new GSmallZoomControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4019, -122.1419), 13);
}
}

function showAddress(address) {
geocoder.getLatLng(address,
function(point) {
if (!point) {
alert(address + " not found");
} else {
map.setCenter(point, 13);
var marker = new GMarker(point);
map.addOverlay(marker);
alert('['+ point.x + ', ' + point.y +']');
}
}
);
}

// Programatically load the map after onload.
var abo = document.getElementsByTagName("body");
if (abo != null) {
abo[0].onunload = GUnload;
abo[0].onload = loadGMap;
}


And you're done! Type in your address and see what happens.

Also the Google Maps API Documentation provides a TON of useful examples.

kick it on DotNetKicks.com

February 08, 2007

HowTo: Strongly Typed View with SubSonic

I had a little trouble yesterday trying to get a Strongly Typed view working correctly in SubSonic. I spent a good 2 hours beating my brain trying to figure it out (I don't have internet at home yet - no Googling). Well after an hour break I came back and it hit me. It's very easy to implement, so lets start.

First off SubSonic will create your view as a collection. If your view is named v_RecentShares then you'll get a VRecentSharesCollection object.

You can then use that to query your view and iterate with a Strongly Typed reference:

Dim V as VRecentSharesCollection() = new VRecentSharesCollection().Load()
Dim Row as VRecentShares()
 
For Each Row in V
Dim ShareName as String = Row.ShareName
Next

kick it on DotNetKicks.com

February 05, 2007

Book Review: 175 Ways to Get More Done in Less Time!

I just read through this book and it has some great tips. Straight and to the point, no models, history, deep discussions, etc... Just straight to the point, trivial tips that you can start using literally right now. If you're looking to get a few extra ideas on how to squeeze more time out of your day then this is a handy start.

I've got a few tips bookmarked. This isn't a one-time read, as a matter of fact I'll be going back and bookmarking a few more tips suggested in this book. This book even sprung another idea on me for my website.

The book is only 36 pages long and you can read through it, front to back, in no more than 15 minutes. You'll want a highlighter around to underline the tips that can help you. Most will help, some you already do, but you'll certainly pick up some new ideas.

175 Ways to Get More Done in Less Time!
by David Cottrell and Mark C. Layton
CornerStone Leadership Institute © 2004 (36 pages)
ISBN:0965878848

kick it on DotNetKicks.com

January 31, 2007

Reading value of a CheckBox in DataGrid

Want to know how to get the value of a check box in a Template Field inside a DataGrid? Check it out:

        Dim chkMiss As CheckBox

' Go through each row and find a check box
For Each i As DataGridItem In dgActive.Items
chkMiss = CType(i.FindControl("chkMiss"), CheckBox)

' Check if miss was selected
If chkMiss.Checked Then
' Use my checkbox
End If
Next

That's all you need on the server-side code, and now for the HTML... Inside your datagrid just create a template column and it should look something like:

  <asp:TemplateColumn HeaderText="Select Check Box">
<ItemTemplate>
<asp:CheckBox id="chkMiss" Text='SomeText' runat="server">
</asp:CheckBox>
</ItemTemplate>
</asp:TemplateColumn>

And you're done! The same method applies to all other controls as well.

kick it on DotNetKicks.com

kick it on DotNetKicks.com

January 20, 2007

Sys is undefined - AJAX 1.0 RC

Okay, I am frustrated. My project was working fine a few days ago and now I'm getting the dreaded Sys is undefined error. I've been trying to track it down with no luck.

A Google search shows that there are many people with this same issue. I've gone through my config file and everything looks correct.

I'll keep working on it and will post here as soon as anything comes up.


Update: A little farther...

Ok it seems as if my ScriptResource.axd file is being encoded! I'm using the Blowery HTTP Compression Module and after adding an exclusion for the mime type: application/x-javascript my WebResource.axd started coming back - it was coming up with a blank file before. However I keep getting the error Invalid character. I think its because ScriptResource.axd is encoded and not being decoded!

It's also telling me that the Type.RegisterNamespace function cannot be found (this function exists in ScriptResource.axd). I checked with Fiddler and ScriptResource.axd is being GZIP encoded. So I removed any reference to blowery and still no luck! You can view my posts on the ASP.NET Forum here for further detail, my user name is SuperGhost (the Batman logo).

You can check if your script is being encoded by opening up Fiddler and calling your ScriptResource.axd. Run your page first and get the source. The source will contain the correct path and querystring to the ScriptResource.axd file as well as the WebResource.axd file.

I'll post an update when this gets resolved!


Resolved: Finally

Ok found the problem a few days ago. The file was being encoded and the problem was that I had earlier uncommented a line in my web.config and then commented it back out again. Apparently the setting remained, not sure why. This is the line:

<scriptresourcehandler enablecompression="true" enablecaching="true">

You can see the enableCompression is set to true. So a simple change was all it needed. I uncommented the line and set compression to false:

<scriptresourcehandler enablecompression="false" enablecaching="true">

And that's it! Resolved! Also the Blowery HTTP Module was not affecting the script at all. I hope this helps anyone else having this issue!

kick it on DotNetKicks.com

January 16, 2007

Blocking DoS attacks, maybe...

Mads / .NET Slave has posted an HttpModule for blocking DoS attacks. How does it work? Well any IP address that accesses your page more than 10 times per second gets banned for 5 minutes. All settings are configurable, for example you could ban on 15 requests per 2 seconds for 10 minutes.

I would certainly recommend that you do some testing to find a decent setting. Also some comments have come up on Mads' post wondering about more detail like: What if you're being hit by AOL's proxy server or a search engine bot? You'll have to take into account how your visitors access your website too. I will be playing around with the source and seeing how it reacts to an AJAX-enabled site as well.

kick it on DotNetKicks.com

January 12, 2007

A Better IIF for VB.NET

After browsing around a while I came across a code snippet that is very useful yet hardly used! I've always been jealous of C#'s easy-to-use ? operator:

if x ? a : b
But I didn't mind using IIF for VB.NET. Anyways, apparently IIF does some nasty typecasting in the background and isn't very Option Strict On friendly. Say hello to the new and improved Generic IIF function:
Public Function IIf(Of T)(ByVal expression As Boolean, _
        ByVal truePart As T, ByVal falsePart As T) As T

  If expression Then
    Return truePart
  Else
    Return falsePart
  End If
End Function

kick it on DotNetKicks.com