find out index of several using directive / angular - angularjs

i wrote a directive that give out some clickable divs for a kicker game, it look like that:
<span>Team 1</span>
<scoreDisplay>
<div ng-click="setScore(0)" class="score-item">1</div>
<div ng-click="setScore(1)" class="score-item">2</div>
<div ng-click="setScore(2)" class="score-item">3</div>
<div ng-click="setScore(3)" class="score-item">4</div>
<div ng-click="setScore(4)" class="score-item">5</div>
<div ng-click="setScore(5)" class="score-item">6</div>
</scoreDisplay>
<span>Team 2</span>
<scoreDisplay>
<div ng-click="setScore(0)" class="score-item">1</div>
<div ng-click="setScore(1)" class="score-item">2</div>
<div ng-click="setScore(2)" class="score-item">3</div>
<div ng-click="setScore(3)" class="score-item">4</div>
<div ng-click="setScore(4)" class="score-item">5</div>
<div ng-click="setScore(5)" class="score-item">6</div>
</scoreDisplay>
after a click on a score-item, i want to get the index of the directive,
where the items inside, here the scopefunction inside the controller:
$scope.game = {
team_1:{name:'Ateam',score:0}
team_2:{name:'Bteam',score:0}
};
$scope.setScore = function(itemindex, directiveindex){
$scope.game["team_"+(directiveindex+1)].score = (itemindex+1)
}
any idea, how i can get the directive-index (the parent elemment dom index) with angular?
thanks for helping.

Use ng-repeat directive for code parts like:
<div ng-click="setScore(0)" class="score-item">1</div>
<div ng-click="setScore(1)" class="score-item">2</div>
<div ng-click="setScore(2)" class="score-item">3</div>
<div ng-click="setScore(3)" class="score-item">4</div>
<div ng-click="setScore(4)" class="score-item">5</div>
<div ng-click="setScore(5)" class="score-item">6</div>
You can replace in controller:
$scpe.teams = [...]
In template:
<div ng-repeat="team in teams" ng-click="setScore(team.score,$index)" class="score-item">{{team.name}}</div>
You can make similar change for scoreDisplay

Found a solution with a attribute "index":
<scoreDisplay index="1"></scoreDisplay>
<scoreDisplay index="2"></scoreDisplay>
This works fine, but i will search for a better solution
like this or with something like:
angular.element("body scoreDisplay").index($event.target);

Related

AngularJS - Display Banner after 2 rows, followed by another 2 Rows

