Showing posts with label CSS. Show all posts
Showing posts with label CSS. Show all posts

Thursday, February 14, 2019

Changing Styles for print media query

I had a situation where I needed to change what would be printed based on what button on the web page the user clicked. Here is an easy way to do that.



<style type="text/css" media="print" id="printStyles">
</style>

<script>
    function printOptionA() {
        var styles = "#optionA {display: block;} #optionB {display:none;}";
        $('#printStyles').text(styles);
        window.print();
    }

 function printOptionB() {
        var styles = "#optionB {display: block;} #optionA {display:none;}";
        $('#printStyles').text(styles);
        window.print();
    }
</script>

The two functions can be called from button, hyperlinks, etc.

If the user just does a Control-P to print in the browser it will print the page as expected (neither of these changes). There is no need to undo these changes after printing.

Wednesday, February 13, 2019

Changing the first line preview in email clients

In many email clients it will now show you the first line of the email body before you open it. If you are a developer creating this email sometimes it shows things like a url of a header image instead of something more useful. The good news is you can trick the email clients into displaying whatever you want. Just make sure the first thing in your body tag (can be after the style tag, etc) is the following:

<!-- HIDDEN PREHEADER TEXT -->
<div style="display: none; mso-hide: all; width: 0px; height: 0px; max-width: 0px; max-height: 0px; font-size: 0px; line-height: 0px;">
    Whatever you want to see in the preview here
</div>

Wednesday, July 10, 2013

How to Center a DIV tag horizontally using CSS

I miss the days of using the CENTER tag. Now it seems it is not really a good idea to use the CENTER tag. It is recommended that CSS be used instead. It seems that it is a bit more difficult to do with CSS.
In this example, my DIV only contains text, but it could contain anything. If it was just text, text-align:center could be used, but to center a div tag and its contents it takes a bit more.

First thing we need to do is give the DIV a width and then it can be centered. Here is an example of how to center a DIV that is 400px wide.


<div style="width:400px; display:block; margin-left:auto; margin-right:auto>">
some stuff here
</div>


You can also create a CSS class and reference it, but I have put the style inline for simplicity, but probably not a good for maintainability.

Thankfully, this is pretty simple once you know what to do.

Friday, June 3, 2011

How to Download File from inside an UpdatePanel in ASP.NET

PartialPageRendering when used with the UpdatePanel is a great thing in general. One problem comes when you want to mess with the Response and call things like End which is required when you return want to return a file instead of the page you were on. An example of this is a GridView with a Download button below it. If you are not using the UpdatePanel then there is no problem and clicking the Download button will all you to download the file as expected. There are lots of posts on the web on how to do this so I won’t go into the code. However, it involves calling things like Response.Clear(), Response.ContentType, Response.AddHeader(), Response.End().
Now let’s assume you put the GridView in an UpdatePanel. All those Response calls noted above are things that the PartialPageRendering and UpdatePanel don’t know what to do with because they were expected something like the page that made the request. So we need to work around the issue. I found some solutions on the internet, but didn’t really find them very easy or straight forward. So, I came up with my own.

Solution 1

One solution is to put the Download button outside the UpdatePanel. This tends to work best, but is not always possible.

Solution 2

If you can’t do solution 1, then consider faking it. What I mean is move the Download button which in my case is implemented as a LinkButton outside the UpdatePanel and hide it using css. Then add a Hyperlink inside the UpdatePanel. Now, on your page load you can set the hyperlink to have the same postback url as the LinkButton that is outside the UpdatePanel. That way when you click the hyperlink inside the UpdatePanel you are effectively doing the same thing as if you clicked the hidden LinkButton that is outside the UpdatePanel. Fairly simple.
Here is the snippets of code to help you see what I am talking about.
Here is the HyperLink that is inside the UpdatePanel and is also the button that you will be clicking in the Browser.
<asp:HyperLink ID="btnExportToExcelClicker" runat="server" Text="Export all rows to Excel" />

Here is the LinkButton that is invisible to the user and is outside the UpdatePanel
<asp:LinkButton ID="btnExportToExcel" runat="server" onclick="btnExportToExcel_Click" Text="Export all rows to Excel" style="display:none;" />

