Call jQuery function from AngularJS Controller - angularjs

I have a below button when on clicked shows a small popup like notification
<button id="element" type="button" onclick="ShowNotifications()" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Text inside popup">Notifications</button>
<script type="text/javascript">
function ShowNotifications() {
$('#element').popover('open');
}
</script>
My Intention is to Show this popup every few seconds without clicking the button, but from the AngularJS Controller.
var showPop = function () {
//how can i call that jQuery function here ??
$timeout(showPop, 1000);
}
$timeout(showPop, 1000);
Tried with the below solution
app.directive("showNotifications", ["$interval", function ($interval) {
return {
restrict: "A",
link: function(scope, elem, attrs) {
$interval(function () {
$(elem).popover("open");
alert('hi');
}, 1000);
}
};
}]);
Also included the scripts
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="js/app.js"></script>
<script src="js/postsService.js"></script>
<script src="js/directive.js"></script>
<script src="js/controllers.js"></script>
using the directive like this
<button id="element" type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Friend request 1" **show-notifications**>Live Notifications</button>
I see an error "the object has no method popover"

Directives are used for DOM manipulation:
<button show-notifications>
And the directive
.directive("showNotifications", ["$interval", function($interval) {
return {
restrict: "A",
link: function(scope, elem, attrs) {
//On click
$(elem).click(function() {
$(this).popover("open");
});
//On interval
$interval(function() {
$(elem).popover("open");
}, 1000);
}
}
}]);

The following steps can be followed,
var jq = $.noConflict();
then create any regular angular module and controller and create a function inside the controller which we can use it for the calling any jquery function, e.g. I want to add a class to a div element.
angular.module('myApp',[]).controller('hello',function($scope){
$scope.name = 'Vikash';
$scope.cities = ['Delhi','Bokaro','Bangalore'];
$scope.hide = function(){
jq('#hideme').addClass('hidden');
}
});
and we will create some regular html to utilize that method with the controller.
<body ng-controller="hello">
<div class="container" id="hideme">
Hello Dear
</div>
<button ng-click="hide()">Hide Hello</button>
</body>
Now here you can see that we are about call addClass method from the jQuery inside the function declared in the controller and part of the $scpe.

Instead of a $ just place the key word angular
angular.element("#id").val()

Related

How to call function from directive in controller? AngularJS

