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

Server + Ajax Binding

19 Answers 179 Views
TabStrip
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Victor
Top achievements
Rank 1
Victor asked on 09 Dec 2010, 01:48 PM
Hi!

Our plan is to use the TabStrip component as a contaner for Grids and other content. We would like a combination of:
http://demos.telerik.com/aspnet-mvc/tabstrip/accessibility
and
http://demos.telerik.com/aspnet-mvc/tabstrip/ajaxloading
(the latter of which we are currently using)

Are there any examples for this/could you give us any hints? We would like the tab content to stay in separate pages to avoid clutter in the main file and are using MVC3 and Razor if that makes any difference.


Kind regards
Victor Ström

19 Answers, 1 is accepted

Sort by
0
Georgi Krustev
Telerik team
answered on 10 Dec 2010, 04:04 PM
Hello Victor,

 
We currently do not have example which covers your requirements.

Nevertheless you can achieve your goal with the following actions:
1. Define TabStrip UI component without setting items' content:

    <% var tabstrip = Html.Telerik().TabStrip()
            .Name("TabStrip")
            .Items(tabstrip =>
            {
                tabstrip.Add()
                    .Text("ASP.NET MVC")
                    .ImageUrl("~/Content/Common/Icons/Suites/mvc.png")
                    .ImageHtmlAttributes(new { alt = "ASP.NET MVC suite logo" })
                    .Url(Url.Action("Accessibility", "TabStrip", new { selectedIndex = 0 }));
 
                tabstrip.Add()
                    .Text("Silverlight")
                    .ImageUrl("~/Content/Common/Icons/Suites/sl.png")
                    .ImageHtmlAttributes(new { alt = "Silverlight suite logo" })
                    .Url(Url.Action("Accessibility", "TabStrip", new { selectedIndex = 1 }));
}).toComponent();
 
%>

2. Depending on the posted selectedIndex select item and apply appropriate content:
<%
  tabStrip.Items[selectedIndex].Content = () => Html.RenderPartial(/* Determine which partial Grid to render*/);
%>

3. Render the tabstrip.
tebStrip.Render();

Second option is to not use accessible TabStrip UI component (will not post on every item select) and define LoadContentFrom Action methods, which will render partial grids. If you need to avoid rendering Grids with same IDs, you can empty Content of all items and then put the content returned from defined Action method into current selected item.


All the best,
Georgi Krustev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 10 Dec 2010, 04:34 PM
Thank you for that reply, we will look into this issue more next week.

/Victor
0
Victor
Top achievements
Rank 1
answered on 17 Dec 2010, 01:11 PM
Hi,

I have now started putting this code to work, but am having some issues. Using this type of code (Razor syntax):

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
var tabStrip = Html.Telerik().TabStrip()
            .Name("TabStrip")
            .Items(tabstrip => {
                tabstrip.Add()
                    .Text("Tab 1")
                    .Selected(true);
                tabstrip.Add()
                    .Text("Tab 2");
            }).ToComponent();
  
//Commented for now, but basically works
//switch(tabStrip.SelectedIndex) {
//    default:
//        tabStrip.Items[0].Content = () => Html.RenderAction("Companies", "Companies");
//        break;
//}
  
  
<text>
Testing some text
</text>
  
//Tried both with and without flush
    Response.Flush();
    tabStrip.Render();
  
<text>
Testing some text
</text>
  
}

I get this output (note that the tabstrip is at the very top of the document, even before the <html> tag!  (The test text is positioned correctly though)
<div class="t-widget t-tabstrip t-header" id="TabStrip"><ul class="t-reset t-tabstrip-items"><li class="t-item t-state-default t-state-active"><span class="t-link">Administer Companies</span></li><li class="t-item t-state-default"><span class="t-link">Revive Deleted Companies</span></li></ul></div><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<head>
Have I misunderstood anything or do you have any suggestions of how to solve this?

Thanks
/Victor
0
Atanas Korchev
Telerik team
answered on 17 Dec 2010, 01:26 PM
Hi Victor,

 Using Render() with razor will not currently work. Render() uses the Response.Write which is not supported by Razor. As a workaround you can try this:

@{
var tabStripBuilder = Html.Telerik().TabStrip()
            .Name("TabStrip")
            .Items(tabstrip => {
                tabstrip.Add()
                    .Text("Tab 1")
                    .Selected(true);
                tabstrip.Add()
                    .Text("Tab 2");
            });
var tabStrip = tabStripBuilder.ToComponent();
//other code
}

<!-- render the tabstrip -->
@tabStripBuilder

Regards,
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 17 Dec 2010, 03:55 PM
Hi again,

Unfortunately we now get the case where the content of the tab is displayed first, then the tabstrip component with the content again. I'll attach a screenshot to show the result. The grid is a partial view, produced by the Companies view. The code producing this is:

var tabStripBuilder = Html.Telerik().TabStrip()
            .Name("TabStrip")
            .Items(tabstrip => {
                tabstrip.Add()
                    .Text("Administer Companies")
                    .Selected(true);
                tabstrip.Add()
                    .Text("Revive Deleted Companies");
            });
 
var tabStrip = tabStripBuilder.ToComponent();
 
switch(tabStrip.SelectedIndex) {
    default:
        tabStrip.Items[0].Content = () => Html.RenderPartial("Companies");
        break;
}
 
 
<text>
Testing some text
@tabStripBuilder
</text>
 
 
<text>
Testing some text
</text>
 
}


