Tuesday, December 22, 2009

Gray Scale images in all Browsers

7 comments
Its been a while since I blogged on anything.
Today I came across a post at forums.asp.net: change color image to gray scale

GrayScale - Converts the colors of the object to 256 shades of gray.
An example will be



Since GrayScale filter is a filter present in the Internet Explorer,
we can achieve this result in IE simply by using the css property
.greyscale_filter{ 
 filter: gray;
}
or
.greyscale_filter{
 -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";
 filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
}
Here the second method is more advanced and must have Internet Explorer 5.5 or later to work properly.

There are number of filters in IE apart from GrayScale. Here are some lists

1. Static filters by MSDN
2. CSS Visual Filters
3. IE Multimedia filters reference


This is the case with Internet Explorer.
Now the big question.

Why does not the GrayScale filter work with browsers like Chrome, Firefox and Safari?
Simple. The filter is specific to IE only.

While I was searching through the internet for a good solution, I found this at SO
There I discovered a wonderful javascript coder named James Padolsey who is just 19!

Copied his GrayScale.js which according to James Padolsey is

Grayscale.js is an experimental attempt to emulate Microsoft's
proprietary 'grayscale' filter (available in most IE versions).

And it worked like a charm.

So here are the steps involved in achieving the hover effect

1. Grab the GrayScale.js from James Padolsey's site. (The link is here)

2. Add refernce to jQuery. Please note that jQuery is not required for grayscale.js - it's only used for this demo
Its better to refer jQuery like this (Read Dave Ward ka Encosia on this topic)
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
  
than
<script type="text/javascript" src="/js/jQuery.min.js"></script>
  
3. Add a small javascript snippet like this
$(document).ready(function(){
     $('img.greyonhover').hover(function(){
    grayscale(this);
   }, function(){
    grayscale.reset(this);
   })
  });
  
4. Assign the class="greyonhover" for the image you want to implement grayscale effect onhover
<img class="greyonhover" src="images/naveenj-thumb.jpg" />
  

This is all you have to do to achieve greying effect on hover. Download Source Code(9k)
Read more...

Wednesday, October 21, 2009

Selectable GridViewRow using Javascript

0 comments
Hope you have read my post about Selectable GridViewRow
If you haven't done that please do that before you proceed further.
This is a sort of sequel to that post.

Here I am making a GridView Selectable using __doPostBack(...) function

Suppose you have a GridView populated from the Products table of the NorthWind Database.

So the ASPX looks like this

<asp:GridView ID="gvwProducts" runat="server"
AutoGenerateColumns="False" 
DataKeyNames="ProductID"
DataSourceID="sdsProducts"
OnRowDataBound="gvwProducts_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Contact Name">
<ItemTemplate>
<asp:Label ID="lblProductName" runat="server"
Text='<%#Eval("ProductName") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Stock">
<ItemTemplate>
<asp:Label ID="lblunitsInStock" runat="server"
Text='<%#Eval("UnitsInStock") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>

</Columns>
<SelectedRowStyle ForeColor="Green" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
</asp:GridView>
<asp:SqlDataSource ID="sdsProducts" runat="server" 
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT ProductID, ProductName, UnitsInStock FROM Products"
SelectCommandType="Text">
</asp:SqlDataSource>



Now on RowDataBound lets set the click attribute for selectable row.
You can also use RowCreated for this.
Note that we are also giving some fancy color changes in onmouseover and onmouseout events.
Discard them if you dont want color changes.

protected void gvwProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//e.Row.Attributes["onmouseover"] = "this.style.color='DodgerBlue';this.style.cursor='hand';";
e.Row.Attributes["onmouseover"] = "javascript:return ChangeRowColor('m_over', this.style)";
//e.Row.Attributes["onmouseout"] = "this.style.color='Black';";
e.Row.Attributes["onmouseout"] = "javascript:return ChangeRowColor('m_out', this.style)";
e.Row.Attributes["onclick"] = "javascript:return __doPostBack('" + gvwProducts.ClientID.Replace('_','$') + "', 'Select$" + e.Row.RowIndex + "');";
e.Row.ToolTip = "Click on the row to select it";
}
}



Now register these postbacks for event validation at Page_Render to avoid



System.ArgumentException: Invalid postback or callback argument. Event validation is enabled using in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation



protected override void Render(HtmlTextWriter writer)
{
// .NET will refuse to accept "unknown" postbacks for security reasons. 
// Because of this we have to register all possible callbacks
// This must be done in Render, hence the override
for (int i = 0; i < gvwProducts.Rows.Count; i++)
{
Page.ClientScript.RegisterForEventValidation(new System.Web.UI.PostBackOptions(this.gvwProducts, "Select$" + i.ToString()));
}
// Do the standard rendering stuff
base.Render(writer);
}