How in controller can I call function clearCopy from directive?
This is part of my html:
<tr ng-form="mForm" my-directive>
<td>
<div>
<button class="btn btn-default" ng-click="saveData(row)"> </button>
</div>
</td>
</tr>
This is my Directive:
angular.module("w.forms").directive("myDirective", function () {
return {
require: ["^form"],
link: function (scope, element, attrs, ctrls) {
scope.$watch(function () {
// ...... something
}, true);
scope.clearCopy = function () {
// do something
}
}
};
});
This is my Controller:
angular.module("app").controller("datalesController", function ($scope) {
$scope.saveData(row) = function {
// do something then run function from directive
// till this part everything works fine
$scope.clearCopy() // unfortunately it doesn't work :(
}
}
Everything works fine, except function $scope.clearCopy() in controller doesn't work.
HTML
<html>
<script src="library/angular.min.js"></script>
<script src="practice.js"></script>
<head>
</head>
<body ng-app="app" ng-controller="datalesController">
<div my-directive>
<button ng-click="saveData()">press </button>
</div>
</body>
</html>
controller
angular.module('app',[]).controller("datalesController", function ($scope) {
$scope.saveData = function() {
// do something then run function from directive
// till this part everything works fine
$scope.clearCopy(); // unfortunately it doesn't work :(
};
});
Directive
angular.module('app',[]).directive("myDirective" , function () {
return {
restrict:'A',
link: function (scope, element, attrs, ctrls) {
scope.clearCopy = function () {
console.log("calling from controller");
};
}
};
});
I change your code for running your request

How to write directive to hide div clicking anywhere on page?

This is first time that I am writing directive. I am trying to write directive to hide my div.This is my html:
<div id="loggedIn" close-logged-in class="fade-show-hide" ng-show="loggedInOpened" ng-cloak>
#Html.Partial("~/Views/Shared/_LoggedInPartial.cshtml")
</div>
I find element but when I click anywhere on page I dont get anything.Can someone help me how to write directive so that when shown user click anywhere on page, it will hide that div.Any suggestion?
'use strict';
angular.module("accountModule").directive('closeLoggedIn', function () {
return {
scope: {},
restrict: 'A',
link: function (scope, element, attrs) {
var loggedIn = angular.element(document.getElementById("loggedIn"));
console.log(loggedIn);
var isClosed = false;
loggedIn.on('click', function (e) {
console.log("LOGGED IN ON CLICK ", loggedIn);
});
}
}
I dont get this message "LOGGED IN ON CLICK"
You don't need getElementById("loggedIn") The <div> is already there for you as the element argument in the link function. There should rarely be any need to reference elements by their ID's in Angular.
Is this what you are trying to achieve?
DEMO
html
<div hide-when-click-anywhere default-display='block'>Click anywhere to hide me</div>
js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $window) {
$scope.isHidden = false;
});
app
.directive('hideWhenClickAnywhere', function ($window) {
return {
// bind a local scope (i.e. on link function scope) property
// to the value of default-display attribute in our target <div>.
scope: {
defaultDisplay: '#'
},
restrict: 'A',
link: function (scope, element, attrs) {
var el = element[0];
// set default css display value. Use 'block' if
// the default-display attribute is undefined
el.style.display = scope.defaultDisplay || 'block';
angular.element($window).bind('click', function(){
// Toggle display value.
// If you just want to hide the element and
// that's it then remove this if block
if(el.style.display === 'none'){
el.style.display = scope.defaultDisplay || 'block';
return;
}
el.style.display = 'none';
});
}
};
});
Update
Ok after reading you comments I think this might be more what you're trying to achieve;
Take note of this line in the <button> element defined in template.html:
ng-click="contentHidden = !contentHidden; $event.stopPropagation();"
$event.stopPropagation() stops the event from bubbling up and triggering the 'click' listener we have defined on $window in our directive.
DEMO2
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $window) {
$scope.hideOnStart = true;
});
app
.directive('panel', function ($window) {
return {
scope: {
// this creates a new 'isolate' scope
// '=' sets two-way binding between the directive
// scope and the parent scope
// read more here https://docs.angularjs.org/api/ng/service/$compile
hideOnStart: '=',
panelTitle: '#'
},
transclude: true,
templateUrl: 'template.html',
restrict: 'E',
link: function (scope, element, attrs) {
console.log(scope.panelTitle)
// div content is hidden on start
scope.contentHidden = scope.hideOnStart || false;
angular.element($window).bind('click', function(e){
// check if the content is already hidden
// if true then ignore
// if false hide the content
if(!scope.contentHidden){
scope.contentHidden = true;
// we have to manually update the scope
// because Angular does not know about this event
scope.$digest();
}
});
}
};
});
template.html
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">{{panelTitle}}
<button
type="button"
class="close"
ng-click="contentHidden = !contentHidden; $event.stopPropagation();"
aria-label="Close"
>
<span ng-hide="contentHidden">close</span>
<span ng-hide="!contentHidden">open</span>
</button>
</div>
</div>
<div class="panel-body" ng-hide="contentHidden" ng-transclude></div>
</div>
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container">
<h1>Demo</h1>
<div class="row">
<div class="col-sm-6">
<panel panel-title="Title" hide-on-start="hideOnStart">
<h4>Content...</h4>
<p>foo bar baz</p>
</panel>
</div>
</div>
</div>
</body>
</html>

Angular Bootstrap Modal leaves backdrop open

