Is it possible to combine ng-include and other static content? - angularjs

I am just getting started working with AngularJS and have stumbled on combining multiple bits of content under the same element. In our previous version (using knockout/durandal) we were able to leverage "container-less syntax" to make this work but it doesn't seem like we can do the same with AngularJS.
<ul>
<li>this item comes from an ng-include</li>
<li>this item is defined statically</li>
</ul>
What I thought would work:
<ul>
<ng-include src="'thefile.html'" />
<li>this item is defined statically</li>
</ul>
Unfortunately, the resulting html includes an extra DOM layer wrapper which breaks my css - I am using a "ul > li" selector.
<ul>
<ng-include class="ng-scope" src="'thefile.html'">
<li class="ng-scope">
...
</li>
</ng-include>
<li>this item is defined statically</li>
</ul>
Attempt #2 was to include the content on the itself. It also didn't work. The static content was omitted completely:
<ul ng-include src="'thefile.html'">
<li>this item is defined statically</li>
</ul>
Is there a smarter/correct way to do this? I believe I'm looking for something similar to a "replace" property that I could use on a directive.
Thanks in advance.

If your css is the only thing that is causing you problems. Try
ul li{
color:red;
}
or
ul > li,
ul > ng-include > li{
color:red;
}

Related

ng-class not working in one situation. What are some possible cause of this?

