简体   繁体   中英

What is the right way to rebind a kendo grid, to former search criteria from another view (the back button does not work)

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?

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); } }); } 

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM