I use angular-ui tooltips (https://github.com/angular-ui/bootstrap/blob/master/src/tooltip/tooltip.js) or angular strap tooltip (http://mgcrea.github.io/angular-strap/#/tooltips#tooltips)
I need show tooltip on element, when the some event or expression.
Example below, we have the input. And i need to show tooltip, when data.model.count == 5. And then hide tooltip of beyond the 5 second. Help me please!
<input type="text" ng-model="data.model">
Write a directive! plunker
angular.module('ui.bootstrap.demo').directive('showTip', function($timeout){
return {
restrict: 'A',
scope: {
showTip: "="
},
link: function(scope, elm, attr){
var tooltip;
scope.$watch('showTip', function(newVal){
if(newVal == 5){
tooltip.css({visibility: 'visible'});
$timeout(function(){
tooltip.css({visibility: 'hidden'});
}, 5000)
}
})
elm.bind('DOMSubtreeModified', function(){
tooltip = elm.find('div');
tooltip.css({visibility: 'hidden'});
})
}
}
});
Related
I am using Angular 1.5.1. I have a checkbox on my form. I do not care about the truth/false indicator of the checkbox being checked/unchecked and so I do not want ng-model on it. What I care for is:
when checkbox is unchecked, I delete a specific array from my model
when checkbox is checked, I add an empty array back to my model
So I have created a directive that provides me with this functionality, very simple:
.directive('cbOnChecked', function() {
return {
restrict: 'A',
link: function(scope, element, attr) {
element.on('click', function(event) {
if(element[0].checked)
scope.$apply(attr.cbOnChecked);
});
}
};
})
.directive('cbOnUnchecked', function() {
return {
restrict: 'A',
link: function(scope, element, attr) {
element.on('click', function(event) {
if(!element[0].checked)
scope.$apply(attr.cbOnUnchecked);
});
}
};
})
Now I can do something like:
<input type="checkbox" cb-on-checked="counter = counter + 1" cb-on-unchecked="counter = counter - 1"/>
Or
<input type="checkbox" cb-on-checked="deleteUserList()" cb-on-unchecked="users = []"/> No users<br/>
The problem with this is - the form within which the checkbox is won't get marked as $dirty if there is no ng-model on the checkbox. Is there any way around this?
Here is an example js-fiddle. Thanks.
If you really want to go with your own directives you can just require parent form controller and mark it $dirty manually:
.directive('cbOnChecked', function() {
return {
require: '^form',
restrict: 'A',
link: function(scope, element, attr, ngFormController) {
element.on('click', function(event) {
ngFormController.$setDirty();
if(element[0].checked)
scope.$apply(attr.cbOnChecked);
});
}
};
})
Please see relevant jsFiddle
Within my directive whenever I paste an item on the 'searchBar' or text box I am not getting the updated value of the element text.
Here is my directive:
app.directive('searchBar', function() {
return {
restrict: 'AE',
replace: true,
template: '<input type="text" ng-model="searchData" placeholder="Enter a search" id="searchbarid" />',
link: function(scope, elem, attrs) {
elem.on('paste', function(evt) {
alert(evt.target.value);
});
}
};
});
Wrap the event inside of a $timeout of 0 so that it evaluates in the next $digest after angular evaluates all of its watches.
elem.on('paste', function(evt) {
$timeout(function() {
alert(evt.target.value);
},0)
});
http://jsfiddle.net/36qp9ekL/530/
Ok, so I have an input field that i would like to enhance with 2 custom directives:
<input type="text" number-format validation-message="Only numeric values are valid!" class="form-control" id="num1" ng-model="num1" />
The first directive validates any input on the moment of entering text -> in this case I check for numbers with a regex: (this is actually working fine)
.directive('numberFormat', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var invalidNumber = /^[0-9]+$/.test(viewValue);
if (invalidNumber || viewValue === ''){
ctrl.$setValidity('numberFormat', true);
} else {
ctrl.$setValidity('numberFormat', false);
}
});
}
};})
And then, I tought it might be useful to have a tooltip displayed saying that only numbers are valid for this input field. And i would like to show it in the moment of the validation failing.
The 2nd directive that I have so far looks like this:
.directive('validationMessage', function () {
return{
restrict: 'A',
template: '<input tooltip tooltip-placement="bottom" >',
replace: true,
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
var valid = ctrl.$valid;
if (valid) {
attrs.$set('tooltip', "");
} else {
attrs.$set('tooltip', attrs.validationMessage);
scope.tt_isOpen = true; // doesn't work!?
}
return viewValue;
});
}
};})
Well, basically it does work in the way, that the tooltip and tooltip-placement attributes are updated to the input element.
But for some reason the tooltip is not shown immediately when the validity has failed (and the tooltip attribute with its text is set). The user needs to hover out and back in the input element by the mouse to see the tooltip.
I've created a plunker for a better visualisation of this behaviour: http://plnkr.co/edit/3QOiOom6VQm3cXAstB3j?p=info
I tried 'scope.tt_isOpen' but it does not seem to have any effect. What exactly am i missing to show the tooltip?
Many thanks for every tip.
You can use:
tooltip-trigger="{{{true: 'keyup', false:'never'[myForm.inputName.$invalid]}}"
UI Bootstrap uses a so called triggerMap to determine on which mouse events to show/hide the tooltip.
// Default hide triggers for each show trigger
var triggerMap = {
'mouseenter': 'mouseleave',
'click': 'click',
'focus': 'blur'
};
app.config(['$tooltipProvider', function($tooltipProvider){
$tooltipProvider.setTriggers({
'mouseenter': 'mouseleave',
'click': 'click',
'focus': 'blur',
'keyup': 'keydown',
'never': 'mouseleave' <- to make sure tooltip will go
});
}]);
You can specify your desired event to trigger the tooltip.
I have a directive that work on check-box that also has ng-model.
In the directive on link function the check box not get the value of the model.
It is work if add timeout( doesn't matter how long, even with 0 ).
My control and directive:
var myApp = angular.module("myApp",[])
.directive("checkBox", function($timeout){
return {
restrict: 'A',
link: function (scope, element, attrs, ctrl) {
console.log("Check box is : " + element[0].checked);
scope.message += "Check box is : " + element[0].checked + " , ";
$timeout(function(){
scope.message += "Check box is : " + element[0].checked;
console.log("Check box is : " + element[0].checked);
},0);
}
}
});
function myCtrl($scope){
$scope.checkBoxModel = true;
$scope.message = "";
}
HTML:
<div ng-app="myApp" ng-controller="myCtrl" >
<input type="checkbox" ng-model="checkBoxModel" check-box>
<br/>
{{message}}
</div>
Fiddel - http://jsfiddle.net/myyjL/
Thanks in advance.
You probably should not do what you are trying to do, but it is possible.
Here is a plunkr that works, without timeout:
http://jsfiddle.net/myyjL/2/
.directive("checkBox", ['$timeout', function($timeout){
return {
restrict: 'A',
replace: false,
scope: {
ngModel:'='
},
transclude: true,
link: function (scope, element, attrs, ctrl) {
scope.$watch('ngModel', function(newValue){
scope.$parent.message = 'Checkbox value is: ' + newValue;
});
}
}
}])
The problem with that approach is that your directive knows about stuff that is outside of it (as in the {{message}} variable). That is a bad design and you should rework that. Also, in your fiddle you use the element[0].checked, while you can easily use the ng-modal value. But the ng-modal might not be there. Also, the input might not be a real checkbox, so your approach also fails. How to fix that? I'm gonna write you a demonstrative plunkr in a sec:
http://plnkr.co/edit/jyY6sQwXmtlGOvpdzETR?p=preview
angular.module('myApp', [])
.directive('box', [function(){
return {
restrict: 'E',
scope: {
ngModel: '='
},
templateUrl: 'box.tpl.html',
replace: true
};
}])
.controller('MyController', ['$scope', function MyController($scope){
$scope.checkboxValue = true;
}]);
What we did here is make sure our directive is always a checkbox by providing the checkbox inside the template. The you are able to do styling etc, of your directive.
I am using directive to display textbox based on data model. If data mode is in edit state then I display textbox. I want that textbox focus should be set when it is rendered. I tried however couldn't find anything. Please help. Following is an example for review.
var myModule = angular.module('myModule', []);
myModule.directive('textbox', function() {
return {
restrict: 'E',
replace: true,
template: '<div ng-if="data.mode==edit"> <input type="text" ng-model="data.value"/> </div>',
link: function (scope, element, attrs)
{
scope.data = {"mode":"edit","value":"This is text box"};
}
};
});
JSFiddle
This will do the trick.
scope.$watch('data.mode', function(newValue, oldValue) {
if (newValue == 'edit') {
element.find('input')[0].focus();
}
});
JSFiddle