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

[Solved] LoadContentFrom/Ajax binding with infinite nested Grid TabStrip

14 Answers 314 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.
frederic rybkowski
Top achievements
Rank 1
frederic rybkowski asked on 15 Mar 2011, 05:01 PM
Hi,

For some
time I read the forum to address various issues concerning multiple nestings Grid / TabStip with Ajax Binding.
On the forum many posts relate to these problems.

In my current project I wanted to use a Grid with a detailview containing a tabstrip (LoadOnDemand), which contains Ajaxed Grid  or Ajaxed(LoadOnDemand) TabStrips (With Ajaxed.... and so on).

Following investigations into the code of the package, I corrected with some changes that solved my problems.
It seems that now I can embed/nest Ajaxed components(Grid/TabStrip) infinitely (deeply).

I work with
.net 4.0
MVC 3.0
Telerik MVC 2010.3.1318
(Automapper, Ninject...)

in Grid.cs :
private GridBindingSettings Server   //Line 218. instead of public
public GridBindingSettings CurrrentBinding //Line 762. instead of private

then replace
Grid.Server.Select with Grid.CurrrentBinding.Select everywhere needed to satisfy the compiler.

in GridUrlBuilder.cs (add test in bold):


   if
(result.Count == 0) // Line 57. because it is needed only when no binding is provided
   {
    foreach (string key in grid.ViewContext.HttpContext.Request.QueryString)
    {
        if (key != null && !result.ContainsKey(key))
        {
            result[key] = grid.ViewContext.HttpContext.Request.QueryString[key];
        }
    }
   }

