Saturday, July 26, 2008

Paging in ListView

5 comments
Paging in ListView is pretty different from Paging in GridView.
We page data on a ListView using DataPager.
Its a joyful ride that has so many features we have dreamed of
ListView with Top and Bottom Pagers attached to it
Paging in GridView is with a twist and not an extension of gridview paging.
It uses the ListView event for Paging called
"OnPagePropertiesChanging"

Here is an example of doing it using two datapagers so that paging gets displayed
both on top and bottom of the page (google serach page style)
As used at almost all my examples, the database Northwind is used.

In ASPX

The Top Pager

<asp:UpdatePanel ID="updPanel" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <div class="pager">
            <asp:DataPager ID="pgrTopDetails" runat="server"
                    PageSize="10"
                    PagedControlID="ListView1">
                <Fields>
                    <asp:NextPreviousPagerField ButtonCssClass="command"
                                        PreviousPageText="Previous"
                                        RenderDisabledButtonsAsLabels="true"
                                        RenderNonBreakingSpacesBetweenControls="true"
                                        ShowFirstPageButton="false"
                                        ShowNextPageButton="false"
                                        ShowLastPageButton="false"
                                        ShowPreviousPageButton="true"/>
                    <asp:NumericPagerField ButtonCount="10"
                                        NumericButtonCssClass="command" 
                                        CurrentPageLabelCssClass="current" 
                                        NextPreviousButtonCssClass="command"
                                        RenderNonBreakingSpacesBetweenControls="true"/> 
                    <asp:NextPreviousPagerField ButtonCssClass="command"
                                        NextPageText="Next"
                                        RenderDisabledButtonsAsLabels="true"
                                        ShowFirstPageButton="false"
                                        ShowPreviousPageButton="false"
                                        ShowNextPageButton="true"
                                        ShowLastPageButton="false" />
                </Fields>
            </asp:DataPager>
        </div>
        <asp:ListView ID="ListView1" runat="server"
                    DataKeyNames="ProductID"
                    OnPagePropertiesChanging="ListView1_PagePropertiesChanging">
            <LayoutTemplate>
                <table class="datatable">
                    <tr>
                        <th>ID</th>
                        <th>Name</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>In Stock</th>
                        <th>On Order</th>
                    </tr>
                    <tr id="itemPlaceholder" runat="server"></tr>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr class="row">
                    <td><%# Eval("ProductID") %></td>
                    <td><%# Eval("ProductName") %></td>
                    <td><%# Eval("QuantityPerUnit") %></td>
                    <td><%# Eval("UnitPrice") %></td>
                    <td><%# Eval("UnitsInStock") %></td>
                    <td><%# Eval("UnitsOnOrder") %></td>
                </tr>
            </ItemTemplate>
        </asp:ListView>
        <div class="pager">
            <asp:DataPager ID="pgrBottomDetails" runat="server"
                        PageSize="10"
                        PagedControlID="ListView1">
                <Fields>
                    <asp:NextPreviousPagerField ButtonCssClass="command"
                                        PreviousPageText="Previous"
                                        RenderDisabledButtonsAsLabels="true"
                                        RenderNonBreakingSpacesBetweenControls="true"
                                        ShowFirstPageButton="false"
                                        ShowNextPageButton="false"
                                        ShowLastPageButton="false"
                                        ShowPreviousPageButton="true"/>
                    <asp:NumericPagerField ButtonCount="10"
                                        NumericButtonCssClass="command" 
                                        CurrentPageLabelCssClass="current" 
                                        NextPreviousButtonCssClass="command"
                                        RenderNonBreakingSpacesBetweenControls="true"/> 
                    <asp:NextPreviousPagerField ButtonCssClass="command"
                                        NextPageText="Next"
                                        RenderDisabledButtonsAsLabels="true"
                                        ShowFirstPageButton="false"
                                        ShowPreviousPageButton="false"
                                        ShowNextPageButton="true"
                                        ShowLastPageButton="false" />
                    <asp:TemplatePagerField>
                        <PagerTemplate>
                            <br />
                            Displaying&nbsp;<%# Container.StartRowIndex + 1 %>&nbsp;to&nbsp;
                            <%# Container.StartRowIndex + Container.PageSize %>&nbsp;of&nbsp;
                            (<strong><%# Container.TotalRowCount%></strong>) Profiles Found.
                        </PagerTemplate>
                    </asp:TemplatePagerField>
                </Fields>
            </asp:DataPager>
        </div>                             
    </ContentTemplate>
</asp:UpdatePanel>



In ASPX.CS

private static NorthwindClassesDataContext database;
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        database = new NorthwindClassesDataContext(ConfigurationManager
                        .ConnectionStrings["NorthwindConnectionString"]
                        .ConnectionString);
        BindListView();
    }
}
protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
    this.pgrTopDetails.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
    this.pgrBottomDetails.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
    //custom function to bind your listview
    BindListView();
}

