Create a list without ngRepeat - angularjs

I would like to create a directive, that does not need ngRepeat, because there is some additional functionality on the directive, that doesn't play good with ngRrepeat.
This is my directive with ng-repeat:
<div>
<ul>
<li ng-repeat="item in items track by $index" ng-class="attrs.itemTheme" data-item="{{ item[attrs.itemId]}}">
<div ng-include="attrs.tpl"></div>
</li>
</ul>
</div>
attrs.tpl, nt-dimension is another directive, that uses the items values from ngRepeat:
<script type="text/ng-template" id="dimension-item-tpl.html">
<div nt-dimension x-attrs="item"></div>
</script>
Without ngRepeat:
<div>
<ul></ul>
</div>
Can some please give me an example, I am quit struggling with this.
Example of code:
http://jsfiddle.net/mato75/4zhLtjbw/
Not working example:
http://jsfiddle.net/mato75/ztLhpf2g/
Got to compile and append the ngIncluded template, but the problem is, that it compiles only the last one, because the digest cycle is to slow.
var el = jqElm.find('ul');
scope.attrs.list.forEach(function (vl) {
var tmp =
'<li class="' + attrs.itemTheme + '" data-item="' + vl.id + '">' +
'<div ng-include="\'' + attrs.itemTpl + '\'"></div>' +
'</li>';
scope.item = vl; // this is to slow :(
var b = $compile(tmp)(scope);
el.append(b);
});

You need to manually create an own scope for each li, so each item has its own data.
var ul = jqElm.find('ul');
scope.list.forEach(function (vl) {
var li = '<li><div ng-include="\'item-tpl2.html\'"></div></li>';
var newScope = scope.$new();
newScope.item = vl;
var cLi = $compile(li)(newScope);
ul.append(cLi);

Related

insert ng-click in append statment angular js

for(var i = 0 ; i<data.success.length; i++)
{
// console.log(data.success[i]);
$("#show_rules").append("<li style='display: flex;'><div class='checkbox' id='container_divv'><a id='mm'ng-click='edit_initial_infoq()' >"+data.success[i].name+"</a><button ng-click='edit_initial_infoq()'>dd</button></div></li>");
}
})
};
$scope.edit_initial_infoq= function(){
console.log('edit_initial_infoq');
};
it's not giving me error and cant process the edit_initial_infoq function
I believe the issue is that you're appending to the html and angular isn't aware of the changes and therefore the ng-click isn't working. Try the following:
Instead of:
var html = "<li style='display: flex;'><div class='checkbox' id='container_divv'><a id='mm' ng-click='edit_initial_infoq()'>"+data.success[i].name+"</a><button ng-click='edit_initial_infoq()'>dd</button></div></li>";
#("#show_rules").append(html);
Try doing:
var html = "<li style='display: flex;'><div class='checkbox' id='container_divv'><a id='mm' ng-click='edit_initial_infoq()'>"+data.success[i].name+"</a><button ng-click='edit_initial_infoq()'>dd</button></div></li>";
var myElement = angular.element( document.querySelector( '#show_rules' ) );
myElement.append( $compile(html)($scope) );
HOWEVER... you shouldn't do this. You shouldn't manipulate the DOM inside of a controller as you're doing. Instead, try doing the following:
JavaScript:
YourService.loadRules().then(function(data){
$scope.rules = data.success;
});
HTML:
<ul id="show_rules">
<li ng-repeat="rule in rules" style='display: flex;'>
<div class='checkbox' id='container_divv'>
<a id='mm' ng-click='edit_initial_infoq()'>
{{rule.name}}
</a>
<button ng-click='edit_initial_infoq()'>dd</button>
</div>
</li>
</ul>
Here is a great SO question to read, the first answer is loaded with great information: "Thinking in AngularJS" if I have a jQuery background?

AngularJS ng-change not working for Angularjs $compile

