jQuery live sibling-selector not working - css-selectors

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();

Related

Angular's $interpolateProvider working only partially

I have a really weird problem. I am using $interpolateProvider in my Angular app as I am passing some variables with Node which is "{{ }}" by default so I have set Angular's symbols to be: "{[ ]}".
See below:
mainApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[');
$interpolateProvider.endSymbol(']}');
});
Now, this works everywhere except in one part of my app. See the HTML below:
<ul class="nav navbar-nav navbar-right" ng-controller="navBarController">
<li>Profile</li>
<li>
<notification-icon count="{[notificationsCount]}"><i class="fa fa-envelope-o fa-2x"></i></notification-icon>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown">Settings<strong class="caret"></strong></a>
<ul class="dropdown-menu">
<li>
Profile Settings
</li>
<li class="divider"></li>
<li>
Logout
</li>
</ul>
</li>
{[notificationsCount]}
</ul>
The bit that doesn't work is:
count="{[notificationsCount]}"
The bit that does work is right at the end:
{[notificationsCount]}
On the browser, I get this error from Angular and when I inspect the element, it is in plain text like: {[notificationsCount]} and doesn't get converted to the number which is does on the 2nd last line of the HTML code.
I suspect this might be due to the 3rd party module I am using, which is angular-notification-icons but I can't be sure.
I have no idea how to proceed with this. Any input will help.
Thanks a lot!
You need write without {[]} in place where the code doesn't work
<notification-icon count="notificationsCount"><i class="fa fa-envelope-o fa-2x"></i></notification-icon>
look carefully at the examples from https://github.com/jacob-meacham/angular-notification-icons , notificationsCountused directly such as directive attributes.

Neither ng-hide nor ng-show change the visibility of the element

I began to use AngularJS, and I decided to make a list appear when I click on a button.
My code is rather simple, but it doesn't work, and I don't understand why:
<div ng-app="myGame" ng-controller="gameCtrl">
<h1>{{showLevels}}</h1>
<p ng-show="showLevels">
<ul>
<li>Level 1</li>
<li>Level 2</li>
<li>Level 3</li>
</ul>
</p>
<button ng-click="toggle()">Begin Game !</button>
</div>
And, in the JavaScript file:
var app = angular.module("myGame", []);
app.controller("gameCtrl", function ($scope) {
$scope.showLevels = false;
$scope.toggle = function () {
$scope.showLevels = !$scope.showLevels;
};
});
The levels are always shown, whether I use the ngShow or ngHide directive, despite the fact that $scope.showLevels is toggled, as I can see next to the title.
Where does this problem come from?
The paragraph element <p> can only accept phrasing content, and the unordered list element <ul> is not such a content.
Therefore, your browser translates your code into another one making more sense for it, by taking the <ul> out of the <p>. Your HTML is in fact:
<p ng-show="showLevels"></p>
<ul>
<li>Level 1</li>
<li>Level 2</li>
<li>Level 3</li>
</ul>
That's why your list is always visible, no matter the content of the $scope.showLevels variable. The solution is to use another element, a document division element <div> for instance, or to remove this intermediate element completely:
<ul ng-show="showLevels">
<li>Level 1</li>
<li>Level 2</li>
<li>Level 3</li>
</ul>

Firebase join collections for angular repeat

How would one join collections with Firebase and then later use it in an angular repeat?
Heres my database structure in Firebase:
I want to join wishes with the appropriated list and listId - but how?
And would I be able to do as such?:
<ul>
<li ng-repeat="list in lists">{{list.listName}}
<ul>
<li ng-repeat="wish in lists.wishes">{{wish.itemName}}</li>
</ul>
</li>
</ul>
Hope thing make sense!
You could try below snippet.
<ul>
<li ng-repeat="list in lists">{{list.listName}}
<ul>
<div ng-repeat="wish in lists.wishes">
<li>{{wish.itemName}}</li>
<li>{{list.listId}}</li>
<div>
</ul>
</li>
</ul>
<div> inside ul is not allowed but in HTML5 it will work without breaking anything, Refer Link