I'm trying to display a Banner <div> after 2 rows of 4 x "col-md-3", followed by another 2 Rows - so the resulting markup would look like:
<div class="col-md-3">1</div>
<div class="col-md-3">2</div>
<div class="col-md-3">3</div>
<div class="col-md-3">4</div>
<div class="col-md-3">5</div>
<div class="col-md-3">6</div>
<div class="col-md-3">7</div>
<div class="col-md-3">8</div>
<div class="col-md-12" id="Banner">Banner</div>
<div class="col-md-3">9</div>
<div class="col-md-3">10</div>
<div class="col-md-3">11</div>
<div class="col-md-3">12</div>
<div class="col-md-3">13</div>
<div class="col-md-3">14</div>
<div class="col-md-3">15</div>
<div class="col-md-3">16</div>
Trying to simulate this using AngularJS so would have to use ng-repeat - but cannot seem to get this working. Any help appreciated: My Plunker
<div ng-repeat="n in Numbers">
<div class="col-md-3">{{n}}</div>
</div>
There are just a couple of problems with your plunker. First maincontroller.js is missing the .js extension, so it is never loaded.
Next all of the references to load angular should start with https instead of just http.
To display the banner after a certain number of rows place it within the first div and use something like:
<div class="col-md-12" id="Banner" ng-if="$index==5">Banner</div>
Not sure if 5 is the number you want there or if you want to use some kind of expression to see if ng-if is divisible by a certain value, but using $index and ng-if should get you there.
You could use ng-repeat-start and ng-include with a ng-if to conditionally include the banner if it's at the correct index with n===8.
Please have a look at the code below or in this plunkr.
angular.module("app", [])
.controller("MainController", mainController);
function mainController($scope) {
$scope.Numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-controller="MainController" ng-app="app">
<h1>Demo</h1>
<div class="col-md-3" ng-repeat-start="n in Numbers">{{n}}</div>
<div ng-include="'banner.html'" ng-if="(n === 8)" ng-repeat-end></div>
<script type="text/ng-template" id="banner.html">
<div class="col-md-12" id="Banner">Banner</div>
</script>
</div>

Why is my ng-hide / show not working with my ng-click?

I want to show the elements that contain displayCategory.name with the ng-click above it, but it's not working as expected.
.divider-row
.row-border(ng-hide="showMe")
.row.row-format
.col-xs-12.top-label
Find where you stand
%hr.profile
.row.labelRow
.col-xs-12
%ul
%li(ng-repeat='category in service.categories')
.clear.btn.Category(ng-click='thisCategory(category) ; showMe = true') {{category.name}}
.divider-row
.row-border(ng-show="showMe")
.row.row-format
.col-sm-12.col-md-12.top-label.nopadLeft
What do you think about {{displayCategory.name}}
I dropped your haml into a converter and this is what it spat out (clearly incorrect):
<div class="divider-row">
<div class="row-border">(ng-hide="showMe")
<div class="row row-format">
<div class="col-xs-12 top-label">
Find where you stand
</div>
</div>
<hr class="profile"/>
<div class="row labelRow">
<div class="col-xs-12">
<ul>
<li>(ng-repeat='category in service.categories')
<div class="clear btn Category">(ng-click='thisCategory(category) ; showMe = true') {{category.name}}</div>
</li>
</ul>
</div>
</div>
</div>
<div class="divider-row"></div>
<div class="row-border">(ng-show="showMe")
<div class="row row-format">
<div class="col-sm-12 col-md-12 top-label nopadLeft">
What do you think about {{displayCategory.name}}
</div>
</div>
</div>
</div>
So after some quick googling I found that you should be writing it like this:
.divider-row
.row-border{"ng-hide" => "showMe"}
.row.row-format
.col-xs-12.top-label
Find where you stand...
As that will convert to what you need:
<div class="divider-row">
<div class="row-border" ng-hide="showMe">
<div class="row row-format">
<div class="col-xs-12 top-label">
Find where you stand
Using curly braces instead of round ones for attributes
I cannot run your code to verify, but I think the problem is that the binding property showMe should be replaced with some object like status.showMe.
For example, define $scope.status = { showMe: false}; outside the ng-repeat (in your controller maybe).
Please check a working demonstration: http://jsfiddle.net/jx854d3y/1/
Explanations:
ng-repeat creates a child scope for each item. The child scope prototypical inherits from the parent scope. In your case, the primitive showMe is assigned to the child scope. While you use it outside the ng-repeat, where it tries to get the value from the parent scope, which is undefined. That is why it is not working.
Basic rule is: always use Object, instead of primitive types, for binding.
For more details, please refer to: https://github.com/angular/angular.js/wiki/Understanding-Scopes

Angular wrap transcluded elements separately?

I am fairly new with Angular. And although I've made a lot of progress there are still a couple of things I don't know.
Currently I am running into a transclusion 'problem'.
Basically what we want is to wrap every transcluded element/directive seperately with html that's controlled by the parent directive.
Example:
<my:directive>
<my:sub-directive>Child 1</my:sub-directive>
<my:sub-directive>Child 2</my:sub-directive>
<my:sub-directive>Child 3</my:sub-directive>
</my:directive>
Desired result (I've left the directive elements to make the example a bit more clear):
<my:directive>
<ul>
<li>
<div class="panel">
<div class="header">
// Some stuff that's controlled by my:directive comes here
</div>
<div class="content">
<my:sub-directive>Child 1</my:sub-directive>
</div>
</div>
</li>
<li>
<div class="panel">
<div class="header">
// Some stuff that's controlled by my:directive comes here
</div>
<div class="content">
<my:sub-directive>Child 2</my:sub-directive>
</div>
</div>
</li>
<li>
<div class="panel">
<div class="header">
// Some stuff that's controlled by my:directive comes here
</div>
<div class="content">
<my:sub-directive>Child 3</my:sub-directive>
</div>
</div>
</li>
</ul>
</my:directive>
Does anyone have a clue how to handle this? I know in my example I could introduce a panel directive, but note this is just an example of the same problem.
You can pass a fifth parameter to your directive's link function transclude and then do your manipulation in there, here's a quick example:
angular.directive('myDirective', function ($compile) {
return {
restrict:'EA',
transclude:true,
link: function (scope, elm, attrs,ctrl,transclude) {
transclude(scope,function(clone) {
//clone is an array of whatever is inside your main directive
clone.filter('mySubDirective').each(function(index, value){
//create your html and you might have to $compile it before:
elm.append(myHtml);
});
});
}
};
})

Get id of parent element of currently clicked element in AngularJS

How do I get the id of a parent element of currently clicked element in AngularJS?
<div id="d8" class="menutitles ng-scope" ng-repeat="title in list">
<div class="right" ng-click="showsubmenu($event)">+</div>
<div class="left" ng-click="showsubmenu($event)">Unit 9</div>
</div>
How to get the value d8 in showsubmenu($event) function?
Below is what I tried but it doesn't work
$scope.showsubmenu=function(obj)
{
alert(obj.target.parent.attributes.id)
}
It should be parentNode, not just parent:
alert(obj.target.parentNode.id);
Also attributes is redundant as you can access id property directly.
But note, that since you have ngRepeat, it will create invalid markup, since ids are going to be duplicated. You probably want to fix this too, maybe like this or use classes:
<div id="d8{{$index}}" class="menutitles ng-scope" ng-repeat="title in list">
<div class="right" ng-click="showsubmenu()">+</div>
<div class="left" ng-click="showsubmenu()">Unit 9</div>
</div>
<div id="d8" class="menutitles ng-scope" ng-repeat="title in list">
<div class="right" ng-click="showsubmenu()">+</div>
<div class="left" ng-click="showsubmenu()">Unit 9</div>
</div>
It should be enough :D
function showsubmenu($event){
$($event.target).parent();
}
Have a nice day
As an addition to Pedro's answer I'd say that using the jQuery method closest would be preferable.
function showsubmenu($event){
var parent = $($event.target).closest('.yourclass'); // or any selector you prefer
}

change angular ui-view inside ng-repeat

I am using multiple named ui-views in a single controller. Everything is working as spected when name the ui-view in the html file with this code:
<div class="box">
<div ui-view="selector"></div>
<div ui-view="widget1"></div>
<div ui-view="widget2"></div>
<div ui-view="widget3"></div>
<div ui-view="widget4"></div>
</div>
But when I want to load dynamically some of those views with a ng-repeat it does not update the information.
<div class="widgets">
<div class="widget-container" ng-repeat="widget in widgets">
<div ui-view="{{widget}}"></div>
</div>
</div>
How could I load ui-views from my ng-repeat?
This hadn't been answered so i decided to go ahead and show how to do it. Unfortunately for some reason the attempt in the question didn't work but what you can do is link to a function between curly brackets and return the string of the view you want. For instance the controller would look like this:
$scope.groups = ['main','cases', 'models'];
$scope.pickView = function(index){
return $scope.groups[index];
};

Resources