Here is the code-behind. In my code btnExportToExcelClicker is the button that is in the UpdatePanel and btnExportToExcel is the button that is outside the UpdatePanel. You will actually be clicking btnExportToExcelClicker because btnExportToExcel is hidden.
protected void Page_Load(object sender, EventArgs e)
{
    btnExportToExcelClicker.NavigateUrl = Page.ClientScript.GetPostBackClientHyperlink(btnExportToExcel, null);
}

This technique uses GetPostBackClientHperlink and can be expanded for other purposes and other controls. In some cases you may need to consider using GetPostBackEventReferences, though I haven’t tried it.

UPDATED: November 5, 2013

Solution 3

This is my new favorite solution due to its simplicity. This involves creating a new page in your application. Call it ReportDownload.aspx (or whatever you desire). It is critical that it not have an update panel. Best choice is usually to not even use a master page for this. The reason is that we are not going to use anything on the ReportDownload.aspx file. We will however change the ReportDownload.aspx.cs file. On the page load just put your download streaming code that would be something similar to the following:

var response = Page.Response;
response.Clear();
response.AddHeader("content-disposition", string.Format("attachement; filename=\"{0}\"", "Report.pdf"));
response.ContentType = "application/octet-stream";
response.WriteFile(@"c:\temp\DB.pdf");
response.End();

You just need to put this in the Load or PreRender events. To test this, just go to the new page you created in your favorite browser. You should see the file you specified in the code above. Now that you know that going to the url works, it is just a matter of using that url anywhere on a page (including in an UpdatePanel). I used it in LinkButton or HyperLink. You can pass a code (i.e. a record id, etc) in the url to generate the url. The nice thing is you can also incorporate security on the ReportDownload.aspx as well.

Tuesday, April 26, 2011

AzGroups 8th Annual Scott Guthrie Event

Things to check out:

NUGET

(pronounced NEWGET) – it is built into VS2010 (Visual Studio 2010) and makes finding, downloading, and installing libraries (open source included) into your project. It even does some configuration in the config files, etc. Pretty awesome. You can get it here.

elmah

It is an error logging facility that is completely pluggable that can added to a running ASP.NET web application without re-compilation or deployment. When an exception occurs it logs it, but allows you decide where to log it to such as a database, RSS, email, etc. It also records A LOT of VERY useful information for determining what happened.  See here for more details.

IIS Express

Can be used side-by-side with the built in web server (Cassini) in VS2010. It launches fast just like the web server built into VS2010, but doesn’t require you setup virtual directories, etc like you do with IIS (full version). You now get best of both worlds. It now let’s you develop using the IIS 7.x feature-set. It is now as easy to use as the web server built into VS2010. It doesn’t require admin account. You don’t have to change any code or the way you work to take advantage of it. See Scott’s blog for more details.

Web Matrix

You should still continue to use Visual Studio for professional work, but Web Matrix project are great for hobby, family sites, etc. It has been totally reworked to be a task based tool. It makes publishing very easy. If the site gets more complex the project can be opened up in Visual Studio.

SQL Server Compact Edition 4

It is great for ASP.NET development. It is light weight and free. It is an embedded database (no SQL Server required) so it is in the binaries (bin directory) that you can xcopy to your server. You can use Standard SQL Server syntax so anything that supports the ADONET provider model (such as LINQ and EF) will work. You are also licensed to redistribute it. All this means you can now deploy this in a medium trust ASP.NET shared web hosting such as DiscountASP, GoDaddy, etc. This means you don’t have to pay for the SQL database. It integrates into VS2010 (coming soon). It is different from previous version because it is safe to use with multi-threaded environments (such as ASP.NET). and no longer blocked from being used with ASP.NET. The catch is that it is for light-usage production (4GB or less for datafile) usage scenarios and it does NOT support stored procedures. For high-volume usage usage, you’ll probably want to use SQL Server Express (which is still free), SQL Server, or SQL Azure. Also, since stored procs are not supported the ASP.NET Membership is not supported (though they will be shipping new providers so that they do). The only change to your code when you migrate is your configuration string. See Scott’s blog for more details.

 

