i created a directive called bootstrap-switch and put it as attribute to and input tag.
now, when i am trying to add some angular directives (like: ng-show, ng-disabled) it isn't working!
the html:
<input ng-show="false" type="checkbox" name="my-checkbox" bootstrap-switch>
the js:
sharedSwitch.directive('bootstrapSwitch', ["regService",
function(regService) {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
if (Number(attrs.ioStatus))
{
$(element).bootstrapSwitch('state',true,true);
}
else
{
$(element).bootstrapSwitch('state',false,true);
}
$(element).bootstrapSwitch('onSwitchChange',function(event,state){
flagNumber = Number(scope.baseFlag) + Number(scope.$index);
regService.fSave('F',flagNumber ,state);
});
}
};
}
]);
the input is showed any way.. and that because of the "bootstrap-switch" and i dont know why or how to fix it...
thank you for your help!
Related
I'm in the middle of refactoring an old project to use custom directives, and I'm already running into a problem. I'm just trying to make a simple directive and build from there. I have a logger function in my directive's link function that just runs a console.log. I'm not sure what I'm missing here, and I'm sure it's something simple. Here's my directive:
'use strict';
(function() {
angular
.module('sigFig')
.directive('myDirective', myDirective);
function myDirective(sigFigFactory) {
var directive = {
restrict: 'E',
replace: 'true',
templateUrl: 'Directives/directiveTemplate.html',
link: link,
compile: compile
};
return directive;
function link(scope, element, attrs) {
scope.logger = function() {
console.log('DING!!!');
}
}
function compile(scope, element, attrs) {
console.log('I AM A COMPILE FUNCTION');
}
}
})();
The HTML template for it is just:
<button ng-click="logger()">CLICK ME</button>
And I'm calling it in my HTML like this:
<my-directive></my-directive>
The button appears and that console.log in my compile works, but the ng-click does not. What is it I'm missing? Thanks in advance!
Add scope to directive variable: scope:{},
function myDirective(sigFigFactory) {
var directive = {
scope:{},
restrict: 'E',
replace: 'true',
templateUrl: 'Directives/directiveTemplate.html',
link: link,
compile: compile
};
return directive;
I have never created an angular application without a controller. So I'm positive that that is your issue here.
Example of your code with a controller.
html:
<body ng-app='sigFig' ng-controller='ctrl'>
<my-directive></my-directive>
</body>
js:
(function() {
angular.module('sigFig', [])
.controller('ctrl', function($scope){
$scope.itemH = 'hahaha'
})
.directive('myDirective', myDirective);
function myDirective() {
return {
restrict: 'E',
template: '<button ng-click="logger()">{{item}}</button>',
link: function link(scope, element, attrs) {
scope.item = "Logger Click Me";
scope.logger = function() {
alert('logger')
}
}
};
function compile(scope, element, attrs) {
console.log('I AM A COMPILE FUNCTION');
}
}
})();
I have a input type= number field.It allows whole number and decimal number.But I need only whole number to be enter in the input.I have created a directive which is working only for input type=text,not working for input type=number.The reason is I need a number keyboard in mobile.
Below code is for number only,
Angularjs :
.directive('numbersOnly', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModelCtrl) {
function fromUser(text) {
if (text) {
var transformedInput = text.replace(/[^0-9-]/g, '');
if (transformedInput !== text) {
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
}
return transformedInput;
}
return '';
}
ngModelCtrl.$parsers.push(fromUser);
}
};
})
Html:
<input type="number" ng-model="points" numbers-only required>
Any suggestions welcome
Try this
html
<input type="text" ng-model="myText" name="inputName" numbers-only>
directive
myApp.directive('numbersOnly', function(){
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'').replace('.','') : null;
if (transformedInput != inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
https://jsfiddle.net/vorant/Lzw0yoma/
I have a directive
configModule.directive('iMemoryDiv',function () {
return {
restrict: 'E',
scope: {},
replace: true,
templateUrl: '/memoryDiv.html',
link: function(scope, el, attrs) {
scope.iObj = scope.$parent[attrs.bIObject];
if(angular.isDefined(scope.iObj)){
getSummary(scope.iObj);
}
function getSummary(iObj){
}
}
};
}
);
and I am calling it from html by passing an object attribute
<i-memory-div b-i-object="app"></i-memory-div> //here app is declared in a respective controller
but, here directive is getting loaded before the controller where value for 'app' is getting assigned.So scope.iObj = scope.$parent[attrs.bIObject] is always giving me undefined.
How can make directive load after the app value is getting assigned ??
Isn't it easier doing it this way:
configModule.directive('iMemoryDiv',function () {
return {
restrict: 'E',
scope: {
'bIObject': '=',
'getParentObject': '&'
},
replace: true,
templateUrl: '/memoryDiv.html',
link: function(scope, el, attrs) {
scope.$watch('bIObject', function(newValue) {
if(angular.isDefined(newValue)) {
getSummary(scope.getParentObject({name: newValue}));
}
});
function getSummary(iObj){
}
}
};
}
Or do you need more from the parent scope??
You could give your directive an isolated scope and add bIObject as a scope property:
scope: {
bIObject: '=',
},
you could then put your code in the controller: rather than link:
Use $observe service in link function,like this
if(attrs. bIObject) {
attrs.$observe('bIObject', function(value) {
console.log(value);
})
}
Suppose I have something that looks like this:
<input ng-model="object.properties.property_name" options="{ updateOn: 'blur' }" ng-change="object.save('property_name')">
I would like that to instead be really short like this:
<input name="property_name" autosave="object">
But to do that I need to dynamically bind an ngModel to the existing input. I've shortened it up so far to look like this:
<input ng-model="object.properties.property_name" name="property_name" autosave="object">
And this is the directive that gets me that far:
.directive('autosave', [function() {
return {
restrict: 'A',
scope : {
autosave : '=',
},
link: function(scope, element, attrs) {
element.bind('change', function(){
scope.autosave.save(attrs.name);
});
}
}
}])
How do I dynamically add scope.autosave.properties[attrs.name] to the ngModel and bind it to the input tag?
I haven't found a way to create a model, which was the original question, but I have made it shorter by pulling the property name from the model like this:
<input ng-model="object.properties.property_name" autosave="object">
and this directive
.directive('autosave', [function() {
return {
restrict: 'A',
scope : {
autosave : '=',
},
link: function(scope, element, attrs) {
element.bind('change', function(){
var property_name = attrs.ngModel.match(/(?=[^.]*$)(\w+)/)[1];
scope.autosave.save(property_name);
});
}
}
}])
It's not ideal, but it's better.
I have a question. I coded a HTML page with an angularjs directive
this is my code
<menufileupload visible="rightVisible" alignment="right">
<input type="text" ng-model='expr'/>
<!--Other stuff-->
</menufileupload>
I'm trying to use a $watch to check any change in the text field
$scope.$watch(...) only worked when the text field is out of the
directive. So I think that I have to create a $watch in the directive. I did that. But it didn't work.
Directive
app.directive("menufileupload", function() {
return {
restrict: "E",
template: "<div>bla</div>",
link: function(scope, elem, attrs) {
scope.$watch('expr', function(obj) {
alert("it changed");
}, true);
}
};
});
Thanks for your help
You have a template in your directive, so everything inside it will be replaced by that <div> tag.
It works fine if you remove the template. I made a codepen example of your code:
http://codepen.io/argelius/pen/jEzQVJ
angular.module('test', [])
.directive('menufileupload', function () {
return {
restrict: "E",
link: function(scope, elem, attrs) {
scope.$watch('expr', function(obj) {
alert("it changed");
}, true);
}
};
});
If you want your input element to be shown inside the directive DOM you should use the ngTransclude directive. Please check it out in the documentation.