In Angular.js, is it possible to replace an ng-switch directive element with its contents? - angularjs

I'm using a switch to conditionally include different content. I want the inner content (e.g. welcome directive) to replace the parent ng-switch element. I know that you can do this with custom directives using the replace=true configuration property, but is this possible to do with built in directives such as ng-switch?
<div id="container">
<ng-switch on="tabIndex">
<welcome ng-switch-when="welcome"></welcome>
<main ng-switch-when="main"></main>
<help ng-switch-when="help"></help>
</ng-switch>
</div>
For example, When the value of tabIndex is 'help', I want the following html to result:
<div id="container">
<help><!-- contents of help template --></help>
</div>

You'll always need the logic there, but you don't have to use an element for a switch. It'll work just as well as an attribute on the parent:
<div id="container" ng-switch on="tabIndex">
<welcome ng-switch-when="welcome"></welcome>
<main ng-switch-when="main"></main>
<help ng-switch-when="help"></help>
</div>

Related

HTML form in ng-if environment

Structure of my app is like following:
<div class="parent">
<div class="child" ng-if="showChild">
<div class="child-view-1" ng-if="!isShown">
</div>
<div class="child-view-2" ng-if="isShown">
</div>
</div>
</div>
Inside child-view-2 I have form element, and of course, it is undefined in controller, probably beacuse of ng-if (as it creates child scope).
isShown variable just switches divs from child-view-1 to child-view-2.
What do you suggest, how can I make form visible all time in controller?
EDIT: My fault, the outer child is controlled by showChild flag...
You have an outer ng-if (on div class="child") based on the value of isShown. When isShown is true the content will be added to the DOM, and the class="child-view-1" will obviously not be added to the DOM because of ng-if="!isShown"
The second div's ng-if is redundant because it is the same condition as the outer one:
<div class="parent">
<div class="child" ng-if="isShown">
<div class="child-view-1" ng-if="!isShown">
<!-- THIS WILL NEVER BE DISPLAYED -->
</div>
<div class="child-view-2" ng-if="isShown">
<!-- THIS WILL ALWAYS BE DISPLAYED WHEN isShown IS TRUE -->
</div>
</div>
</div>

How do I include one angular template in another so that bootstrap classes still work?

I have a directive which uses three different templates:
http://jsfiddle.net/edwardtanguay/pLrkya7r/4
These templates each have a panel and I want them to include a header template which is the same for each of them, like this:
<script type="text/ng-template" id="itemMenuTemplateUndefined">
<div class = "panel panel-default" >
<div ng-include="'itemMenuTemplatePanelHeading'"></div>
<div class="panel-body">
<div>Age: {{item.age}}</div>
</div >
</div>
</script>
The included template looks like this:
<script type="text/ng-template" id="itemMenuTemplatePanelHeading">
<div class="panel-heading">{{item.firstName}} <b>{{item.lastName}}</b> (PROBLEM INCLUDED BUT NO COLOR)</div>
</script>
The problem is that although it includes the scope variable values and HTML, it doesn't seem to have the same HTML structure which causes e.g. the panel header color not to display.
How can I get this example to work so that it has the same HTML structure as without ng-include so that Bootstrap continues to work?
The problem is that the bootstrap css is very specific in targeting the panel heading as a direct child of the panel using selectors like .panel-warning>.panel-heading.
The extra <div> for the ng-include breaks this child relationship making it
<div class="panel">
<div ng-include>
<div class="panel-heading>
Some possible choices:
Add appropriate classes to the ng-include div
Copy the css rules and replace the > in selector with a space
Use your own directive instead of ng-include and within the options
set replace:true

Clone a DOM element with ng-click in AngularJS markup without scope function

Is it possible to clone an DOM element in AngularJS when clicked on it without using a custom function defined in controller/scope?
Example:
<div>
<div ng-click="create copy of this">some content</div>
</div>
becomes:
<div>
<div ng-click="create copy of this">some content</div>
<div ng-click="create copy of this">some content</div>
</div>
No. ng-click always calls functions in the scope. You could create a directive if you wanted to.

Is there a way to have directives like ng-switch replace the div that contains the ng-switch with the correct outcome?

For example, is there a way for:
<div ng-switch on="value">
<div ng-switch-when="1"> 1 </div>
<div ng-switch-when="2"> 2 </div>
</div>
to "return" the final form as simply (pretending that value = 1)
<div ng-switch-when="1"> 1 </div>
without the encompassing div?
Or is there another directive that can do this?
It would save me a lot of modifying CSS...
I recommend using ng-if:
<div ng-if="value==1"> 1 </div>
<div ng-if="value==2"> 2 </div>
Example: http://plnkr.co/edit/h8uap4NMJ9uGsFDy8Ck7?p=preview
Yes you can use ngIf Directive to add element into DOM conditionally.
ngIf
<div ng-if="myVar == '1'">Hello world</div>
This DIV will render only if value of myVar is 1.
Note : ngIf will create new scope. It won't work with ng-repeat.
For ng-repeat, you can use ngShow or ngHide directive. It works same as ngIf but it just add display:none by css class named as hide. So its better to use ngIf. ngShow or ngHide is expensive.
ngShow
<div ng-show="myVar == '1'">Hello world</div>
ngHide
<div ng-hide="myVar == '1'">Hello world</div>
By using this, you will not see Hello world but it will be in DOM

AngularJS: 1.2.0rc2 ng-switch does not remove previous content

updated: made a smaller poc, in plunkr to show the problem without the entire application around it.
see it here
issue: data-ng-switch works on inline content, but does not remove the previous element when switching using external templates via data-ng-include.
works
<div data-ng-switch="view">
<div data-ng-switch-when="template1">content 1</div>
<div data-ng-switch-when="template2">content 2</div>
</div>
doesn't work
<div data-ng-switch="view">
<div data-ng-switch-when="template1" data-ng-include="'template1.html'"></div>
<div data-ng-switch-when="template2" data-ng-include="'template2.html'"></div>
</div>
Best solution I currently found can be seen in the plunkr
you basically cannot use ng-include on the same dom level as the ng-switch anymore. The same goes for other logical directives like ng-show ng-hide...
adding the ng-include on a child node of the ng-switch-when element works:
<div data-ng-switch="view">
<div data-ng-switch-when="template1">
<div data-ng-include="'template1.html'"></div>
</div>
<div data-ng-switch-when="template2">
<div data-ng-include="'template2.html'"></div>
</div>
</div>
update
Should be fixed in .rc3!
This was confirmed as a bug in the angular rc2 version (confirmation in this google group discussion).
The actual bugticket can be found here.

Resources