Portable Library Project

It is a special kind of project in VS2010 that only allows code that will work on particular targets. In particular, the targets are Silverlight and Silverlight for Window Phone 7. Intellisense only lets you see Intellisense on methods, properties, classes, namespaces, etc that are compatible with both. The most I could find on it was here.

Silverlight 5

Great stuff coming with Silverlight 5. Better DataBinding support for MVVM. Improved Printing and Text. Finally there will be a 64-Bit version of Silverlight. 3D Modeling that use Hardware acceleration. 3D and 2D can be used together. Breakpoints on XAML Bindings.

MVC 3

I am really impressed with MVC3. I am very tempted to try a project with MVC3. It takes advantage of HMTL 5 including Data validation, round corners, etc.

MVC Basics

The basic idea is that a url is mapped to a controller and method on that controller. That method makes calls to the model where most of the business logic resides, and then typically returns a view which is responsible for rendering the response (page). It maps url to action methods on controller class. In general the best practice with MVC is to have skinny controllers and fat models. Default method is called Index() and is called when no action is specified. Can pass entities as parameters to methods; just need to map them. Default parameters can be used as well. (i.e. int num = 5). ASP.NET MVC forces separation, while ASP.NET Forms does not.

Routing

When determining which rule matches it starts with the one that was added first. It then proceeds down the list until one matches. Routing is used to map urls to controllers and actions, but it is also used to generate urls in the application.

Glimpse

It is a an open source tool that allows you to diagnose what is happening on the server, but from the client. It is very useful when trying to figure out what happened once your request made it to the server. For example, what route was executed. It is basically Fiddler for the server.

For more information see here.

Razor

It is a View Engine for MVC. For more info see ScottGu’s blog. Razor files are .cshtml. Tags start with @ and it automatically figures out where code ends and content begins. Content and code can be intermingled. A layout page is basically like a master page in ASP.NET Forms. You can use traditional parameters or Named parameters. Use Custom helpers for custom rendering; refactoring in a way.

MVCScaffolding package

It is a code generator for MVC; a smart one at that. Highly recommended so you don’t have to write so much code to do CRUD UIs. Use NuGet Package Manager to get and install it.

Entity Framework 4.1

Great code first support. You can use POCO objects, make changes and the database just updates. It is so cool. This behavior is optional, but very nice. You can setup database initialization code to populate some basic data when the database is dropped.

Modernizr

A great tool that allows you to take advantage of HTML 5 when it is available and downgrade when it is not. An example of this is round corners. Very nice tool that can be used in most any ASP.NET project. http://www.modernizr.com/

Windows Phone 7

Later this year there will be a new release called Mango. It is a very exciting release as it will bring the Windows Phone 7 much closer to the competition as far as its offering. To get started with Windows Phone 7 development go here. Everything that is developed for Windows 7 Phone falls into two categories: Silverlight or XNA. XNA is for games (also used for XBOX), and Silverlight is for everything else. You can import some XNA libraries (such as audio) into Silverlight. Tombstoning is basically storing state to appear like the application never quit when in fact it did. It basically works by providing a state bag that most anything can be written/read to when different events such as (navigate to and from are called). It works much like Viewstate does in ASP.NET except it is not automatic. So more specifically it works like adding and retrieving stuff to/from viewstate in ASP.NET. The cost is $99 per year to put your application (or as many as you want except not more than 15 free ones) in the Marketplace. You can register to developer unlock your Windows Phone 7. Visual Studio 2010 comes with an emulator, but the one that will be in the mango release is sooo much better because it simulates things like sensors. The talk was given by Jeff Wilcox.

Tips on Windows Phone 7 development

