4

QUESTION

Can anyone suggest how a loading image can be displayed until a gridview is fully loaded?

This gridview is to be rendered on page load. There must be a simple solution to detect when gridview is loading/loaded so a simple toggle between load image and gridview visibility can be achieved.

Please do not suggest using any of the Ajax toolkit methods unless the desired code can be isolated and used standalone. I have found the toolkit to be easy on implementation but bloated and slow on performance. I do not wish to include any scripts, files or code in my release package that is not going to be used.

ASP.NET

      <img src="~/Loading.gif"></img>

      <asp:GridView ID="gv" runat="Server" AutoGenerateColumns="False" EnableModelValidation="False">
        'content...
      </asp:GridView>

VB

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'connection info

    If Not IsPostBack Then
      Me.Bindgv()
    End If
  End Sub


  Private Sub Bindgv()
    'Load gridview
  End Sub

POSSIBILITIES

I am open to any suggestions however I was attemting to implement a solution using jquery page methods but need assistance to follow through.

JAVASCRIPT

$(function() {
  $.ajax({
    type: "POST",
    url: "Default.aspx/UpdateGV",
    data: "{}",
    contentType: "application/json",
    dataType: "json",
    success: function() {
      // Run return method.
    }
  });
});

VB.NET

Imports System.Web.Services

Public Partial Class _Default
    Inherits System.Web.UI.Page

    <WebMethod(EnableSession := False)> _
    Public Shared Function UpdateGV() As String
         Return 
         Me.Bindgv()
    End Function
End Class
DreamTeK
  • 32,537
  • 27
  • 112
  • 171
  • What is GridView render in html : Table HTMLelement ? – Abdennour TOUMI Jun 05 '14 at 15:23
  • Please could you elaborate? Not sure what you are asking. – DreamTeK Jun 05 '14 at 15:25
  • No AJAX Toolkit, so this is out of question? http://stackoverflow.com/questions/2813590/ajax-loading-icon-with-updatepanel-postbacks – emerson.marini Jun 05 '14 at 15:27
  • Ajax toolkit has been a constant headache for me. I would rather avoid it. I am looking to create a solution that will have rapid execution. – DreamTeK Jun 05 '14 at 15:31
  • Got it. I'll see if there's something else around here. – emerson.marini Jun 05 '14 at 15:35
  • 1
    Using `jQuery` you could hide the image when your AJAX call reaches the `complete` status. http://api.jquery.com/jquery.ajax/ Not so sure the `GridView` would be ready at the same point though. – emerson.marini Jun 05 '14 at 15:40
  • Also, this could possibly fit into the same solution, if using `jQuery`: http://api.jquery.com/load-event/ Then you would probably be able to check if the `GridView` is completely loaded. – emerson.marini Jun 05 '14 at 15:43
  • 1
    If the gridview is heavy to load why would you load it on Page_Load? I would move it to a simple web api controller that returns the data, make an ajax call on document.ready and wait til that ajax call has finished to present the data. – Robban Jun 10 '14 at 06:27
  • @Robban Your idea sounds interesting. Would you be kind enough to elaborate on implementation. – DreamTeK Jun 10 '14 at 15:36
  • @Obsidion my VB is rusty, but I'll post a simple answer in C# and hope you'll be able to translate (the jquery will be the same regardless). – Robban Jun 11 '14 at 05:35
  • How about just overlaying a DIV over the grid, and showing and hiding using javascript? – TechGirl Jun 12 '14 at 13:20

6 Answers6

13

You can achieve this using jquery, there is a jquery block UI project on github and you could just use that one to block the grid view without using ajax.

here is the code you will need to do this, and it' tested and works fine like below:

Step 1 add these two lines in your page head

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  <script src="http://malsup.github.io/jquery.blockUI.js"></script>

Step 2 an extension jquery after the codes above:

<script type="text/javascript">
    $(document).ready(function () {
        $('#Button1').click(function () {
            $('.blockMe').block({
                message: 'Please wait...<br /><img src="Images/loadingBar.gif" />',
                css: { padding: '10px' }
            });
        });
    });
