Showing posts with label datalist. Show all posts
Showing posts with label datalist. Show all posts

Saturday, March 24, 2012

Paging using DataGrid and DataList (referring to ScottGus paging tutorial)

I have a webpage that uses a Datalist adapted from ScottGu's example athttp://weblogs.asp.net/scottgu/archive/2006/01/07/434787.aspx. It does not seem to benefit from Ajax partial updates (update panel), since as it pages, it actually asks for different pages' urls, etc...(Please see ScottGu's fantastic tutorial there for more details).

Question: If I use a DataGrid that has paging turned on, will it (magically) perform the operations mentioned in Scott's article, that is, sending only that data through each page request that is pertinet to that page?

Question 2 There is a slim chance that ASP.Net Ajax is actually so smart as to do what I said above, however, I need a DataList (for formatting reasons) that does not have paging .

Is there a way for the paging mentioned in ScottGu's article to be applied to the asynchornous paging, and for the paging control on the page (a hyperlink) to fetch data from that stored "stash"?

Thanks,

Paolo

Dogs Rule!

Just glancing through Scott's post, it doesn't look like this will "just work" inside an UpdatePanel, because as you mention, it's requesting a new page URL with the page number in the query string.

To get something like this to work, you'd need to first convert it to use postbacks instead of page navigation. (So change the hyperlink to a HyperLinkButton and pass the page number as an argument to the event handler instead of as a query string parameter.)

Basically, if you have a page that works with postbacks, it should be easy to use UpdatePanels to get AJAX functionality. If you have navigation, however (new URLs), then the UpdatePanel won't help you.


View this code

CODE
Sub BindData()
Dim mydt As New yourdatable()
Dim tba As NewyourobjectTableAdapters.yourtableadaper()


tba.Fill(mydt, Me
dgPager.CurrentPageIndex * Me.dgPager.PageSize , Me.dgPager.PageSize)

Me.dgPager.VirtualItemCount = yourqueryrecordcount

Me.
dgPager.DataSource = mydt
Me.
dgPager.DataBind()

Me.DataList1.DataSource = mydt
Me.DataList1.DataBind()

End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
BindData()

End If
End Sub

Protected Sub dgPager_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs)
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
e.Item.Visible = False
End If

End Sub

ProtectedSub dgPager_PageIndexChanged(ByVal source As Object, ByVal e AsSystem.Web.UI.WebControls.DataGridPageChangedEventArgs)
Me.dgPager.CurrentPageIndex = e.NewPageIndex
BindData()

End Sub
ASPX page

<form id="form1" runat="server">
<asp:DataList ID="DataList1" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
<ItemTemplate>
<%# Eval("YourDataField") %><br />
</ItemTemplate>
</asp:DataList>
<asp:DataGridID="dgPager" runat="server" AllowPaging="True"AutoGenerateColumns="False" GridLines="None" PageSize="8"ShowHeader="False" OnPageIndexChanged="dgPager_PageIndexChanged"OnItemCreated="dgPager_ItemCreated" AllowCustomPaging="True">
<PagerStyle Mode="NumericPages" />
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

</form>

Paging With AJAX Using a Datalist.

I've spent a good 6 hours trying to figure this out and came up with nothing... nothing worked nor was it going to. So now I'm posting because I need HELP! I have a datalist that spits out images from a database. Simple enough... now I need only 5 of those images to display at any given time with a next and previous button to flip through all the pics as if they were thumbnails without the page reloading... so thats where ajax comes into play. My problem is that I'm still fairly new to ajax and I've already jumped into asp.net ajax. Does anybody know how I can accomplish this?

The easiest way is using UpdatePanel.

http://www.asp.net/ajax/documentation/live/overview/UpdatePanelOverview.aspx


I've looked into the updatepanel but I've never used one before. Looks interesting but i'm still confused as to how to use what i have in it to only show 5 images at a time with next and previous buttons. Can someone point me in the right direction?

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server">
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:ObjectDataSource ID="ImageObjectDataSource" runat="server" TypeName="IllumiCell.NorthOfTorontoUG.BLL.Image" OldValuesParameterFormatString="original_{0}" SelectMethod="GetImageDataByAlbumId">
<SelectParameters>
<asp:QueryStringParameter DefaultValue="0" Name="albumId" QueryStringField="albumId" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
<script type="text/javascript" language="javascript">
var xmlHttpRequestObject = false;

try
{
// Firefox, Opera 8.0+, Safari
xmlHttpRequestObject = new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttpRequestObject = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Your browser does not support AJAX!");
window.location="Default.aspx";
}
}
}