Change splashscreen (an image) to all black if you app launches immediately. That way it is perceived as faster and cleaner. If your app takes a few seconds to load then put in a custom splashscreen (change the image) to give a more professional look. Add scrollviewer or list so that scrolling will always be available if something doesn’t fit on the screen. Use the metro look and feel styles, don’t hard code styles. If things don’t align as expected, then use 12px margins. Promote your app by creating a site for it. Prompt a user for review of your app after you think they have used it for a while. Statistically most apps are only used once and never used again. Use Watson to collect crash information, bugs, etc. Use Google Analytics to track page navigation within your app. Keep your main dll as small as possible since the entire thing is checked before loading into memory. Delay load pages / dlls on an as needed basis to help accomplish this. This also helps with startup times. Use a tombstoning helper. Use caching whenever possible.

Windows Azure – by Scott Guthrie and Mark Russinovich

Windows Azure is a great technology that needs some work with regards to deployment speed, and in general ease of use, but it is extremely well architected for scaling your application in a very elastic way. It allows you to worry about your app and not the infrastructure it is running it. It is Microsofts offering of cloud computing. The idea is that if you need 100 servers for an event you have them. Then after the event you don’t need them. With traditional models you would have to have servers ready to go at all times and pay for that much power. Since Microsoft has a giant server farm called Windows Azure and a middle tier between you and the server OS you only pay for what you use for the length of time you use it. Everything is continually monitored for 99.? uptime.

Mark went into all the details or the architecture. He convinced me it is very complex and robust, but not so fun to listen to a discussion about it. way too much details for my interest level. However, here as some of the things I found interesting. SQL is actually much slower than the way Windows Azure does it. They actually have everything as read only. Once it is read the objects are de-serialized and used. If they need to update, they are written back to the cloud as serialized objects. This takes only a trillionth of a second instead thousandths of a second that SQL takes. This allows them to scale fast. Their belief is that in the next 10 years or so this will scenario will be common more so than the relational database. Currently options in Azure are SQL, Blobs, and Queries. I believe SQL Azure is part of Windows Azure.

Some Barriers / solutions to get over before cloud computing will be accepted are: Trust of proprietary data being outsourced; loss of control; confidence (ISO and other certifications will help); Private clouds may be an alternative; license to run in own data center may help also.

Thursday, October 14, 2010

Adding a border around text to make it look like a TextBox

The scenario applies to simple Label or Literals in ASP.NET. I am currently using a DynamicControl with the Mode set to ReadOnly. This causes the generation of a Literal and thus looks like plain text in the browser. This is great in most cases.

However, sometimes I want the text to have a border around it and maybe a different background to make it look like a read only TextBox.

Thankfully there is an easy solution. Using CSS we can define a style

.DDTextWithBorder
{
        border: solid 1px #bcbcbc;   
}

We could include background color if we wanted to change that also.

To use the style, we can put a span tag around whatever we want the border around and setting the class=”DDTextWithBorder” attribute.

An example of that is:

<span class="DDTextWithBorder"><asp:DynamicControl ID="TotalPointsDynamicControl" runat="server" DataField="TotalPoints" Mode="ReadOnly"/></span>

Another way is to just set the CssClass property of the control we want to put a border around.

<asp:DynamicControl ID="TotalPointsDynamicControl" runat="server" DataField="TotalPoints" Mode="ReadOnly" CssClass="DDTextWithBorder"/>

That’s it. Quite simple, but powerful.

Thursday, June 11, 2009

Controlling Opacity of a background color using CSS

If you want want to have a background color be semi-transparent (a color with opacity of less than 100%), Cascading Style Sheets (CSS) may be what you have been looking for.

FireFox and Internet Explorer implement the feature differently. However, both implements can co-exist in one CSS class so there is no need for fancy code to swap between the two depending on the browser.

.mySemitransparentBackground {
background-color: Gray;
filter:progid:DXImageTransform.Microsoft.alpha(opacity=70);
opacity: 0.7;
}

In this example, the background color is Gray, but could be any color. The line that starts filter is for Internet Explorer, and the line that starts with opacity is for FireFox. Notice that Internet Explorer takes the value 70 to specify that the color is 70% opaque, and FireFox use the decimal version which is 0.7 to specify the same 70% opacity. Note, that 100% means that your color will be solid / not transparent (no background will be seen through it). Be sure both values represent the same value, otherwise you will get different opacity for each browser.

