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?
Related
In angularjs to show/hide dynamic submenu, I am adding and removing dynamic classes in js file. Every time when the state changes in url (i.e ui-sref={{mymenu.url}}) sub menu is not visible. If there is no state change sub menu is working properly. Can anyone please suggest.
Html
<li ng-repeat='mymenu in menuItems' ng-click="showHideMenu($event);" >
<a class="iconsize" ui-sref={{mymenu.url}}>
<i class={{mymenu.image}}></i> <strong>{{mymenu.menuName}}</strong>
<span class="fa fa-chevron-down"></span>
</a>
<ul class="submenuHide">
<li class="" ng-repeat='submenu in mymenu.submenu'>
<a>{{submenu.submenuName}}</a>
</li>
</ul>
JS
$scope.showHideMenu = function(event) {
var classname = event.target.parentElement.parentElement.children[1].className;
if(classname == 'submenuHide'){
$(event.target.parentElement.parentElement.children[1]).removeClass('submenuHide');
$(event.target.parentElement.parentElement.children[1]).addClass('submenuShow');
}else if(classname == 'submenuShow'){
$(event.target.parentElement.parentElement.children[1]).removeClass('submenuShow');
$(event.target.parentElement.parentElement.children[1]).addClass('submenuHide');
}
}
A couple things. One, you'll need to make sure your menu is outside of the individual templates you're working with. Two, using ng-class bound to an ng-model ensures that your menu state is included in the digest cycle. This will save you the jqLite and dom parsing logic.
Here's an example plunker.
So your code might look like this:
<body ng-controller="MainCtrl">
<a ui-sref="hello">Hello</a>
<a ui-sref="about">About</a>
<button ng-click="toggleMenu()">Show / Hide Menu</button>
<ui-view></ui-view>
<ul ng-class="{showMenu: show, hideMenu: !show}">
<li ng-repeat="letter in ['a','b','c','d']">{{letter}}</li>
</ul>
</body>
With this JS:
app.controller('MainCtrl', function($scope) {
$scope.show = false;
$scope.toggleMenu = function() {
$scope.show = !$scope.show;
};
});
I am wanting to create a bind to an element with an array, for when the array is changed, the HTML to be updated. But, it's not work.
HTML
<body ng-controller="Game as game">
<div>
<span ng-bind="game.testString"></span>
</div>
<div>
<span ng-bind="game.testArray"></span>
</div>
<input type="button" ng-click="game.btnAddLetter()" value="Change">
</body>
JS
angular.module('notesApp', [])
.controller('Game', [function() {
var self = this;
self.testString = 'a';
self.testArray = ['a'];
self.btnAddLetter = function() {
self.testString = 'X';
self.testArray.push('X');
}
}]);
I expected the two span would be updated, however, only the testString has been updated. For what reason did this happen? How to solve this problem?
You must use the JSON filter:
<span ng-bind="game.testArray | json"></span>
I have HTML code with ng-click event:
<div class="btn share" ng-click="do($event)">
<span">1</span>
</div>
Angular JS:
$scope.do = function (event) {
var target = angular.element(event.target);
var parsed = parseInt(target.find('span').text(), 10);
}
When I click to element div or child element span is called event do().
But if I click on span my counter inside span is not increment. Only by clicking parent element div.
How I can set same $event for div and span elements?
I would recommend to work with scope bindings instead of DOM textContent:
<div class="btn share" ng-click="do()">
<span>{{count}}</span>
</div>
and in controller
$scope.count = 0;
$scope.do = function () {
$scope.count++;
};
If you however still want to know why it failed with your approach, it's because you need to use currentTarget, not just target:
angular.module('demo', []).controller('MainCtrl', function($scope) {
$scope.do = function(event) {
var target = angular.element(event.currentTarget);
var parsed = parseInt(target.find('span').text(), 10);
target.find('span').text(parsed + 1);
};
});
<script src="https://code.angularjs.org/1.4.3/angular.js"></script>
<div ng-app="demo" ng-controller="MainCtrl" class="btn share" ng-click="do($event)">
<span>1</span>
</div>
But don't do this, controller should not work with DOM at all, this is
not what controllers are for.
You're doing it the wrong way. Angular is not jQuery. You shouldn't do any DOM manipulation in the controller. The view should be generated based on the model, and not vice-versa.
The code should be
<div class="btn share" ng-click="do()">
<span>{{ counter }}</span>
</div>
and in the controller:
$scope.counter = 1;
$scope.do = function() {
doSomethingWithCounter($scope.counter);
}
Have you tried adding the same click event to your span also?
Like this
<span ng-click="do($event)"> 1 </span>
Please see relevant JSFiddle
Within this code I dynamically added in sanitized HTML code using ng-bind-html but when assigning ng-show to the html it does not work. I tried using $compile but so far nothing as well.
I am trying to hide and show an element using ng-show but both are visible.
JS:
var app = angular.module('App', ['ngSanitize'])
app.controller('MyCtrl', function($scope, $compile) {
$scope.myHTML = [];
$scope.myHTML.push('<li ng-show = "visible(1)">Test1</li>');
$scope.myHTML.push('<li ng-show = "visible(0)>Test2</li>');
$scope.visible = function(arg)
{
if (arg == 1) return true;
if (arg == 0) return false;
}
$compile($scope.myHTML)($scope);
});
HTML:
<div ng-app="App">
<div ng-controller="MyCtrl">
<ul ng-repeat="snippet in myHTML" ng-bind-html="snippet"></ul>
</div>
</div>
Your controller should pretty much never be aware of markup, ever. That's the power of MVC. You should repeat across a real dataset and build up markup in your view. Something like the following, where you set items = [item1, item2] in a controller.
<div ng-app="HelloApp">
<div ng-controller="MyCtrl">
<ul ng-repeat="item in items">
<li ng-show = "test($index)">Test{{$index}}</li>
</ul>
</div>
</div>
If you really need to do it the way you're doing, you should use a custom directive and use angular.element to append your compiled html to the current directive element. ng-bind-html doesn't expect a compiled node, rather just an html string.
Your method is not true.
First , your ng-repeat is in ul, scope.myHTML will loop ul instead of adding DOM in ul, so you should ng-repeat in li. code like this:
<ul>
<li ng-repeat="snippet in myHTML" ng-bind-html="snippet" ng-show="snippet.visible">{{ snippet.content }}</li>
</ul>
app.controller('MyCtrl', function($scope, $compile) {
$scope.myHTML = [{content:'Test1', visible:1},{content:'Test2', visible:0}];
$scope.visible = function(arg)
{
if (arg == 1) return true;
if (arg == 0) return false;
}
});
Maybe, you want to just add DOM like jQuery. code like this:
<ul>
</ul>
app.controller('MyCtrl', function($scope, $compile) {
$scope.visible = function(arg)
{
if (arg == 1) return true;
if (arg == 0) return false;
}
$('ul').html($compile('<li ng-show="visible(1)">Test1</li><li ng-show="visible(0)">Test2</li>')($scope));
});
i used $timeout function it's working with me : sample code
$scope.allowDelete = false;
$scope.allowDeleteCount = '';
$timeout(function () {
$('div').append($compile('<button type="button" ng-show="allowDelete" class="btn btn-danger btn-sm btn-delete"><i class="fa fa-trash-o"></i> Delete <span>{{allowDeleteCount}}<span></button>')($scope))
},1000);
I have a number of links on the page, dynamically generated like so:
<a href="#" class="more-info-item" ng-click="showStats(item, $event)">
More information
</a>
I also have a simple custom template that should show an item's name:
<script type="text/ng-template" id="iteminfo.html">
<div class="item-name">
{{item.name}}
</div>
</script>
What I would like to do is: when the link is clicked, to dynamically compile the template, and insert it in the DOM right after the link. I tried using $compile within showStats method to compile the template, but I got an error that $compile wasn't found. How would I go about doing this (and also provide item as part of the scope for the newly generated template)?
Here is a solution using a custom directive which injects the item dynamically using ng-if:
View Solution with Plunker
html:
<script type="text/ng-template" id="iteminfo.html">
<div class="item-name" ng-if="item.visible">
{{item.name}}
</div>
</script>
<div ng-repeat="item in items" >
<a href="#" class="more-info-item" more-info="item" ng-click="item.visible =!item.visible">
More information
</a>
</div>
script:
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.items = [{name:'apples', visible:false},{name:'pears', visible:false},{name:'oranges', visible:false}];
})
.directive('moreInfo', function($compile,$templateCache) {
return {
restrict: 'A',
scope: '=',
link: function(scope, element, attr) {
var itemInfo = angular.element($templateCache.get('iteminfo.html'));
var lfn = $compile(itemInfo);
element.parent().append(itemInfo);
lfn(scope);
}
};
});
You can use the built-in ngInclude directive in AngularJS
Try this out
Working Demo
html
<div ng-controller="Ctrl">
<a href="#" class="more-info-item" ng-click="showStats(item, $event)">
More information
</a>
<ng-include src="template"></ng-include>
<!-- iteminfo.html -->
<script type="text/ng-template" id="iteminfo.html">
<div class="item-name">
{{item.name}}
</div>
</script>
</div>
script
function Ctrl($scope) {
$scope.flag = false;
$scope.item = {
name: 'Manu'
};
$scope.showStats = function (item, event) {
$scope.item = item;
$scope.template = "iteminfo.html";
}
}