Directive: append templateUrl as a sibling element - javascript

I want to append, as a sibling element, the contents of a template file using an attribute directive on an Input Text field.
I've tried this, but the contents of the template are being wrapped inside of <input></input> tags and this is not the desired behavior. I need to put the content of template file as a sibling of the input text. Anyway, angular code is executed without error on the template file.
I tried with Transclude but without success.
HTML
main page
<input type="text" ng-model="myModel" name="inputName" ng-my-directive>
template.html
<div>
<div ng-repeat="row in rows">
<button ng-repeat="button in row">{{button}}</button>
</div>
</div>
JS
.directive('ngMyDirective', function ($compile) {
return {
require: '?ngModel',
restrict: 'A',
transclude:true,
templateUrl: 'template.html',
controller: ['$scope', function ($scope) {
...
},
link: function (scope, element, attrs, ngModelCtrl, transclude) {
...
element.append(transclude());
}
Currently, I have this (wrong) result:
<input type="text">
<div>
...
</div>
</input>
And I need this result:
<input type="text">
<div>...</div>
<div>...</div>
...
Thanks in advance for your effort!

You could try using element.after() with the template contents:
angular.module('myApp', [])
.directive ('ngMyDirective', function() {
return {
restrict: 'A',
link: function(scope, element) {
element.after('<h3>sibling content</h3>');
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<input type="text" ng-model="myModel" name="inputName" ng-my-directive>
</div>
The problem with this approach is to append a "template.html" file. In this case, you could fetch the HTML contents in an ajax request. Example:
app.directive('ngMyDirective', function($http, $compile) {
return {
restrict: 'A',
link: function(scope, element){
$http.get('template.html')
.then(function(response){
element.after($compile(response.data)(scope));
});
}
});

Related

How to avoid rendering directive element

Is it possible to hide my directive html element?
I mean if I have this directive:
app.js
angular.module("myApp", [])
.directive("myDirective", function() {
return {
restrict: "E",
template: "<div><p>Some text...</p></div>"
}
);
Only render the content of the template.
<div>
<p>Some text...</p>
</div>
Not the directives element:
<my-directive>
<div>
<p>Some text...</p>
</div>
</my-directive>
yes just put the replace: true in the directive. it will remove the element
angular.module("myApp", [])
.directive("myDirective", function() {
return {
restrict: "E",
template: "<div><p>Some text...</p></div>",
replace: true
}
);
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
}).directive("myDirective", function() {
return {
restrict: "E",
template: "<div><p>Some text...</p></div>",
replace : true
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<my-directive>
</my-directive>
</div>
Note that replace: true is marked as deprecated (I use it myself nonetheless from time to time)
See: Explain replace=true in Angular Directives (Deprecated)

How to call link function method from html ng-click?

I have the following code in my directive:
testModule.directive('TestOne',function(){
return{
replace: true,
controller: 'TestCtrl',
link: function(scope, element, attrs){
element.on('click', function(e) {
//my own code is there
});
}
}
}
I wanted to call the above click function on ng-click with the below event in html(ng-click="mytest()"). How can I call or write exactly so that I can execute my function requirements in the above directive's element click function as per my requirements.
html:
<div test-one ng-repeat="items in testjson">
<div class="title">{{items.name}}</div>
<div class="context-menu">
<ul>
<li ng-click="mytest()">TestFunction</li>
</ul>
</div>
</div>
Thanks in advance.
First make the first letter of the directive simple
directive('TestOne',function(){
to
directive('testOne',function(){
Then create a scope function for ng-click inside the link function
.directive('testOne',function(){
return{
restrict : 'A',
replace: true,
link: function(scope, element, attrs){
scope.mytest = function() {
console.log("working")
}
}
}
})
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.testjson = [{"name":"sss"},{"name":"ssss"}]
}).directive('testOne',function(){
return{
restrict : 'A',
replace: true,
link: function(scope, element, attrs){
scope.mytest = function() {
console.log("working")
}
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div test-one ng-repeat="items in testjson">
<div class="title">{{items.name}}</div>
<div class="context-menu">
<ul>
<li ng-click="mytest()">TestFunction</li>
</ul>
</div>
</div>
</div>

How to add an inner wrapper to an element in angular?

I want an angular diretive to add an inner wrapper to a DOM element. Unfortunately it's not wrapping but replacing the inner part of the element. (see plunker)
So I have this html snippet:
<body ng-app="plunker">
<div class="outer" wrapp-my-content>
<label>Name: </label>
<input type="text" ng-model="name" />
<p>Hello {{name}}</p>
</div>
</body>
The directive should change this into
<body ng-app="plunker">
<div class="outer" wrapp-my-content>
<div class="inner-wrapper">
<label>Name: </label>
<input type="text" ng-model="name" />
<p>Hello {{name}}</p>
</div>
</div>
</body>
But what I get is
<body ng-app="plunker">
<div class="outer" wrapp-my-content>
<div class="inner-wrapper">
</div>
</div>
</body>
Directive Code:
var app = angular.module('plunker', []);
app.directive('wrappMyContent', function() {
return {
restrict: 'A',
transclude: true,
replace: true,
link: function(scope, element) {
var innerWrapper = angular.element('<div class="inner-wrapper" ng-transclude></div>');
element.prepend(innerWrapper);
}
}
});
How can I fix that?
You've mixed up ng-transclude and custom transclude by link:
1. Use template of directive (demo):
var app = angular.module('plunker', []);
//Recommended angular-way
app.directive('wrappMyContent', function() {
return {
restrict: 'A',
transclude: true,
template:'<div class="inner-wrapper" ng-transclude></div>',
link: function(scope, element) {
}
}
});
2. Do transclude by custom link (demo) :
var app = angular.module('plunker', []);
//Equals transclude by your self
app.directive('wrappMyContent', function($compile) {
return {
restrict: 'A',
scope:true,
link: function(scope, element) {
var innerContent = element.html();
var innerWrapper = angular.element('<div class="inner-wrapper"></div>').append(innerContent);
//Do compile work here.
$compile(innerWrapper)(scope.$parent)
element.empty().append(innerWrapper);
}
}
});
Use a template for your '<div class="inner-wrapper" ng-transclude>' part instead of just making an element and prepending it... the ng-transclude directive won't be processed unless it's compiled which the template will be.

How to include custom directive to another custom directive's template(html) in angular js

I hava a directive already(appView) and that has some html to load through templateUrl. As of now, I need to add one more custom directive to the template that is being used by another directive(appView).
Please see my code below and it is not working as expected. Any help on this how i can make this work please?
View.html (template)
<div>
<div class="dragdrop" id="dropzone" dropzone> //here is my custom directive
<div class="fileUpload btn btn-primary">
<span>UPLOAD ASSETS</span>
<input id="dzFile" type="file" class="upload" />
</div>
</div>
</div>
angular js
var appModule = angular.module("Newapp", []);
appModule.directive("appView", appView);
function appView(){
var directive = {
restrict: 'E',
templateUrl: 'app/View.html'
};
return directive;
}
appModule.directive("dropzone", function(){ //This is added to the View.html as attribute(see above html code with **)
var directive = {
restrict: 'A',
link: FullDragDrop
};
return directive;
});
function FullDragDrop(){
console.log("soemthing goes here");
}
How can I make this possible Please?
This code works for me.
Make sure templateUrl: 'app/View.html' exists
<script>
var appModule = angular.module("Newapp", []);
appModule.directive("appView", appView);
function appView(){
var directive = {
restrict: 'E',
templateUrl: 'view.html'
};
return directive;
}
appModule.directive("dropzone", function(){ //This is added to the View.html as attribute(see above html code with **)
var directive = {
restrict: 'A',
link: FullDragDrop
};
return directive;
});
function FullDragDrop(){
console.log("soemthing goes here");
}
</script>
<script type="text/ng-template" id="view.html">
<div class="dragdrop" id="dropzone" dropzone> //here is my custom directive
<div class="fileUpload btn btn-primary">
<span>UPLOAD ASSETS</span>
<input id="dzFile" type="file" class="upload" />
</div>
</div>
</script>
<body>
<app-view></app-view>
</body>

Create a list of items built using angularjs

I would like to create a list of items built in Directive and share through controllers.
Here is my example in plunker: Example of my code
Here is my code in js:
var app = angular.module('app', []);
app.controller("BrunchesCtrl", function ($scope, $log) {
$scope.brunches = [];
$scope.addNew = function () {
$scope.brunches.push({ address: "" });
};
$scope.$watch('brunch.address', function(value) {
$scope.address = value;
$log.info($scope.address);
});
$scope.$watch(function() { return $scope.brunches.length; }, function() {
$scope.brunches = $scope.brunches.map(function (brunch) {
return brunch;
});
});
});
app.directive('brunchesView', function ($compile) {
return {
restrict: 'E',
templateUrl: 'brunch.html',
controller: 'BrunchesCtrl',
replace: true,
link: function (scope, element, attrs, controller) {
}
};
});
app.directive('businessSubmit', function ($log, $compile, formManagerService) {
return {
restrict: 'AE',
controller: 'BrunchesCtrl',
link: function (scope, element, attrs, controller) {
formManagerService.init();
var hasError;
element.on('click', function (e) {
e.preventDefault();
$log.info("brunches: \n");
$log.info(scope.brunches);
});
}
};
});
Here is an HTML:
<!DOCTYPE html>
<div class="controls">
<a class="btn btn-danger" id="addBrunch" data-ng-click="addNew()">
<i class="icon-plus-sign"></i>
add new...
</a>
</div>
</div>
<brunches-view class="well" data-ng-repeat="brunch in brunches">{{brunch}}</brunches-view>
<br/>
<p class="well">
JSON: {{brunches | json}}
</p>
<div class="control-group">
<div class="controls">
<a class="btn btn-primary" href="#" data-business-submit>
<i class="icon-save"></i>
Save...
</a>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script src="script.js"></script>
And here is the template:
<div class="fc-border-separate">
<div class="control-group">
<label class="control-label">Address</label>
<div class="controls">
<input type="text" class="span6 m-wrap"
name="Address" data-ng-model="address"
value="{{address}}" />
</div>
</div>
</div>
The final thing I want to save the whole data inside the BusinessSubmit directive.
Help please...
Several issues with your code.
First, your ng-model for the <input> is set to address, but the object you are wanting to bind it to a brunch object that has an address property. Important to realize that ng-repeat will create a child scope for every repeated item
<input data-ng-model="brunch.address"/>
Another issue is you are assigning the parent controller to a directive as well. Important to understand that controllers are singletons so if you use controller more than once , each is a separate instance. Therefore nesting the parent controller in a directive makes no sense.
DEMO- [ng-model] fix
If you want the data shared with other controllers you should set up a service that holds the brunches data by injecting it into whatever controllers will need access

Categories