NOTE: I have verified that the FireFox stuff also works for Safari on Windows. If anyone else confirms any other browsers or platforms, please let me know. Thx!

Tuesday, May 12, 2009

How to get FireFox to wrap PRE tag text

For some reason FireFox does not wrap code or other text (with no good word-breaking point) that is in a PRE tag. I noticed the problem when I was trying to stop a Blogger template from truncating (cutting of) the end of lines (that were too long). I want FireFox to wrap the long lines just like Internet Explorer. As it turns out, it is quite easy to fix. Just add the following to your CSS styles.

pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

Friday, March 6, 2009

ASP.NET GridView Scrollable area and Fixed Header Solution

I have search long and hard and spent much of my own time trying to find a good Fixed Header and Scrollable rows for the ASP.NET GridView. I think I have finally come up with a combination of my own efforts and the best of borrowed from other solutions. Unfortunately, I didn't keep track of where I got some of the code that I borrowed. My apologies to the original authors.

This solution attempts to remedy all the buggy solutions I found on the internet. Some of the common problems were

  • The solution did work for the GridView
  • The solution assumed we had more control of the generated html from the GridView
  • The solution required modifying the html generated by the GridView
  • The solution stopped working when windows is resized
  • The solution assumed that there was only one scrollable area on the page. (To be fair, my solution doesn't assume this, but it would require some duplication of style sheets, jscript code, etc.)

Here is a sample implementation of my solution. It works quite well with only one scrollable area that has a fixed header. You will need to change duplicate the JavaScript file and CSS and all references to "container" if want more than one scrollable area that has a fixed header. Another alternative is to generate a customized .css .js file based on a special url. That is beyond the scope of this though.

There are several key things I would like to point about the .aspx page. The .js and .css are just really items you need to reference and don't really require any changes (except as noted above). So, I really just want to highlight what you would need to add to your page (that has a working GridView that does not have any special Fixed column header) to make this solution work.

  1. The DOCTYPE line is VERY important. This is NOT the default that Visual Studio adds to your page. Replace the line that Visual Studio puts in your .aspx page with the one shown below.
  2. Copy and Paste the GridView1_PreRender event handler to your .cs file. If you have a different name for your GridView you will need to change references to it to make the name you gave it. You will also want to set the height and width that you want. A word of warning, I did not implement the width yet, so actually that doesn't do anything. Currently the width of the GridView is not set here. Don't forget to change the references to GridView1 in the literals to match the name you use. Also, un/comment the appropriate example. If you want the GridView to be the Maximum height available and expand as the window resizes use the SetFixedHeaderWithMaxHeight call. Otherwise, if you want a fixed height, use the SetFixedHeader example.
  3. Register the GridView1_PreRender event handler with the GridView1. One easy way to do this is to add the following line to the GridView1 tag.
    OnPreRender="GridView1_PreRender"
    NOTE: You will of course need to make this match what you specified in step 2.
  4. Create a .css file by copying the CSS lines below into its own file. Alternatively, you could just include it in a style tag in the head of the page, though I don't recommend this approach.
  5. Create a .js file by copying the JavaScript lines below into its own file. Alternatively, you could just include it in a script tag in the head of the page, though I don't recommend this approach.
  6. Reference the .js and .css file in the head of the page.
  7. Copy and Paste the HeaderStyle tag in the GridView.
  8. Copy and Paste the DIV tag that has the id="container" and is directly around the GridView. It is important that there is no other DIV tags or other tags in between the DIV and the GridView. If you change this, you will need to make changes to the CSS and JavaScript.

<%@ Page Language="C#" %>

<!-- This comment keeps IE6/7 in the reliable quirks mode -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
http://www.w3.org/TR/html4/loose.dtd">


<script runat="server">
    protected void GridView1_PreRender(object sender, EventArgs e)
    {
        if (GridView1.Rows.Count > 0)
        {
            //This replaces <td> with <th> and adds the scope attribute
            GridView1.UseAccessibleHeader = true;

            //This will add the <thead> and <tbody> elements
            GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;
        }

        GridView1.Style["border-collapse"] = "separate";

        string height = "450px";
        string width = "200px";
        string gv1FixedHeaderJScript = string.Format("SetFixedHeader('{0}', '{1}', '{2}');", GridView1.ClientID, height, width);

        // MAX Height Example
        string gv1FixedHeaderJScript = string.Format("SetFixedHeaderWithMaxHeight('{0}', '{1}', '{2}');", GridView1.ClientID, width, "20px");

        // Fixed Height Example
        //ScriptManager.RegisterStartupScript(this, this.GetType(), "gvGridView1FixedHeaderKey", gv1FixedHeaderJScript, true);


    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>GridView Test</title>
    <link href="FixedHeader.css" rel="stylesheet" type="text/css" />
    <script language="JavaScript" src="FixedHeader.js"></script>
</head>
<body>
    <form id="form1" runat="server">
   
     <div id="container" style="border-style:none;">
        <asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource1"
            OnPreRender="GridView1_PreRender">
         <HeaderStyle CssClass="DataGridFixedHeader" />
        </asp:GridView>
       
    </div>
        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetDelinquentActions"
            TypeName="DAL"></asp:ObjectDataSource>
    </form>
</body>
</html>


// JScript File

// This is the function that gets called to resize the scrollable area to the size we want.
// We have to use the setTimeout() with a 1ms delay IF we call this function
// from within the form tag instead of just before the bottom of the body end tag.
// The reason is that in IE any of the height and width (scrollHeight, offsetHeight, style.height)
// are not set until after the form has finished rendering. This means, that the call to the
// SetFixedHeader2 method must occur after the form has been rendered. When using master pages
// as we are doing the location we need can only be specified in the .aspx page of the master page.
// Since we use this setting for different pages we can't hard code it there.
// Also, we can't use the ScriptManager.RegisterStartupScript unless we use the
// setTimeout either. This is because using this method puts the code just before the form end tag,
// which is again not where we need it to be. However, using setTimeout allows us to use this method.
function SetFixedHeader (gvClientID, height, width)
{
    var expr = "SetFixedHeader2('" + gvClientID + "', '" + height + "', '" + width + "')"
    setTimeout(expr, 1);
}

// This is essentially the same as SetFixedHeader function except the height is
// always going to be the height on the body - bottomMargin - top of GridView.
// bottomMargin is the number of pixels that create the gap between the bottom of
// the window and the bottom of the GridView
function SetFixedHeaderWithMaxHeight (gvClientID, width, bottomMargin)
{
    // get the max height that the GridView can be
    var maxHeight = getMaxHeight() - parseInt(bottomMargin);
   
    // We need to resize the GridView when the Window is resized
    window.onresize = MaximizeGridViewScrollableArea;
       
    var expr = "SetFixedHeader2('" + gvClientID + "', '" + maxHeight + "', '" + width + "')"
    setTimeout(expr, 1);
   
    gridViewClientID = gvClientID;
    desiredHeight = maxHeight;
    desiredWidth = width;
    desiredBottomMargin = bottomMargin;
}

function MaximizeGridViewScrollableArea()
{
    SetFixedHeaderWithMaxHeight(gridViewClientID, desiredWidth, desiredBottomMargin);
}

var gridViewClientID = null;
var desiredHeight = null;
var desiredWidth = null;
var desiredBottomMargin = null;

// height - string - the height of the scrollable area in pixels (not percent) i.e. 330px
// width - string - the width of the scrollable area in pixels or percent i.e. 600px or 50%
function SetFixedHeader2 (gvClientID, height, width)
{   
    // get numeric values for height and width
    var heightNum = parseInt(height);
   
    // adjust the size since the grid view needs to be slightly smaller
    // than the container div
    var heightAdjustment = 40;
    heightNum = heightNum - heightAdjustment;
   
    // do we need scrolling or not?
   
    var gv = document.getElementById(gvClientID);
    var tbody = null;
   
    // loop through the four (or fewer) child nodes of the table
    // and find the tbody node
    for (var i=0; i<gv.childNodes.length; i++)
    {
        var child = gv.childNodes[i];
       
        if (child.tagName)
        {
            if (child.tagName.toUpperCase() == "TBODY")
            {
                tbody = child;
                // we found what we needed, exit the loop
                i = gv.childNodes.length;
            }
        }
       
    }
   
    if (tbody != null)
    {
   
        var gvDiv = GetDivGeneratedByGridView();
       
        // scrolling is needed
        if (parseInt(tbody.scrollHeight) > parseInt(heightNum))
        {
        //alert('needs scrolling');
            //tbody.style.height = height;
            tbody.style.height = (heightNum) + "px"
                     
            if (gvDiv != null)
            {
                // add the height adjustment back in for the container, so it is bigger
                gvDiv.style.height = (heightNum + heightAdjustment) + "px";
            }
        }
        // scrolling is NOT needed
        else
        {
        //alert('NO scrolling');
            tbody.style.height = '100%'
           
            if (gvDiv != null)
            {
               
                gvDiv.style.height = "100%";
            } 
        }        
    }
}

// returns the DIV surrounding the GridView.
// NOTE: This is NOTE the DIV with id="container" that we added.
// This is the DIV that is generated by the GridView when it is rendered.
// This the DIV between teh DIV with id="container" and the table that is
// generated by the GridView.
function GetDivGeneratedByGridView()
{
    // set the size of the container div to be just a little bigger
    // than the grid view
    var container = document.getElementById("container");
   
    var isIE = typeof container.children == 'object';
    var gvDiv = null;
   
    if (isIE)
    {
        gvDiv = container.children[0];   
    }
    else // Firefox
    {
        // NOTE: First childNode is a textnode that is a new line
        gvDiv = container.childNodes[1];   
    }
   
    return gvDiv;
}


// get the max height the GridView can have
// NOTE: This is based on where the GridView is vertically on the page
//       For example, if the GridView is 100 pixels from the top of the
//       top of the body, then this will return the height of the body - 100.
function getMaxHeight() {
  var div = GetDivGeneratedByGridView();
 
  myHeight = 0;
//  alert(document.body.topMargin);
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myHeight = window.innerHeight;
  } else if( document.documentElement && document.documentElement.clientHeight) {
    //IE 6+ in 'standards compliant mode'
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && document.body.clientHeight) {
    //IE 4 compatible
    myHeight = document.body.clientHeight;
  }

  var maxGridViewHeight = myHeight - div.offsetTop;

  return maxGridViewHeight;
 
 
}



/*** The Fixed Header Stylesheet ***/

.DataGridFixedHeader { POSITION: relative; TOP: expression(this.parentNode.parentNode.parentNode.scrollTop-1);}

#container div {
 overflow: auto; /* so the extra columns and rows flow as needed */
 margin: 0 auto;
 }