function changeImage(img)
{
if (xmlHttpRequestObject)
{
var obj = document.getElementById("ViewImage");

xmlHttpRequestObject.open("GET", img);

xmlHttpRequestObject.onreadystatechange = function()
{
if(xmlHttpRequestObject.readyState == 4 && xmlHttpRequestObject.status == 200)
{
// The state is complete and the status is successful.
}
}

/*int originalHeight = obj.width;
int originalWidth = obj.height;
int panelWidth = 576;
int panelHeight;

if (originalHeight >= originalWidth)
{
panelHeight = panelWidth * (originalWidth / originalHeight);
panelWidth = originalWidth / (originalHeight / panelHeight);
}
else
{
panelWidth = panelWidth * (originalHeight / originalWidth);
panelHeight = originalHeight / (originalWidth / panelWidth);
}

obj.style.width = panelWidth + "px";
obj.style.height = panelHeight + "px";*/

obj.src = "album/" + img;
}
else
{
alert("Your browser does not support AJAX!");
window.location="Default.aspx";
}
}

function changeDescription(desc)
{
if (xmlHttpRequestObject)
{
var descObj = document.getElementById("objDesc");

xmlHttpRequestObject.open("GET", desc);

xmlHttpRequestObject.onreadystatechange = function()
{
if(xmlHttpRequestObject.readyState == 4 && xmlHttpRequestObject.status == 200)
{
// The state is complete and the status is successful.
}
}

descObj.innerHTML = desc;
}
else
{
alert("Your browser does not support AJAX!");
window.location="Default.aspx";
}
}
</script>
<div style="background-image:url('img/Header.png'); background-repeat:no-repeat; height:50px;
font-family:Verdana; text-align:center; font-size:medium; font-weight:bold; ">
<br />Photos
</div>
<center>
<asp:UpdatePanel ID="UpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>

</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="ImageViewPanel" runat="server" Height="432px" Width="576px" BorderColor="white" BorderWidth="5px">
<asp:FormView ID="ImageFormView" runat="server" DataSourceID="ImageObjectDataSource" DataKeyNames="ImageId">
<ItemTemplate>
<img src='album/<%# Eval("AlbumId") %>/<%# Eval("ImageName") %>' id="ViewImage" alt="" />
<div id="objDesc"><%# Eval("ImageDescription") %></div>
</ItemTemplate>
</asp:FormView>
</asp:Panel>
<p /><asp:DataList ID="ImageDataList" RepeatDirection="Horizontal" RepeatColumns="5" runat="server" DataKeyField="ImageId" DataSourceID="ImageObjectDataSource">
<ItemTemplate>
<div style="padding:10px;">
<img src='album/<%# Eval("AlbumId") %>/thumb_<%# Eval("ImageName") %>' onclick="changeImage('<%# Eval("AlbumId") %>/<%# Eval("ImageName") %>'); changeDescription('<%# Eval("ImageDescription") %>')"
alt='<%# Eval("ImageDescription") %>' style="background-color:White;" />
</div>
</ItemTemplate>
</asp:DataList>
</center>
<div style="background-image:url('img/Footer.png'); background-repeat:no-repeat; height:44px;
font-family:Verdana; font-size:medium; font-weight:bold;">
</div>
</asp:Content>


Certainly you can use UpdatePanel for Ajaxifying your Page but the DataList control does not have any builtin paging feature like the GridView or DataGrid. For this you have write your own paging solution or use custom pager developed by others. Checkout the following links:

http://www.codeproject.com/useritems/SmartPager.asp
http://www.codeproject.com/aspnet/CollectionPager.asp
http://www.codeproject.com/aspnet/ASPNETPagerControl.asp

Another solution might if you are only showing pictures you can try the SlideShow of Ajax Control Toolkit.
http://www.asp.net/AJAX/Control-Toolkit/Live/SlideShow/SlideShow.aspx


I still can't figure this out... I've been all over google as well. I can't use the updatepanel... doesn't really seem to work with the datalist (i need the datalist so that i can show 5 columns). And I also need it to be ajax enabled. Does anybody know how they can take a datalist control with 5 columns... cut off the proceeding rows and make it act like a pager without a postback? My heads about to burst!


Hmm... I think I'll give silverlight a try.

Wednesday, March 21, 2012

Parital Rendering using a DataList for Trigger

Lets say I have a DataList that describes the type of a widget. I want to use that DataList to populate a list of all widgets with that type.

<

atlas:ScriptManagerID="AtlasScriptManager1"EnablePartialRendering="true"runat="Server"/><asp:DataListid="dlWidget"runat="server"RepeatColumns="4"Width="100%"><ItemTemplate><asp:LinkButtonOnCommand="PickWidget"CommandArgument='<%# DataBinder.Eval(Container.DataItem,"TypeId") %>'id="cmdGenre"runat="server">

<%

#DataBinder.Eval(Container.DataItem,"Type") %></asp:LinkButton></ItemTemplate></asp:DataList>

Here is the repeater

<atlas:UpdatePanelID="atUpdateWidget"runat="server"><ContentTemplate><asp:Repeaterid="rptPickedWidget"runat="server"Visible="False"><ItemTemplate><tr>

<tdclass="trackListing"><%#DataBinder.Eval(Container.DataItem,"WidgetName") %></td></tr></ItemTemplate></asp:Repeater></ContentTemplate><Triggers><atlas:ControlValueTriggerControlID="rptPickedWidget"PropertyName="DataSource"/></Triggers></atlas:UpdatePanel>

