add custom directive in element programmatically instead of HTML - javascript

I like to add custom directory in element which is run-time added from script.
eg: <input type="number" my-focus = "focusField" > in this i am adding 'my-focus' directive from html.
Can I add this directive from JavaScript because my element is dynamically added and I want to add focus on that element.

You can use $compile
Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.
Here is an example
$scope.html = $compile('<a ng-click="click()" href="#">Click me</a>')($scope);
(function(angular) {
'use strict';
angular.module('myApp', [])
.controller('Controller', ['$scope','$compile',
function($scope, $compile) {
$scope.html = $compile('<a ng-click="click()" href="#">Click me</a>')($scope);
angular.element(document.querySelector('#x')).append($scope.html);
$scope.click = function() {
console.log('Yahoooooooooooo')
}
}
]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="Controller">
<div id="x">
</div>
</div>
</div>

Related

How to ignore images in the textAngular editor

Facing issue with the textAngular editor when user copy and paste text.
(clip board contains text and image)
You can find library from here https://github.com/fraywing/textAngular.
Checkout this fiddle. It uses ta-past directive of textAngular and replaces all image elements by using regex .replace(/<img[^>]*>/g,""); on your input string.
View
<div ng-app="test">
<div ng-controller="testController">
<div text-angular
name="testEditor"
ng-model="htmlContent"
ta-paste="stripFormat($html)"></div>
</div>
</div>
AngularJS Application
angular.module('test', ['textAngular'])
.controller('testController', function($scope, $timeout, textAngularManager, $filter) {
$scope.htmlContent = '<p>Hello There!</p>';
$scope.stripFormat = function ($html) {
return $html.replace(/<img[^>]*>/g,"");
};
});

Using jquery from angular directive does not work

I am trying to implement jquery-ui's sortable on the elements inside the ng-repeat.
Problem : i cannot actually do the sortable action on the elements inside the ng-repeat.
I've checked for answers. My code seems similar to most answers which apparently work, but my code doesn't work
Below is the html snippet:
<div class="container-fluid rt-widget-list-dim-adj">
<div my-dir>
<div ng-repeat="widget in model.widgets" ng-switch="widget.widgetType">
<div ng-switch-when="HEADER">
<ng-include src="'views/widget/widget-header.view.client.html'">
</div>
<div ng-switch-when="IMAGE">
<ng-include src="'views/widget/widget-image.view.client.html'">
</div>
<div ng-switch-when="YOUTUBE">
<ng-include src="'views/widget/widget-youtube.view.client.html'">
</div>
</div>
</div>
</div>
my app.js:
(function(){
angular.module("myApp", ['ngRoute', 'myDir']);
})();
below is my custom directive:
(function () {
angular
.module("myApp", [])
.directive("myDir", makeSortable);
function makeSortable() {
var directive = {
restrict : 'ACE',
link : linker
};
function linker(scope, element, attrb) {
element.sortable();
}
return directive;
}
})();
element in linker function args is not jQuery, it is a jqLite wrapper.
If you want to apply jQuery, try this:
$j(element[0]).sortable();

use jQuery.matchHeight from Angular directive

I am trying to set elements to the same height using jQuery.matchHeight. I call the function from an Angular directive
angular.module('myApp')
.directive('matchHeight', ['$timeout', function ($timeout) {
var linkFunction = function(scope, element) {
$timeout(function() {
angular.element(element).matchHeight();
});
};
return {
restrict: 'A',
link: linkFunction
};
}]);
The matchHeight plugin and jQuery are included in index.html
<html>
<head>
all head stuff
</head>
<body>
<div class="row usps">
<div class="col-sm-4 usp-block" ng-repeat="block in content.marketing" match-height>
<a href="{{block.link_url}}" class="thumbnail">
// Rest of html
</a>
</div>
</div>
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/matchHeight/dist/jquery.matchHeight.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/directives/matchheight.js"></script>
</body>
</html>
The problem is that the height is not set although the directive is being applied to the element.
The jQuery.matchHeight plugin will set all the items in an array to the height of the tallest element in that array.
the match-height directive is applied to a single element. Because there is no array, the height is not set on the element.
Moving the directive to the parent element in the DOM and adding the class equal to the child element(s) gives the array needed to set the height.
<div class="row usps" match-height>
<div class="col-sm-4 usp-block equal" ng-repeat="block in content.marketing">
<a href="{{block.link_url}}" class="thumbnail">
// Rest of html
</a>
</div>
</div>
In the service I apply the matchHeight function to all elements with the class equal
angular.module('myApp')
.directive('matchHeight', ['$timeout', function ($timeout) {
var linkFunction = function(scope, element) {
$timeout(function() {
angular.element(element).find('.equal').matchHeight();
});
};
return {
restrict: 'A',
link: linkFunction
};
}]);
Check this out, guys.
https://github.com/christopher-weir/AngularJs-MatchHeight
this custom directive is working fine. Also, codebase is pretty simple you can tweaks as your project need.

uibCollapse nested in an directive element won't work,

When I click my-dir, collapsed elements won't expand.
I have set size in css for .btn class to ensure actually click event.
// index.html
<body ng-controller="ctrl">
<p>{{hello}}</p>
<div class="btn" my-dir></div>
</body>
// app.js
var app = angular.module('app', ['ui.bootstrap']);
app.controller('ctrl', function($scope){
$scope.hello = 'hello';
});
app.directive('myDir', function() {
return {
restrict: 'A',
replace: false,
templateUrl: './tmpl.html',
link: function (scope, element, attrs) {
scope.isCollapsed = true;
element.bind('click', function (e) {
scope.isCollapsed = !scope.isCollapsed;
})
}
};
});
// tmpl.html
<div class="dir-box">
<div uib-collapse="isCollapsed">
<p>Hello World!</p>
<p>Nice to meet You!</p>
<p>: )</p>
</div>
</div>
Why uibCollapse does not work in this situation ?
Any ideas ?
plunker here
There are 2 things that you need to fix:
1.Change click binding to ng-click. By default angular does not run its $digest cycle on jquery events. You can fix that by adding $scope.$apply() or $timeout in your code, but I recommend using ng-click as a more proper way.
<div class="btn" my-dir ng-click="isCollapsed = !isCollapsed"></div>
By your original code I should add it inside your directive template, but your dir-box position does not overlap with the blue area...
2.Use overflow:hidden on uib-collapse element.
<div uib-collapse="isCollapsed" style="overflow: hidden;">
The contents were still showing when the parent height is 0
plunker

Angularjs show hide css issue

I had a hard issue figuring out on how to hide and show icon/text with angular code. I am completely new to angular and tried hard on the below fiddle code. How do I hide + or minus icon with .closest in such dom scenarios.
<div ng-controller="MyCtrl">
{{name}}
<div data-toggle="collapse" aria-expanded="true" data-target="#list-item-line-0" id="expandCollapseChild" ng-click="addExpandCollapseChildIcon()">
<div>
<div>
<label>
<div>
<span class="icon-expand">-</span>
<span class="icon-collapse">+</span>
</div>
<div>
Click me to hide minus icon
</div>
</label>
</div>
</div>
</div>
</div>
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.addExpandCollapseChildIcon = function() {
alert('');
if (angular.element('#expandCollapseChild').hasClass('collapsed')) {
angular.element(this).closest('.icon-collapse').css('display', 'none');
} else {
if (angular.element('#expandCollapseChild').hasClass('collapsed')) {
angular.element(this).closest('.icon-collapse').css('display', 'block');
}
}
}
In Angular, this is the wrong approach. You shouldn't actually show or hide elements inside the controller. That's applying a jQuery style (working directly on the DOM) to Angular.
In Angular, you'd use something like ng-if, ng-show or ng-class, all of which can link back to a property on the scope object that is accessible via the controller.
Here are some examples:
<div ng-if="myProp === 'ShowMe'">
<div ng-show="myProp === 'ShowMe'">
<div ng-class="{myCssClass: myProp === 'ShowMe'">
Inside your controller, you'd have something like this:
function MyCtrl($scope) {
$scope.myProp = 'ShowMe';
$scope.addExpandCollapseChildIcon = function(newPropValue) {
$scope.myProp = newPropValue;
}
}
Here's some links to documentation on ng-if, ng-show and ng-class:
https://docs.angularjs.org/api/ng/directive/ngIf
https://docs.angularjs.org/api/ng/directive/ngShow
https://docs.angularjs.org/api/ng/directive/ngClass
AngularJS has a bunch of angulary ways of doing things, your question for example might look like this:
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
$scope.collapsed = true;
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ctrl">
<span ng-bind="collapsed ? '+' : '-'"></span>
</div>
</div>
It watches a model and changes it's appearance based on that model using the ternary operator within ng-bind.
The way you defined your app and controller was incorrect. There's a bunch of different ways to do this as you can see from the answers.
I took this approach:
<div ng-app='myApp' ng-controller="MyCtrl">
{{name}}
<div>
<div>
<div>
<label>
<div>
<span ng-show='(collapsed != false)' class="icon-expand">-</span>
<span ng-show='(collapsed == false)' class="icon-collapse">+</span>
</div>
<div ng-click='collapsed = !collapsed'>
Click me to hide minus icon
</div>
</label>
</div>
</div>
</div>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.name = 'Superhero';
$scope.collapsed = false;
});
</script>
Create a scoped variable that indicated whether or not it is collapsed . Then change that variable and the ng-shows will react.

Categories