Error: $compile:ctreq
Missing Required Controller
Controller 'ngModel', required by directive 'ngChange', can't be found!
sample code
//create dynamic UI
var targetQDom = '<div id="' + item.id + '" style="width=100%;background: white;" ><div class="head" style="border-bottom-color: azure;border-bottom-style: double;"><a style="color:aliceblue"><i class="fa fa-times-circle-o fa-fw fa-2x bt-right" style="margin-top: -4px;" ng-change="removeR(' + item.id + ',' + (index + 1) + ',$event)"></i></a> <a style="color:white;" data-toggle="collapse" class="collapsed" data-target="#' + item.id + '-rule-' + (index + 1) + '" ng-change="targetqClick(' + item.od + ',' + (index + 1) + ',' + item.req + ')" >' + item.text + '</a></div></div>';
var $targetQDom = window.j$(targetQDom).appendTo('#appendRules');
$compile($targetQDom)($scope);
the above code will be there in the controller.
above code is dynamically creating HTML based on model data.
after running app I am getting the above error in console and it not creating UI.
If I user using the ng-click the above code works fine.
other issues with MAC OS Google chrome
but ng-click has issued in MAC OS google chrome drop-down change not working.
. If I try to change drop down value it's not triggered.so the target drop-down value is not changing.
I tried to replicate it and found some error on your code. check with this.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js">
</script>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<div id="someid" style="float: left;">
<select id="some-condition-list" class="some-control cursor_Hand"
ng-model="selectedsome" ng-change="somechange(someindex,$event)" >
<option value="">Show All</option>
<option ng-repeat="some in somes.condtions " value="{{some.Id}}">{{some.name}}
</option>
</select>
</div>
<script>
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.count = 0;
$scope.some="Hey";
$scope.somes ={};
$scope.somes.condtions =[];
$scope.somes.condtions =[{'Id':'1', 'name':"Gayani"},{'Id':'2',
'name':"Chaminda"}];
$scope.selectedsome="HI";
$scope.someindex=1;
$scope.somechange = function(item, item1){
alert(item);
}
}]);
</script>
</body>

how to bind $index from ng-repeat to controller