I have tried several different triggers and no matter what I pick the entire page refreshes. I have verified the entire page refresh both by noting the progress bar in the browser and placing a JS alert message outside of the update panel. If I change my DataList to a DropDownList and then use the SelectedValue as the Trigger the Partial Render works just fine. However in my particular case using a DropDownList isn't viable due to the number of items that it would have to contain.

Has anybody had any experience with this setup?


hello.

i assume that you made a typo because you're using the ID of the repeater instead of the datalist.

ok, back to the problem:

1. attempt number one: put the ID of the datalist on the trigger

2. if 1 doesn't work ( i really don't remember how the datalist generates the HTML, but i'm assumign that it generates a table with the ID of the control), then besides putting the ID of the datalist on the trigger, you could also try to call the registerasyncpostbackcontrol (ScriptManager class) and pass it a reference to the datalist control

note that i haven't tried any of this; if it doesn't work, come back here and, if possible, post a demo page. thanks.


Actually I did mean to put the ID of the repeater my idea was to trigger the panel to update whenever the datasource for the repeater was changed. Each time an item in the datalist is pressed the datasource on the repeater gets changed so that it displays a new set of "widgets".

I did make a little progress (and then a little regress). I used the ItemDataBound event to create a trigger for each option in the datalist. When I first load the page I can click on any of the datalist linkbutton objects and the updater panel refreshes (without reloading the whole page). Once the page has been reloaded, any subsequent click causes a full refresh. It would appear that the trigger collection gets lost.

Also, I am having some problems with Javascript not working either. Everything works just dandy on a full page load, but it is a partial render I lose JS functionality.

I really like Atlas in general and the examples show it being a really cool tool, I am just having issues getting in to real life examples.


Sorry for the double post, but I can't seem to edit my posts.

http://test.bfrd.biz/

I have set up a demonstration of what I am hoping to accomplish.


hello.

hum...not sure on what you're doing here. from your previous posts, it seems like you want to get a partial update when you change an item from the datalist, ie, you want to refresh the repeater when you selec a new thing on the datalist control. if this is what you want, then you should wrap the repeater in an udpatepanel (you're already done this) and you should also set a trigger between the panel and the datalist control. no need to set it between the panel and repeater because all the event of the repeater the require a postback (ex.: clicking on a button placed inside the repeater) should give you an automatic partial postabck.


I added the source code (see links at the top) to my example of what I would like to have happen.

http://test.bfrd.biz/DataListType.aspx

You mentioned that I should use a DataList event to fire the update, but what type of DataList event would know that I clicked on a LinkButton inside its Item Template? I was binding directly (or at least trying) to the LinkButton contained within the DataList. Hopefully the source code will help identify my intentions more clearly.

Also, to re-iterate my current problem. When the page first loads (see link above) the user is presented with a JS alert message. This is just to signify that the entire page has loaded. The user is then presented with the Products for the first Category by default. If the user clicks on any of the items in the DataList the Repeater is refreshed and the page only updates partially (no JS alert message). This appears to be working as it should, however if the user then selects another Category the entire page loads and all subsequent Category Click events cause the entire page to load. It would appear that the Trigger Collection that I populated on the Initial Page Load is not maintained by the built-in State Control. Is there a way to do this, or am I stuck?

Thanks


hello again.

well, i'm not seeing your code. what i can tell you is that during the initial loading of the page, all the links are being correclty added to the async controls collection maintained in the pagerequestmanager client object. during a partial postback, it doesn't have the correct values. that's why you're getting a full postback. what are you doing only during the initial loading of the page?


Sorry to be unclear the code is at the top ofhttp://test.bfrd.biz/DataListType.aspx. I added them in as seperate links. The reason I only populate the DataList on the initial page load, was that I didn't see the reason in getting the list of Categories each time (it doesn't change that much).

hello.

well, you'll have to run the trigger code on all the postbacks. i guess that you might change your code slighlty so that you fo through all the rows of the datalist, find the button and run the code you've already got for creating a trigger.


Ok, I added a routine that Populates the Trigger collection everytime that the Repeater is populated. But once again, the routine works the first time and the stops working on subsequent tries.

http://test.bfrd.biz/DataListType.aspx

As always the current code is available by clicking the links at the top of the page.


hello again.

hum...i think i'm starting to see the problem. if you use fiddler (or another http sniffer) you'll see that you're not getting the correct values for the asyncpostbackcontrolsids property. can you send me a small sample (with the db) to my email to see if i get any idea on how to solve this?


The current code for both the dropdown and datalist examples can be found using the buttons at the bottom of each page. The database is the Northwind example database which I got when I installed SQL 2000. I will zip up the project and send it to you once I get to work. Could you please PM me a location to send to?

Thanks for all of your help.

P.S. At least I got the code viewer control to use Atlas like I wanted it to. :)


hello.

send it to labreu at gmail.com thanks


Did you find any solution to this problem?

hello.

well, i'm almos positive that i've received the sample and i've replied...i can't seem to recall what i've said though...