#container table {
 width: 99%;  /*100% of container produces horiz. scroll in Mozilla*/
 
 /* Gets rid of the 1 pixel space on the top of the header that shows through when scrolling */
 border: none ! important;
 }
 
#container table>tbody {  /* child selector syntax which IE6 and older do not support*/
 overflow: auto;
 overflow-x: hidden;
 }
 
#container thead tr {
 position:relative;
 top: expression(offsetParent.scrollTop); /*IE5+ only*/
 }
 
#container table tfoot tr { /*idea of Renato Cherullo to help IE*/
      position: relative;
      overflow-x: hidden;
      top: expression(parentNode.parentNode.offsetHeight >=
   offsetParent.offsetHeight ? 0 - parentNode.parentNode.offsetHeight + offsetParent.offsetHeight + offsetParent.scrollTop : 0);
      }

#container td:last-child {padding-right: 20px;} /*prevent Mozilla scrollbar from hiding cell content*/

#container thead td, thead th {
 
 /* the background color for the header to something other than transparent
  so that the rows don't show behind while scrolling */
 background-color:white;
 
 }
 
 
/*** Purely Cosmetics ***/

#container div {
 width: 99%;  /* table width will be 99% of this*/
 height: 50px;  /* a small efault value so user won't really see resize if delay rendering 1ms. it is changed by the SetFixedHeader() javascript function. Must be greater than tbody*/
 } 