ng-repeat - content to show if array is empty or null

I've a deep nested ng-repeat lists, and only in the last loop I've to display alternate content if list was empty. I'm new to angular, saw some posts online please help me where can I use content if list is empty. The ng-repeat=sessions in day could be empty.
<ul class="day">
<li ng-repeat="sessions in day">
<ul class="table-view">
<li class="table-view-cell" ng-repeat="(heading, session) in sessions">
<span class="group">{{heading}}</span>
<ul class="cell">
<li class="cell-content" ng-repeat="val in session" ng-click="getSession(val.id)">
<div class="time" style="background-color:#{{val.color}}">
<span>{{val.start | date:"h:mma"}}</span>
<span>to</span>
<span>{{val.end | date:"h:mma"}}</span>
</div>
<div class="session" ng-class-odd="'odd'" ng-class-even="'even'">
<span class="name">{{val.name}}</span>
<span class="room">Room: {{val.room}}</span>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
1). CSS approach. I usually use pure CSS approach in such cases. With this markup (stripped extra-html):
<ul class="day">
<li ng-repeat="sessions in day">
...
</li>
<li class="no-sessions">
No sessions on this day.
</li>
</ul>
and CSS rules to hide .no-sessions li by default and make it visible only if there are no previous li tags:
li.no-sessions {
display: block;
}
li + li.no-sessions {
display: none;
}
So when sessions array is empty, there will be no li rendered and only no-sessions one will be visible. And if will hide as soon as there is at least one session on this day.
Demo: http://plnkr.co/edit/KqM9hfgTTiPlkdmEevDv?p=preview
2). ngIf approach. Of course you can use ngIf/ngShow directives for show no-records element when sessions array is empty:
<li ng-if="!day.length">
No sessions on this day.
</li>
I think this would work for your case:
<li ng-hide="day.length > 0">
No sessions on this day.
</li>
No extra CSS needed. Assumes day is an array.
http://plnkr.co/edit/WgDviOKjHKS1Vt5A5qrW
I would recommend handling that in your controller. Keeping your logic in the controller and javasript makes debugging easier and more manageable. I can think of 2 approaches: using ng-show/ng-hide or a condition for your day variable when its empty.
Option 1
ng-show/ng-hide approach:
$scope.isDayEmpty = function(){
return $scope.day.length > 0 ? false : true;
}
html:
<ul class="day">
<li ng-repeat="sessions in day" ng-hide="isDayEmpty">
...
</li>
<li ng-show="isDayEmpty">
No Sessions this Day
</li>
</ul>
Option 2:
ng-repeat approach
if($scope.day.length == 0){
$scope.day.push("No Sessions this Day");
}
This should get you essentially the same result. The first approach would make your CSS styling easier assuming you want to do something different in that case.
The second approach can vary in style depending on your code but thats an example of how you can do it. I don't know your javascript so I can't be more specific to your scenario.

Uncertainty about the use of ngInclude

I render recursive template with ngInclude. Here is my code:
<!--
definitionsRenderer.html
-->
<ul data-ng-if="currentLoc.definitions && templateIsloaded">
<li ng-repeat="definition in currentLoc.definitions">
{{definition.text}}
</li>
</ul>
<ul data-ng-if="templateIsloaded">
<li ng-repeat="loc in currentLoc.loc" ng-include="'./partials/definitionsRenderer.html'"></li>
</ul>
I need code to be executed asynchronous. So for scope of every included template
I want to have a variable - templateIsloaded with value false by default. When template is loaded and rendered it value to be true. How do that?
Best regards.
To have separate $scope for each of recursive called includes you can simply add ng-controller.
<li ng-repeat="loc in currentLoc.loc" ng-controller="definitionsRendererCtrl" ng-include="'./partials/definitionsRenderer.html'"></li>

Resources