How to close a popover on click outside in angular js - javascript

I want to close the popover if the user click outside the popover. in the below code .tried it with few examples that were posted for clicking outside the popover but not working.
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="https://code.angularjs.org/1.2.22/angular.js"></script>
</head>
<body ng-app="myApp">
<div class="example" ng-controller="MyCtrl">
<a class="btn btn-lg btn-success" href="javascript:;" popover ng-click="click()">popover</a>
<div style="display:none">
<div class="pop-content" id="val">
{{ myVar }}
<input type="button" />
</div>
</div>
<input ng-model="myVar">
</div>
</body>
</html>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.myVar = 3 + 4;
})
myApp.directive('popover', function ($compile) {
return {
link: function (scope, element, attrs) {
// define popover for this element
$(element).popover({
html: true,
placement: "top",
// grab popover content from the next element
content: $compile($(element).siblings(".pop-content").contents())(scope)
});
}
}
});
</script>

Seems like you ran into a Twitter bootstrap bug.. see this question here
you need to change you html to allow this feature.
<a class="btn btn-lg btn-success" href="javascript:;" popover ng-click="click()">popover</a>
to
<a popover class="btn btn-lg btn-success" href="javascript:;" tabindex="0" data-trigger="focus" >popover</a>
another problem is that you're not providing the content in JavaScript properly.
$(element).siblings("div").children(".pop-content").contents()
I did this inside you link function.
here is the plunk
Note: now you can't close it with the anchor itself..
-----------Update----------
To achieve this you'll have to do something like this data-trigger="click focus", but by using this I am running into an unusual bug. on first click the popover flick opens and closes immediately..

Related

How to toggle between elements in angularJS

I have two elements, only one of them is supposed to show up at a time while the other element stays hidden until the visible element is made to disappear (button click), here an example of the last logic I have tried to use.
.......
<div ng-show='show'>
Visible element
<button ng-click='toggle()'> Toggle </button>
</div>
<div ng-hide='show'>
Hidden Element
</div>
.......
And I have something like this in my controller
........
$scope.show = true;
$scope.toggle = function(){
$scope.show =!$scope.show;
}
.........
Now, anytime I click the button, the first element will disappear but the second element will not show. Please I really need help.
You have to put your button out of the ng-show div like this
<div ng-show='show'>
<div>Visible element</div>
</div>
<div ng-hide='show'>
<div>Hidden Element</div>
</div>
<button ng-click='toggle()'> Toggle </button>
then its work fine. Hope this help...
Here is the solution
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.show = true;
$scope.toggle = function(){
$scope.show =!$scope.show;
}
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-show='show'>
Visible element
</div>
<div ng-hide='show'>
Hidden Element
</div>
<button ng-click='toggle()'> Toggle </button>
</body>
</html>

ng-repeat elements are not showing up

In my application I'm making a get request through Angular's http service and in the view looping over the returned data to show an unordered list. But the problem is even though data is available after the get request , its not getting dispplyed on the page. Seems to be a CSS style problem, but don't know how to fix it. I want to show the unorder list within a bootstrap panel as a body.
Below is the angular piece of code inside the controlller for setting up the data
$http.get('/messages').success(function(data) {
console.log("Messages are "+data);
$scope.records=data;
});
Here is the html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Bootstrap News plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="/libs/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/libs/css/font-awesome.min.css"/>
<link rel="stylesheet" href="/libs/css/custom.css"/>
<script src="/libs/js/jquery-3.0.0.min.js" type="text/javascript"></script>
<script src="/libs/js/newsbox.min.js" type="text/javascript"></script>
<script src="/libs/js/angular.min.js" type="text/javascript"></script>
<script src="/libs/js/main.js" type="text/javascript"></script>
</head>
<body ng-app="mean" ng-controller="MainCtrl">
<br/>
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<span class="glyphicon glyphicon-list-alt"></span><b> What you wanna do before you die ...</b>
</div>
<div ng-cloak class="panel-body">
<div class="row">
<div class="col-xs-12">
<ul class="demo1">
<li class="news-item" ng-repeat="item in records">
<table cellpadding="4">
<tr>
<td >
<img class="img-circle" width="60"
ng-src="/images/{{($index+11) % 10}}.png"/>
</td>
<td ng-cloak>
{{$index+1}}. {{item.username}}
</td>
</tr>
</table>
</li>
</ul>
</div>
</div>
</div>
<div class="panel-footer"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-2 col-md-offset-1 ">
<form name="messageForm" novalidate="novalidate" ng-submit="onSubmit()" id="message-box">
<div class="form-group">
<textarea required ng-model="formModel.message"
style="background-color:#ffffe6;border:double 4px orange;border-radius: 0.5em;" rows="3" cols="50" id="message" placeholder="Write your message and press enter.."> </textarea>
<button class="btn btn-primary" type="submit">Shoot it</button>
</div>
<p ng-cloak class="help-block" ng-show="formModel.nameError">Looks like you forgot to mention your name !!!</p>
<p ng-cloak class="help-block" ng-show="formModel.messageEmpty">Really you don't wanna do anything before you die !!! </p>
<p ng-cloak class="help-block" ng-show="formModel.messageTooLong">You are trying to do too many things buddy, just 150 characters !!! </p>
</form>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$(".demo1").bootstrapNews({
newsPerPage: 12,
autoplay: true,
pauseOnHover:true,
direction: 'up',
newsTickerInterval: 4000,
onToDo: function () {
//console.log(this);
}
});
});
</script>
</body>
</html>
When I check through chrome dev tool, data is present in that unordered list, data is present but somehow not getting displayed properly within bootstrap panel.
See this image
I noticed there is one undefined element at the bottom of unordered list while checking through dev tools. Any idea whats going wrong?
The panel body is empty
Why is the [ul] tag style set to "height:0px; overflow-y:hidden"? -- this would hide your content
you could also move the ng-cloak to the div.panel-body to the div.row and remove it from the child td
--
Delay bootstrapNews binding
$(function(){
if ($('.panel-body[ng-cloak]').length > 0)
return window.setTimeout(arguments.callee, 10);
$(".demo1").bootstrapNews({...});
});
I think you should write a directive for getting a callback when ng-repeat is done and that is a better solution instead of any 'delay' tactics.
Might help you to go through how I have done in my code- used a directive to emit a render finished event:
dashboard.directive('onFinishRender', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit(attr.onFinishRender);
});
}
}
}
});
In the controller I keep the event listener:
$scope.$on('dataLoaded', function(ngRepeatFinishedEvent) {
// your code to add bootstrapNews binding
});
and in the html side, I call them like this:
<div class="add_tenant_name" ng-repeat="tenant in tenants" on-finish-render="dataLoaded">
// more divs
</div>

How to make a On/Off button in Ionic

I need to put a button in Ionic that stays activated after it's been pressed, and only deactivates after it's been pressed again.
There is a similar question but it only applies to icon buttons. (How to adding navigation bar button having ionic-on/ ionic-off functionality).
EDIT
I can't use a toggle button, it is required to be a regular looking buttom (in this case an Ionic button-outline) that stays active when pressed.
Here is some code:
<div class="botones">
<div class="row">
<div class="col">
<button class="button button-outline button-block button-positive">
Promociones
</button>
</div>
<div class="col">
<button class="button button-outline button-block button-energized" >
Aprobados
</button>
</div>
<div class="col">
<button class="button button-outline button-block button-assertive" >
Alerta
</button>
</div>
<div class="col">
<button class="button button-outline button-block button-balanced" >
ATM
</button>
</div>
</div>
</div>
As you can see is a simple horizontal array of buttons. They suppose to act as filters for a message inbox, so they have to stay pressed (one at the time at most) as the filter is active. Like a tab but not quite.
The main question is, how can I access the activated state of the button so I can mantain it activated.
In Ionic, you can add class 'active' to a .button, to make it look pressed/active.
And to make only one active at a time, you can do something like this:
angular.module('ionicApp', ['ionic'])
.controller('MainCtrl', function($scope) {
$scope.buttons = [
{icon: 'beer', text: 'Bars'},
{icon: 'wineglass', text: 'Wineries'},
{icon: 'coffee', text: 'Cafés'},
{icon: 'pizza', text: 'Pizzerias'},
];
$scope.activeButton = 0;
$scope.setActiveButton = function(index) {
$scope.activeButton = index;
};
});
<html ng-app="ionicApp">
<head>
<link href="//code.ionicframework.com/1.1.0/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/1.1.0/js/ionic.bundle.js"></script>
</head>
<body ng-controller="MainCtrl">
<ion-content class="padding">
<div class="button-bar">
<button
ng-repeat="button in buttons"
ng-class="{'active': activeButton == $index}"
ng-click="setActiveButton($index)"
class="button icon ion-{{button.icon}}"
>
{{button.text}}
</button>
</div>
</ion-content>
</body>
</html>
Also, you can view a demo on Codepen.
You may find toggle button useful. Here's the official link to this example:
<ion-toggle ng-model="airplaneMode" toggle-class="toggle-calm">Airplane Mode</ion-toggle>
edit:
Here's a demo from Codepen
and the code pasted here:
angular.module('mySuperApp', ['ionic'])
.controller('MyCtrl',function($scope) {
});
<html ng-app="mySuperApp">
<head>
<meta charset="utf-8">
<title>
Toggle button
</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body class="padding" ng-controller="MyCtrl">
<button class="button button-primary" ng-model="button" ng-click="button.clicked=!button.clicked" ng-class="button.clicked?'button-positive':'button-energized'">
Confirm
</button>
</body>
</html>