I'm stuck. Cannot figured this out. This question is very simple to show, but I'm not really sure how to put it as a question, therefore I'll try my best.
First, here's the layout of my whole app (The problem lies in the Header.jsp):
<jsp:include page="../home/Header.jsp" />
<jsp:include page="../home/Modals.jsp" />
<div data-ng-view data-save-scroll-position data-position-relative-to-menu></div>
<jsp:include page="../home/Footer.jsp" />
The problem is very simple. I have the following data-ng-class in the data-ng-view section that change a tab to active if something is true (The problem is it won't work in one scenario even though it displayed true in the tab name):
<ul class="nav nav-tabs">
<li role="presentation" data-ng-class="tab.isSelected ? 'active' : ''" data-ng-repeat="tab in ctrl.tabs"
data-ng-click="ctrl.fetchBIReports(tab)">
</li>
</ul>
In the JSP that use data-ng-include for the above markup, there's a side nav to change to this page. Once clicked this side-nav, it highlighted the tab 'active' as expected (trying not to include the whole jsp):
<div class="side-navbar">
<ul>
<li class="{{ ctrl.navigate.path == 'bi/schedule' ? 'active-link' : 'normal-link'}}">
Schedule Reports
</li>
</ul>
</div>
<div class="content-right" data-ng-include="ctrl.navigate.path"></div>
content-right includes the JSP mentioned in the second markup.
So far, so good. Here's a demo of it working (including both side-navbar and content-right):
The problem is, in my Header.jsp, there's a nav bar that takes me to the same page. If it is clicked from a different page with different controller, then it works. But if I'm in the current controller and click that nav bar link, then data-ng-class does not take 'active' as its class. Here's the markup for the Header.jsp for that link:
<li class="dropdown" data-roles="['ROLE_ADMIN']">
<a href="#/bi" class="dropdown-toggle" data-toggle="dropdown" data-ng-click="ctrl.changeNavigation('bi/schedule')"
role="button" aria-haspopup="true" aria-expanded="false">BI Management<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Schedule Reports</li>
</ul>
</li>
Here is the demo of it not working even though it is printing out true in the UI:
The only problem is with this UI. All the data are populated. Records are displayed for the correct tab. Even side nav-bar is displaying the correct active class.
Your syntax for ng-class is off a bit. The format is "{ '[class-name]': [expression that evaluates to true or false] }". You can have multiple class values separated by commas each with their own expression. When an expression is true, the corresponding class is applied to the element and when it is false the class is removed from the element. The way you have written it would almost work for the plain class attribute, but you would need to include the interpolation characters: {{ and }}. Here is a very simple example to illustrate ng-class.
angular.module('app', []);
.red {
color: #fff;
background-color: #e21d1d;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app">
<label>
<input type="checkbox" ng-model="applyRedClass" /> Apply 'red' class
</label>
<div ng-class="{'red': applyRedClass}">
This is a simple example of how to use ng-class.
</div>
</div>

Angular JS Animation ng repeat two collections

I am trying to work out ng repeat animation when I add/remove items from two different arrays one after another but it doesn't seem to work really smoothly on chrome-it works on firefox. Here is the following example codes:
template.html
<ul>
<li ng-repeat='item1 in arr1' class="repeated-item">
<span>{{ item1 }}</span>
</li>
</ul>
index.html
<div>
<div ng-include='template.html'></div>
<ul>
<li ng-repeat='item2 in arr2' class="repeated-item">
<span>{{ item2 }}</span>
</ul>
</div>
I notice animation works quite well for outside repeat except ng-included template. Hope you guys can help to figure out this.
You didn't close the <div ng-include='template.html'> tag properly. Add the closing tag </div>.

angular-bootstrap-ui full-width table or list inside accordion

I am working with angularjs and the angular-bootstrap-ui package. Specifically, I am using bootstrap list-groups within the body of an accordion-group. I would like the list-group-items to extend all the way to the containing accordion-group's border. Here is a fiddle of the fragment, http://jsfiddle.net/qwesmv1d/1/. The list-group-items are being displayed with padding; however, I would like it to be 'full-width' as in this example, http://getbootstrap.com/components/#panels-list-group.
Code snippet ...
<accordion>
<accordion-group heading="Subject">
<ul class="list-group">
<li class="list-group-item">One</li>
<li class="list-group-item">Two</li>
</ul>
</accordion-group>
</accordion>
Any help appreciated .. thanks.
Override panel-body padding:
Add this into your main css
.panel-body{
padding : 0px;
}

How to change the content of a tab while you are on the same tab using AngularJS and Bootstrap?

Using AngularJS and Bootstrap, let say there are 3 tabs: tab1, tab2, and tab3. There are also some links on each tabs. Now for example, tab1 is active. The question is: how to change the content of the tab1 by clicking a link within the same tab?
main.html:
<div class="tabbable">
<ul class="nav nav-tabs">
<li ng-class="{active: activeTab == 'tab1'}"><a ng-click="activeTab = 'tab1'" href="">tab1</a></li>
<li ng-class="{active: activeTab == 'tab2'}"><a ng-click="activeTab = 'tab2'" href="">tab2</a></li>
<li ng-class="{active: activeTab == 'tab3'}"><a ng-click="activeTab = 'tab3'" href="">tab3</a></li>
</ul>
</div>
<div class="tab-content">
<div ng-include="'/'+activeTab"></div>
</div>
tab1.html:
<h1>TAB1</h1>
Something
something.html
<h1>SOMETHING</h1>
Now the question is how to change the tab1 content to something.html while the tab1 is active?
As pointed out in other examples there are many ways to do this. Direct DOM manipulation is not really the Angular way of thinking about this kind of use case. A better way to think about it might be:
What possible content can this tab contain?
What will control its' being displayed?
Using the ng-if or ng-switch directive allows you to selectively limit the content based on a variable defined in the scope.
Consider this possibility:
<div class="tabbable">
<ul class="nav nav-tabs">
<li ng-class="{active: activeTab == 'tab1'}"><a ng-click="activeTab = 'tab1'" href="">tab1</a></li>
<li ng-class="{active: activeTab == 'tab2'}"><a ng-click="activeTab = 'tab2'" href="">tab2</a></li>
<li ng-class="{active: activeTab == 'tab3'}"><a ng-click="activeTab = 'tab3'" href="">tab3</a></li>
</ul>
</div>
Based on your code for the included file you could do this:
<div class="tab-content">
<div ng-if="content==='A'" ng-include="'/'+activeTabA"></div>
<div ng-if="content==='B'" ng-include="'/'+activeTabB"></div>
</div>
Another approach is to utilize ng-view and routing. It is more complicated than conditionally including but less complicated than writing a whole new directive.
In short, you define a container element with the ng-view attribute like this
<div ng-view></div>
Then set up a routing table in your javascript code like this
$routeProvider.when('/tab1', {templateUrl: 'partials/tab1.html', controller: 'tab1Controller'});
$routeProvider.when('/tab2', {templateUrl: 'partials/tab2.html', controller: 'tab2Controller'});
For more detail see this link: http://docs.angularjs.org/api/ngRoute.directive:ngView
This is actually a fairly common AngularJS issue, and is handled pretty nicely by nested directives. It works well enough that it's actually one of the demos in the Custom Directive Guide on the AngularJS docs page. It's the last example, "Creating Directives that Communicate". You can see the full code there, but the idea is that you create a 'container' directive for the tab group and a 'pane' directive for the inside content. Your HTML ends up looking like this:
<my-tabs>
<my-pane title="Hello">
<h5 id="pane1">Hello</h5>
<p>This content is in the first pane.</p>
</my-pane>
<my-pane title="World">
<h5 id="pane2">World</h5>
<em>This content is in the second pane.</em>
</my-pane>
</my-tabs>
As #musically_ut pointed out in his comment, there are a lot of ways to handle this. This is just one way, but I think it works out pretty well.

jQuery live sibling-selector not working

I have this CSS selector, which just won't bind .live(), but works perfectly with .bind():
$('.treeView li ~ :has("ul")').prev('li')
I've read somewhere, that using the .prev() and .next() could be troublesome coupled with .live(), so I wanted to create an pure CSS selector (or ANYTHING that works with .live()!) to do the job - but I just can't figure it out!
Here's what I want to do:
Select all li-elements, which is followed by an li containing an ul.
Here's an HTML markup example, I want to select the ones where the comment says "selected"
<div class="treeView" id="processSegmentsTree">
<ul>
<li>Ostetanke</li> //selected
<li>
<ul>
<li>Tank 1</li>
<li>Tank 2</li>
</ul>
</li>
<li>Presse</li> //selected
<li>
<ul>
<li>Sub-leaf 1</li>
<li>Sub-leaf 2</li> //selected
<li>
<ul>
<li>test</li>
<li>test</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Any help is much appreciated, since this is a bit of a thorn in my eye :(
There is no such Selector to accomplish this task.
What I highly recommend you to do is to add ANYTHING as a flag to use when selecting your desired elements.
add attribute, wrapper, ANYTHING YOU WANT, then the task will be as easy as it should be.
This may work: // not css selector
$(".treeView li:has('ul')").prev();

Resources