AngularJS+Bootstrap-UI: Enable tooltip on button when button is disabled - angularjs

Please see my jsfiddle code here
http://jsfiddle.net/695qtssv/2/
How can I get the button to display the tooltip while its disabled?
html
<div class="panel panel-default">
<div ng-repeat="item in itemDetails" tooltip="{{item.name + (isDisabled(item.name)?' is not available' : '')}}">
<button ng-disabled="isDisabled(item.name)" class="btn btn-primary" ng-click="select(item)">{{item.name}}</button>
</div>
</div>
JS:
var myApp = angular.module('myApp', ['ui.bootstrap']);
function MyCtrl($scope) {
$scope.myModel = "Tooltip only works when input is enabled.";
$scope.isDisabled = false;
}
I have tried using the tooltip on a div that wraps the button but still had no luck as shown in the example.
This tooltip works with but I cannot use that in the app that I am working on.
Any help would be greatly appreciated.

I think disabled elements does not not fire mouse events.
See Event on a disabled input
Based on above link I offer this kind of solution:
<div class="panel panel-default">
<div ng-repeat="item in itemDetails" style="display:inline-block; position:relative;">
<button ng-disabled="isDisabled(item.name)" class="btn btn-primary" ng-click="select(item)">{{item.name}}</button>
<div style="position:absolute; left:0; right:0; top:0; bottom:0;" tooltip="{{item.name + (isDisabled(item.name)?' is not available' : '')}}"></div>
</div>
</div>
Fiddle: http://jsfiddle.net/695qtssv/3/

Basically it is not possible to directly set the tooltip of the input element and show it when it is disabled. This is because there are no events fired from the browser on disabled input. This is discribed in this issue.
However you are on the right way. You have to wrap the input element. I have this solution from the issue above.
var myApp = angular.module('myApp', ['ui.bootstrap']);
function MyCtrl($scope) {
$scope.myModel = "Tooltip only works when input is enabled.";
$scope.isDisabled = false;
}
.layer-mask {
position: relative;
}
.layer {
position: absolute;
top: 0;
left:0;
right:0;
bottom:0;
}
.layer-mask button[disabled] {
position: relative;
z-index: -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" />
<br />
<br />
<br />
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="container">
<div class="row">
<div class="layer-mask" tooltip="My Tooltip">
<div class="layer"></div>
<button class="input-xxlarge" ng-disabled="isDisabled" ng-model="myModel">
My disabled button
</button>
</div>
<br/>
Disable/Enable <input type="checkbox" ng-model="isDisabled"/>
</div>
</div>

Related

Angular toggle show/hide based on attribute

Here is my Angular code:
<div ng-repeat="messages" ng-hide="isAdmin" data-type="{{msg.typetext}}">
</div>
The html output is:
<div ng-repeat="messages" ng-hide="isAdmin" data-type="1">Some Text</div>
<div ng-repeat="messages" ng-hide="isAdmin" data-type="0">Some Text</div>
<div ng-repeat="messages" ng-hide="isAdmin" data-type="1">Some Text</div>
These div s has an attribute called data-type and I am trying to filter these items based on this attribute with two buttons, 1 mean admin and 0 mean others.
Buttons:
<button type="button" ng-click="isAdmin=true">
Admin
</button>
<button type="button" ng-click="isAdmin=false">
Other
</button>
<button type="button" ng-click="isAdmin=false">
All
</button>
What I got so far is, show/hide div. How can I toggle show/hide div based on this attribute?
What I want to achieve is, If click Admin Button, should just show div that has data-type="1" and if click on Other Button, should just show div that hasdata-type="0" and if click on All Button, should show all div.
try this
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="msg in message" ng-show="select == msg.typetext || select == '2'">{{msg.msg}}
</div>
<button type="button" ng-click="select=1">
Admin
</button>
<button type="button" ng-click="select=0">
Other
</button>
<button type="button" ng-click="select=2">
All
</button>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.select = 2;
$scope.message = [
{typetext:1,msg:'admin'},
{typetext:0,msg:'other'}
]
});
</script>
</body>
</html>
#Rahul did it while am typing my answer. Here is my code:
angular.module("test",[]).controller("testc",function($scope) {
$scope.data=[{"typetext": "0","role": "User"},{"typetext": "1","role": "Admin"}]; });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="testc">
<div ng-repeat="value in data" ng-show="value.typetext==IsAdmin || IsAdmin==undefined">
{{value.typetext}}
</div>
<input type="button" ng-click="IsAdmin=1" value="Admin"/>
<input type="button" ng-click="IsAdmin=0" value="User"/>
<input type="button" ng-click="IsAdmin=undefined" value="All"/>
</div>

html2canvas not working in angularjs

