Showing posts with label Tips/Tricks. Show all posts
Showing posts with label Tips/Tricks. Show all posts

Wednesday, September 23, 2009

Using Variabled TOP Select Statements

After a day of trying to figure out how to get a stored procedure to work for me, I ran across something that makes my life a heck of a lot easier. I always assumed this didn't work because I could never figure out the syntax, but luckily it does! Ever need to select a certain number of rows based off a variable? You can use the following to do just that:

SELECT TOP (@top) * FROM <table>
Now, if you need a certain number of random rows you can also use the following:
SELECT TOP (@top) * FROM <table> ORDER BY NEWID()

Note: This is only applicable in SQL Server 2005+. 2000 you need to use dynamic SQL or a subselect.

Wednesday, September 09, 2009

Getting The Pixel Width And Height Of A String

I've recently been making an application that required a popup image to dynamically appear beside text, which is variable in length. Since I always want the image to show up 15px to the right of the text, I needed to get the width of the string. What I could do (if you are positive of the font face it's show in) is take the average width of each character, get the number of characters and get the width that way. However, you throw in a few "..." or move between browsers that have differeing rendering for the same font and you may be SOL depending on your application.

I was looking around the web for a solution and found the following article. The article had an example with an existing TD, however, what you're doing, and what I did, may not be in a TD. So I came up with the following to make it dynamic:

function GetStringPixelWidth(str)
{
var elem = document.createElement('SPAN');
elem.innerHTML = str;
elem.style.visibility = 'hidden';
document.body.appendChild(elem);
var w = elem.offsetWidth;
document.body.removeChild(elem);
return w;
}

One must append it to the document so the offsetWidth is actually calculated. I added it to the body, but you can add it to the parentElement that str is coming from so you can get the width of wrapping text.

UPDATE: I found that in Mozilla FireFox, adding the TD doesn't work. In light of this, I've updated the code to instead add a SPAN element. I'm thinking FF doesn't know how to handle adding a single TD into the document; it kept returning 2 as the offsetWidth. It didn't matter if I created TABLE and TR elements and nested them. Always 2. With the span, it's still a dynamic width, unlike DIVs, and can be independently added to the page with no issues.

Tuesday, July 14, 2009

Missing __doPostBack Method On ASP.NET Page

Sometimes, ASP.NET programming has called for a JavaScript call to .NET's JavaScript function __doPostBack. This function exists on (almost) every .aspx page with controls that would create a postback. Once in a while, however, you won't have a control that creates a postback (or for some other odd reason) and the __doPostBack function won't be available. In these situations, you can create your own custom method.
  1. Add two hidden fields to hold the postback information. You can add these anywhere on the page.

    <asp:HiddenField ID="__EVENTTARGET2" runat="server" />
    <asp:HiddenField ID="__EVENTARGUMENT2" runat="server" />

  2. Create a custom JavaScript __doPostBack method. I often call it __doPostBack2 just incase for some reason the original is created. Don't want to confuse the application. form1 is the form name. It might be ASPForm or something. Best way to find out is to view the source of the page and use that.

    function __doPostBack2(target,argument)
    {
    var f = document.getElementById('form1');
    document.getElementById('__EVENTTARGET2').value = target;
    document.getElementById('__EVENTARGUMENT2').value = argument;
    f.submit();
    }

  3. Add the postback function to the element in question.

    <input id="txt1" type="text" ondblclick="javascript:__doPostBack2(this.id,this.value);" />
Next up: Adding custom events to controls.

Tuesday, June 30, 2009

Custom Link In Gridview

One control I try to use as much as possible is the Gridview. Quick, simple and customizable, for it's purpose, to the 'T'. I do wish that the Gridview allowed more customization in the area of display. Several times I've a display that required full width column spans throughout the table for some reason and I've had to resort to building my own HTML and injecting it into a div or literal control. But, when I can, I use the Gridview.

One hold back is that the Gridview has the command buttons, which is Update, Delete, etc, but only if tied to a data source object, which I'm not sure if anyone uses. I often find that I need to put in a "View" linkbutton. But how do we capture the linkbutton postback and then tie that to the correct ID of the row and execute what we need to?

