1

I'm rather new to MVC Razor and Telerik. My application has a heavy amount of JQuery and Kendo UI grids. I have a search page... All it is doing is searching for data, and populating a Kendo grid. Then you are able to click a 'View' button in the grid, which calls a javascript 'GotoDetails' Like so:

  @(Html.Kendo().Grid<Intranet.Models.courseclass>()
          .Name("grid")
          .DataSource
            (
               dataSource => dataSource // Configure the grid data source
                    .Ajax() // Specify that ajax binding is used
                    .Read(read => read.Action("gridfill", "Course") 
                    .Data("productsReadData") // Specify the JavaScript function which will return the data
                    ) // Set the action method which will return the data in JSON format
            )


          .Columns(columns =>
          {
              columns.Command
                (command =>
                {
                    command.Custom("Detail").Click("GotoDetails").Text("View");
                }
             );
              columns.Bound(x => x.CourseID);
              columns.Bound(x => x.PartNumber);
              columns.Bound(x => x.CourseTitle);
              // Add more fields later
          })
          .Pageable() // Enable paging
          .Sortable() // Enable sorting
          .HtmlAttributes(new { 
                style = "display: none" //Hide
            })
        )
 function GotoDetails(e) {
    var dataitem = this.dataItem($(e.target).closest("tr"));
    var url = '@Url.Action("Detail", "Course", new { CourseID = "__id__" })';
    url = url.replace('__id__', dataitem.CourseID);
    window.location.href = url;
}

All of that stuff works just fine. The user clicks the 'View' and goes to the 'Details' page. The problem is, this 'grid' is a pageable grid. I want the user to be able to get back to this 'Search' view, and even see the same 'Page' on the grid, he left. I tried something as simple as a browser back button, but that doesn't work.

I tried a few things: But I got bogged down in the details of the process. What is the best practice? I know I can send the: var grid = $("#grid").data("kendoGrid"); var currentPage = grid.dataSource.page(); And I can send the search criteria. You may want to see the 'gridfill' codebehind:

    public ActionResult gridfill([DataSourceRequest]DataSourceRequest request, string text) 
    {
        if (text == "") text = "RLFfudgefactor"; //return no results - fudge factor
        hiddentablesEntities1 db = new hiddentablesEntities1();
        var result_1st = db.tab_course
                        .Where(x => x.CourseTitle.Contains(text) || x.CourseID.ToString().Contains(text) || x.CoursePartNumber.Contains(text))
                        .OrderBy(x => x.CourseTitle);


        IQueryable<tab_course> courselist = result_1st;
        // Convert the Product entities to ProductViewModel instances

        DataSourceResult result = courselist.ToDataSourceResult(request, product => new courseclass
        {
            CourseID = product.CourseID,
            PartNumber = product.CoursePartNumber,
            CourseTitle = product.CourseTitle
        });            

        return Json(result, JsonRequestBehavior.AllowGet);

    }

Edit: I added a back to search button: It's script has this:

    function backtosearch() {
    var url = '@Url.Action("Search", "Course", new { text = "__cid__", Page = "__pid__"  })';
    var pagenumber = @Model.pagenumber +0;
    var searchvalue = '';
    @{
        if (Model.searchvalue != null)
        {
            @Html.Raw("searchvalue = '" + Model.searchvalue + "';");
        }
    }
    url = url.replace('__pid__', pagenumber);
    url = url.replace('__cid__', searchvalue);
    window.location.href = url;
}

I feed the data over the Model. Then on the Search View:

I have this code in script:

    $(document).ready(startfunction);

function startfunction() {
    @{
        try
        {
            if (Model.searchvalue != null)
            {
               <text>
                //1st run
                var pagenumber = @Model.pagenumber +0;
                var searchvalue = @MvcHtmlString.Create("'" + Model.searchvalue + "'") + '';
                var grid = $("#grid").data("kendoGrid");
                $("#AutoComplete1").val(searchvalue);
                grid.dataSource.read(); //Keep the grid in sync
                grid.dataSource.page(pagenumber);
                $("#grid").attr("style", "display: block;");
                debugger
                </text>
            }
       }
       catch {}
    }
}