I'm trying to convert div element to canvas using html2canvas library inside angularjs controller, it throws no error in console but only gives an empty canvas, I included the html2canvas script in master page and the div element is inside a template page which is loaded using ng-view
the div element is
<div id="barcodeHtml" style="background-color: #82c6f8">
<div style="width: 20%;float: left;display: list-item;"></div>
<div style="width: 40%;float: left; align-content: center">
<h2 style="display: inline;">CCAD</h2>
<br>
<div style="float: left;width: 50%">
<h4>MEMBER NAME</h4>
<h2>{{memberName}}</h2>
</div>
<div style="float: right;width: 50%"></div>
<br>
<br>
<div style="float: left;width: 100%">
<h4>MEMBER SINCE</h4>
<h3>{{memberSince}}</h3>
</div>
<br>
<br><br>
<br>
<img src="{{imgSource}}"/>
</div>
</div>
<a class="btn btn-custom" ng-click="getCanvas()">get Canvas</a>
and the angular controller
$scope.getCanvas=function()
{
$scope.memberName=data.html.name;
$scope.memberSince=data.html.year;
$scope.imgSource=data.html.code;
html2canvas($("#barcodeHtml"), {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
}
what am I missing?
thank you in advance..
The issue is your div with id="barcodeHtml" does not have height so it is not able to append to the body.
Try this
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.getConvas=function()
{
html2canvas($("#barcodeHtml"), {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
}
})
</script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div id="barcodeHtml" style="background-color: #82c6f8; height: 200px;">
<div style="width: 20%;float: left;display: list-item;"></div>
<div style="width: 40%;float: left; align-content: center">
<h2 style="display: inline;">CCAD</h2>
<br>
<div style="float: left;width: 50%">
<h4>MEMBER NAME</h4>
<h2>{{memberName}}</h2>
</div>
<div style="float: right;width: 50%"></div>
<br>
<br>
<div style="float: left;width: 100%">
<h4>MEMBER SINCE</h4>
<h3>{{memberSince}}</h3>
</div>
<br>
<br><br>
<br>
<img src="{{imgSource}}"/>
</div>
</div>
<a class="btn btn-custom" ng-click="getConvas()">get Convas</a>
</div>
</body>
</html>
There is an issue with your inline-styling.
I tried with removing float: left; from your upper div [from here : <div style="width: 40%;float: left; align-content: center">], then it worked.
See the working fiddle

AngularJS: Why is the ng-controller behaving odd with ng-show and ng-click and <p> tag?

Here's the code snippet of the Angular js app.
var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
$scope.get = function() {
$scope.thiss = false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
<p ng-controller="myctrl">
<button ng-click="get()">Click</button>
<p ng-show="thiss">This is it</p>
</p>
</div>
i have been learning AngularJS. I cannot understand why this simple example fails to work. I have been followng w3cschools tutorial and the syntax seem to perfect align with it. Is it something to with scoping ? or do i have to bind ng-show with model data.
I also did the following but it doesnot seem to work.
<div ng-app="list" ng-init="thiss = true">
<p ng-controller="myctrl" >
<button ng-click="thiss=false">Click</button>
<p ng-show="thiss"> This is it</p>
</p>
</div>
Why is placing the controller on the div tag works ? But fails to work when it is in the child element?
It does not work because you have a <p> tag within a <p> tag. It should work if you change you code as follows.
<div ng-controller="myctrl" >
<button ng-click="thiss=false">Click</button>
<p ng-show="thiss"> This is it</p>
</div>
var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
$scope.get = function() {
$scope.thiss = false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
<div ng-controller="myctrl">
<button ng-click="get()">Click</button>
<p ng-show="thiss">This is it</p>
</div>
</div>
Check out Why <p> tag can't contain <div> tag inside it? for the reason why <p> cannot include block level elements
Please, don't try to make your HTML standard, follow some rule defined by HTML.
Don't put nested <p> tags. AngularJS sometimes don't work for invalid DOM. I used <span> tag instead of nested <p> works fine.
var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
$scope.get = function() {
$scope.thiss = false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
<p ng-controller="myctrl">
<button ng-click="get()">Click</button>
<span ng-show="thiss">This is it</span>
</p>
</div>
For more information validate HTML. Please, check following HTML code at: https://validator.w3.org/#validate_by_input
<!doctype html>
<html>
<head>
<title>Test</title>
</head>
<body>
<p>
<p>
</p>
</p>
</body>
</html>
Try this. I have just remove ng-controller from <p> and put it inside div with ng-app. don't know the reason behind this behavior of angularjs but it works as you want.
var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
$scope.get = function() {
$scope.thiss = false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true" ng-controller="myctrl">
<p>
<button ng-click="get()">Click</button>
<p ng-show="thiss">This is it</p>
</p>
</div>
Try following code.
var app=angular.module("list",[]);
app.controller("myctrl",function($scope){
$scope.get=function(){
$scope.thiss = false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-controller="myctrl">
<p ng-init="thiss=true">
<button ng-click="get()">Click</button>
{{thiss}}
<p ng-show="thiss">Show Content</p>
<p ng-show="!thiss">Hidden Content</p>
</p>
</div>
try after removing the blank array from the dependency
var app = angular.module('list');
make sure that the controller should be placed in <div ng-controller="myctrl">
Your code:
<p ng-controller="myctrl">
<button ng-click="get()">Click</button>
<p ng-show="thiss">This is it</p>
</p>
this is how a browser interprets html according to DOM :
<p ng-controller="myctrl">
<button ng-click="get()">Click</button>
</p>
<p ng-show="thiss">This is it</p>
<p></p>
therefore the scope of your controller "myctrl" does not apply on nested para,
try using div instead of nested <p>
var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
$scope.get = function() {
$scope.thiss = false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
<div ng-controller="myctrl">
<button ng-click="get()">Click</button>
<p ng-show="thiss">This is it</p>
</div>
</div>

Angular - animate ng-show

I've this simple HTML markup using Angular and Bootstrap:
Toggle panel: <input type="checkbox" ng-model="toggle"><br/>
<br/>
<div class="container">
<section id="content">
<div class="panel panel-default animate-show" ng-show="toggle">
<div class="panel-heading">
<h3 class="panel-title">Panel title1</h3>
</div>
<div class="panel-body">
Content1
</div>
</div>
<div class="panel panel-default animate-show" ng-hide="toggle">
<div class="panel-heading">
<h3 class="panel-title">Panel title2</h3>
</div>
<div class="panel-body">
Content2
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Panel title3</h3>
</div>
<div class="panel-body">
Content3
</div>
</div>
</section>
</div>
And this small Angular controller:
function MainController($scope) {
$scope.toggle = true;
}
See this JSFiddle: http://jsfiddle.net/dennismadsen/1hr9q1ra/1/.
How can I add animations on the panels when they are shown/hidden?
I made it work here.
A few words though - I changed the angular version to 1.3 since I used ng-animate module.
Basically just added this css:
.panel {
padding:10px;
border:1px solid black;
background:white;
}
.panel {
-webkit-transition:all linear 0.5s;
transition:all linear 0.5s;
}
.panel.ng-hide {
opacity:0;
}
And a very slight modification here:
var app = angular.module("myApp", ['ngAnimate']);
function MainController($scope) {
$scope.toggle = true;
}
app.controller("MainController", MainController);

Using ng-click inside np-repeat

I'm trying to implement a shortlisting functionality in a case where I'm using ng-click inside ng-repeat.
While the $index is being displayed correctly outside the ng-click, $index is only the index of the last object in the JSON array in all the cases where the html is generated using ng-repeat.
I was expecting the respective venue or venue.id to be passed as an argument to shortlistThis(). I'm guessing that this could be an issue related to event binding.
Can someone help me understand what's going wrong here and probably a better way to do this if possible.
I did try checking this Bind ng-model name and ng-click inside ng-repeat in angularjs The fiddle here works just fine but, mine doesn't.
Update: I've found something interesting here. When the shortlist button is placed just under the ng-repeat, it work just as intended. But when, nested inside a div with a ng-class, it isn't working as intended. Can anyone explain and suggest a fix for this ?
//locationsapp.js var locationsApp = angular.module('locationsApp', []);
var venues = [{
id: "Flknm",
name: "ship",
}, {
id: "lelp",
name: "boat",
}, {
id: "myp",
name: "yacht",
}, ];
var shortlistedVenues = [];
var locationsApp = angular.module('locationsApp', ['ui.bootstrap']);
locationsApp.controller("getvenues", function($scope) {
$scope.venues = venues;
$scope.shortlistThis = function(venue) {
console.log(venue);
if (shortlistedVenues.indexOf(venue) == -1) {
shortlistedVenues.push(venue);
//alert('If');
} else {
console.log('already shortlisted')
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="locations" ng-app="locationsApp">
<div ng-controller="getvenues">
<div ng-repeat="venue in venues" ng-mouseover="" class="venue">
<div ng-controller="manageInfo">
<div class="row-fluid">
<div class="control" ng-click="showInfo()">
</div>
<div class="maps" class="info">
<div ng-class="class">
<div class="close-info" ng-click="hideInfo()">
<i class="fa fa-times">
</i>
</div>
<div class="row full-venue-contents" ng-app="ui.bootstrap.demo">
<div class="">
<div class="row-fluid myclass">
<div class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup" ng-click="shortlistThis(venue)">
Shortlist{{$index}}
</button>
</div>
</div>
</div>
</div>
</div>
<!-- End of Full Info Container -->
</div>
</div>
</div>
</div>
<div class="compare">
<button type="button" class="btn btn-default btn-lg btn-sup">
Compare ( {{shortlistedVenues.length}} )
</button>
</div>
</div>
</div>
</div>
</div>
The problem is with your button div which was position: fixed, it is actually showing the 1st button but clicking on it firing last button click, I'd suggest you should suggest you render only the shortlist button which has been selected by you. For that you can use ng-if and render those button which index is the same as that of selected $index
HTML
<div ng-if="selected==$index" class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup"
ng-click="shortlistThis($parent.$index)">Shortlist{{$index}}</button>
</div>
</div>
</div>
& then put ng-click="selected='$index'" on ng-repeat div like
<div ng-repeat="venue in venues" class="venue" ng-click="selected=$index">
Working Fiddle
Hope this could help you, Thanks.

Resources