private void BindListView()
{
    ListView1.DataSource = database.Products.OrderBy(p => p.ProductID);
    ListView1.DataBind();
}


Download Source Code(16kb)

Simple enough, right?
Happy Coding!

P.S: The above shown style is a shameless port of gridview style by Matt Berseth.

He is a wonderful coder with so many superb wonders done on DataPresentation Controls at .NET
Read more...

Thursday, July 17, 2008

Nested GridView

7 comments
Sometimes there will be tables in databases corresponding to another ones
Suppose we have a table named Customer and another named Orders(made by each customer)
In that case it will be better to use Nested GridView.
Here we are making it a little fancier using Javascript.

Here is a ScreenShot of the Nested GridView



Prequisites

1.Create a folder in your project called "Images" and put two images
arrowright.jpg and arrowdown.jpg which are arrows pointing to the defined directions.

2.Create a ConnectionString named "NorthWindConnectionString" in the web.config pointing to the Northwind DB in your system

In ASPX Page
<asp:GridView ID="GridView1" runat="server"
AllowPaging="True"
AutoGenerateColumns="False"
DataKeyNames="CustomerID"
DataSourceID="SqlDataSource1"
PageSize="20"
OnRowDataBound="GridView1_RowDataBound" 
CellPadding="4" 
ForeColor="#333333" 
GridLines="None">

<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />


<Columns>
<asp:TemplateField>
<ItemTemplate>
<a href="javascript:ShowChildGrid('div<%# Eval("CustomerID") %>');">
<img id="imgdiv<%# Eval("CustomerID") %>" 
alt="Click to show/hide orders" 
border="0" 
src="Images/arrowright.jpg"/>
</a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
<asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="PostalCode" HeaderText="PostalCode" SortExpression="PostalCode" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
<asp:TemplateField>
<ItemTemplate>
</td>
</tr>
<tr>
<td colspan="100%">
<div id="div<%# Eval("CustomerID") %>" style="display:none;position:relative;left:25px;" >
<asp:GridView ID="GridView2" runat="server"
AutoGenerateColumns="false"
DataKeyNames="OrderID"
EmptyDataText="No orders for this customer."
Width="80%" 
CellPadding="4" 
ForeColor="#333333" 
GridLines="None">
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<Columns>
<asp:BoundField DataField="OrderDate" HeaderText="Order Date" DataFormatString="{0:MMM-dd-yyyy}" HtmlEncode="False" />
<asp:BoundField DataField="ShippedDate" HeaderText="Shipped Date" DataFormatString="{0:MMM-dd-yyyy}" HtmlEncode="False" />
<asp:BoundField DataField="ShipCity" HeaderText="Shipped To" />
</Columns>
</asp:GridView>
</div>
</td>
</tr>
</ItemTemplate>
</asp:TemplateField>
</Columns>        
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
ConnectionString="<%$ ConnectionStrings:NorthWindConnectionString %>"
SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName], [Address], [City], [PostalCode], [Phone] FROM [Customers]">
</asp:SqlDataSource>


In ASPX.CS Page

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
GridView gv = (GridView)e.Row.FindControl("GridView2");
SqlDataSource dbSrc = new SqlDataSource();
dbSrc.ConnectionString = ConfigurationManager.ConnectionStrings["NorthWindConnectionString"].ConnectionString;
dbSrc.SelectCommand = "SELECT * FROM Orders WHERE CustomerID = '" + GridView1.DataKeys[e.Row.RowIndex].Value + "' ORDER BY OrderDate";
gv.DataSource = dbSrc;
gv.DataBind();
}
}


Put this JavaScript in the header of your ASPX Page


function ShowChildGrid(obj)
{
var div = document.getElementById(obj);
var img = document.getElementById('img' + obj);
var theFlag = div.style.display == "none";
div.style.display = (theFlag) ? "inline" : "none";
img.src = (theFlag) ? "Images/arrowdown.jpg" : "Images/arrowright.jpg";
}


Happy Coding!
Read more...

Trim(Remove Spaces) using JavaScript

0 comments
Here is a simple JS function to trim the outer spaces inside a string.
Mainly used while validating User Inputs.