It does preserve/show the last searched, item in the grid. However, it does not change the page. I'm guessing because the page has not yet sync'd properly with the action. Is there a way to add it to the Grid properties?

tereško
  • 58,060
  • 25
  • 98
  • 150
Robert Koernke
  • 436
  • 3
  • 18

2 Answers2

1

Update:

You can use web storage (sessionStorage or localStorage) to save your last position before you leave the page. sessionStorage will only last as long as your session (generally when you close your browser it will expire), or you can use localStorage which will persist though to the next session (will not expire).


Note: Local Storage saves everything as a string, so you will have to parse it.

//returns the page your grid is on and saves it in sessionStorage
sessionStorage.page = $('#grid').data('kendoGrid').dataSource.page());

And as a part of page load

//Parse out the int and set the page
if(sessionStorage.page != null)
  $('#grid').data('kendoGrid').dataSource.page(parseInt(sessionStorage.page));

If the sessionStorage.page has never been set it will return null


You can set the page the grid is on with this JQuery.
$('#grid').data('kendoGrid').dataSource.page(2);


As Nitin suggested though I think this may be a good place to use a kendo window and just throw your content on the page. An ajax function to accomplish this may look like this.
function loadWindow(){
    $('body').prepend("<div class='my-window'><span class='k-loading-image'>&nbsp;</span></div>");

    $('.my-window').kendoWindow({
        width: $(window).innerWidth() - ($(window).innerWidth() / 5),
        height: $(window).innerHeight() - ($(window).innerHeight() / 5),
        close: function(e) { e.sender.destroy(); }      
    });

    var window = $('.my-window').data('kendoWindow').center().open();
    return window;
}

function GotoDetails(e){
    var window = loadWindow();

    var dataitem = this.dataItem($(e.target).closest("tr"));
    var url = '@Url.Action("Detail", "Course", new { CourseID = "__id__" })';
    url = url.replace('__id__', dataitem.CourseID);

    $.ajax({
        url: url,
        type:'html',
        success: function(data){
            window.content(data);
        }       
    });
}
BenMorel
  • 34,448
  • 50
  • 182
  • 322
  • We have decided not to go with the model-popup or kendo-window format. I already pointed to the datasource.page concept above. The problem I was running into was how to hand the data back and forth. – Robert Koernke Aug 21 '14 at 19:56
  • When I want to redirect back to the 'Search' View from the detail view. I may have the data with me in the client side. But when I do the post or redirect there seems to be no way to tell the 'Search' page have those extra details. At least I don't have the concept yet in this MVC. In web-forms it would be easy. – Robert Koernke Aug 21 '14 at 20:00
  • You can use web storage or cookies to save this info before you goto a new page. I suggest web storage as it will not be a part of requests. http://www.w3schools.com/html/html5_webstorage.asp – Jonathan Buchanan Aug 21 '14 at 20:24
  • I have edited my stuff above to include the new direction I went in. No I didn't go with the Cookies. Even if I did, I believe I would still run into the same issue. After opening the view: How to get it to change the page of a grid that has not been bound yet... – Robert Koernke Aug 22 '14 at 19:31
0

I got it:

See this other post that gave me what I was looking for: Changing the page programmatically

The difference here is that I changed my code above to this:

    $(document).ready(startfunction);

function startfunction() {
    @{
        try
        {
            if (Model.searchvalue != null)
            {
               <text>
                //1st run
                var pagenumber = @Model.pagenumber +0;
                var searchvalue = @MvcHtmlString.Create("'" + Model.searchvalue + "'") + '';
                var grid = $("#grid").data("kendoGrid");
                $("#AutoComplete1").val(searchvalue);
                grid.dataSource.query({ page: pagenumber, pageSize: 10 });
                $("#grid").attr("style", "display: block;");
                </text>
            }
       }
       catch {}
    }
}

Now the grid.dataSource.query command requests the very same 'Page' number I left, with the same data.... Wallah!

Community
  • 1
  • 1
Robert Koernke
  • 436
  • 3
  • 18