Now compare the RowDataBound event to first example and you note some changes in the way the row attributes for onmouseover and onmouseout are set. (Check the commented lines in the RowDataBound event) What we do here is to set a foreground color "Green" to the Selected Row and persists that color onmouseout and onmouseover of the selected row. Inorder to achieve that, place this javascript function on the page.
function ChangeRowColor(eventtype, rowStyle){
if(rowStyle.color.toLowerCase() != "green"){
if(eventtype == "m_over"){
rowStyle.color='DodgerBlue';
rowStyle.cursor='pointer';
}
else{
rowStyle.color='Black';
}
}
else{
rowStyle.cursor='default';
}
}

Now some developers may get the
__doPostBack(...) object required
To circumvent this error place these on the ASPX Page Two Hidden Fields
<input type ="hidden" name ="__EVENTTARGET" value ="" />
<input type ="hidden" name ="__EVENTARGUMENT" value ="" />

Javascript Function
//



Happy Coding!
Read more...

Monday, October 19, 2009

Selectable GridViewRow

1 comments
I have always found using Select Button in GridView to select a row cumbersome.
It would be always better to click anywhere on the GridViewRow and Select the row.

Here's a snippet on how to do it.

On RowDataBound

protected void gvwProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{

e.Row.Attributes["onmouseover"] = "this.style.color='DodgerBlue';this.style.cursor='hand';";
e.Row.Attributes["onmouseout"] = "this.style.color='Black';";
e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.gvwProducts, "Select$" + e.Row.RowIndex);
e.Row.ToolTip = "Click on the row to select it";
}
}


Now if we run the code and click on the row we will get this error



System.ArgumentException: Invalid postback or callback argument.
Event validation is enabled using in configuration
or <%@ Page EnableEventValidation="true" %> in a page.
For security purposes, this feature verifies that arguments to postback or callback events originate
from the server control that originally rendered them.
If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method
in order to register the postback or callback data for validation.



To avoid this we override the Page's Render Event.
Inside that event we register an event reference for validation on each GridViewRow

The overridden Page Render

protected override void Render(HtmlTextWriter writer)
{
// .NET will refuse to accept "unknown" postbacks for security reasons. 
// Because of this we have to register all possible callbacks
// This must be done in Render, hence the override
for (int i = 0; i < gvwProducts.Rows.Count; i++)
{
Page.ClientScript.RegisterForEventValidation(new System.Web.UI.PostBackOptions(gvwProducts, "Select$" + i.ToString()));
}
// Do the standard rendering stuff
base.Render(writer);
}
Here I am posting the ASPX markup of the GridView also The ASPX
<asp:GridView ID="gvwProducts" runat="server"
AutoGenerateColumns="False" 
DataKeyNames="ProductID"
DataSourceID="sdsProducts"
OnRowDataBound="gvwProducts_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Contact Name">
<ItemTemplate>
<asp:Label ID="lblProductName" runat="server"
Text='<%#Eval("ProductName") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Stock">
<ItemTemplate>
<asp:Label ID="lblunitsInStock" runat="server"
Text='<%#Eval("UnitsInStock") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>

</Columns>
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
</asp:GridView>
<asp:SqlDataSource ID="sdsProducts" runat="server" 
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT ProductID, ProductName, UnitsInStock FROM Products"
SelectCommandType="Text">
</asp:SqlDataSource>
Just paste the last xml snippet on ASPX and first two code snippets on cs page. Change the connectionstring to the one you have and run the code to see the result. We are not finished yet From time to time, some developers will experience the "__doPostBack object expected" error in the page Postback. This occurs at the second time we try to fire the row click event The Reason
We add onclick feature for GridView in the RowDataBound event using ClientScript.GetPostBackClientHyperlink(...) But RowDataBound event gets fired only the first time(at !IsPostBack). This creates the __doPostBack() function when the page is first time loaded. Now from the second time onwards(at IsPostBack) RowDataBound doesn't get fired. So no ClientScript.GetPostBackClientHyperlink(...) is called and no __doPostBack() function is created
The solution. Just place this line under Page_Load event
protected void Page_Load(object sender, EventArgs e)
{
ClientScript.GetPostBackClientHyperlink(this, "");
}

Happy Coding! For Better understanding please read Selectable GridViewRow using JavaScript Points to Note: 1. I have given a SelectedRowStyle to show that the row is actually selected by giving it a different color. 2. The table used is Products from Microsoft's Sample DataBase Northwind
Read more...