I'm using AngularUI to integrate Bootstrap components in my Angular 1.4 app, such as Modals.
I'm calling a Modal in my controller like so:
var modalInstance = $modal.open({
animation: true,
templateUrl: '/static/templates/support-report-modal.html',
controller: 'ModalInstanceCtrl'
});
Unfortunately, when I want to close the Modal by using:
modalInstance.close();
The modal itself dissapears, and the backdrop also fades out, but it isn't removed from the DOM, so it overlays the whole page leaving the page unresponsive.
When I inspect, I'm seeing this:
In the example in the Documentation on https://angular-ui.github.io/bootstrap/#/modal The class modal-open is removed from body and the whole modal-backdropis removed from the DOM on close.
Why is the Modal fading out but the backdrop not removed from the DOM in my example?
I've checked out many of the other questions about the backdrop of bootstrap Modals but I can't seem to figure out what's going wrong.
This is apparently due to a bug. AngularUI doesn't support Angular 1.4 yet. Once http://github.com/angular-ui/bootstrap/issues/3620 is resolved this will work.
Until the team gets this sorted here is a work around.
<div class="modal-footer">
<button class="btn btn-primary"
ng-click="registerModal.ok()"
remove-modal>OK</button>
<button class="btn btn-warning"
ng-click="registerModal.cancel()"
remove-modal>Cancel</button>
</div>
/*global angular */
(function () {
'use strict';
angular.module('CorvetteClub.removemodal.directive', [])
.directive('removeModal', ['$document', function ($document) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.bind('click', function () {
$document[0].body.classList.remove('modal-open');
angular.element($document[0].getElementsByClassName('modal-backdrop')).remove();
angular.element($document[0].getElementsByClassName('modal')).remove();
});
}
};
}]);
}());
Unfortunately it appears that the team is not on the same page concerning this issue as it was pushed to a separate thread by a contributor and then the thread it was pushed to was closed by another as it was considered "off topic" by another.
Simply you can do like this, first close the modal u have opened
$('#nameOfModal').modal('hide');
basically id of modal Second this to remove if any
$('body').removeClass('modal-open');
lastly to close backdrop
$('.modal-backdrop').remove();
<button type="button" class="close" onclick="$('.modal-backdrop').remove();"
data-dismiss="modal">
$(document).keypress(function(e) {
if (e.keyCode == 27) {
$('.modal-backdrop').remove();
}
});
I am using Angular version 1.3.13 and have a similar issue. I been researching the problem and believe this bug extends from angular version 1.3.13 to 1.4.1 details here https://github.com/angular-ui/bootstrap/pull/3400
And if you scroll to the bottom of that link you will see a post by fernandojunior showing the versions he tested and upgraded to still showing the same issue. He even created a plnker to simulate the issue http://plnkr.co/edit/xQOL58HDXTuvSDsHRbra and I've simulated the issue in the code snippet below using the Angular-UI modal code example.
// angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular
.module('ui.bootstrap.demo', [
'ngAnimate',
'ui.bootstrap',
]);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.animationsEnabled = true;
$scope.open = function (size) {
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.toggleAnimation = function () {
$scope.animationsEnabled = !$scope.animationsEnabled;
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<!-- angular 1.4.1 -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.js"></script>
<!-- angular animate 1.4.1 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-animate.min.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn btn-default" ng-click="open()">Open me!</button>
<button class="btn btn-default" ng-click="open('lg')">Large modal</button>
<button class="btn btn-default" ng-click="open('sm')">Small modal</button>
<button class="btn btn-default" ng-click="toggleAnimation()">Toggle Animation ({{ animationsEnabled }})</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</body>
</html>
In you submit button or which ever button/selection that moves you to another page, just have data-dismiss="modal" and that should take care of the back drop. It is just telling to dismiss the modal when you have made your selection.
I am also using Angular 1.3.0 and I am also using UI bootstrap-tpls-0.11.2 and for some reason my issue was happening when I was redirecting to the new page and the backdrop was still displaying, so I ended up adding this code...
.then(function () {
$("#delete").on('hidden.bs.modal', function () {
$scope.$apply();
})
});
which I actually found here....
Hide Bootstrap 3 Modal & AngularJS redirect ($location.path)

How can i access next sibling's proprties/attributes of element using angularjs?

I am trying to access the class of button which is placed next to paragraph. As soon as the focus gets on paragraph the class of button should change. Please see HTML the code below :
<div>
<span id="key" class="col-lg-2">email : </span>
<span ng-focus="focused($event)" id="value" contenteditable="true">abcd#abc.com</span>
<input type="submit" name="update" value="update"
class="update-hide" data-ng-click="updateValue($event)">
</div>
The angular code for controller is :
var TestParseController = function($scope, $window, $http, $routeParams, $sce,
$compile) {
$scope.focused = function(focusedValue) {
var par = focusedValue.target.parentNode;
var nodes = par.childNodes;
nodes[2].className="update-regular";
}
}
How could this be done in angular way? I know its something like $$nextSibling , but accessing the class name is problamatic. I have googled a lot and found nothing. Please help!!!
Please suggest any dynamic way i can not hardcode any id for button also.
This can be like below:
angular.module("app",[])
.controller("MainCtrl", function($scope) {
$scope.focused = function(focusedValue) {
var par = focusedValue.target.parentNode;
angular.element(par.querySelector("input[type=submit]")).addClass("update-regular");
}
});
.update-regular {
background: red;
}
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-controller="MainCtrl">
<div>
<span id="key" class="col-lg-2">email : </span>
<span ng-focus="focused($event)" id="value" contenteditable="true">abcd#abc.com</span>
<input type="submit" name="update" value="update"
class="update-hide" data-ng-click="updateValue($event)">
</div>
</body>
</html>
But mostly DOM manipulation must be done via directives. Controller must act mostly like ViewModel. So if you could create a directive and add it to the contenteditable span tag.
angular.module("app", [])
.directive("focusAdjacentButton", function () {
return {
restrict: "AEC",
link: function (scope, element, attrs) {
element.on("focus", function () {
angular.element(element[0].parentNode.querySelector("input[type=submit]")).addClass("update-regular");
});
// if you want to remove the class on blur
element.on("blur", function () {
angular.element(element[0].parentNode.querySelector("input[type=submit]")).removeClass("update-regular");
});
}
}
});
In your HTML:
<span focus-adjacent-button id="value" contenteditable="true">abcd#abc.com</span>

Angular Accordion Panel Color Change

I have an accordion that dynamically has html controls added to it. I am trying to figure out how to change the color of the accordion's panel to yellow when any of the child controls become dirty; has been touched.
Here is the plnkr code that I have so far. [1]: http://plnkr.co/edit/MdMWysRUEtGOyEJUfheh?p=preview
Layout below.
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
<script src="script.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap-theme.cs" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body ng-controller="bookcontroller">
<accordion id="accordion_{{$index+((currentPage-1)*20)+1}}" close-others="true">
<accordion-group is-open="isopen" >
<accordion-heading class="container-fluid grey">
Book Hearder
</accordion-heading>
<form name="form">
<div class="form-row" ng-repeat="record in records">
<table>
<tr ng-formfield></tr>
</table>
</div>
</form>
</accordion-group>
</accordion>
</body>
</html>
SCRIPT.JS code
var app = angular.module("app", ['ui.bootstrap']);
app.controller('bookcontroller', ['$scope', function ($scope) {
$scope.records=[
{
RecordId: 91,
Type:'Label',
Label: 'Favoritebook'
},
{
RecordId: 92,
Type: 'Dropdown',
Label: 'Favoritebook',
DDLValue: [{ 'value': '1', 'text': 'HarryPotter' },
{ 'value': '2', 'text': 'StarGate' }]
},
{
RecordId: 93,
Type:'Text',
Label: 'The TextBox'
}]
}
]);
app.directive('ngFormfield', function ($compile) {
return {
link: function (scope, element, attrs) {
if (scope.record.Type == 'Label') {
element.html('<label togglecolor type="label" ng-model="record.DDLValue.value"/>' + scope.record.Label + '</label>');
}
else if (scope.record.Type == 'Text') {
element.html('<td colspan="8">'+scope.record.Label + ': <input togglecolor type="text" name="fname"></td>');
}
else if (scope.record.Type == 'Dropdown') {
element.html('<td colspan="8"><select class="btn btn-default dropdown" togglecolor ng-model=record.DDLValue.value ng-options="obj.value as obj.text for obj in record.DDLValue"></select></td>');
}
$compile(element.contents())(scope);
}
}
});
app.directive('togglecolor', [function(){
return{
restrict: 'A',
link: function(scope, element, attrs, controller){
scope.$watch(function() {return element.attr('class'); }, function(newValue){
debugger;
if (element.hasClass('ng-dirty')) {
element.parent().addClass('toggle-yellow');
} else {
element.parent().removeClass('toggle-yellow');
}
});
}
}
}]);
Any idea how to get this togglecolor directive working?
I think the problem is in the togglecolor directive. It appears that element.parent() is not the element whose color you want to change.
I would recommend selecting the element that you want to change explicitly.
In html, load jQuery and add an id to the element whose colour you want to change:
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
...
<accordion-group id="bookHeader" is-open="isopen" >
In js, use jQuery to select the element by id and change the colour if it is dirty:
if (element.hasClass('ng-dirty')) {
$('#bookHeader').addClass('toggle-yellow');
}
You can use ngClass to accomplish this. Either by attaching an ngChange directive on your forms that affects a variable in the controller.
Attaching an additional watcher adds performance overhead, so you want to avoid that when possible.
Further, it might not make sense to use a table for this form. It looks like you're using it for formatting?

Resources