/*** print style sheet ***/

@media print {

#container div {overflow: visible; }
#container table>tbody {overflow: visible; }
#container td {height: 14pt;} /*adds control for test purposes*/
#container thead td {font-size: 11pt; }
#container tfoot td {
 text-align: center;
 font-size: 9pt;
 border-bottom: solid 1px slategray;
 }
 
#container thead {display: table-header-group; }
#container tfoot {display: table-footer-group; }
#container thead th, thead td {position: static; }

#container thead tr {position: static; } /*prevent problem if print after scrolling table*/
#container table tfoot tr {     position: static;    }

}


/*** Global Print Styles ***/
@media print {

.noprint {display: none;}

body {
 font-family:"Palatino Linotype", Georgia, Garamond, serif;
 background-image: none;
 }
 
#container {
 border: none;
 padding: 0;
 }

}

Wednesday, September 10, 2008

Override any CSS style (even inline styles) no matter where it is defined

Cascading Style Sheets (CSS) are very nice for formatting HTML. In general, I think it is a very bad idea for an ASP.NET control to emit inline styles because it prevents the developer from overriding the formatting. This is of course unless there is a corresponding property or programmatic way provided of changing it.

The ASP.NET GridView is a great example of this. It emits the following inline style for the table tag it emits.

style="border-collapse:collapse"