In Angular I wanted to bind $index to controller. How can I send $index value in to my controller. Here is my html code.
<body>
<div class="container">
<div class="row row-content" ng-controller="demoController as demoCtrl">
<ul>
<li ng-repeat="val in demoCtrl.list" >Hello {{$index}}</li>
</ul>
</div>
</div>
Here is my controller code
var app = angular.module('confusionApp',[])
app.controller('demoController', function(){
var list = [1,2,3,4,5];
this.list = list;
var array = ['abc','def','ghi','jkl','mno']
this.array = array
console.log(this.array[index]);
});
I need to use ng-modal in HTML and bind that value to some variable in my controller.
Based on the selection of index, it should check in array and respective array should have to print.
Can any of you please help
To get your current iteration position in your controller you have define a function.
So your html code like this.
<body>
<div class="container">
<div class="row row-content" ng-controller="demoController as demoCtrl">
<ul>
<li ng-repeat="val in demoCtrl.list" ng-click="dispArray($index)">Hello {{$index}}</li>
</ul>
</div>
</div>
And your controller code
var app = angular.module('confusionApp',[])
app.controller('demoController', function($scope){
$scope.dispArray = function(index){
// console.log(index);
// your code
}
});
Depending on what you're trying to accomplish you might be better served creating a custom iterator.
function makeIterator(array){
var nextIndex = 0;
return {
next: function(){
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
}
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
Angular is going to iterate over everything in the list when you use ngRepeat. If you're trying to track which list item a user clicks then you'll just add that in there using $index.
<li ng-repeat="val in demoCtrl.list" >
<span ng-click="demoCtrl.userClicked($index)"> Hello {{$index}}</span>
</li>
If you're just trying to print the data in each item, ng-repeat is already iterating everything for you.
<li ng-repeat="val in demoCtrl.list" >
<span ng-click="demoCtrl.userClicked($index)"> Hello {{val}}</span>
</li>
It all depends on what you're trying to do.
i dont konw what u want to do. if u want to use event. you can pass $index to your controller function like:
<li ng-repeat="val in demoCtrl.list" ng-click="getIndex($index)">Hello {{$index}}
$scope.getIndex = function($index) {
console.log($index)
}
hope to help u.

How to reference divs by class by index in AngularJS?

I am new to AngularJS. This is my first Plunker.
I am trying to make it so that if a user clicks on a link in a section, the value of the link appears in the results. The other two results should be cleared of their values.
I can't find any documentation on how to reference specific items in a class by index. In jQuery, I would normally do something like...
// get this index of the thing that was clicked
$this = $(this),
Idx = $BUTTONS.BigButtons.index($this),
ThisButton.eq(Idx).doSomething();
<body ng-controller="MainController as main">
<div class="title" ng-repeat="i in [1,2,3]">
<p>This is section {{i}}</p>
<ul>
<li ng-repeat="j in [1,2,3]">
section {{i}} - link {{j}}</li>
</ul>
<div class="results" ng-bind="main.results"></div>
</div>
</body>
var app = angular.module('controllerAsDemo', []);
app.controller('MainController', function() {
this.results = "Lame default";
this.displayContent = function(firstIdx, secondIdx) {
this.results = "populate section "
+ firstIdx
+ " with the number "
+ secondIdx
+ " - other two results should be empty"
;
};
});
Here is the Demo
I think you should not be looking at classes to achieve what you want. Angular repeat and various other directives give you the ability to do that.
I have touched your code a little and it works now. See below.
var app = angular.module('controllerAsDemo', []);
app.controller('MainController', function($scope) {
$scope.name = 'Cool Clicking';
$scope.results = [];
$scope.displayContent = function(firstIdx, secondIdx) {
$scope.results = [];
$scope.results[firstIdx] = "populate results "
+ firstIdx
+ " with the number "
+ secondIdx
+ " - other two results should be empty"
;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="controllerAsDemo" ng-controller="MainController as main">
<p>{{main.name}}!</p>
<!-- LOOP THROUGH A GALLERY THEME -->
<div class="title" ng-repeat="i in [1,2,3]">
<p>This is section {{i}}</p>
<ul>
<li ng-repeat="j in [1,2,3]">
section {{i}} - link {{j}}
</li>
</ul>
<div class="results" ng-bind="results[i]"></div>
</div>
</body>
That said, if you want to use jQuery in Angular then you simply can.
I will suggest you read about Angular Dom Manipulation here
Another approach can be seen in this plunkr where each item in the gallery has his result.

How to add a line break in an Angular Foundation Popover content?

This seems like it should be a simple problem but it's turning out to be a lot more involved that I initially thought.
I have a couple of items inside my Angular Foundation Popover directive that i would like to separate with a line break.
.div{ 'popover' => "Name: {{ user.name }} /br Age: {{ user.age }}", 'popover-trigger' => 'click' }
What is the solution to adding a line break where the /br is in this line of html?
This is quite tricky. If you are using angular-foundation (and I realy recommand to use it), you can modify the official popover template to be HTML unsafe - than you can use HTML in popovers:
JS
"use strict";
// app definition - don't forget to include angular-foundation module
angular.module("app", ["mm.foundation"]);
// just o controller, nothing special
angular
.module("app")
.controller("MainController", MainController);
function MainController() {
var vm = this;
vm.name = "John Doe"
vm.email = "john.doe#example.com"
}
// unsafe filter - this is used in the template below
angular
.module("app")
.filter("unsafe", unsafe)
function unsafe($sce) {
return function (val) {
return $sce.trustAsHtml(val);
};
};
// oficial popover template modification
angular
.module("template/popover/popover.html", [])
.run(["$templateCache", function($templateCache) {
$templateCache.put("template/popover/popover.html",
"<div class=\"joyride-tip-guide\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
" <span class=\"joyride-nub\" ng-class=\"{\n" +
" bottom: placement === 'top',\n" +
" left: placement === 'right',\n" +
" right: placement === 'left',\n" +
" top: placement === 'bottom'\n" +
" }\"></span>\n" +
" <div class=\"joyride-content-wrapper\">\n" +
" <h4 ng-bind-html=\"title | unsafe\" ng-show=\"title\"></h4>\n" +
" <p ng-bind-html=\"content | unsafe\"></p>\n" +
" </div>\n" +
"</div>\n" +
"");
}]);
HTML
<main ng-app="app" ng-controller="MainController as vm">
<div class="row">
<div class="small-12 column">
<div popover="{{vm.name + '<br />' + vm.email}}" popover-trigger="mouseenter">
<h1>Hover me!</h1>
</div>
</div>
</div>
</main>
Here you are working CodePen example.
You can also make your own directive to have both HTML safe popovers and HTML unsafe popovers - or you can use tooltip insetead which has support for HTML unsafe by default (directive tooltip-html-unsafe).

Resources