</script>

Step 3 in my case I bind my grid view using a button , but you could always use any other controls as well:

<asp:Button ID="Button1" runat="server" Text="Bind Grid View" 
            ClientIDMode="Static" OnClick="Button1_Click" />
    <div class="blockMe">
        <asp:GridView ID="GridView1" runat="server" Width="100%">
        </asp:GridView>
    </div>

Step 4 bind the grid view on button clicked

    protected void Button1_Click(object sender, EventArgs e)
    {
        DataTable tblCourse = myAccount.GetEnroledCourse("arpl4113");

        //Bind courses
        GridView1.DataSource = tblCourse;
        GridView1.DataBind();
    }

and that's it, NO AJAX Toolkit (only jQuery) so the result will be look like this:

enter image description here


A trick to do the above solution at the page load

First of all this is NOT a function on Page_Load event on server side but on the client side ;-)

So to achieve this you need to have a hidden control to keep a value on page view-state and also make the same button hidden to trigger it on page load. and a little changes on the extension jQuery above. Done!

Step 1. Add the css below to your page header:

 <style> .hidden { display: none; } </style>

Step 2. Add a hidden field plus make your button hidden like this:

    <asp:HiddenField ID="hidTrigger" runat="server" ClientIDMode="Static" Value="" />
    <asp:Button ID="btnHidden" runat="server" ClientIDMode="Static" 
                OnClick="btnHidden_Click" CssClass="hidden" />
    <div class="blockMe">
        <asp:GridView ID="GridView1" runat="server"></asp:GridView>
    </div>

Step 3. Make this changes on your extension script like below:

  <script type="text/javascript">
    $(document).ready(function () {

        //check whether the gridview has loaded
        if ($("#hidTrigger").val() != "fired") {

            //set the hidden field as fired to prevent multiple loading
            $("#hidTrigger").val("fired");

            //block the gridview area
            $('.blockMe').block({
                message: 'Please wait...<br /><img src="Images/loadingBar.gif" />',
                css: { padding: '10px' }
            });

            //fire the hidden button trigger
            $('#btnHidden').click();
        }
    });
</script>

That's it! and your button click on the code behind remains the same as before, in this example I only change the name of the button. no code on Page_Load event though.

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void btnHidden_Click(object sender, EventArgs e)
    {
        DataTable tblCourse = myAccount.GetEnroledCourse("arpl4113");

        //Bind courses
        GridView1.DataSource = tblCourse;
        GridView1.DataBind();
    }

I hope it helps you.

DreamTeK
  • 32,537
  • 27
  • 112
  • 171
Ali
  • 2,574
  • 1
  • 17
  • 24
  • This is looking good. I will give you feedback once I have had chance to test it out. Thanks for clear and concise answer. – DreamTeK Jun 10 '14 at 15:34
  • This is a good alternative however I have one questions. When I change this to run on page load it remains on loading. Could you show code for on page load? (My only change was removing $('#Button1').click(function () {}); Gridview binds onload without script). – DreamTeK Jun 16 '14 at 08:21
  • 1
    Ok, first you should know the fact that this could not happen unless you have partial page postback(AJAX), because "you cannot see a loading area unless your page is loaded completely". but there is a trick to do this with the above solution that gives the users the same feeling as what you want. I'll add it to the code above for you. – Ali Jun 16 '14 at 23:07
1

