4

i have created one repeater and now i want to refresh that repeater after each 1 minute . blow is my code :

 <asp:Repeater ID="gvd" runat="server">

                <ItemTemplate>
                    <tr class="gradeA">
                        <td>
                            <asp:Label ID="lblcategory" runat="server" Text='<%#Eval("Firstname")%>'></asp:Label>

                        </td>
                        <td>
                            <asp:Label ID="lblcontent" runat="server" Text='<%#Eval("Lastname")%>'></asp:Label>
                        </td>

                     </tr>
                </ItemTemplate>

            </asp:Repeater>

It is give perfect output but now i want to refresh this whole repeater via javascript because using updatepanel it is increase the load on the server

so how can i do this via javascript?

mason
  • 31,774
  • 10
  • 77
  • 121
  • Do not think of it as "refreshing the repeater". Think of it as refreshing the table, because the Repeater exists purely on the server side, the resulting markup is on the client. Anyways, many people are starting to shy away from "continuously poll server for updates" in favor of using new technology to push the updates from the server to the client. In the .NET stack, the technology for this is [SignalR](http://signalr.net/). You'll find that SignalR is much better than constantly polling the server, lightening strain on the client, on bandwidth, and server resources. – mason Sep 04 '14 at 16:15

3 Answers3

5

SignalR was created to solve exactly the problem you are describing.

Here's your situation: You want a way to display information that could change constantly. At any point, the most up to date information should be displayed.

A Web Forms centric approach would be to use an UpdatePanel. But myself and some others don't really like those. They usually cause problems later on down the road, because they don't play well with other technology. They're also "expensive", they send a lot of data back and forth between the client and server, using up bandwidth and resources.

Another approach, somewhat touched on by deostroll, is to use AJAX to poll the server at a regular interval for the data. This isn't a bad approach, though I would not have implemented it the way he did. His/her way would be a massive drain on bandwidth and resources because you're recreating the entire table every few seconds. Boiled down to a conversation type format, his/her approach look like this:

Client -> Server - Send me the entire table.
Server -> Client - Here's a 1MB table.
Client -> Server - Send me the entire table.
Server -> Client - Here's an 1MB table.
Client -> Server - Send me the entire table.
Server -> Client - Here's a 1.5MB table.
Client -> Server - Send me the entire table.
Server -> Client - Here's a 1MB table.

Instead, an AJAX polling based approach should look like this:

3:30PM Client -> Server - The last data I have is from 3:30PM. Got anything new?
3:30PM Server -> Client - No.
3:31PM Client -> Server - The last data I have is from 3:30PM. Got anything new?
3:31PM Server -> Client - No.
3:32PM Client -> Server - The last data I have is from 3:31PM. Got anything new?
3:32PM Server -> Client - No.
3:33PM Client -> Server - The last data I have is from 3:32PM. Got anything new?
3:33PM Server -> Client - Yes, two new records. Here you go, 10KB.
3:34PM Client -> Server - The last data I have is from 3:33PM. Got anything new?
3:34PM Server -> Client - No.

That uses much less bandwidth. I'm not going to bother showing you how to do it in code, though understand it's relatively straightforward and represents a massive improvement over deostroll's approach.

Instead, I want to describe how a SignalR based approach would work. SignalR is "real time". It takes advantages of several techniques for "pushing" changes from the server to the client. One technology used to implement this is called web sockets, which is the preferred method. But if the client or server isn't capable of web sockets, SignalR gracefully switches to other techniques. You don't have to worry about that though, it's all taken care of for you.

Let's look at a simple way to implement this in SignalR. Every time you change the table data, you want to run a JavaScript function on the clients to update them with the latest data.

First, we need a hub on the server.

public class TableHub : Hub
    {
    }

On the client side, do this to wire up an event:

 $(function () {
    var tableHub= $.connection.tableHub;
    tableHub.client.tableChanged= function (html) {
    //append the html markup to your DOM
    };
});

Then whenever the table data changes, call this code on the Server:

var context = GlobalHost.ConnectionManager.GetHubContext<TableHub >();
string html="<table><tr><td>Some data</td></tr></table>"; //obviously you'd built the HTML table up here
context.Clients.All.TableChanged(html); //call tableChanged() on the client!

That will actually end up calling the tableChanged() function on the client side in near real time, initiating it from the server side! That's basically Remote Procedure Call. So not only is this taking care of selecting the best available transport mechanism (web socks, Server Sent Events, Long Polling) but it resolves client side functions and lets you call them by using dynamics on the server side.

That was a very basic example. We're sending the entire HTML for the table down, which isn't ideal. But, with a little work you could have the client notified of when to make an AJAX call to an API to retrieve only the changed table data, instead of retrieving the entire table. In fact, that's an approach I took on a website I recently created to push new articles from the server to the client in real time.

Community
  • 1
  • 1
mason
  • 31,774
  • 10
  • 77
  • 121
  • Does the second code block go inside the tablehub, or in a function with some kind of timer? – C Bauer Sep 05 '14 at 00:54
  • That would go in your page's JavaScript (it's using jQuery). Note you'll also have to add SignalR to your project and embed the appropriate SignalR scripts on your page (examples in the very first link of my answer). Note that I didn't give a complete example, I didn't tell you how to embed the SignalR scripts (it's easy) or map SignalR (it's also easy) in your project, and where you place the 3rd code block depends on where your source data might change. I know this requires a bit of a paradigm shift but I really think it will improve your application if you do decide to implement – mason Sep 05 '14 at 04:18
  • 1
    Hello Thank you for your answer. i am clear about this. But where i can put my repeater ? and where i have to create Hub? can you please guide me in detail.? –  Sep 05 '14 at 06:11
  • 1
    or give me any example reference for this. –  Sep 05 '14 at 11:37
  • @Deepak You put the repeater where you would normally put it- on the .aspx page. If you want clear examples, then look at the very first link I put in my answer. They have an excellent example that will help you get started with SignalR. – mason Sep 05 '14 at 13:14
  • I have checked that link and check the example..It is very complex and very confusing..I am new in SignalR..so some code are very difficult to understand.. –  Sep 05 '14 at 15:38
  • @deepak Don't just check the example. Run it. Learn it. It's an incredibly powerful and simple framework to use. There's excellent videos from Microsoft Build and TechEd that go through it as well. – mason Sep 05 '14 at 15:55
  • @deepak I've posted [another example](http://stackoverflow.com/questions/25829343/how-to-implement-real-time-data-for-a-web-page/25829361) that tries to break down some of this information. – mason Sep 14 '14 at 01:48
1

Based on your rep and profile, I don't believe you'd catch all this fast. You really need to explore if you want to know why we are doing it this way.

You need some javascript of the style as mentioned in the answers already here. You need to do some ajax calls to a page/generic handler (ashx) to generate repeater markup.

There are several ways to render a control (i.e. a repeater), but for your case its best using a usercontrol to do that job. And that has certain challenges (not explaining why though).

Here is the generic way of doing just that alone - rendering a user control - using a generic handler

public class refresh : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        FormlessPage page = new FormlessPage();
        Control ctrl = page.LoadControl("~/RepeaterHoster.ascx");
        StringWriter sw = new StringWriter();
        HtmlTextWriter hw = new HtmlTextWriter(sw);
        page.Controls.Add(ctrl);
        page.RenderControl(hw);
        context.Server.Execute(page, hw, false);
        context.Response.Write(sw.ToString());
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

You'd notice I've used a Formless page. That is defined as follows:

public class FormlessPage : Page
{
    public override void VerifyRenderingInServerForm(Control control)
    {
        //keeping it empty

        //base.VerifyRenderingInServerForm(control);
    }
}

Then your aspx page can look like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.DynamicRepeater.WebForm1" %>

<%@ Register Src="RepeaterHoster.ascx" TagName="RepeaterHoster" TagPrefix="uc1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Repeater Refresh Demo</title>
    <style>
        #content {

            border:1px dotted;
            line-height:2em;
        }

            #content div {

                background-color:#00ff90;
                padding:3px;
                display:inline;
                margin:3px;
                text-align:center;

            }
    </style>
    <script src="Scripts/jquery-2.1.1.min.js"></script>
    <script>
        $(function () {
            var content = $('#content');
            setInterval(function () {
                content.load('refresh.ashx');
            }, 5000);
        });
    </script>
