I have introduced ng-repeat where static contents are already there. Its working properly. When i put ng-class and set the variable its not working. How to fix that issue and why its happening.
Click on each li. Its not working on dynamic elements.
Please find the code in fiddle.
<h3>FIFA Mactch Summary:</h3>
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-class='{"selectedClass":classHilight==1}' ng-click="filterNews(3);classHilight=1"> My static content 1</li>
<li ng-class='{"selectedClass":classHilight==2}' ng-click="filterNews(3);classHilight=2" > My static content 2</li>
<li ng-class='{"selectedClass":classHilight==3}' ng-click="filterNews(3);classHilight=3"> My static content 3</li>
<li ng-repeat="item in items" ng-class='{"selectedClass":classHilight==item.id}' ng-click="filterNews(item.id);classHilight=item.id" >My Dynamic Content {{item.id}}</li>
</ul>
http://jsfiddle.net/gowthambsvg/2m41tjq9/
It is said that, You must always have . in your model.
In ng-repeat classHilgiht doesn't refer to the scope variable classHilight. It creates its own scope for each item in ng-repeat. It does not refer to classHilight. But when classHilight is used as key of test object, object inherits the property from the child scope of the ng-repeat directive.
Try this:
var m = [{
id: 4
}, {
id: 5
}, {
id: 6
}];
function MyCtrl($scope) {
$scope.test = {};
$scope.items = m;
$scope.setClass = function() {
}
}
.selectedClass {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<h3>FIFA Mactch Summary:</h3>
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-class='{"selectedClass":test.classHilight==1}' ng-click="test.classHilight=1">My static content 1</li>
<li ng-class='{"selectedClass":test.classHilight==2}' ng-click="test.classHilight=2">My static content 2</li>
<li ng-class='{"selectedClass":test.classHilight==3}' ng-click="test.classHilight=3">My static content 3</li>
<li ng-repeat="item in items" ng-class='{"selectedClass":test.classHilight==item.id}' ng-click="test.classHilight=item.id">My Dynamic Content {{item.id}}</li>
</ul>
</div>
Fiddle here
Edit: One can not say classHilight is not updated in ng-repeat, it is being updated but within its own scope. [Ref]
Related
I am trying to create company structure.
One employee can been employeed in two sector, but this is same employee with same ID id = employee1.
Checking if is item selected or deselected and this is working.
I having problem with nodes with same id.
When selected node with id employee1, I want select/deselect all node where is id employee1.
Thank you in advance.
<div id="companyEmplyee">
<ul>
<li class="folder" id="company1">Company
<ul>
<li class="folder" id="sector1">Sector 1
<ul>
<li class="emplyee1">Emplyee 1</li>
<li id="emplyee2">Emplyee 2</li>
</ul>
</li>
<li class="folder" id="sector2">Sector 2
<ul>
<li class="emplyee1">Emplyee 1</li>
<li id="emplyee35">Emplyee 35</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<script type="text/javascript">
$(function () {
var tree = $("#companyEmplyee").fancytree({
checkbox: true,
selectMode: 2,
keyPathSeparator: "/",
clones: {
highlightClones: true
},
select: function (event, data) {
var s = data.tree.getNodeByKey(data.node.key);
var s3 = s.key;
var s2 = $.map(data.tree.getSelectedNodes(), function (node) {//
return node.key;
});
if ($.inArray(s3, s2) == -1) {//
$("tr#" + s3).addClass("deleted");
//DESELECTED
$('table#tblID tr#' + s.key).remove();
alert(s.key + ' DESELECT');
}
else {
//SELECTED
alert(s.key + ' SELECT');
}
}
});
});
</script>
id should be unique in same document, use general class emplyee1 instead :
<div id="companyEmplyee">
<ul>
<li class="folder" id="company1">Company
<ul>
<li class="folder" id="sector1">Sector 1
<ul>
<li class="emplyee1">Emplyee 1</li>
<li id="emplyee2">Emplyee 2</li>
</ul>
</li>
<li class="folder" id="sector2">Sector 2
<ul>
<li class="emplyee1">Emplyee 1</li>
<li id="emplyee35">Emplyee 35</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Or use unique ids, like you see in fancytree documentation the key (Node id) should be unique :
Node id (must be unique inside the tree)
Update :
Try to use the following hack :
select: function (event, data) {
if(data.node.extraClasses!=''){
if( $(data.node.li).find('.fancytree-node').hasClass('fancytree-selected') )
$('.'+data.node.extraClasses).addClass('fancytree-selected');
else
$('.'+data.node.extraClasses).removeClass('fancytree-selected');
}
}
Working example.
hope this helps.
Duplicated Id are invalid in HTML, violates the spec and cause problems.
https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#the-id-attribute
Assign classes instead of ids.
As noted in the previous answers, duplicate node keys are not allowed in Fancytree (and duplicate IDs are not allowed in HTML as well).
Since it is a common scenario to have multiple object instances inside one tree, there is a concept of 'clones'.
Basically you include the clones extension and pass the employee ID as refKey instead of key, e.g.
<li data-refKey="emplyee1">Emplyee 1</li>
You also need to enable the extension:
$("#tree").fancytree({
extensions: ["clones"],
checkbox: true,
selectMode: 2,
...
After that, you can access related instances like so:
select: function(event, data) {
var nodes = data.node.getCloneList();
...
},
See here for details: https://github.com/mar10/fancytree/wiki/ExtClones
and example http://wwwendt.de/tech/fancytree/demo/sample-ext-clones.html
I have a myList directive, which transcludes it's content. The problem occurs when I try and nest a <my-list> element inside another <my-list>.
JS Fiddle: http://jsfiddle.net/fqj5svhn/
The directive:
var MyListDirective = (function () {
function MyListDirective() {
this.restrict = 'E';
this.replace = true;
this.transclude = true;
this.scope = {
myListType: '='
};
this.controller = function () {
this.classes = 'my-class';
};
this.controllerAs = 'myList';
this.bindToController = true;
this.template = '<ul ng-class="myList.classes" ng-transclude></ul>';
}
return MyListDirective;
})();
angular.module('myApp', []).directive('myList', function () {
return new MyListDirective();
});
Example usage of the directive:
<div ng-app="myApp">
<my-list my-list-type="'someType'">
<li>foo</li>
<li>bar</li>
<li>
<my-list my-list-type="'anotherType'">
<li>cats</li>
<li>dogs</li>
</my-list>
</li>
</my-list>
</div>
What gets rendered:
<div ng-app="myApp" class="ng-scope">
<ul ng-class="myList.classes" ng-transclude="" my-list-type="'someType'" class="ng-isolate-scope my-class">
<li class="ng-scope">foo</li>
<li class="ng-scope">bar</li>
<li class="ng-scope">
<ul ng-class="myList.classes" ng-transclude="" my-list-type="'anotherType'" class="ng-isolate-scope my-class">
</ul>
</li>
<li class="ng-scope">cats</li>
<li class="ng-scope">dogs</li>
</ul>
</div>
As you can see the list items from the inner myList appear to be transcluded by the outer myList.
What I want to happen:
<div ng-app="myApp" class="ng-scope">
<ul ng-class="myList.classes" ng-transclude="" my-list-type="'someType'" class="ng-isolate-scope my-class">
<li class="ng-scope">foo</li>
<li class="ng-scope">bar</li>
<li class="ng-scope">
<ul ng-class="myList.classes" ng-transclude="" my-list-type="'anotherType'" class="ng-isolate-scope my-class">
<li class="ng-scope">cats</li>
<li class="ng-scope">dogs</li>
</ul>
</li>
</ul>
</div>
Suggestions?
It is happening because when browser renders the page it expects <li> to be inside <ul>, but it your case it is inside <my-list> which is an invalid markup. All these things happen before Angular bootstraps and runs directives. There is no way you can predict how the browser would interpret your markup when it's invalid, in this particular case it pushes <li>'s out to be together.
In this fiddle I've replaced <ul> and <li> with <div>, which does not have any requirements for nesting, and transclusion works just fine.
I have a nested set of objects I would like to sort. The first example, directly below, is my prototype / test. It works nicely. The outer groups sort, and the inner groups sort. the inner groups are locked inside - cant be moved outside. Just exactly like i want...
<div id="example5">
<ul class="table">
<li class="group" style="width:300px;">Group 1
<ul style="padding:0px;">
<li class="field">Group 2</li>
<li class="field">Group 3</li>
</ul>
</li>
<li class="group">Group 2</li>
<li class="group">Group 3</li>
<li class="group">Group 4</li>
</ul>
</div>
And
$("#example5 ul").sortable({
});
This is the same structure I am trying to impart in my program. Everything seems the same to me, just with some added complexity. Clearly, I am breaking it somehow. The outer groups sort, while the inner ones do not.
I think its important to note that in the previous example, the script and html are in the same file. In the second example, below, the html is dynamically created with createElement() function
<div id="logtable">
<ul id="ultable" class="table ui-sortable">
<li id="" class="groupcontainer" style="width:auto; margin:2px;">
<ul>
<li class="fieldcontainer">
<div class="fieldname"></div>
<div class="fieldgroup"></div>
<div class="fieldname"></div>
<div class="fieldname"></div>
<div class="fieldname"></div>
</li>
</ul>
</li>
<li id="a" class="groupcontainer" style="margin: 2px;"></li>
<li class="groupcontainer" style="margin: 2px;"></li>
</ul>
</div>
Javascript:
$(function() {
var fieldstart;
var fieldend;
$("#logtable ul").sortable({
start: function(event, ui) {
fieldstart = ui.item.index();
},
update: function(event, ui) {
fieldend = ui.item.index();
var fieldcount = jsonstring.tracelog.fields.length;
var fieldobjects = jsonstring.tracelog.fields;
var placed = false;
jsonstring.tracelog.fields.move(fieldstart, fieldend);
writejson();
}
});
});
Following up, this site... http://www.trace-log.com/sortworks.php is copied from the "inspect element" output. it works exactly like i want. http://www.trace-log.com is the site i generated it from. basically, add a value to the field name, it will generate a new field. entering a value in the first text box will initiate the "grouping" of fields. cant understand why this isn't working.
so as it stands, it works if i statically recreate the page, but doesnt work correctly on the dynamically created page. could it be somehow with the way the sortable function is being called?
In the second example the field container is an li and the field names are div tags. The first example you had the field container as an ul tag and the fields as li. I think this might be your issue.
see fiddle here http://jsfiddle.net/4Mk4K/3/
You can try adding a custom class to the elements you want to be sortable and then use that class in the items option of sortable.
Demo:http://jsfiddle.net/lotusgodkk/GCu2D/161/
HTML:
<div id="logtable">
<ul id="ultable" class="table ui-sortable">
<li id="" class="groupcontainer item" style="width:auto; margin:2px;">Z
<ul>
<li class="fieldcontainer">
<div class="fieldname item">A</div>
<div class="fieldgroup item">B</div>
<div class="fieldname item">C</div>
<div class="fieldname item">D</div>
<div class="fieldname item">E</div>
</li>
</ul>
</li>
<li id="a" class="groupcontainer item" style="margin: 2px;">F</li>
<li class="groupcontainer item" style="margin: 2px;">G</li>
</ul>
</div>
JS:
$(function () {
var fieldstart;
var fieldend;
$("#logtable ul").sortable({
items: '.item',//Custom class of items which needs to be sorted.
start: function (event, ui) {
fieldstart = ui.item.index();
},
});
});
After much fiddling and fussing, relocating the sortable function into the function that creates the DOM objects solved the problem. I think the way it was originally structured, some DOM objects were created AFTER the sortable function - and sortable didn't know they existed.
So yes, there was something else structurally wrong with my code. Thanks everyone for the help.
Using Angular 1.0.7, how can I specify a single index for nested ng-repeats, so that each item on the inner arrays get's a consecutive index value? (i.e. 0, 1, 2, 3 and so on for all elements in all inner arrays)
To illustrate:
<ul>
<li ng:repeat="item in arr1">
<ul>
<li ng:repeat="child in item.children">{{consecutiveIndex++}}</li>
</ul>
</li>
</ul>
I tried to achieve it in the following manner:
var cindex= -1;
$scope.cindex= function () {
console.log('cindex', cindex);
return ++cindex;
};
HTML:
<ul>
<li ng:repeat="item in arr1">
<ul>
<li ng:repeat="child in item.children">{{index()}}</li>
</ul>
</li>
</ul>
I am getting quite exotic AngularJS errors using this (believe me, you don't wanna know).
I have also found out (following the console output), that even for an array with a mere 4 elements, ng-repeat hit my cindex() function over 80 times. Meaning instead of 0, 1, 2 and 3 - I got 84, 85, 86 and 87.
Any ideas?
You can't depend on your {{index()}} to be called a fixed amount of times. Whenever angular decides to dirty check a scope it will run all the bindings.
You can generate the value based on other indexes. Demo plunker
HTML
<body ng:controller="MainCtrl">
<ul>
<li ng:repeat="item in arr1">
<ul ng:init="parentIndex = $index">
<li ng:repeat="child in item.children">{{getConsecutiveIndex(parentIndex, $index)}}</li>
</ul>
</li>
</ul>
</body>
JS
app.controller('MainCtrl', function($scope) {
$scope.arr1 = [{children:[0,1,2,3]}, {children:[4,5]}, {children:[6,7,8]}];
$scope.getConsecutiveIndex = function(parentIndex, $index) {
var total = 0;
for(var i = 0; i < parentIndex; i += 1) {
total += $scope.arr1[i].children.length;
}
return total + $index;
}
});
The ngRepeat directive provides a special $index property which should suit your needs. It is zero-based and is exposed on the local scope of each template instance.
Try this:
<ul>
<li ng:repeat="item in arr1">
<ul>
<li ng:repeat="child in item.children">{{$index + 1}}</li>
</ul>
</li>
</ul>
I have a clickable drop-down List as following:
<ul class="dropdown">
<li ng-repeat="item in items" ng-controller="ListCtrl">
{{item.name}}
</li>
</ul>
I have following code of AngularJS in same html page :
<li ng-repeat="item in items" ng-controller="ListCtrl">
<div id="{{item.itemIndex}}">
Some Code Here
</div>
</li>
Now i want to add each div in to my page when click on the list item every time. I calling addWidget() function like this :
<script type="text/javascript">
function addWidget(){
document.getElementById('').style.display='block';
}
</script>
Now My question is if i assign a static id to div and passing it in to getElementByID then it works fine but in the dynamic case how i pass the id so it will work fine in each case ?
You don't want to be adding javascript like that.
Here is an example of how to do this:
<body ng-app="myApp">
<div ng-controller="ListCtrl">
<ul class="dropdown">
<li ng-repeat="item in items">
{{item.name}}
</li>
</ul>
<ul>
<li ng-repeat="item in items" ng-show="item.show">
<div>Some Code Here</div>
</li>
</ul>
</div>
</body>
And your controller:
function ListCtrl($scope){
$scope.items = [{name: 'one'}, {name: 'two'}];
$scope.addWidget = function(item){
item.show = !item.show;
};
};
And finally a working example is here on jsfiddle