I hope the title isn't misleading too much as I have no idea how else to call it, but here's the problem:
I am developing an app with Angular 2 and use the nested templates (hope that's the right name for them) in several instances.
Now the issue I have is that my app consists of several "widgets" which can contain other widgets. This can create a sort of circle in the template calls.
Example:
home.html:
<div> some html stuff </div>
<widget1 *ng-for="#widget of widgetList" [widget]="widget"></widget1>
widget1.html:
<div> some html stuff unique to widget1 </div>
<div *ng-if="widget.widgetSubList">
<div *ng-for="#widget of widget.widgetSubList">
<div [ng-switch]="widget.type">
<p *ng-switch-when="2"><widget2 [widget]="widget"></></widget2></p>
<p *ng-switch-when="3"><widget3 [widget]="widget"></></widget3></p>
</div>
</div>
</div>
widget2.html
<div> some html stuff unique to widget2 </div>
<div *ng-if="widget.widgetSubList">
<div *ng-for="#widget of widget.widgetSubList">
<div [ng-switch]="widget.type">
<p *ng-switch-when="1"><widget1 [widget]="widget"></></widget1></p>
<p *ng-switch-when="3"><widget3 [widget]="widget"></></widget3></p>
</div>
</div>
</div>
widgetSubList is a property of the widget that is filled if it has sub-widgets, the ng-if does work in this case and doesn't crash the code if there are no sub-widgets.
That's the point where the whole thing crashes since it creates the mentioned "circle" of widgets containing widgets that have been in the above part of the tree already since widget1 can call widget2 which can call widget1 again.
I can't change that structure since it's predetermined by the API I use in this case.
So now the question: Is there a way to have this work?
Since all widgets require different implementations, I can't really work around it without creating one giant html file filled with ng-ifs, which I would like to avoid.
PS: I edited the example a bit further to represent the code better.
the #Input part is present in the .ts files.
Right now, I only read out one additional level of sub-widgets from the API for test purposes.
What is a bit strange is that you don't have a loop of widgets within the widget1.html and widget2.html files. With your implement, you always remain on the same widget metadata, so it's normal that you have an infinite loop...
As a matter of fact, you need to have a recursive structure that would allow to define the structure of your component:
widgetList
widget
children
widget
children
widget
children
widget
children
widget
children
(...)
So when the current widget won't have children, the recursive loop will end.
So I would refactor your templates like this (for example for widget1.html):
<div> some html stuff unique to widget1 </div>
<div *ng-for="#subWidget of widget.children">
<div [ng-switch]="subWidget.type">
<p *ng-switch-when="2"><widget2 [widget]="subWidget"></widget2></p>
<p *ng-switch-when="3"><widget3 [widget]="subWidget"></widget3</p>
</div>
</div>
Each widget would have an input corresponding to the widget metadata:
#Component({
selector: 'widget1',
(...)
})
export class Widget1Component {
#Input()
widget: any;
}
Related
DNN 9.3.2 / 2sxc 10.25.2
Using 2sxc Content and c# Razor templates, I'm able to create a content type with some fields and enable the list mode on the template so that I can have a list of items and manage it. This is great because it lets me have one (1) 2sxc Content module on the page and list out as much content as I need.
However, in many cases, I need a "list within a list" so that I can have a repeating list of content within a repeating list of content and manage the design through the template instead of relying on my Content Editors to write HTML. See screenshot for an example.
In this design, I have 1 module that has "List" enabled and in that module I have 3 items called "Spotlights" which are just Content items. But then in each "Spotlight", there is a list of "PRE-CONFERENCE SESSIONS" which each have a title, link, and specific style (colour) for each item. In this setup, I simply made the "PRE-CONFERENCE SESSIONS" section a DNN Editor (tinymce) and then manually edit the HTML to make the FontAwesome caret and assign a CSS class to style each accordingly (each colour is important as it indicates the type of session). This method works but is cumbersome and involves me as a developer to maintain the list as the Content Editors don't know HTML.
I know that I can break this 1 module apart into 3 modules where each Spotlight is the Header content, and then the PRE-CONFERENCE SESSIONS links are the content item, but I was hoping to keep everything contained in 1 module for ease of maintenance. I also run into other scenarios in design where a sort of "sub" (or nested) list content would be really useful.
Is it possible to do this in 2sxc? Or is there a better way of achieving this?
I've done something similar to this where I created an Bootstrap Accordion and then also had a nested Bootstrap Accordion within that. Here's an example, maybe it'll help. https://www.crawfordinsurancegroup.com/commercial-insurance expand the Target Markets Accordion and you'll see a nested one within it.
I used the concept of Content-Blocks for this. In the main Accordion, I added another field called AccordionItem and made it an Entity Type and the Input Type as ContentBlocks. This give you the ability to select another 2sxc entity within your content,
https://www.screencast.com/t/iwCn2zmH8H
In your template, you can add a foreach to loop through the content items and render them
#foreach(var cb in AsDynamic(Content.AccordionItem)){
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<a role="button" data-toggle="collapse" data-parent="#accordion-#(Dnn.Module.ModuleID)" href="#collapse-#cb.EntityId" aria-expanded="true" aria-controls="collapseOne">
<strong>#cb.Title</strong>
</a>
<div class="panel-title"></div>
</div>
<div id="collapse-#cb.EntityId" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
#Html.Raw(cb.Content)
</div>
</div>
</div>
}
So in my example, I'm creating new Bootstrap accordions. You can reference the fields that are part of the nested entity (cb in my case) and output them in the template as you need them. Hope this helps.
Just as an added info: 2sxc 11.0 enhances lists-in-lists, so that the edit-toolbar of items-in-property-lists actually also get buttons like move-up/move-down etc.
enjoy ;)
I have a component A with its html/ts file. When I inherit a second component B from A, this will take all properties and method on the first. If I want to use the component A html, I can reference the comp A html in the templateUrl property.
I have a problem. I want use the component A html, but I want extend it. So my idea is "include" the first component html to the second. It's possible in Angular2? Is there another way?
I don't want to create an instance of component A in the component B. I want only the html markup.
EDIT:
In this example there is my problem:
https://stackblitz.com/edit/ng-content-projection-lzjwea
when I inherited the Hello2 ts, If I create an instance of hello component in hello2 html, it take its name property. I found three solutions:
Change all properties that need to be used in all inherit component to input and inject the
Duplicate html code
Find a way to reference the html of first component without creating an instance of it.
I think the best solution is the third. But I don't know a way to do it..
ng-content could be used to project dynamic content in a component.
For example, consider the following
hello.component.html
<div id='border'>
<h1>Base Component</h1>
<p>ng-content could be used for projecting dynamic content within a component</p>
<ng-content>
<!-- Dynamic content goes here -->
</ng-content>
</div>
So, now whatever that is in between
<hello>
<!-- dynamic html here -->
</hello>
app.component.html
<hello>
<div style="border: 2px solid red">
<h2>Child Component</h2>
<button id="sample1"> Sample 1 </button>
<button id="sample2"> Sample 2 </button>
</div>
</hello>
Example
Hope this helps
EDIT:
I would like to conditionally display templates inside of a larger template as long as the presence of the larger template is True.
in sidebar.hbs
<div id="sidebar-wrapper" class="super-super-float-right-col">
<div id="sidebar-wrapper" class="super-float-right-col">
<div id="sidebar-wrapper" class="float-right-col">
{{#if permit.id}}
{{render 'applicant'}}
{{render 'location'}}
{{else}}
<h2>Nope!</h2>
{{/if}}
</div>
</div>
</div>
In application.hbs I call the sidebar and the outlet
{{render sidebar}}
{{outlet}}
So technically the sidebar is currently unrelated to the results of the {{outlet}}.
I want to connect the the results of the {{outlet}} with which templates are rendered in sidebar.hbs.
Right now I'm getting "Nope!"
EDIT: I was able to use {{#if this.id}} to make the conditions on the permit.hbs page true. Now I'm trying to figure out how to apply that same logic for rendering
Much love,
Ian
If you're in the permit template there is no point in checking if you're in the template. That's analogous to saying if true, because the only reason that code would be executing would be because it's there executing it.
If that wasn't exactly what you meant update your question.
If you want something in your template to change based on the route, the application controller has a property called currentPath which has the current application path, you can watch it and create computed properties that change based on the current path.
http://emberjs.jsbin.com/iCIkEsib/2/edit
My module position in my Joomla template is just a div with a "row" class. When I add content to that module position using the custom html module and give it module class suffixes of "first", "mod-light" and "bord-left"it appears to nest 2 divs within my module position both with the same classes which is causing problems. How do I modify this so that it is not creating this nested structure or at least does not apply these classes to the inner div?
For example, if I simply entered this raw html into the editor...
"<p>...entered content appears here...</p>"
I would get this output from Joomla...
<div class="moduletable first mod-light bord-left span4">
<div class="custom first mod-light bord-left">
<p>...entered content appears here...</p>
</div>
</div>
How can I make Joomla do this instead...
<div class="moduletable first mod-light bord-left span4">
<p>...entered content appears here...</p>
</div>
You can use custom module chrome to create your own module layouts:
http://docs.joomla.org/Applying_custom_module_chrome
I'm using context to print blocks into a region. However, I'd like to have the region print wrapper DIVs around the blocks of the given area. I know this is possible with region.tpl.php in Drupal 7. I can't seem to figure out the best way in Drupal 6.
<div class="{region classes i.e. sidebarleft}">
<div class="{block 1}"></div>
<div class="{block 2}"></div>
<div class="{block 3}"></div>
<div class="{block 4}"></div>
</div>
However, currently it prints like this:
<a id="context-block-region-right" class="context-block-region">Right Sidebar</a>
// the previous anchor tags is hidden
<div id="block-block-82" class="clear-block block block-block">
<h2>Community Navigation Block</h2>
<div class="content">
<div id="community-landing-navigation-menu">
<div class="joinCommunityBox">
<div class="community-landing-pagePanelWrapperSideBar">
<div class="community-landing-pagePanelWrapperSideBar">
<a id="context-block-block-82" class="context-block editable edit-community_contexts"></a>
</div>
</div>
I wish it would print a region wrapper tag around ALL of that...
Also, I want to keep my page.tpl.php clean of extra wrapper tags. It would be better if we could preprocess regions to print a wrapper tag.
I figured it out... The answer is actually borrowed from zen. If you click the link below, several 'preprocess functions' are rendering a new region template. Then, blocks are collected into that region, and printed.
http://www.drupal.org/node/223440#comment-5304866
It works great, and is going to go production soon.