As you are not willing to use the ASP.NET Update panel which is designed to handle the kind of requirement you have. Using jquery AJAX and using the web method to update the Grid will not work as you expect because you need to update the viewstate and other information. One of the solution that you can apply is showing the modal dialog box till your page is completed loaded its html which includes your Grid data.

              <script type = "javascript/text">
              $(document).ready(function() { // show modal dialog });
              $(window).load(function() {// hide the dialog box});
              </script> 
Devesh
  • 4,500
  • 1
  • 17
  • 28
  • 1
    Most .NET programmers already know how to do this with ASP.NET Update panel using AJAX toolkit. This question is exclusively how to do this WITHOUT this tool. If we could extract only the desired scripts needed to accomplish this task without having to include huge amount of bloated code then it could be a possibility. As for your other suggestion: this is more along the lines of the desired effect however this will create a loading image for entire page and not the isolated gridview. – DreamTeK Jun 09 '14 at 13:22
1

I would implement this by using a web api controller that returns the appropriate data and then simply try to load the data on document.ready with jquery. Something along the lines of this (Will be posting the answer in c# but it should be simple enough to translate):

 public class TableDataController : ApiController
  {
     public IEnumerable<SimplePocoForOneTableRow> Get()
     {
        var tableData = GetTableDataFromSomewhere();

        return tableData;
     }
  }

To learn more about how to setup a WebApiController in a web forms project, please refer to this article.

I would implement the HTML something like this:

<table class="tableToLoadStuffInto">
   <tr>
       <td><img src="yourCoolSpinningAjaxLoader.gif" /></td>
   <tr>
</table>

And the jquery to load the data and present it in the table would look something like this:

<script type="text/javascript">
$(document).ready(function () {
    jQuery.ajax({
            url: '/api/TableData',
            type: 'GET',
            contentType: 'application/json; charset=utf-8',
            success: function (result) {
            if(!result) {
                //Show some error message, we didn't get any data
            }                    

            var tableData = JSON.parse(result);
            var tableHtml = '';
            for(var i = 0; i<tableData.length; i++){
                    var tableRow = tableData[i];
                    tableHtml = '<tr><td>' + 
                    tableRow.AwesomeTablePropertyOnYourObject +
                    '</td></'tr>'
               }    
             var table = $('.tableToLoadStuffInto');
             //Could do some fancy fading and stuff here
             table.find('tr').remove();
             table.append(tableHtml);
            }
        });
});
</script>

To tidy the string concatenation of the jQuery up a bit you could use a template like handlebars, but it's not strictly necessary.

Robban
  • 6,729
  • 2
  • 39
  • 47
1

You should load grid in another page and call that page in a div on parent page and display required loading image while loading div as per below code:

  $(document).ready(function()
   {
 $("#loader").show();
 $.ajax({
    type: "GET",
    url: "LoadGrid.aspx",
    data: "{}",
    contentType: "application/json",
    dataType: "json",   
    success: function(data) {
        $("#loader").hide();
       $(#dvgrid).html(data);
    },
    // it's good to have an error fallback
    error: function(jqhxr, stat, err) {
       $("#loader").hide();
 $(#dvgrid).html('');
       $("#error").show();
    }
  });
});

In LoadGrid.aspx you should load grid by normal C# code. and simply your parent page will call the LoadGrid.aspx and rendered html will display in parent div with loading image...

ashish
  • 247
  • 2
  • 3
0

From your code :

$(function() {
  $.ajax({
    type: "POST",
    url: "Default.aspx/UpdateGV",
    data: "{}",
    contentType: "application/json",
    dataType: "json",
    success: function() {
      // Run return method.
    },
    // add these lines
    beforeSend:function {
       //this will show your image loader
       $("$Loader").css("display","block");
    },
    complete:function {
       //this will hide your image loader provided that you give an id named Loader to your image
       $("$Loader").css("display","none");
    }
  });
});
DreamTeK
  • 32,537
  • 27
  • 112
  • 171
Saechel
  • 152
  • 10
0

Use beforeSend in conjunction with success and error like so:

$(function() {
  $.ajax({
    type: "POST",
    url: "Default.aspx/UpdateGV",
    data: "{}",
    contentType: "application/json",
    dataType: "json",
    beforeSend: function() {
        $("#loader").show();
    },
    success: function() {
        $("#loader").hide();
        // Run return method.
    },
    // it's good to have an error fallback
    error: function(jqhxr, stat, err) {
       $("#loader").hide();
       $("#error").show();
    }
  });
});

(provided you have <img id="loader" src="..." /> and <img id="error" src="..." />)

complete fires after success and error so using both success and error instead of complete and error assures no overlap.

Hope this was what you were looking for!

jczimm
  • 360
  • 3
  • 11