Let's say we have a program that develops tests and we have a Gridview that displays a list of all tests: Name (bound), Date Created (bound), View (item template > link button). Let's name the View linkbutton lnkView for convention-sake. If there's one thing that good security calls for it's almost NEVER showing database IDs. Just not a good idea. So, where do we store the test's ID that we want to view for each row? Easy, in the link button. You can do the following to rename each lnkView to hold the ID of the given test of that row, given that ds is a DataSet holding your data from the database:

Protected Sub GridView1_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.DataBound
Dim rowIndex As Integer = 0
For Each gvr As GridViewRow In GridView1.Rows
Dim lnk As LinkButton = CType(gvr.FindControl("lnkView"), LinkButton)
lnk.ID = "lnkView" + ds.Tables(0).Rows(rowIndex)("ID").ToString
rowIndex += 1
Next
End Sub

Now that all of your lnkViews have been renamed, you can now capture it when a user clicks on it. In the page load event, wrapped in a IsPostBack If statement, you can enter this to determine if the lnkView has been clicked and grab the ID of the test that it corresponds to:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then
If Request("__EVENTTARGET").ToString.Contains("lnkView") Then
Dim TestID As Integer = CInt(Replace(Request("__EVENTTARGET").ToString, "lnkView", ""))
End If
End If
End Sub

We kept "lnkView" in the lnkView's ID so we can easily decide if the postback target is the link button we're looking for. The Request("__EVENTTARGET") grabs the ID of the control that caused the postback, in this case the lnkView linkbutton. The Request might return the ClientID so it might looks something like:

ctl00$GridView1$ctl02$lnkView181

but you can just parse it.

Monday, June 29, 2009

CSS Z-Index

One CSS rule (as I have come to learn them to be called) that is a pain in the ass is the Z-Index. Why? Because it works the way you want it about 60% of the time every time. Besides the obvious movie reference (Anchorman for anyone not familiar), it's just a confusing rule. Basically, it allows the programmer to stack elements on the Z-Index, as the rule name so aptly describes. So here are some basic guides to Z-Index.
  1. You should try any other possible method to get the stacking order you wish before using Z-Index
  2. If Z-Index is the only way to go, every stacking element must have the CSS property 'position' set to 'absolute' or 'relative'
  3. The lower the Z-Index, the lower in the stack it goes (less visible).
That's about it. Again, I hate Z-Index, but I do find that sometimes you have to use it...

Wednesday, June 24, 2009

Centering A Page Layout Using CSS

One thing that often stumps new developers is how to center a page layout for a site. It is often over looked by rookies that display changes when you change the window size, and putting a margin-left CSS tag will not show a centered page layout when you increase or decrease the window size. So, in order to have a centered page layout that will work in any browser at any resolution, you can use the following:

<style>
#frame
{
position:absolute;
left:50%;
width:780px;
margin-left:-390px;
}
</style>

<div id="frame">
[page content]
</div>

position:absolute; pulls the div up out of relative positioning, allowing you to place it anywhere. The 'left:50%' puts the left edge of the div in the center of the page. We then set the width of the div, in this case 780px. Then, to center the div's center to the page's center, we pull back the left margin by half the width of the div; in this case -390px. If the width were set to 700px, the margin-left would then be -350px.

That's it. Easy, pretty, and works cross-browser/resolution.

Monday, June 22, 2009

Text Output Parameters For SQL Server 2005 - Tip

I've decided to change this blog into a programming tool and publish tips, tricks and insights. For my first post in my newly formatted blog, I decided to keep it simple and reveal a little tip for people who might have suffered the same confusion. If you are hitting a SQL Server 2005 (and perhaps 2000) and are receiving a text output parameter, you might have received perhaps only the first letter of your expected output, even if when you run the query inside the DBMS it returns the entire string. The answer: the size property. It seems the default size for a varchar or nvarchar output parameter is only one character. So, to receive any and all returned text, you must set the size, such as the following:

Dim retSupp As SqlParameter = cmd.Parameters.Add("@@returnMsg", SqlDbType.VarChar)
retSupp.Size = Integer.MaxValue
retSupp.Direction = ParameterDirection.Output

If you expect a crazy large string in return, you can changed Integer.MaxValue to Long.MaxValue and get the same effect.