in telerik.tabstrip.js (don't only use ContentUrl, but items href if not an alias. add the bold lines):

(function ($) {
 
    var $t = $.telerik;
 
    $t.tabstrip = function (element, options) {
        this.element = element;
 
        var $element = $(element);
 
        this.$contentElements = $element.find('> .t-content');
 
        $.extend(this, options);
 
        if (this.contentUrls)
            $element.find('.t-tabstrip-items > .t-item')
                .each($.proxy(function (index, item) {
                    var $link = $(item).find('.t-link'),
                        href = $link.attr('href');
                    var isAnchor = (href && (href.charAt(href.length - 1) == '#' || href.indexOf('#' + this.element.id + '-') != -1));
                    if (isAnchor)
                        $(item).find('.t-link').data('ContentUrl', this.contentUrls[index])
                    else
                        $(item).find('.t-link').data('ContentUrl', href)
 
                }, this));


Didn't see any errors at this time... :)
Is that correct ?

14 Answers, 1 is accepted

Sort by
0
frederic rybkowski
Top achievements
Rank 1
answered on 15 Mar 2011, 05:22 PM
The following now works.
I use T4 template for Mvc for Action Names and Controller Names.

index.aspx (Ajaxed Grid with LoadOnDemand TabStrip):

<%: Html.Telerik().Grid<RBid_DTO>()
    .Name("Bids")
     
    .DataKeys(keys => {
        keys.Add(x => x.Bid_Number);
    })
    .Columns(columns =>
    {
        columns.Bound(x => x.Bid_Number);
        columns.Bound(x => x.Buyer_Id);
        columns.Bound(x => x.Bid_Status);
        columns.Bound(x => x.Date_Delevery_Due);
        columns.Bound(x => x.Date_Entered);
    })
     
     
    .DetailView(details => details.ClientTemplate(
         
            Html.Telerik().TabStrip()
                .Name("TabStrip_<#= Bid_Number #>")
                .SelectedIndex(0)
                .Items(parent =>
                {
                    parent.Add()
                        .Text("Items")
                        .LoadContentFrom(
                            MVC.Bid.ActionNames._getBidView,
                            MVC.Bid.Name,
                            new
                            {
                                Bid_Number = "<#= Bid_Number #>",
                                Bid_View = Url.Encode(MVC.Bid.Views._BidLines)
                            }).ToString();
 
                    parent.Add()
                        .Text("Vendors Information")
                        .LoadContentFrom(
                            MVC.Bid.ActionNames._getBidView,
                            MVC.Bid.Name,
                            new
                            {
                                Bid_Number = "<#= Bid_Number #>",
                                Bid_View = Url.Encode(MVC.Bid.Views._BidVendors)
                            }).ToString();
                })
                .ToString()
         
    )
    )
    

Action to get the views:

[HttpGet] // Ajax GET by TabStrip
public virtual ActionResult _getBidView(string Bid_Number, string Bid_View)
{
    var model = new RBid_DTO {Bid_Number = Convert.ToInt32(Bid_Number)};
    return PartialView(Bid_View, model);
}


_BidVendors.ascx (ajaxed Grid):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RBid_DTO>" %>
 
<% Html.Telerik().Grid<RBidVendor_DTO>()
    .Name("Grid_BidVendors_" + Model.Bid_Number.ToString())
    .DataBinding(dataBinding => dataBinding.Ajax()
        .Select(
            MVC.Bid.ActionNames._getBidVendors,
            MVC.Bid.Name,
            new
            {
                Bid_Number = Model.Bid_Number.ToString()
            })
    )
    .Columns(columns =>
    {
        columns.Bound(c => c.Vendor_Id);       
        columns.Bound(c => c.Vendor_Name);
        columns.Bound(c => c.Address_City);
        columns.Bound(c => c.Address_PostalCode);
        columns.Bound(c => c.Address_Country);
        columns.Bound(c => c.Bid_Email);
    })
    .Filterable()
    .Sortable()
    .Render();
%>

_BidLines.ascx (ajaxed Grid)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RBid_DTO>" %>
 
<% Html.Telerik().Grid<RBidLine_DTO>()
    .Name("Grid_BidLines_" + Model.Bid_Number.ToString())
    .DataBinding(dataBinding => dataBinding.Ajax()
        .Select(
            MVC.Bid.ActionNames._getBidLines,
            MVC.Bid.Name,
            new
            {
                Bid_Number = Model.Bid_Number.ToString()
            })
    )
    .Columns(columns =>
    {
        columns.Bound(c => c.Bid_LineNumber);       
        columns.Bound(c => c.Item_Description);
        columns.Bound(c => c.Purchase_Qty);
    })
    .Filterable()
    .Sortable()
    .Render();
%>

0
frederic rybkowski
Top achievements
Rank 1
answered on 16 Mar 2011, 09:01 AM
Telerik dev team,

Please review this code fix for all binding (server, service, ajax) problem when multiple components are embedded !

Thanks for your work.
0
frederic rybkowski
Top achievements
Rank 1
answered on 24 Mar 2011, 03:06 PM

This fix cover :

When Grids are builded, the routes of the Request are first used (the one from a Ajax call to PartialViewResult, described in the TabStrip LoadContentFrom for example...).

The binding of the nested Grids (Ajax, Service or Server) will then be sadly ignored....

Somebody will have a look at this !?
0
Atanas Korchev
Telerik team
answered on 24 Mar 2011, 03:35 PM
Hello frederic rybkowski,

 I read the entire forum thread and I cannot understand what the problem which you are trying to fix is. I think you are most probably not including the required JavaScript files for the grid - a problem which has been documented here. You can also check this code library showing how to use a grid inside a tabstrip when the grid is loaded via ajax.


Regards,
Atanas Korchev
the Telerik team
0
frederic rybkowski
Top achievements
Rank 1
answered on 24 Mar 2011, 07:01 PM
Hi Atanas,

Based on the GridLoadedWithAjaxInTabStrip sample:
Upgraded to 2010.3.1318 still MVC 2.
I modified  Index.aspx this way but it doesn't work :

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>
 
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
 
 
<% Html.Telerik().Grid<GridLoadedWithAjaxInTabStrip.Models.Customer>()
            .Name("Grid_Root")
        .Columns(columns =>
        {
            columns.Bound(c => c.ID).Width(200);
            columns.Bound(c => c.Name);
        })
        .DetailView(details => details.ClientTemplate(
            Html.Telerik().TabStrip()
                        .Name("TabStrip_<#= ID #>")
                        .SelectedIndex(0)
                        .Items(tabs =>
                        {
                            tabs.Add()
                                .Text("List One")
                                .LoadContentFrom("Grid""Home"new { tabstrip = "one", num = "<#= ID #>" });
                            tabs.Add()
                                .Text("List two")
                                .LoadContentFrom("Grid""Home"new { tabstrip = "two", num = "<#= ID #>" });
                        }).ToString()
        ))
        .DataBinding(dataBinding => dataBinding.Ajax().Select("_Select""Home"new { grid = "0" })) /* configure the grid for ajax binding */
        .Sortable()
        .Pageable()
        .Groupable()
        .Filterable()
        .Render();
%>
 
<%--
    <%: Html.Telerik().TabStrip()
            .Name("TabStrip")
            .SelectedIndex(0)
            .Items(tabs => 
            {
                tabs.Add().Text("List One").LoadContentFrom("Grid", "Home", new { tabstrip = "one", num = "1" }); // Define the action method which will render the partial view (Grid.ascx)
                tabs.Add().Text("List two").LoadContentFrom("Grid", "Home", new { tabstrip = "two", num = "2" }); // Define the action method which will render the partial view (Grid.ascx)
            })
    %>
--%>
</asp:Content



With HomeController modified this way :

        public ActionResult Grid( string tabstrip, int num)
        {
            ViewData["num"] = num;
            return PartialView();
        }

Message = "The parameters dictionary contains a null entry for parameter 'num' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Grid(System.String, Int32)' in 'GridLoadedWithAjaxInTabStrip.Controllers.HomeController'. An optional parameter ...

That's why I proposed to modify telerik.tabstrip.js.
What is the official solution ?

Thank you for your response.

- Frederic
0
Atanas Korchev
Telerik team
answered on 25 Mar 2011, 08:59 AM
Hi frederic rybkowski,

Could you please send us the modified code?

Regards,
Atanas Korchev
the Telerik team
0
frederic rybkowski
Top achievements
Rank 1
answered on 25 Mar 2011, 11:34 AM
Here it is.


TabStrip builder problem... so I take tab item href... (telerik.tabstrip.js. is modified...)

Cannot reproduce my binding problem in the sample...
It appears when bindings is at beginning of the grid builder description.
At this time AjaxBinding is defined but ServerBinding is used everywhere.
While looking in the code I found that CurrentBinding was not used... and it seems to be defined for this...

You can see for example that the link on the refresh button of the grid is wrong (it takes the routes of the Tab).

Thank you for reading.

- Frederic
0
Atanas Korchev
Telerik team
answered on 25 Mar 2011, 11:55 AM
Hello frederic rybkowski,

 When the grid is ajax bound the link of the refresh button is actually not used at all. It is required only for server binding. This shouldn't be a problem at all.

 I checked the suggested code and we cannot include it in our code base because of this line:
if (result.Count == 0)
{
}

The copying of urls is actually needed because users can have more than one grid in the page. This code is copying all query string parameters. You would also not want to lose any state when your user changes the grid page (any query string argument).

Still I am not sure what the initial problem was - you only mention "various problems". What are those various problems? Can I reproduce them with this project? If yes - how? Again having some problem with the url of the refresh link should not be an issue - it is not used when refreshing the grid in this case. Without reproduction I cannot provide any help.

Regards,
Atanas Korchev
the Telerik team
0
frederic rybkowski
Top achievements
Rank 1
answered on 25 Mar 2011, 11:57 AM
Here is the SnapScreen.
You can see :

The Grid refresh button href has the link of the TabStrip...
This have no impact in this sample.
But I ran into serious problems in my site, I cannot reproduce in the sample at this time......... :(

- Frederic
0
Atanas Korchev
Telerik team
answered on 25 Mar 2011, 12:00 PM
Hi frederic rybkowski,

 Let me know if you manage to reproduce the problem in a sample project. I cannot help without reproducing it first.

Regards,
Atanas Korchev
the Telerik team
0
frederic rybkowski
Top achievements
Rank 1
answered on 25 Mar 2011, 12:01 PM

Thank you for your response.
...
0
frederic rybkowski
Top achievements
Rank 1
answered on 25 Mar 2011, 12:03 PM
Concerning TabStrip.

The .js is actually modified in the sample...
Otherwise it will not work.
0
Atanas Korchev
Telerik team
answered on 25 Mar 2011, 12:07 PM
Hi frederic rybkowski,

 I checked the javascript files and I think we have applied a similar fix in our code already. You can try using a newer version.

Regards,
Atanas Korchev
the Telerik team
0
frederic rybkowski
Top achievements
Rank 1
answered on 25 Mar 2011, 12:44 PM
Thank you for your patience Atanas.
I will upgrade to the latest build.
Tags
Grid
Asked by
frederic rybkowski
Top achievements
Rank 1
Answers by
frederic rybkowski
Top achievements
Rank 1
Atanas Korchev
Telerik team
Share this question
or