I'm very new to angularjs.
I want to load a script tag using a custom angularjs directive. Below is the example code for what I want to achieve:
angular.module('app')
.directive('myScript', function () {
return {
restrict: 'E',
template : function(e,a){
return '<script>document.write(5 + 6);</script>';
}
};
});
So, 11 will be displayed when the directive is added in html:
<div><my-script></myscript></div>
But I couldn't manage to achieve that. So, I guess my code is wrong? Please help me with this. Thanks in advance.
All right, why would you like to do it by a script tag, Yin?
You can you a built-in directive to do this.
Something like ng-bind or even curly braces {{}}
AngularJs will evaluate your expression and set the tag value as the result.
Example:
<span ng-bind="5 + 6"></span>
Result:
<span>11</span>
Whenever you need to evaluate an expression you can do this way :)
Related
This is the first time to use angular js.
The following code gives desired output:
Hello
It opens a page:
http://www.example.com/xyz/cat/
But the below code is not working as expected:
<a href='javascript:void(0)' onClick='javascript:window.open("http://www.example.com/xyz/{{life.animal}}/","Windows","width=1150,height=450,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,titlebar=no,location=no,directories=no,status=no");return false')'>Hello </a>
It opens page:
http://www.example.com/xyz/{{life.animal}}/
I think I am doing some basic mistake but please help me.
The Angular scope is not available outside of Angular, i.e. vanilla JS.
To set a click function the angular way you should use ng-click
Create a function in your controller or directive such as
scope.open = function() {
$window.open(...)
}
In the template do
ng-click="open()"
angular doesn't interact with strings, but you try to do that in your onclick handler that opens a window (you pass a string there). Stop the string and concat with the variable:
onClick='javascript:window.open("http://www.example.com/xyz/" + life.animal)'
Also, as #Enzey has noted, use ng-click instead of onClick, and then bring out the javascript from your html and do that stuff in a controller instead.
E.g.:
HTML
Foo
Controller
$scope.myFunction = function() {
window.open(...whatever...);
}
The double hash are used for angular directives not for Javascript Vanilla apart of that is better if you use ng-href instead href in a <a> tag. You can check this here
I'm trying to use an element directive (restrict: "E") to define a custom component. Here's my page.html template, which gets pulled into index.html via the ng-view directive:
<eng-popup>This text appears, but is rendered in a span</eng-popup>
Angular IS running; index.html has the ng-app="templatesApp" directive in the body tag and app.js sets up the module as below:
var app = angular.module("templatesApp", ['ngRoute']);
Further along, in app.js I have the popup directive defined:
app.directive('engPopup', function() {
console.log("This console log does not trigger. I have tried 'eng-popup' as the directive's first parameter, but that doesn't work either.");
return {
restrict: 'E',
transclude: false,
template: '<div id="thisDoesNotEvenAppear"></div>'
};
});
The problem is, when I look at the resultant html of the component, it looks like this:
<span class="ng-scope" jQuery110209261664696867675="7">This text should appear, surely</span>
</eng-popup class="ng-scope" jQuery110209261664696867675="8"><//eng-popup>
So I have a few questions:
Why does the eng-popup directive console.log call NOT get triggered?
Why does the content in the eng-popup tag end up in a span?
And most mysteriously of all, why does the eng-popup tag start with an END tag and end with a tag with 2 slashes?
Finally, what am I messing up, to make this all happen?
EDIT
As requested, here's a Plunker. It looks like the span and end-tag issues are not happening in this simplified version, but the eng-popup directive is still not being triggered:
https://plnkr.co/edit/mVa6Mye5besJAtWihMWF?p=preview
RE-EDIT
Just in case this is still solvable, here's the latest Plunkr I've been able to put together. It's not working, which it at least has in common with our real project. Not sure if it's the same problem though.
https://plnkr.co/edit/sJoYnYjqx9ZGIH0KhObC
I've modified your example a bit (very little), and it seems to work OK?
https://plnkr.co/edit/3NlHNDOCBVRktk3ZcsnV?p=preview
What i've done is, remove the ui-router requirement, since you had not added the script reference. After that, it works. So, are you including ui-router in your project properly?
So a colleague has pointed out it 'works' in Chrome. Turns out it's an IE8 issue. Who would have thought...
(The whole reason we're using 1.2.29 is because many of our users will be accessing it via IE8, but it looks like custom directives are off the table).
I have a custom directive which holds a <textarea> element along with other HTML elements in its template using templateUrl. This directive should allow a user to type with any Indian Language (using any writing script like devanagri and others). The user will get to select the input language.
This directive will be used like this in my HTML:<keybuddy></keybuddy>
Now my problem is, in my main code, how should I retrieve the text entered in the textarea that is located in the template.html specified by templateUrl? I have the text available in the scope of my link function since I used ng-model on the textarea.
<textarea id="inputField"
placeholder="start typing....."
ng-model="inputText"
rows="5">
</textarea>
In my index.html, I should be able to do something like this:
<keybuddy></keybuddy>
<button onclick="printText()">Show Text</button>
<script>
var printText = function () {
console.log($("keybuddy").value);
}
</script>
How do I do it? Is there any other better way using the power of AngularJS? I went through these posts but wasn't helpful. Or might be I could not understand how to use it in my work. How to set a native attribute from AngularJS directive?, How to get evaluated attributes inside a custom directive
my complete code on github: keybuddy
Note:
I should be able to use this directive anywhere in the application, any number of times.
It should be portable; I should be able to use it in any of my project or any other developer should be able to use it without much
Go Angular :-)
You don't need the use of jQuery here. Angular is sufficient enough. You can change your code like this:
In your View:
<keybuddy model="myInputText"></keybuddy>
<button ng-click="showText()">Show Text</button>
In your View controller:
$scope.showText = function() {
console.log($scope.myInputText);
}
And update your directive to have scope like below (replace your `scope: true):
scope: {
inputText: '=model'
}
Read more on Isolating scope of a directive
You can setup a bi-directional binding to the directive scope. This will allow your directive to change a value in the parent scope, which you can then read from your controller.
In your directives configuration setup the scope property with the name of an attribute to use for the binding, such as:
scope: {
model: '='
}
In your directive's template then you can set the textarea's ng-model to that binding name.
<textarea ng-model="model"></textarea>
In the parent where you use the directive, pass the attribute you configured set to the name of a variable on the scope.
<keybuddy model="inputText"></keybuddy>
Then in your controller you can access the textarea's current content by reading $scope.inputText.
$scope.printText = function(){
alert($scope.inputText);
}
Template:
<button ng-click="printText();">Print text</button>
Since it's already in the scope, you could simply use
console.log($("keybuddy textarea").scope().inputText);
AngularJS version:
console.log(angular.element("keybuddy textarea").scope().inputText);
EDIT: Adapted to match the actual source code.
i am trying to write a directive that replaces an input field with an custom made input field. However, I can not get the databinding to work as the model does not show in the directive input field.
I have created a jsFiddle here:
http://jsfiddle.net/6HcGS/392/
I guess i dont really know what to place here for the databinding to work:
tElement.replaceWith('<input ng-model="ngModel" type="text" />');
If anybody could help me out i would be very grateful as this has been a problem for me for a whole day now.
Cheers!
tElement.replaceWith('<input ng-model="ngModel" type="text" />');
Angularjs doesn't know that ngModel is a binding. It's interpreted as a simple string. So you need to tell angular this.
I've updated your jsfiddle to show you how to do this:
http://jsfiddle.net/6HcGS/393/
But you can do it even simpler by removing the isolated scope in the directive:
http://jsfiddle.net/6HcGS/394/.
Like lort already mentioned the attributes are getting passed to the element during replacement. Of course only if you dont use isolated scope.
I don't understand what you're trying to do but it seems that following code example is all you need:
angular.module('zippyModule', [])
.directive('zippy', function(){
return {
restrict: 'C',
replace: true,
template: '<textarea></textarea>',
}
});
This one changes initial input into textarea. Binding through ng-model still works because other attributes are not deleted from element during replacement.
I have a partial, which has a directive which renders a bunch of things in a loop, using compiled HMTL-as-a-string inside the directive. This HTML-as-a-string itself contains an ng-include, which doesn't render out.
Please see my jsfiddle example
Basically, this doesn't include template2.html:
element.html('<span>The name is ' + scope.content.name + '!</span><div ng-include src="template2.html"></div><br>');
Any pointers would be much appreciated.
Thanks!
WORKING DEMO
just needed to write as
src=" \'template2.html\'"
var linker = function(scope, element, attrs) {
element.html('<span>The name is ' + scope.content.name + '!</span><div ng-include src=" \'template2.html\'"></div><br>');
$compile(element.contents())(scope);
};
more info in DOCS
Vinod's answer above (replace src="template2.html" with src="\'template2.html\'") is correct, though I would recommend using an actual template instead of manually compiling the template yourself inside the link function. In your example, you aren't actually receiving the benefit of the two way binding. You are just taking the html output of the compile function, and it will never update if the underlying data changes. Here is your example modified to show the bindings (and Vinod's template fix):
http://jsfiddle.net/kf3vZ/5/
Notice how if you change the value of any of the checkboxes, the value in the directives do not change.
Now here is a version using the template argument to the directive:
http://jsfiddle.net/kf3vZ/7/
Now if you change the text fields, the directive values will change also.
Another note, since you are already using the script tags for your templates, you could replace template in your directive with templateUrl and provide the id of the script template.