ng-if showing empty DOM element when condition is not true - angularjs

I have the following in a view file:
<p class="presentation black">Sections:
<span data-ng-if="currentTab == 'tab1'">
<div ng-repeat="question in filtered = (template.questions | unique:'sectionName')"></div>
<p class="presentation black">{{filtered.length}}</p>
</span>
<span data-ng-if="currentTab == 'tab2'">
<div ng-repeat="sheet in filtered = (template.sections[0].sheets | unique:'name')"></div>
<p class="presentation black">{{filtered.length}}</p>
</span>
</p>
When tab1 is selected, the information is displayed correctly. However when on tab2, it appears that <p> element in both spans is being displayed - an empty value in displayed for the <p> element related to tab1. By looking at the DOM tree it also seems that when on tab2, the ng-if condition is not displaying: <!-- end ngIf: currentTab == 'tab2' -->. Can anyone see where the issue may be? Let me know if more code is required.

The "p" shouldn't be in a "span" according to HTML5 specs. Change the "span" to a "div".
HTML
<p class="presentation black">Sections:
<div data-ng-if="currentTab == 'tab1'">
<div ng-repeat="question in filtered = (template.questions | unique:'sectionName')"></div>
<p class="presentation black">{{filtered.length}}</p>
</div>
<div data-ng-if="currentTab == 'tab2'">
<div ng-repeat="sheet in filtered = (template.sections[0].sheets | unique:'name')"></div>
<p class="presentation black">{{filtered.length}}</p>
</div>
</p>

Related

How to bind a part of a variable already binded

I have a loop ng-repeat that displays sevral icons.
<div class="box">
<div class="box-body">
<div class="row" >
<div class="col-sm-6" style="margin-bottom: 5px;" ng-repeat="record in newlayout.display" align="center">
<a class="btn btn-app" ng-href="#newlayout/{{newlayout.url}}{{newlayout.itemValue}}" >
<span class="badge bg-yellow" style="font-size:22px;">{{record.numberOfSamples}}</span>
<i class="fa fa-{{newlayout.labStyle}}"></i> {{record.lab}}
</a>
</div>
</div>
</div>
</div>
My issue is that the second part of the binded variable itemValue should be dynamic
In my Js, I have this
newLayout.url = 'sublabs/?labName=';
newLayout.itemValue = 'record.lab';
The URL is dynamic.
When I click on the first displayed Icon, the url should look like this :
But it didn't work as I had a compilation error..
Does someone have an idea how to fix this:
http://localhost:8181/#/newlayout/sublabs?labName=PIA/C1 - Shiftlabo
Where the record value "PIA/C1 - Shiftlabo" change.
So basically here if I change
<a class="btn btn-app" ng-href="#newlayout/{{newlayout.url}}{{newlayout.itemValue}}" >
{{newlayout.itemValue}} by {{record.lab}} it would work..but the {{record.**lab**}} should be dynamic as it will have another value when I click on the icon. It will change to {{record.subLab}}
Thanks
Use property acccessor bracket notation inside the binding:
<div>{{record[labOrSublab]}}</div>
JS
var isSublab = false;
$scope.labOrSublab = "lab";
$scope.clickHandler = function() {
isSublab = !isSublab;
$scope.labOrSublab = isSublab ? 'subLab' : 'lab';
};

AngularJS filter is requiring two clicks before it filters results

I am a beginner at angular. I am pretty certain I am doing this the completely incorrect way but because I finally have it "somewhat working" as it works on the second click I am stuck going in this direction and can't seem to figure out another way to do it.
The filter sorts on the second click because it is initialing as "undefined" before the first click and sets it based on that I believe.
In my html:
<div class="col-xs-12 col-sm-4 location-list" ng-repeat="key in careerlist.location">
<div class="locations" ng-click="careerlist.criteriaMatch()">{{key}}
</div>
</div>
<div class="col-xs-12">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 job-container" ng-repeat="job in careerlist.career | filter : searchText | filter: selectExperience | filter: careerlist.criteria.name">
<h2>
{{job.title}}
</h2>
<h3>
{{job.location}}
</h3>
<div class="job-description" ng-bind-html="job.description | limitHtml : 200">
</div>
<br><br>
<button>Read More</button>
</div>
<br><br>
</div>
</div>
In my controller:
cl.criteriaMatch = function( criteria ) {
jQuery(document).on('click', '.locations', function(){
cl.criteria = {};
console.log("just the element text " + jQuery(this).text());
cl.criteria.name = jQuery(this).text();
return function( criteria ) {
return criteria.name === criteria.name;
};
});
};
Use ng-click instead of jQuery#on('click'). Angular does not know that the filter should be updated.
Update
#Makoto points out that the click is bound twice. It very much looks like you should just remove the jQuery binding altogether. I would even go so far as suggesting removing jQuery from you project.

Ng-Switch not Working properly with String.length - AngularJS

