This is a migrated thread and some comments may be shown as answers.

[Solved] Grid - Refresh and Paging button URL customization?

8 Answers 147 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Shannon
Top achievements
Rank 1
Shannon asked on 22 Feb 2012, 11:47 PM
I have a grid on a view that renders a lot of data that once retrieved from the database goes through a decryption process prior to being displayed - Bit of a performance hog to say the least.  As such I have implemented a caching strategy so the data is not retrieved from the DB and decrypted again on subsequent requests unless it is absolutely necessary.

I need to be able to include a query string parameter for the refresh button with one value and the same query string value on the paging buttons with another value that tells me if I should retrieve and decrypt the data again or if I should pull the data from the cache - Something like this:

Refresh URL = Controller/Action?retrieveFromCache=False
Paging URL(s) = Controller/Action?retrieveFromCache=True&page=2

Any thoughts?  Many thanks!

8 Answers, 1 is accepted

Sort by
0
Dadv
Top achievements
Rank 1
answered on 23 Feb 2012, 11:27 AM
Hi,

Do you try to save the last page load?

<script type="text/javascript">
var currentPage = <%= ViewBag.CurrentPage %>;
function onDataBinding(e) {
        e.data = {retrieveFromCache : e.page != currentPage
        };
        currentPage = e.page;
    }
</script>

In the Grid :

 .ClientEvents(events => events.OnDataBinding("onDataBinding"))

Try this it will work in both server and client side i think.

Regards,
0
Shannon
Top achievements
Rank 1
answered on 23 Feb 2012, 03:22 PM
Thanks for the reply but this does not seem to work...

I have wired up the event handler successfully but the controller action that retrieves the data is not being invoked.

Example:  The "Index" action gets called fine when the page first loads [] but when I click the refresh button or any of the paging buttons the client side event handler fires but the "Index" action is not being called.

Do I need to explicitly set the select action as follows:

.DataBinding(dataBinding => dataBinding
        .Server().Select("Index", "Controller", new { retrieveFromCache = true })
)

For reference, here is the controller action stub:

public ActionResult Index(bool retrieveFromCache = false) { ... }
0
Dadv
Top achievements
Rank 1
answered on 23 Feb 2012, 05:48 PM
ClientEvents is more likely for Ajax binding i think.

In server binding you should do the job in server side :
In grid :
...
.EnableCustomBinding(true)
.DataBinding(dataBinding => dataBinding
         .Server().Select("Index", "Controller", new { currentPage= ViewBag.CurrentPage })
) 
...

in controller :

[GridAction(GridName = "Grid")]
public ActionResult Index(GridCommand command, int currentPage =-1 )
{
if(currentPage == command.Page)
{
// Cached Datas
}
else
{
// Uncached Datas
}

ViewData.CurrentPage = currentPage  == -1 ? 1 : command.Page;

...
 }
 
0
Shannon
Top achievements
Rank 1
answered on 23 Feb 2012, 08:04 PM
Thanks again but this does not really solve my problem...I need to associate different url parameter values for the refresh and paging buttons.  The methods you have proposed allow me to associate url parameter values but they are the same parameter values for both the refresh and paging buttons.

I think I'm going to check for the "page" parameter and if it doesn't exist in the url then assume the request if for a refresh.  This feels very hackish though!
0
Shannon
Top achievements
Rank 1
answered on 23 Feb 2012, 11:12 PM
Update...

This is how I ended up solving the problem.  I am using server binding and supply the default model via the Index action.  I then bind the "Select" action to a secondary GetGridData action [So I can be sure the request is as a result of a grid action] that inspects the query string and looks for a page parameter:

        public ActionResult GetGridData()
        {
            bool paging = Request.QueryString.AllKeys.Where(key => key.ToLower() == "page").Any();

            List<MyObj> items = this.GetItems(retrieveFromCache = paging);

            return View("Index", items);
        }

Thanks for all your help!
0
Dadv
Top achievements
Rank 1
answered on 24 Feb 2012, 10:49 AM
Well, i'm not sure that your code work fine..

what happen if you refresh on page 2?

page parameter will always send i think....

so on other pages refresh should always get the un-cached data , i'm wrong?


Try my methods, in the first step (init of the grid) "page" parameter is 0 (no querystring "page" found) so the data are recover from the database


ps: I fix my previous code by  : ViewData.CurrentPage   => ViewBag.CurrentPage  

   [GridAction(GridName = "Grid")]
        public ActionResult CustomServerBinding(GridCommand command, int currentPage = -1)
        {        
             
            ViewBag.CurrentPage = currentPage == -1 ? 1 : command.Page;
 
            if (currentPage == command.Page)
            {
//Cached data                
            }
            else
            {
                   //UnCached data
            }
...            
        }


<%= Html.Telerik().Grid<Order>()
        .Name("Grid")
        .BindTo(Model)
        .Columns(columns =>
        {
            columns.Bound(o => o.OrderID).Width(100);
            columns.Bound(o => o.Customer.ContactName).Width(200);
            columns.Bound(o => o.ShipAddress);
            columns.Bound(o => o.OrderDate).Format("{0:MM/dd/yyyy}").Width(100);
        })
        .DataBinding(dataBinding => dataBinding.Server().Select("CustomServerBinding", "Grid", new {CurrentPage = ViewBag.CurrentPage}))
        .Pageable(settings => settings.Total((int)ViewData["total"]))
        .EnableCustomBinding(true)
        .Sortable()
        .Filterable()
        .Groupable()
    %>


Test on the samples an work fine.


For your example :

[GridAction(GridName = "Grid")] 
 public ActionResult GetGridData(GridCommand command, int currentPage = -1)
        {
            ViewBag.CurrentPage = currentPage == -1 ? 1 : command.Page; 

            List<MyObj> items = this.GetItems(retrieveFromCache = currentPage == command.Page );

            return View("Index", items);
        } 




Regards,
0
Shannon
Top achievements
Rank 1
answered on 24 Feb 2012, 03:44 PM
You're right that my approach does not work because the refresh action does include the page parameter :-(

However, you still aren't understanding my requirements.  I retrieve *all* the data when the page loads the first time and I cache this data - I do not want to get this data again until the refresh button is pressed.  When navigating from one page to the next I want to use the cached data.

Your example gets the data when the page changes which does not meet my requirements.  What would be nice is if the grid were to pass information about the triggering action via the GridCommand object but that doesn't happen.  Example:  GridCommand.Action = "Refresh" or GridCommand.Action = "Paging".
0
Accepted
Dadv
Top achievements
Rank 1
answered on 24 Feb 2012, 04:23 PM
Ok i saw my mistake,

Well.. if currentpage == command.Page then you can say that refresh is press (revert the cached and un-cached on my previous example)


 but an other option will be to add querystring to refresh link in jquery  (onload event ?):
$('.t-refresh').attr('href', $(".t-refresh").attr('href') + '&refresh=True');

edit : be careful to the '?' first char... in certain case it could be missing.. it's why i prefer the server side approach
Tags
Grid
Asked by
Shannon
Top achievements
Rank 1
Answers by
Dadv
Top achievements
Rank 1
Shannon
Top achievements
Rank 1
Share this question
or