I'm trying to implement an Accordion style for a "Dynamic Data" application and can't find much help. Has anyone been able to do this whether through jQuery or Ajax? Would appreciate your help.
The reason for Accordion is that I have over 150 fields and the form looks overwhelming without an Accordion or Tab to simplify. So, if you have other ideas would love to hear from ya.
Hi Bja58, I used an AJAX tab control in an Entity Template see this articel for tha basic idea
Custom Entity Templates – Dynamic Data 4 I basically used the AJAX Control Toolkit Tab control in an Entity Template to achive this. I should really do an article for that.
See my blog C# Bits | Twitter @sjnaughton Always seeking an elegant solution.
The reason for Accordion is that I have over 150 fields and the form looks overwhelming without an Accordion or Tab to simplify.
To apply the accordion for this purpose is hardly possible.
You can create your own pseudo-accordion, providing it with the appropriate functionality.
The task of mapping groups of fields, I decided to use an ordinary Combo Box. This solution I found the easiest.
If this interest you, I can put the code.
Hi, Sjnaughton. If you can use jQuery Accordion for Dynamic Data Entities, I considered it a miracle, and once again I'll be grateful! In the meantime, I will present a pseudo-accordion, I was talking about. This example is based on your
http://csharpbits.notaclue.net/2010/02/grouping-field-on-details-edit-and.html. Here it is.
[AttributeUsage(AttributeTargets.Class)]
public class ColumnsGroupsAttribute : Attribute
{
public string[] Groups { get; set; }
}
public static string[] GetColumnsGroups(this MetaTable table)
{
var groups = table.Attributes.OfType<ColumnsGroupsAttribute>().DefaultIfEmpty(new ColumnsGroupsAttribute()).First() as ColumnsGroupsAttribute;
return groups.Groups;
}
public static int GetGroupIndex(this MetaColumn column)
{
if (column.GetAttributeOrDefault<DisplayAttribute>().GroupName == null)
return -1;
else
return Convert.ToInt16(column.GetAttributeOrDefault<DisplayAttribute>().GroupName);
}
public partial class DefaultEntityTemplate : System.Web.DynamicData.EntityTemplateUserControl
{
public MetaColumn currentColumn;
public String groupName;
public Boolean groupHeading;
string[] clgr = null;
private int currentGroup = -1;
protected override void OnLoad(EventArgs e)
{
// get a list of groups ordered by group name
var groupings = from t in Table.GetScaffoldColumns(Mode, ContainerType)
group t by t.GetGroupIndex() into menu
orderby menu.Key
select menu.Key;
clgr = Table.GetColumnsGroups();
// loop through the groups
foreach (var groupId in groupings)
{
// get columns for this group
var columns = from c in Table.GetScaffoldColumns(Mode, ContainerType)
where (groupId == -1 && c.GetAttributeOrDefault<DisplayAttribute>().GroupName == null) || c.GetAttributeOrDefault<DisplayAttribute>().GroupName == groupId.ToString()
orderby c.GetAttributeOrDefault<DisplayAttribute>().GetOrder()
select c;
// add group separator
if (groupId!=-1)
{
groupHeading = true;
currentColumn = columns.First();
currentGroup = groupId;
groupName = groupId.ToString();
Control item = new _NamingContainer();
EntityTemplate1.ItemTemplate.InstantiateIn(item);
EntityTemplate1.Controls.Add(item);
}
// add fields
foreach (MetaColumn column in columns)
{
groupHeading = false;
currentColumn = column;
Control item = new _NamingContainer();
EntityTemplate1.ItemTemplate.InstantiateIn(item);
EntityTemplate1.Controls.Add(item);
}
}
}
protected void Label_Init(object sender, EventArgs e)
{
if (!groupHeading)
{
Label label = (Label)sender;
label.Text = currentColumn.DisplayName;
int gr = currentColumn.GetGroupIndex();
label.GetParentControl<HtmlTableRow>().Attributes["class"] += " gr gr" + gr.ToString();
}
else
{
Label label = (Label)sender;
label.CssClass = "button";
label.Width = Unit.Percentage(100);
label.Text = clgr[Convert.ToInt16(groupName)];
var parentCell = label.GetParentControl<HtmlTableCell>();
parentCell.ColSpan = 2;
label.Attributes["onclick"] = "return ChangeTab(event);";
label.Attributes["title"] = currentGroup.ToString();
//parentCell.Attributes.Add("class", "DDGroupHeader");
}
}
protected void DynamicControl_Init(object sender, EventArgs e)
{
DynamicControl dynamicControl = (DynamicControl)sender;
dynamicControl.DataField = currentColumn.Name;
if (groupHeading)
{
// hide Dynamic Control maybe overkill
dynamicControl.Visible = false;
// get the parent cell
var parentCell = dynamicControl.GetParentControl<HtmlTableCell>();
// hide the cell
parentCell.Visible = false;
}
}
public class _NamingContainer : Control, INamingContainer { }
}
dd.js
function pageLoad() {
$(".button").button();
ChangeTab(null);
}
function ChangeTab(evt, bSave) {
var o;
if (evt != null) {
evt = evt || window.event;
o = evt.target || evt.srcElement;
if (o != null) {
o = o.parentNode;
}
}
else {
o = $(".button")[0]
}
if (o == null)
return;
var groupNum = o.title
var oD = $(".gr")
if (groupNum == null)
oD.show();
else {
oD.hide();
oD = $(".gr-1")
oD.show();
if (groupNum != "-1") {
oD = $(".gr" + groupNum)
oD.show(100);
}
}
}
[MetadataType(typeof(OrderMetadata))]
public partial class Order
{
[ColumnsGroups(Groups = new string[] { "Dates", "Ship Info", "Other Info" })]
internal partial class OrderMetadata
{
public Object OrderID { get; set; }
public Object CustomerID { get; set; }
public Object EmployeeID { get; set; }
[Display(Order = 0,GroupName = "0")]
public Object OrderDate { get; set; }
[Display(Order = 1,GroupName = "0")]
public Object RequiredDate { get; set; }
[Display(Order = 2,GroupName = "0")]
public Object ShippedDate { get; set; }
[Display(Order = 4,GroupName = "1")]
public Object ShipVia { get; set; }
[Display(Order = 5,GroupName = "1")]
public Object Freight { get; set; }
[Display(Order = 3,GroupName = "1")]
public Object ShipName { get; set; }
[Display(Order = 6,GroupName = "1")]
public Object ShipAddress { get; set; }
[Display(Order = 7,GroupName = "1")]
public Object ShipCity { get; set; }
[Display(Order = 8,GroupName = "1")]
public Object ShipRegion { get; set; }
[Display(Order = 9,GroupName = "1")]
public Object ShipPostalCode { get; set; }
[Display(Order = 10,GroupName = "1")]
public Object ShipCountry { get; set; }
// Entity Ref
[Display(Order = 12)]
public Object Customer { get; set; }
// Entity Ref
[Display(Order = 13)]
public Object Employee { get; set; }
// Entity Set
[Display(Order = 14)]
public Object Order_Details { get; set; }
// Entity Ref
[Display(Order = 11,GroupName = "1")]
public Object Shipper { get; set; }
}
}
public partial class AjaxTabGroupsTemplate : System.Web.DynamicData.EntityTemplateUserControl
{
private const string STR__AjaxActiveTabIndex = "_AjaxActiveTabIndex";
private String _seperator;
private TabContainer _tabContainer;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
_seperator = this.ClientIDSeparator.ToString();
// create a row with one cell to fill the
// surrounding table from the form view
var row = new HtmlTableRow();
var td = new HtmlTableCell();
row.Controls.Add(td);
this.Controls.Add(row);
// create tab container to hold each children column
_tabContainer = new TabContainer()
{
ID = "tabContainer_" + Table.Name,
// set auto post back to enable events
AutoPostBack = true
};
_tabContainer.ActiveTabChanged += tabContainer_ActiveTabChanged;
// add the tab container to the page
td.Controls.Add(_tabContainer);
}
private void tabContainer_ActiveTabChanged(object sender, EventArgs e)
{
Page.AddValueToSession<int>(Table.Name + STR__AjaxActiveTabIndex, _tabContainer.ActiveTabIndex);
}
protected override void OnLoad(EventArgs e)
{
var activeTab = Page.GetValueFromSession<int>(Table.Name + STR__AjaxActiveTabIndex);
_tabContainer.ActiveTabIndex = activeTab;
// get a list of groups ordered by group name
var scaffoldedColumns = Table.GetScaffoldColumns(Mode, ContainerType);
//var groupings = from t in scaffoldedColumns
// group t by t.GetAttributeOrDefault<GroupAttribute>().Index into columnGroups
// orderby columnGroups.Key
// select columnGroups.Key;
var groupAttribute = Table.GetAttribute<GroupNamesAttribute>();
if (groupAttribute == null)
throw new InvalidOperationException("A GroupsAttribute is required for AJAX tab group to work.");
//if (groupings.Count() != groupAttribute.Groups.Count)
// throw new InvalidOperationException("");
// add table for each group
//foreach (var gi in groupings)
foreach (var gi in groupAttribute.Groups)
{
var groupName = gi.Value;//groupAttribute.Groups[gi];
// create table panel
var tabPanel = new TabPanel()
{
ID = (Table.Name + _seperator + groupName).Replace(" ", _seperator),
HeaderText = groupName
};
// add tab to tab container
_tabContainer.Tabs.Add(tabPanel);
// create table to go inside tab
var tabTable = new HtmlTable();
tabTable.Attributes.Add("class", "DDDetailsTable");
tabTable.Attributes.Add("cellpadding", "6");
tabTable.Attributes.Add("Name", groupName);
// add the DynamicControl to the tab panel
tabPanel.Controls.Add(tabTable);
// get columns for this group
var columns = from c in Table.GetScaffoldColumns(Mode, ContainerType)
where c.GetAttributeOrDefault<GroupAttribute>().Index == gi.Key
orderby c.GetAttributeOrDefault<GroupAttribute>().Index
select c;
// add fields
foreach (MetaColumn column in columns)
{
var tableRow = new HtmlTableRow();
tabTable.Controls.Add(tableRow);
var tdHeader = new HtmlTableCell();
tdHeader.Attributes.Add("class", "DDLightHeader");
tdHeader.InnerText = column.DisplayName;
// add header cell to row
tableRow.Controls.Add(tdHeader);
var tdData = new HtmlTableCell();
var dynamicControl = new DynamicControl(Mode);
dynamicControl.DataField = column.Name;
dynamicControl.ValidationGroup = this.ValidationGroup;
tdData.Controls.Add(dynamicControl);
// add data cell to row
tableRow.Controls.Add(tdData);
}
}
}
protected void Label_PreRender(object sender, EventArgs e)
{
Label label = (Label)sender;
DynamicControl dynamicControl = (DynamicControl)label.FindControl("DynamicControl");
FieldTemplateUserControl ftuc = dynamicControl.FieldTemplate as FieldTemplateUserControl;
if (ftuc != null && ftuc.DataControl != null)
label.AssociatedControlID = ftuc.DataControl.GetUniqueIDRelativeTo(label);
}
public class _NamingContainer : Control, INamingContainer { }
Which is what I will base the Accordian on obviousely I could use the Accordian fromt eh AJAX control toolkit but I facy trying the JuiceUI accordian as it uses jQuery UI :)
You also need this:
public class AdvancedEntityTemplateFactory : System.Web.DynamicData.EntityTemplateFactory
{
public override string BuildEntityTemplateVirtualPath(string templateName, DataBoundControlMode mode)
{
string path = base.BuildEntityTemplateVirtualPath(templateName, mode);
if (File.Exists(HttpContext.Current.Server.MapPath(path)))
return path;
return path.Replace("_" + mode.ToString(), "");
}
public override EntityTemplateUserControl CreateEntityTemplate(MetaTable table, DataBoundControlMode mode, string uiHint)
{
var et = table.GetAttribute<EntityUIHintAttribute>();
if (et != null && !String.IsNullOrEmpty(et.UIHint))
return base.CreateEntityTemplate(table, mode, et.UIHint);
return base.CreateEntityTemplate(table, mode, uiHint);
}
public override string GetEntityTemplateVirtualPath(MetaTable table, DataBoundControlMode mode, string uiHint)
{
var et = table.GetAttribute<EntityUIHintAttribute>();
if (et != null && !String.IsNullOrEmpty(et.UIHint))
return base.GetEntityTemplateVirtualPath(table, mode, et.UIHint);
return base.GetEntityTemplateVirtualPath(table, mode, uiHint);
}
}
Which is used like this:
// add new entity template factory that works with single files also
DefaultModel.EntityTemplateFactory = newAdvancedEntityTemplateFactory();
in the Global.asax.cs to add advanced features to entity templates the main feature is that you only need one EntityTemplate (Default) for all the states (i.e. ReadOnly, Edit and Insert) which my AjaxTabControl takes advantage of.
See my blog C# Bits | Twitter @sjnaughton Always seeking an elegant solution.
bja58
Member
6 Points
9 Posts
Accordion for Dynamic Data Entities
Apr 26, 2012 08:19 PM|LINK
Hello everyone,
I'm trying to implement an Accordion style for a "Dynamic Data" application and can't find much help. Has anyone been able to do this whether through jQuery or Ajax? Would appreciate your help.
The reason for Accordion is that I have over 150 fields and the form looks overwhelming without an Accordion or Tab to simplify. So, if you have other ideas would love to hear from ya.
Thanks.
sjnaughton
All-Star
27308 Points
5458 Posts
MVP
Re: Accordion for Dynamic Data Entities
Apr 27, 2012 11:24 AM|LINK
Hi Bja58, I used an AJAX tab control in an Entity Template see this articel for tha basic idea Custom Entity Templates – Dynamic Data 4 I basically used the AJAX Control Toolkit Tab control in an Entity Template to achive this. I should really do an article for that.
Always seeking an elegant solution.
bja58
Member
6 Points
9 Posts
Re: Accordion for Dynamic Data Entities
Apr 30, 2012 11:03 PM|LINK
Thanks Steve. I had actually read your article before...nice work. I'd love to see a working sample of an Accordion using AJAX.
Can anyone else help?
friendster
Member
749 Points
189 Posts
Re: Accordion for Dynamic Data Entities
May 03, 2012 10:35 AM|LINK
Hi,
If you go for jquery stuff. you can use jquery UI accordion. That is a nice stuff. search for "Jquery UI accordion"
Thanks
Raj
valZ
Member
128 Points
40 Posts
Re: Accordion for Dynamic Data Entities
May 11, 2012 05:28 AM|LINK
To apply the accordion for this purpose is hardly possible.
You can create your own pseudo-accordion, providing it with the appropriate functionality.
The task of mapping groups of fields, I decided to use an ordinary Combo Box. This solution I found the easiest.
If this interest you, I can put the code.
sjnaughton
All-Star
27308 Points
5458 Posts
MVP
Re: Accordion for Dynamic Data Entities
May 11, 2012 11:08 PM|LINK
Try the JuiceUI that will give you the jQuery UI accordian and it should be easyer to do I will give it a try in the morning,
Always seeking an elegant solution.
valZ
Member
128 Points
40 Posts
Re: Accordion for Dynamic Data Entities
May 13, 2012 06:10 AM|LINK
Hi, Sjnaughton. If you can use jQuery Accordion for Dynamic Data Entities, I considered it a miracle, and once again I'll be grateful! In the meantime, I will present a pseudo-accordion, I was talking about. This example is based on your http://csharpbits.notaclue.net/2010/02/grouping-field-on-details-edit-and.html. Here it is.
[AttributeUsage(AttributeTargets.Class)] public class ColumnsGroupsAttribute : Attribute { public string[] Groups { get; set; } } public static string[] GetColumnsGroups(this MetaTable table) { var groups = table.Attributes.OfType<ColumnsGroupsAttribute>().DefaultIfEmpty(new ColumnsGroupsAttribute()).First() as ColumnsGroupsAttribute; return groups.Groups; } public static int GetGroupIndex(this MetaColumn column) { if (column.GetAttributeOrDefault<DisplayAttribute>().GroupName == null) return -1; else return Convert.ToInt16(column.GetAttributeOrDefault<DisplayAttribute>().GroupName); }public partial class DefaultEntityTemplate : System.Web.DynamicData.EntityTemplateUserControl { public MetaColumn currentColumn; public String groupName; public Boolean groupHeading; string[] clgr = null; private int currentGroup = -1; protected override void OnLoad(EventArgs e) { // get a list of groups ordered by group name var groupings = from t in Table.GetScaffoldColumns(Mode, ContainerType) group t by t.GetGroupIndex() into menu orderby menu.Key select menu.Key; clgr = Table.GetColumnsGroups(); // loop through the groups foreach (var groupId in groupings) { // get columns for this group var columns = from c in Table.GetScaffoldColumns(Mode, ContainerType) where (groupId == -1 && c.GetAttributeOrDefault<DisplayAttribute>().GroupName == null) || c.GetAttributeOrDefault<DisplayAttribute>().GroupName == groupId.ToString() orderby c.GetAttributeOrDefault<DisplayAttribute>().GetOrder() select c; // add group separator if (groupId!=-1) { groupHeading = true; currentColumn = columns.First(); currentGroup = groupId; groupName = groupId.ToString(); Control item = new _NamingContainer(); EntityTemplate1.ItemTemplate.InstantiateIn(item); EntityTemplate1.Controls.Add(item); } // add fields foreach (MetaColumn column in columns) { groupHeading = false; currentColumn = column; Control item = new _NamingContainer(); EntityTemplate1.ItemTemplate.InstantiateIn(item); EntityTemplate1.Controls.Add(item); } } } protected void Label_Init(object sender, EventArgs e) { if (!groupHeading) { Label label = (Label)sender; label.Text = currentColumn.DisplayName; int gr = currentColumn.GetGroupIndex(); label.GetParentControl<HtmlTableRow>().Attributes["class"] += " gr gr" + gr.ToString(); } else { Label label = (Label)sender; label.CssClass = "button"; label.Width = Unit.Percentage(100); label.Text = clgr[Convert.ToInt16(groupName)]; var parentCell = label.GetParentControl<HtmlTableCell>(); parentCell.ColSpan = 2; label.Attributes["onclick"] = "return ChangeTab(event);"; label.Attributes["title"] = currentGroup.ToString(); //parentCell.Attributes.Add("class", "DDGroupHeader"); } } protected void DynamicControl_Init(object sender, EventArgs e) { DynamicControl dynamicControl = (DynamicControl)sender; dynamicControl.DataField = currentColumn.Name; if (groupHeading) { // hide Dynamic Control maybe overkill dynamicControl.Visible = false; // get the parent cell var parentCell = dynamicControl.GetParentControl<HtmlTableCell>(); // hide the cell parentCell.Visible = false; } } public class _NamingContainer : Control, INamingContainer { } }dd.js
function pageLoad() { $(".button").button(); ChangeTab(null); } function ChangeTab(evt, bSave) { var o; if (evt != null) { evt = evt || window.event; o = evt.target || evt.srcElement; if (o != null) { o = o.parentNode; } } else { o = $(".button")[0] } if (o == null) return; var groupNum = o.title var oD = $(".gr") if (groupNum == null) oD.show(); else { oD.hide(); oD = $(".gr-1") oD.show(); if (groupNum != "-1") { oD = $(".gr" + groupNum) oD.show(100); } } }[MetadataType(typeof(OrderMetadata))] public partial class Order { [ColumnsGroups(Groups = new string[] { "Dates", "Ship Info", "Other Info" })] internal partial class OrderMetadata { public Object OrderID { get; set; } public Object CustomerID { get; set; } public Object EmployeeID { get; set; } [Display(Order = 0,GroupName = "0")] public Object OrderDate { get; set; } [Display(Order = 1,GroupName = "0")] public Object RequiredDate { get; set; } [Display(Order = 2,GroupName = "0")] public Object ShippedDate { get; set; } [Display(Order = 4,GroupName = "1")] public Object ShipVia { get; set; } [Display(Order = 5,GroupName = "1")] public Object Freight { get; set; } [Display(Order = 3,GroupName = "1")] public Object ShipName { get; set; } [Display(Order = 6,GroupName = "1")] public Object ShipAddress { get; set; } [Display(Order = 7,GroupName = "1")] public Object ShipCity { get; set; } [Display(Order = 8,GroupName = "1")] public Object ShipRegion { get; set; } [Display(Order = 9,GroupName = "1")] public Object ShipPostalCode { get; set; } [Display(Order = 10,GroupName = "1")] public Object ShipCountry { get; set; } // Entity Ref [Display(Order = 12)] public Object Customer { get; set; } // Entity Ref [Display(Order = 13)] public Object Employee { get; set; } // Entity Set [Display(Order = 14)] public Object Order_Details { get; set; } // Entity Ref [Display(Order = 11,GroupName = "1")] public Object Shipper { get; set; } } }Site.master
Thank you.
sjnaughton
All-Star
27308 Points
5458 Posts
MVP
Re: Accordion for Dynamic Data Entities
May 13, 2012 08:10 AM|LINK
Hi Valz, here is my AJAX tab Entity templte
public partial class AjaxTabGroupsTemplate : System.Web.DynamicData.EntityTemplateUserControl { private const string STR__AjaxActiveTabIndex = "_AjaxActiveTabIndex"; private String _seperator; private TabContainer _tabContainer; protected override void OnInit(EventArgs e) { base.OnInit(e); _seperator = this.ClientIDSeparator.ToString(); // create a row with one cell to fill the // surrounding table from the form view var row = new HtmlTableRow(); var td = new HtmlTableCell(); row.Controls.Add(td); this.Controls.Add(row); // create tab container to hold each children column _tabContainer = new TabContainer() { ID = "tabContainer_" + Table.Name, // set auto post back to enable events AutoPostBack = true }; _tabContainer.ActiveTabChanged += tabContainer_ActiveTabChanged; // add the tab container to the page td.Controls.Add(_tabContainer); } private void tabContainer_ActiveTabChanged(object sender, EventArgs e) { Page.AddValueToSession<int>(Table.Name + STR__AjaxActiveTabIndex, _tabContainer.ActiveTabIndex); } protected override void OnLoad(EventArgs e) { var activeTab = Page.GetValueFromSession<int>(Table.Name + STR__AjaxActiveTabIndex); _tabContainer.ActiveTabIndex = activeTab; // get a list of groups ordered by group name var scaffoldedColumns = Table.GetScaffoldColumns(Mode, ContainerType); //var groupings = from t in scaffoldedColumns // group t by t.GetAttributeOrDefault<GroupAttribute>().Index into columnGroups // orderby columnGroups.Key // select columnGroups.Key; var groupAttribute = Table.GetAttribute<GroupNamesAttribute>(); if (groupAttribute == null) throw new InvalidOperationException("A GroupsAttribute is required for AJAX tab group to work."); //if (groupings.Count() != groupAttribute.Groups.Count) // throw new InvalidOperationException(""); // add table for each group //foreach (var gi in groupings) foreach (var gi in groupAttribute.Groups) { var groupName = gi.Value;//groupAttribute.Groups[gi]; // create table panel var tabPanel = new TabPanel() { ID = (Table.Name + _seperator + groupName).Replace(" ", _seperator), HeaderText = groupName }; // add tab to tab container _tabContainer.Tabs.Add(tabPanel); // create table to go inside tab var tabTable = new HtmlTable(); tabTable.Attributes.Add("class", "DDDetailsTable"); tabTable.Attributes.Add("cellpadding", "6"); tabTable.Attributes.Add("Name", groupName); // add the DynamicControl to the tab panel tabPanel.Controls.Add(tabTable); // get columns for this group var columns = from c in Table.GetScaffoldColumns(Mode, ContainerType) where c.GetAttributeOrDefault<GroupAttribute>().Index == gi.Key orderby c.GetAttributeOrDefault<GroupAttribute>().Index select c; // add fields foreach (MetaColumn column in columns) { var tableRow = new HtmlTableRow(); tabTable.Controls.Add(tableRow); var tdHeader = new HtmlTableCell(); tdHeader.Attributes.Add("class", "DDLightHeader"); tdHeader.InnerText = column.DisplayName; // add header cell to row tableRow.Controls.Add(tdHeader); var tdData = new HtmlTableCell(); var dynamicControl = new DynamicControl(Mode); dynamicControl.DataField = column.Name; dynamicControl.ValidationGroup = this.ValidationGroup; tdData.Controls.Add(dynamicControl); // add data cell to row tableRow.Controls.Add(tdData); } } } protected void Label_PreRender(object sender, EventArgs e) { Label label = (Label)sender; DynamicControl dynamicControl = (DynamicControl)label.FindControl("DynamicControl"); FieldTemplateUserControl ftuc = dynamicControl.FieldTemplate as FieldTemplateUserControl; if (ftuc != null && ftuc.DataControl != null) label.AssociatedControlID = ftuc.DataControl.GetUniqueIDRelativeTo(label); } public class _NamingContainer : Control, INamingContainer { }Which is what I will base the Accordian on obviousely I could use the Accordian fromt eh AJAX control toolkit but I facy trying the JuiceUI accordian as it uses jQuery UI :)
You also need this:
public class AdvancedEntityTemplateFactory : System.Web.DynamicData.EntityTemplateFactory { public override string BuildEntityTemplateVirtualPath(string templateName, DataBoundControlMode mode) { string path = base.BuildEntityTemplateVirtualPath(templateName, mode); if (File.Exists(HttpContext.Current.Server.MapPath(path))) return path; return path.Replace("_" + mode.ToString(), ""); } public override EntityTemplateUserControl CreateEntityTemplate(MetaTable table, DataBoundControlMode mode, string uiHint) { var et = table.GetAttribute<EntityUIHintAttribute>(); if (et != null && !String.IsNullOrEmpty(et.UIHint)) return base.CreateEntityTemplate(table, mode, et.UIHint); return base.CreateEntityTemplate(table, mode, uiHint); } public override string GetEntityTemplateVirtualPath(MetaTable table, DataBoundControlMode mode, string uiHint) { var et = table.GetAttribute<EntityUIHintAttribute>(); if (et != null && !String.IsNullOrEmpty(et.UIHint)) return base.GetEntityTemplateVirtualPath(table, mode, et.UIHint); return base.GetEntityTemplateVirtualPath(table, mode, uiHint); } }Which is used like this:
in the Global.asax.cs to add advanced features to entity templates the main feature is that you only need one EntityTemplate (Default) for all the states (i.e. ReadOnly, Edit and Insert) which my AjaxTabControl takes advantage of.
Always seeking an elegant solution.
valZ
Member
128 Points
40 Posts
Re: Accordion for Dynamic Data Entities
May 13, 2012 08:35 AM|LINK
Hi, Sjnaughton. Thank you, I'm starting to learn your decision
sjnaughton
All-Star
27308 Points
5458 Posts
MVP
Re: Accordion for Dynamic Data Entities
May 13, 2012 12:11 PM|LINK
As soon as I get a momnet I will get the accordian working too.
Always seeking an elegant solution.