I'm working on a Store application and I need to show 2 different strings based on a response.
If I receive the response with no item title I need to show "No Item Title Found", else, I need to show item's title limited to a certain amount of characters.
Here is my code:
<div ng-switch on="item.title">
<div ng-switch-when="!item.title.length">
<p class="prod-title cursor-pointer"
ng-click="searchCtrl.openItemTab(item,event)">
{{ item.title = 'Title Not Found'}}</p>
</div>
<div ng-switch-default>
<p class="prod-title cursor-pointer"
ng-click="searchCtrl.openItemTab(item,event)">
{{ item.title | limitTo:60 }}</p>
</div>
</div>
I'm able to see Items titles when their length is greater than 0, but, I'm not able to see "No Item Title Found" when length is equal to 0.
Any suggestion? Thanks in advance.
use ng-if directive to show 'Title not found' when you don't have an available title.
<p ng-if='!item.title' class="prod-title cursor-pointer" ng-click="searchCtrl.openItemTab(item,event)">
Title Not Found
</p>
<p ng-if='item.title' class="prod-title cursor-pointer" ng-click="searchCtrl.openItemTab(item,event)">
{{item.title}}
</p>
Make the ng-switch like:
<div ng-switch on="item.title.length">
<div ng-switch-when="0">
Currently what you have means
if item.title (expression) equals true (!item.title.length == item.title) enter the first block
in any other case enter the second.
Plunker

changing main content on ng-repeat item click

here is the plunker:
http://plnkr.co/edit/Qj2yxQuT7SZ19u3vuXyq?p=preview
like an inbox.
<div class="col-xs-4 leftnav">
<button class="btn btn-primary btn-block">Add News</button>
<br>
<article ng-repeat="x in issues | filter:query" ng-click="makeActive(i)">
<h4>{{x.title}}</h4>
<p>{{x.message | limitTo:numLimit}}</p>
Read More..
</article>
</div>
<div class="col-xs-8 main-content">
<h2>News</h2>
<hr>
<article ng-repeat="x in issues">
<h3 >{{x.title}}</h3>
<p>{{x.priority}}</p>
<p class="lead">{{x.author}} - 6/12/2014</p>
<!-- ng-if="x.author == 'Andy' " -->
<hr>
<p>{{x.message}}</p>
Read More
<hr>
</article>
</div>
having a list of items ng-repeat on the left, then selecting the main content (on the right) from the options, then displaying the full content as the main selection.
ng-if ? ng-show ?
not sure how well I've described this but it should be pretty obvious from the fiddle.
thanks in advance.
I modified your plnkr http://plnkr.co/edit/9qZsp2o22L5x1a0JofPy?p=preview
I create a currectIssue variable for your right content display.
In left content, Read More.. has been change to <a ng-click="showIssue(x)">Read More..</a>
updated plunk: http://plnkr.co/edit/hGsdkybRMoRct8VykCcB?p=preview
well, you might consider:
- use another scope variable to display the selected item from the object
- I'd use ng-if in this case as that will create/destroy the content as needed
// controller
$scope.selectIssue = function(x) {
$scope.issue = x;
}
$scope.selectIssue($scope.issues['1']);
//view
<article>
<h3 >{{issue.title}}</h3>
<p>{{issue.priority}}</p>
<p class="lead">{{issue.author}} - 6/12/2014</p>
<div ng-if="issue.author == 'Andy'">
<hr>
<p>{{issue.message}}</p>
Read More
<hr>
</div>
</article>

Angular UI-Bootstrap 0.7.0 Collapse

I'm using the collapse feature of UI-Bootstrap (http://angular-ui.github.io/bootstrap/#/collapse) but when I use the collapse/toggle it loses the data and just returns "true".
Here is a Plunker to show my issue, http://plnkr.co/edit/e689Wureay8AMZQ9IIno?p=preview
A snippet from the code:
<div ng-repeat="name in names | filter:radioModel:true">
<span ng-model="namesList" ng-click="name = !name">Toggle collapse {{name.firstName}}</span>
<hr>
<div ng-show="name">
<div class="well well-large">{{name}} -</div>
</div>
That is because you are overwriting name in the ng-click here: ng-click="name = !name". That will make name true or false, depending on how many times ng-click was invoked.
What you want is to toggle a property on the model to collapse/uncollapse the following detail:
<div ng-repeat="name in names | filter:radioModel:true" >
<!-- change the property name.collapsed -->
<span ng-model="namesList" ng-click="name.collapsed = !name.collapsed">Toggle collapse {{name.firstName}}</span>
<hr>
<!-- use ng-hide to "collapse" -->
<div ng-hide="!!name.collapsed">
<div class="well well-large">{{name}} -</div>
</div>
</div>
Working demo: http://plnkr.co/edit/at7ceCYDXwWWlqUlKnkQ?p=preview

Resources