If I want to change that *they* provide no way to do so.

However, CSS does provide a way to that I recently found here http://home.tampabay.rr.com/bmerkey/cheatsheet.htm.

So, all I have to do is create a CSS class called something like GridViewStyle by including the following between the head tags on the .aspx page.

<style>
.GridViewStyle { border-collapse:separate ! important; }
</style>

This is the key to this entire solution. Notice the ! important; This means that border-collapse will be set to separate even if the inline style says differently. This is *very* powerful.

To apply this CSS class to the table tag that is emitted by the GridView all we have to do is set the CssClass property of the GridView to GridViewStyle.

Tuesday, August 26, 2008

Hide the bookmarks menu in FireFox 2 and 3

There are many reasons you may want to hide the Bookmarks menu in Firefox. Usually because you have some add-ons that give you similar functionality that you want to use. What ever the reason here is how you hide it.

Open the file userChrome.css which is located at: C:\Documents and Settings\<your username>\Application Data\Mozilla\Firefox\Profiles\<some code>.default\chrome\userChrome.css

In Firefox 2.x add the following to this file
 
#bookmarks-menu {
    display: none;
}


In Firefox 3.x add the following to this file

#bookmarksMenu {
    display: none;
}

Tuesday, July 22, 2008

Adding a loading animation to your AJAX requests

I think AJAX is great. It can be a little confusing for the user if the response is not immediate though. In cases like these it is nice to give the user some feedback so that they know that something is happening and when it is done. I like to a little spinning wheel or something to indicate this condition. You can easily add this to most requests that are AJAX based with only a few lines of code.

// register the event listeners so we will receive the events 
//when they are fired by the AJAX.NET framework
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequest);

function BeginRequest(sender, args) {
  // srcElement is the object that invoked the AJAX call. For example, maybe a textfield
  var srcElement = args.get_postBackElement();
 
  // the path should point to a nice animated gif.
  srcElement.style.backgroundImage = 'url(images/loading.gif)';
  srcElement.style.backgroundRepeat = "no-repeat";
  srcElement.style.backgroundPosition = "right";
}

You can use what ever image you want for the animation. I like this one from the AJAX toolkit. It is from the DynamicPopulate Demo

Wednesday, October 10, 2007

Image alignment in HTML / CSS

Let's assume you have a line that starts with an image with text to the right of it. By default the image and text are vertically aligned to the bottom of the image and the baseline (bottom except for letters like g, j, y, etc) of the text. To make the image be centered on the line of text you do the following.

<img border="0" src="myImage.gif" style="vertical-align:middle"/>my text that is to the right of the image.