RouteChangeStart event fired on initial index.html page load

The route change event is fired on the initial page load itself, ideally i want to fire when the user go to the next page from the initial page not on the initial page load.
Here I have bound the directive "meeee" to the elements and in the link function of the directive I put the callback for routeChangeStart
event.
In which I want to fire the callback to remove the elements from the current page with directive "meeee" when user goes to the next page.
But "routeChangeStart" event is fired for the current page itself, removing all the "meeee" elements at the initial load itself ,
please see this plunkr code http://plnkr.co/edit/h7nLME7YW7dI8qaBk1in?p=preview
Index.html
<!DOCTYPE html>
<html id="ng-app" ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script src=" https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="parentCtrl" class="">
<div ng-view>
</div>
</div>
<div id="d1-Me1" class="meeee">
Meee1
</div>
<div id="d1-Me2" class="meeee">
Meee2
</div>
<div id="d1-Me3" class="meeee">
Meee3
</div>
</body>
</html>
App.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.controller('parentCtrl',['$scope','$window','$location',function ($scope,$window,$location) {
}]);
myApp.config(function($locationProvider,$routeProvider) {
$routeProvider
.when('/p1', {
templateUrl:'page1.html',
})
.when('/p2', {
templateUrl:'page2.html',
})
.when('/p3', {
templateUrl:'partials/page3.html',
})
.when('/default', {
templateUrl:'default.html',
})
.otherwise({
redirectTo:'/default'
});
});
myApp.directive("meeee",['$rootScope','$location', function ($rootScope, $location){
return {
restrict: 'C',
link: function(scope, elm, attr) {
$rootScope.$on('$routeChangeStart', function() {
console.log('attr["id"]: '+attr["id"]);
elm.remove();
});
elm.detach();
angular.element("body").append(elm);
}
};
}]);
default.html
<a href="#/p1">
Page1
</a>
<br>
<br>
<a href="#/p2">
Page2
</a>
<br>
<br>
<a href="#/p3">
Page3
</a>
Page1.html
In Page One
<div id="p1-Me1" class="meeee">
Page 1 Meee1
</div>
<div id="p1-Me2" class="meeee">
Page 1 Meee2
</div>
<div id="p1-Me3" class="meeee">
Page 1 Meee3
</div>
page2.html
<p>In Page Two</p>
page3.html
<p>In Page Three</p>
Thanks in advance for any help.
Add a counter so that if it this the first pageload, it doesn't apply?

Why are my bootstrap btn-inverted buttons showing up as grey instead of a black gradient?

I am using angular, bootstrap and jquery to populate buttons using json. However when i set the styling to style it like this:
it shows up like this:
so how can i get bootstrap to render the buttons correctly?
Stackoverflow code preview isn't working.
Plunk for project is here:
http://plnkr.co/edit/FmK38oyDRZzWOTstoaEo
var bridgeCreek = angular.module('bridgeCreek', []);
bridgeCreek.controller('MyController', ['$scope', '$http', function($scope, $http) {
$http.get('http://www.zaithe.com/demos/bridgeCreek/js/json/navigation.json').success(function(data) {
$scope.navigation = data;
});
}]);
<!DOCTYPE html>
<html ng-app="bridgeCreek">
<head>
<link data-require="bootstrap#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
</head>
<body ng-controller="MyController">
<ul class="nav navbar-right navbar-nav">
<li ng-repeat="item in navigation">
<button type="button" class="btn btn-inverse btn-sm">
<span ng-class="item.glyph" aria-hidden="true"></span> {{item.text}}
</button>
</li>
</ul>
<script data-require="jquery#*" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script data-require="angular.js#*" data-semver="1.4.0-beta.5" src="https://code.angularjs.org/1.4.0-beta.5/angular.js"></script>
<script src="script.js"></script>
<script data-require="bootstrap#*" data-semver="3.3.1" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
</body>
</html>
I had a look at the styles associated with your button elements and there is no style for btn-inverse. Which means you are missing the css files you need.
I just checked the bootstrap docs and it looks like btn-inverse has been discontinued so that is probably why you are missing the css :-(
This text is from their docs:
Changes to Button Color Classes
Add btn-default to btn elements with no other color. Replace btn-inverse with btn-default since inverse has been removed from Bootstrap 3.

Categories