angular directives not working with my directive - html

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

ANGULAR: link function not being called on click in custom directive

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');
}
}
})();

Directive not working for input type=number using angularjs

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/

getting a attribute value in a directive in angular js

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);
})
}

Bind a new ngModel on an existing element

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.

Directive Angularjs, $watch and HTML Element

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.