Also, to explain a bit more, when removing the @tabStripBuilder line nothing is shown.

The first grid (the one outside the tabstrip) is produced by the server-side code, the inner grid (with the menus(!), why is that?) is fetched using ajax after the page loads.

/Victor
0
Atanas Korchev
Telerik team
answered on 20 Dec 2010, 09:18 AM
Hi Victor,

 @tabStripBuilder is actually what renders the tabstrip. The @ symbol in Razor does the output.

The second may occur if you have both a view and a partial view named Companies (Companies.aspx and Companies.ascx). RenderPartial picks the aspx first. 

If you need further assistance please attach a working project to this thread.

Regards,
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 20 Dec 2010, 10:46 AM
Hi Atanas,

Attached is a project which demonstrates the behaviour discussed. It uses Asp MVC 3 RC2.

/Victor
0
Atanas Korchev
Telerik team
answered on 20 Dec 2010, 11:46 AM
Hi Victor,

 This seems to work as expected:

switch(tabStrip.SelectedIndex) {
    default:
        tabStrip.Items[0].Html = Html.Action("ThePartialView").ToHtmlString();
        break;
}

Regards,

Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 20 Dec 2010, 01:09 PM
Hi again,

So - after changing that and figuring some other things out most things basically work, however when I try to add the Ajax support (as in the second example in the first post) i get "You cannot set Url and ContentUrl at the same time.". How do I hook up the Ajax call for browsers that supports it? Right now I basically have:

@{
    var tabStripBuilder = Html.Telerik().TabStrip()
                .Name("TabStrip")
                .Items(tabstrip =>
                {
                    tabstrip.Add()
                        .Text("Tab 1")
                        .Url(Url.Action("Index", "Home", new { selectedIndex = 0 }))
                        .LoadContentFrom("ThePartialView", "Home");
                    tabstrip.Add()
                        .Text("Tab 2")
                        .Url(Url.Action("Index", "Home", new { selectedIndex = 1 }))
                        .LoadContentFrom("ThePartialView2", "Home", new { selectedIndex = 1 });
                })
               .SelectedIndex(Convert.ToInt32(ViewBag.selectedIndex));
 
 
var tabStrip = tabStripBuilder.ToComponent();
 
switch((int)tabStrip.SelectedIndex) {
    case 1:
        //Second tab
        tabStrip.Items[1].Html = Html.Action("ThePartialView2").ToHtmlString();
        break;
    default:
        tabStrip.Items[0].Html = Html.Action("ThePartialView").ToHtmlString();
        break;
}


Edit: Also there seems to be a bug in the code that selects the active tab. If I leave out the "selectedIndex = 0" part (which should not be needed since that is the default) BOTH tabs are selected visually when going to the second tab and none of them are clickable.


/Victor
0
Alex Gyoshev
Telerik team
answered on 23 Dec 2010, 02:32 PM
Hello Victor,

Thank you for reporting this. We are currently fixing the described behavior, though it requires quite a few changes in the code (serialization and client-scripts of both TabStrip and PanelBar). I will post a follow-up with an updated build on Monday next week (27th).

Happy holidays,

Alex Gyoshev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Alex Gyoshev
Telerik team
answered on 27 Dec 2010, 03:18 PM
Hello Victor,

Attached is the updated build, as promised.

Best wishes,
Alex Gyoshev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 30 Dec 2010, 09:05 AM
Thank you for that update!

Do you have any pointers for the main issue described, "You cannot set Url and ContentUrl at the same time."? How do I hook up the Ajax call for browsers that supports it? Or is that addressed as well in the hotfix?

Thanks again
/Victor
0
Alex Gyoshev
Telerik team
answered on 30 Dec 2010, 09:12 AM
Hi Victor,

Indeed, that was the problem that took so long to fix. You can use both Url() and LoadContentFrom() at the same time -- the content will be loaded from the LoadContentFrom() location if the user has JavaScript enabled, and navigate to Url() if JavaScript is disabled (or the user middle-clicks the tab, opening it in a new browser tab).

Regards,
Alex Gyoshev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 30 Dec 2010, 10:17 AM
Perfect, thanks for that clarification!

/Victor
0
Victor
Top achievements
Rank 1
answered on 03 Jan 2011, 03:52 PM
Hi again,

After trying out the new build, most things seems to work. Very nice! The one real issue I'm having is that the first tab is open as well as the second one when using the tabstrip without javascript and clicking the second tab.

(Code-wise, apart from both tab headers being active I also get double divs (both id TabStrip-1 and TabStrip-2 are set as display:block, however only the second one is (as is expected) filled with any content).

Edit: I just discovered a second issue: Navigating to ...?SelectedIndex=1 (second tab) takes you to the second tab when javascript is turned off (expected behaviour). However, when js is turned ON behaviour is very strange. It seems like the second tab is loaded is loaded server-side as it should be, however after that the first tab is loaded using ajax and focus is switched to that tab.



On a side note, would it be possible to get this behavious with less [repeated] code? I feel that I basically would like to specify the action method in the controller (or similairly in the view) as

public ActionResult Index()
{
    ViewBag.Tabs = new[]
                       {
                           new {
                               title = "Administer Persons",
                               actionName = "Persons",
                               controllerName = "Persons"
                            },
                           new {
                               title = "Revive Persons",
                               actionName = "RevivePersons",
                               controllerName = "Persons"
                            }
                       };
 
    return View();
}


Of course some extra parameters would be needed like serverOrAjax = both, serverSideIndexVariable = "selectedTabIndex", ...  but basically that kind of configuration would (should?) be all needed for a complete ajax + accessible serverside solution, which additionally would be very easy to implement and replace an existing structure with.

Any chances of that happening anytime soon?


Thanks
/Victor
0
Accepted
Alex Gyoshev
Telerik team
answered on 04 Jan 2011, 02:55 PM
Hello Victor,

Please take a look at the attached solution. It shows how to implement the requirements for an accessible tabstrip + AJAX content (if JavaScript is available) with the available API of the tabstrip. We don't have plans of supporting this scenario out-of-the-box, since it is quite specific. We would happily promote this as a code library, though, since others might find it useful, too.

All the best,
Alex Gyoshev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 04 Jan 2011, 04:41 PM
Hello Alex,

Thanks for the solution. After switching to the latest dll (2010.3.1303) and scripts, and using ItemAction as you do, everything works as expected - however very strange results occur if you specify "too much" directly in Items.

Specifically:

in "item.Add(...)" currently Text and ContentUrl can be put. If Url is specified here specifying selectedIndex=1 (second tab) gives the content of the second tab twice, on top of each other. Ajax does not work starting from second tab.

Html content for currently selected tab can be specified either in itemAction (using if(item.Selected)) or as suggested before using tabStripBuilder.ToComponent().Items[selectedIndex].Html = ...

Edit: Specifying Html outside of itemAction does not work if ContentUrl is not set in the items.Add() clause.... Even more confusing...

All in all very confusing behaviour to me - very unclear what makes things work in one place and not in the other, especially since everything can be specified in both.


All in all though, I'm happy to say that things now work as expected - very nice! Next step is to get a grid to work inside (and dropdowns inside the grid's editor). Right now the grid show with data as expected, but is unable to use ajax for any actions and reverts back to server-side behaviour. If you have any quick pointers about that that would be appreciated, anyway I'm greatful for the help so far!

/Victor
0
Alex Gyoshev
Telerik team
answered on 05 Jan 2011, 09:34 AM
Hello Victor,

Regarding the problem with the grid -- components that are loaded through AJAX do not register their scripts by themselves, so you need to include them manually. 

I am not experiencing the confusing behavior -- maybe I am not getting it. The following code works, but using ItemAction is more concise:

tabstrip.Add()
    .Text("Sitefinity ASP.NET CMS")
    .LoadContentFrom(Url.Action(contentLocations[4]))
    .Url(Url.Action("Index", new { selectedIndex = 4 }))
    .ImageUrl("~/Content/Icons/Suites/sitefinity.png")
    .Content(Html.Partial(contentLocations[4]).ToHtmlString());

Greetings,

Alex Gyoshev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Victor
Top achievements
Rank 1
answered on 05 Jan 2011, 04:32 PM
Thanks for the help so far. The issues described in above posts that are not solved yet can (together with some other issues) be seen in the support ticket 381359 which i created to be able to discuss a complete solution and many problems at once. Thanks for sorting out the initial problems though and for quick responses!

/Victor
Tags
TabStrip
Asked by
Victor
Top achievements
Rank 1
Answers by
Georgi Krustev
Telerik team
Victor
Top achievements
Rank 1
Atanas Korchev
Telerik team
Alex Gyoshev
Telerik team
Share this question
or