These are the three methods that we normally use

Method 1

Write a TrimString function using regular expression and call it when needed.

function TrimString(stringToTrim){
    return stringToTrim.replace(/^\s+|\s+$/g,"");
}

Now call it like

 var trimmedString = TrimString("    string to be trimmed         ");

If you alert trimmedString, you will get the value "string to be trimmed"

OR Method 2

If you want a more generic function for trimming, I would suggest taking a piece from Douglos Crockfords Remedial Javascript
Here we are extending the javascript String object with our own trim() function.
This is how we do that.
Declare the following prototype on the top of your page before any call to trim() occurs

if (!String.prototype.trim) {
    String.prototype.trim = function () {
        return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, "$1");
    };
}

Now trim the string like

var str = "    string to be trimmed         ";
var trimmedString = str.trim();

OR Method 3

And if you are using jQuery, its much simpler.
jQuery natively has the trim() functionality and so just call it
No points for guessing that though! [:)]
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
var str = "    string to be trimmed         ";
var trimmedString = jQuery.trim(str);

Read more...

GridViewRow as Hyperlink

1 comments
This is a simple technique used in the RowDataBound event of a GridView so that its Entire Row acts as a HyperLink.
For Visual effects styles are applied at mouseover and mouseout.
The cursor is also given a hand like appearance to show the row is a hyperlink


protected void GridView1_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"] = "window.navigate('NavigatedPage.aspx?id=" + e.Row.RowIndex + "')";
// can send anything as querystring
}
}

Read more...

Popup Style DIV using Javascript

8 comments
Update at November 10, 2010:

I am appalled by the numbers of visits this link is getting. Go through it just to understand how its basically done. But I suggest you dont use this code at all :)

Instead, use Malsup's Wonderful jQuery BlockUI Plugin : Demos are here


This sample is to create a pop-up using a DIV in the same page as passing values to and from the pop-up is easier

The Demo Pics are

Before Click



After Click



The CSS.

.opaqueLayer
{
display:none;
position:absolute;
top:0px;
left:0px;
opacity:0.6;
filter:alpha(opacity=60);
background-color: #000000;
z-Index:1000;
}

.questionLayer
{
position:absolute;
top:0px;
left:0px;
width:350px;
height:200px;
display:none;
z-Index:1001;
border:2px solid black;
background-color:#FFFFFF;
text-align:center;
vertical-align:middle;
padding:10px;
}

The Javascript.

function getBrowserHeight() {
var intH = 0;
var intW = 0;

if(typeof window.innerWidth == 'number' ) {
intH = window.innerHeight;
intW = window.innerWidth;
}
else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
intH = document.documentElement.clientHeight;
intW = document.documentElement.clientWidth;
}
else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
intH = document.body.clientHeight;
intW = document.body.clientWidth;
}
return { width: parseInt(intW), height: parseInt(intH) };
}

function setLayerPosition() {
var shadow = document.getElementById('shadow');
var question = document.getElementById('question');

var bws = getBrowserHeight();
shadow.style.width = bws.width + 'px';
shadow.style.height = bws.height + 'px';
question.style.left = parseInt((bws.width - 350) / 2)+ 'px';
question.style.top = parseInt((bws.height - 200) / 2)+ 'px';
shadow = null;
question = null;
}

function showLayer() {
setLayerPosition();

var shadow = document.getElementById('shadow');
var question = document.getElementById('question');

shadow.style.display = 'block';
question.style.display = 'block';

shadow = null;
question = null;
}

function hideLayer() {
var shadow = document.getElementById('shadow');
var question = document.getElementById('question');

shadow.style.display = 'none';
question.style.display = 'none';

shadow = null;
question = null;
}

window.onresize = setLayerPosition;


And now, the HTML itself



<div id="shadow" class="opaqueLayer"> </div>
<div id="question" class="questionLayer">
<br />
<br />
<br />
This is the Popup DIV
<br />
Put anything here, Textbox or Buttons 
<br />
<br />
<br />
<input type="button" onclick="hideLayer();" value="Close" />
</div>
<table style="margin-left:auto;margin-right:auto;">
<tr>
<td style="height:120px;">

</td>
</tr>
<tr>
<td>
<button onclick="showLayer();">Click Me to see the Popup DIV</button>
</td>
</tr>
</table>




Explanation

Here two other DIVS are placed in the page which are hidden at first.
When clicking on the Button they are rendered visible.
These two DIVs are having different Z-Indexes that makes them look like a Popup Window.

Happy Coding!
Read more...