PDA

View Full Version : MVC: Unable to add a chart to tabpanel



marjot2112
Mar 24, 2016, 4:09 PM
Hi,

I evaluate 4.0.0 RC. When I add a partialview with a chart to a tabpanel I get an error.
Everything is correct when I use Html.RenderPartial for the partialview.

What am I doing wrong or is it a bug?

thanks,
Martin


The error message is:


[TokenNotUniqueException: Token is not unique
-------------------
ID = \
TagName = anchor
Match = <#:anchor id="id9a948acade8bbf9f_ClientInit" />
]
Transformer.NET.Token.ParseAnchors() +355
Transformer.NET.TextTransformer.Parse(List`1 tokensType, Dictionary`2 variables) +669
Transformer.NET.TextTransformer.Transform(List`1 tokensType, Dictionary`2 variables) +31
Transformer.NET.TextTransformer.Transform(List`1 tokensType) +25
Transformer.NET.TextTransformer.Transform() +40
Ext.Net.ExtNetTransformer.Transform(String text) +150
Ext.Net.InitScriptFilter.Transform() +72
Ext.Net.InitScriptFilter.Flush() +76
System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +9641741
System.Web.HttpResponse.FilterOutput() +104
System.Web.CallFilterExecutionStep.System.Web.Http Application.IExecutionStep.Execute() +58
System.Web.HttpApplication.ExecuteStep(IExecutionS tep step, Boolean& completedSynchronously) +69

Controller Snippet:


public ActionResult BasicChart()
{
return PartialView(model.ChartModel);
}

public ActionResult Chart()
{
return View(model.ChartModel);
}

Partial View with Chart:



@model List<Ext.Net.MVC.Examples.BasicChartModel>

@Html.X().ResourceManager()

@{
ViewBag.Title = "Line Chart - Ext.NET MVC Examples";
var X = Html.X();
}

@(X.CartesianChart()
.Animation(false)
.FlipXY(false)
.Height(500)
.Store(X.Store()
.Data(Model)
.Model(X.Model()
.Fields(
X.ModelField().Name("Name"),
X.ModelField().Name("Data1")
)
)
)
.Axes(
X.NumericAxis()
.Fields("Data1")
.Position(Position.Left)
.Grid(true)
.Maximum(100)
.Renderer(r => r.Handler = "return label.toFixed(0) + '%';"),

X.CategoryAxis()
.Position(Position.Bottom)
.Fields("Name")
.Grid(true)
)
.Series(
X.LineSeries()
.XField("Name")
.YField("Data1")
.Smooth(3)
.HighlightConfig(X.Sprite().Radius(7))
.Marker(X.CircleSprite().Radius(4).LineWidth(0))
)
)


View with Tab:


@model List<Ext.Net.MVC.Examples.BasicChartModel>

@{
ViewBag.Title = "Chart";
Layout = "~/Views/Shared/_Layout.cshtml";
var X = Html.X();
}


@(X.TabPanel().ActiveTabIndex(0)
.Width(1000)
.Height(350)
.Items(X.Panel().Title("Chart 1")
.AutoScroll(true)
.Html(Html.Partial("BasicChart", Model).ToHtmlString()),

X.Panel().Title("Chart 2")
.AutoScroll(true)
.Html("Hello World")
)
)



Working View:


@model List<Ext.Net.MVC.Examples.BasicChartModel>

@{
ViewBag.Title = "Chart";
Layout = "~/Views/Shared/_Layout.cshtml";
}

@{Html.RenderPartial("BasicChart", Model);}


When I use
.Loader(X.ComponentLoader().Url(Url.Action("BasicChart", Model)) instead of
.Html(Html.Partial("BasicChart", Model).ToHtmlString()) there is no error, but the tab is empty.

fabricio.murta
Mar 24, 2016, 9:22 PM
Hello @marjot2112! Welcome to Ext.NET forums!

I think that your Html.Partial() method is not going to work anyway. But when you use Loader approach, you should be using it in ScriptMode.

Give this example a look: Dynamic Partial Rendering - Partial Content (http://mvc4.ext.net/#/Dynamic_Partial_Rendering/Partial_Content/). There are other usages of partial rendering next to that example that could be useful for you.

I hope this helps!

marjot2112
Mar 28, 2016, 9:04 PM
Hello fabricio.murata,

thanks for your answer. Unfortunately, the answer does not help me.

My goal is to present charts in different tabs, this could be done with static or dynamic partial rendering.

I tried different approaches (based on the example explorer) but all failed. I was successful to load my partial views into the tabs without charts but if I added a chart, I get an error message or the chart was not shown.

I recognized that the ResourceManager and the LoadMode of the Loader has an influence on the behavior, but I can’t find a sufficient documentation of both. It is hard way to evaluate a library by try and error.

I only found the example explorer and a poor api documentation, is there any further documentation of EXT.NET MVC available?

May you can provide a simple example with two tabs, and each tab contains a partial view with a chart, that will help me a lot.

fabricio.murta
Mar 30, 2016, 11:37 AM
Hello @marjot2112!

Can you link where did you find the poor API documentation you mentioned? Actually Ext.NET is a framework written on top of ExtJS so the vast majority of our API reflects the Sencha's ExtJS, which extensive API documentation can be found here: Sencha Documentation on ExtJS 6.0.1 (http://docs.sencha.com/extjs/6.0/6.0.1-classic/).

Also, we try to provide best (although it can not be perfect at the moment) IntelliSense support and documentation, with descriptive texts.

This is my personal thought: The examples are the absolute starting point to understand how a grid or another component should be built. From that point (after exploring examples with different usages), to get specific behavior then you explore options with Intellisense help, then refer to API and in the most specific approaches, you may end up needing to write JavaScript code and/or override. It is usually common to write some helper JavaScript code, specially when you want the page not sending lots of postback which could clobber the server and make the user experience uncomfortable.

Next I will check if there's something that impedes to add a graph from a partial view into a tab and share the code with you if not.

fabricio.murta
Mar 30, 2016, 1:53 PM
Hello again, to the sample you requested:

- It will have two tabs
- Two different graphs, one in each tab
- For simplicity I let the features to a minimum
- I could have done some code reuse in the get data, but left two specific actions and two specific partial views by purpose to illustrate the functionality.
- I have prefixed "c60766" with the forum thread ID to bind the example to this forum thread in my local project, so you are going to see this everywhere.

Controller:


using Ext.Net.MVC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace ExtNetPlaygroundMVC_current.Controllers
{
public class issuesController : Controller
{
public ActionResult c60766_Index()
{
return View();
}

public StoreResult c60766_GetChart1Data()
{
return new StoreResult(new List<object>()
{
new { Name = "a", Value = 1 },
new { Name = "b", Value = 2 },
new { Name = "c", Value = 3 },
new { Name = "d", Value = 4 },
new { Name = "e", Value = 5 }
});
}

public Ext.Net.MVC.PartialViewResult c60766_PV1(string containerId)
{
return new Ext.Net.MVC.PartialViewResult
{
ViewName = "c60766_pv1",
ContainerId = containerId,
RenderMode = Ext.Net.RenderMode.AddTo,
WrapByScriptTag = false
};
}

public Ext.Net.MVC.PartialViewResult c60766_PV2(string containerId)
{
return new Ext.Net.MVC.PartialViewResult
{
ViewName = "c60766_pv2",
ContainerId = containerId,
RenderMode = Ext.Net.RenderMode.AddTo,
WrapByScriptTag = false
};
}

public StoreResult c60766_GetChart2Data()
{
return new StoreResult(new List<object>()
{
new { Name = "x", Value = 3 },
new { Name = "y", Value = 5 },
new { Name = "z", Value = 1 },
new { Name = "k", Value = 2 },
new { Name = "m", Value = 4 }
});
}

}
}


Main view c60766_Index.cshtml:


@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>c60766_index</title>
</head>
<body>
<div>
@(Html.X().ResourceManager())

@(Html.X().TabPanel()
.Title("Tab Panel with partial view Graphs")
.Width(800).Height(600)
.Items(
Html.X().Panel().ID("tab1")
.Title("Tab1")
.Layout(LayoutType.Fit)
.Loader(
Html.X().ComponentLoader()
.Url(Url.Action("c60766_PV1"))
.Mode(LoadMode.Script)
.Params(new { containerId = "tab1" })
),
Html.X().Panel().ID("tab2")
.Title("Tab2")
.Layout(LayoutType.Fit)
.Loader(
Html.X().ComponentLoader()
.Url(Url.Action("c60766_PV2"))
.Mode(LoadMode.Script)
.Params(new { containerId = "tab2" })
)

)
)
</div>
</body>
</html>


Partial view 1 (chart on tab1), c60766_PV1.cshtml:


@(
Html.X().CartesianChart()
.Store(
Html.X().Store().ID("storeChart1")
.Model(
Html.X().Model().Fields("Name", "Value")
)
.Proxy(
Html.X().AjaxProxy().Url(Url.Action("c60766_GetChart1Data"))
.Reader(Html.X().JsonReader().RootProperty("data"))
)
.Data(Model)
)
.Axes(
Html.X().NumericAxis()
.Position(Position.Left)
.Fields("Value")
.Grid(true)
.Title("Value"),
Html.X().CategoryAxis()
.Fields("Name")
.Title("Name")
)
.Series(
Html.X().BarSeries()
.XField("Name")
.YField("Value")
)
)


Partial view 2 (chart on tab2), c60766_PV2.cshtml:


@(
Html.X().CartesianChart()
.Store(
Html.X().Store().ID("storeChart2")
.Model(
Html.X().Model().Fields("Name", "Value")
)
.Proxy(
Html.X().AjaxProxy().Url(Url.Action("c60766_GetChart2Data"))
.Reader(Html.X().JsonReader().RootProperty("data"))
)
.Data(Model)
)
.Axes(
Html.X().NumericAxis()
.Position(Position.Left)
.Fields("Value")
.Grid(true)
.Title("Value"),
Html.X().CategoryAxis()
.Fields("Name")
.Title("Name")
)
.Series(
Html.X().BarSeries()
.XField("Name")
.YField("Value")
)
)


This is pretty much the merge of the examples:
- Dynamic Partial Rendering - Partial Items (http://mvc4.ext.net/#/Dynamic_Partial_Rendering/Partial_Items/)
- Charts - Column - Basic (http://mvc4.ext.net/#/Chart_Column/Basic/)

In a simplified way.

I hope this helps!

marjot2112
Mar 30, 2016, 2:53 PM
Thanks for your extensive help. Your example works fine for me.
At first sight the use of the Ext.Net.MVC.PartialViewResult instead of the PartialView was the missing puzzle piece.

What I meant with poor documentation is the Ext.Net API documentation (http://docs.ext.net). It is only an alphabetically sorted flat list of classes with a minimum of explanation. A structure similar to the ExtJS API documentation would be helpful.

May after working some weeks with the Ext.Net library the approach to use the Sencha ExtJS API Documentation is totally sufficient.

What I’m missing as an absolute beginner is a getting started documentation of the Ext.Net library. How the library is intended to use, and some explanations with examples how I can map the Sencha ExtJS API to the Ext.Net API.

After that the Example Explorer gives a good overview over the extensive Capabilities of the library.

fabricio.murta
Mar 30, 2016, 4:33 PM
Thanks for the suggestions! We really appreciate user feedback so we can improve our introductory experience to new users!

By the way, we do have a getting started section on our examples explorer where we try to address the issues you pointed as an absolute beginner.

Did you browse those sections on the examples explorer? (http://examples4.ext.net/#/Getting_Started/Introduction/Component_Overview/ and the other two neighbor entries: Installation and Overview).

If you didn't browse those getting started sections, did they help you on the issues (some or all) you pointed? Suggestions and feedback are welcome!

Back to the API, probably you see just an alphabetical list of entries in the API reference because we had to make a choice when designing Ext.NET:

- Should we have the user to clobber the code file with using statements for all namespaces, make sub-classes so they have to type longer names (or just, again rely on using aliases), or flatten everything on the same name space so a single namespace reference would do for all the application?

We chose the latter believing it would be the option bringing the most simplicity, readability and also productivity in an Ext.NET, C# (WebForms or MVC) point of view, although this would hurt a little mapping from Ext.NET to ExtJS. We left a reference though by string object.instanceOf() on any Ext.NET classes with the full class name. This is mostly useful for people with Ext.NET source code access (premium users) as when navigating for the definition of the InstanceOf() method the user would be presented with the textual representation of the ExtJS class name.

Thanks again for the feedback and hope some of this clarifies your questions about Ext.NET.