</head>
<body>
    <h2>Repeater Refresh Demo</h2>
    <form id="form1" runat="server">
        <div id="content">
            <%-- content here (in this div) refreshes every 5 seconds--%>
            <uc1:RepeaterHoster ID="RepeaterHoster1" runat="server" />

        </div>
    </form>
</body>
</html>

The user control is fairly very simple for illustration purposes. I am just showing 5 product names at random from db (northwind) - mdf file. There is nothing significant in its code behind hence omitting that one.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="RepeaterHoster.ascx.cs" Inherits="WebApp.DynamicRepeater.RepeaterHoster" %>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
    <ItemTemplate>
        <div>
            <%# ((System.Data.DataRowView)Container.DataItem)[0] %>
        </div>
    </ItemTemplate>
</asp:Repeater>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:NorthwindDB %>" 
    SelectCommand="SELECT TOP (5) ProductName FROM [Alphabetical list of products] ORDER BY NEWID()"></asp:SqlDataSource>

Now, why exactly are we doing all this? Why not simply use a repeater control instead of a user control?

Well, if you truly want to know, you'd really want to figure all this yourself. :)

Happy programming...

deostroll
  • 11,661
  • 21
  • 90
  • 161
0

setTimeout(functionName, milliseconds) will set a specific function to run after the {milliseconds} argument.

You can just have, at the end of that refresh function, a call to setTimeout(refreshFunction,60000)

You can also use the method __doPostBack('UpdatePanel1', ''); to update the panel in that refresh method.

So your code might look like:

function() RefreshPanelEveryMinuteLoop {
    __doPostBack('UpdatePanel1', '');
    setTimeout(RefreshPanelEveryMinuteLoop, 60000);
}
C Bauer
  • 5,003
  • 4
  • 33
  • 62
  • Or I should say that it is extremely nontrivial to do what you want to do here. – C Bauer Sep 04 '14 at 12:27
  • where i have to put update panel ? before repeater or inside the repeater? –  Sep 04 '14 at 12:28
  • @CBauer An UpdatePanel is not necessary to accomplish this, and often introduces fresh problems. I wouldn't suggest an update panel for this scenario. And if I did, I would use a timer rather than manually causing a postback with JS. – mason Sep 04 '14 at 16:16
  • @mason Considering what OP is trying to do, and the lack of familiarity with the options for doing it, I doubt very much that OP could easily deal with anything more complex. Look at deostroll's answer, that is going to be an unmaintainable nightmare for OP. This is 3 lines of code and an asp.net control. And SignalR? Good luck with that. What's wrong with an updatepanel for doing a partial refresh on a control? It's exactly what OP wants and won't introduce any additional complexity. – C Bauer Sep 04 '14 at 17:13
  • Like I said, a Timer should be used rather than plan JavaScript if you want an UpdatePanel to postback at an internval. SignalR is quite simple. Perhaps you're not familiar with it, but that doesn't mean it's not a simple solution. UpdatePanel's seem like a good option, but then you implement them and run into all sorts of problems down the road. They're a poor abstraction for the kind of thing that using AJAX and a proper web service is actually meant for. And as noted in the OP, he wants to avoid UpdatePanel to decrease strain on the server. – mason Sep 04 '14 at 17:35
  • @mason SignalR is simple for people who understand web architecture. Does OP occur to you as a person who understands web architecture? He's asking how to do a partial page refresh on stackoverflow. You really think he'll get SignalR up and running? – C Bauer Sep 04 '14 at 18:10
  • Sure, SignalR is easy, and will cause less problems than UpdatePanel. I'm not sure what you mean by "for people who understand web architecture". Yes, clearly the OP doesn't have a solid understanding of how to implement this, but that doesn't mean we should provide him/her with poor solutions or discredit ones that work well due to unfamiliarity. – mason Sep 04 '14 at 18:18
  • @mason Well if SignalR is a better solution to implement, and the updatepanel will cause him so many headaches, and SignalR is clearly better and/or this solution is "poor", than why haven't you written an answer explaining how to do it so they can use it? – C Bauer Sep 04 '14 at 18:35