angularjs variable in javascript - javascript

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

Related

Calling a function with ng directive from injected html via Google Chrome Extension

I'm trying to use a Chrome Extension as a complimentary tool for the web app I'm developing.
I used chrome.tab.executeScript to manipulate the DOM of the web app and append a button inside a DIV.
chrome.tabs.executeScript({
code: 'var e = document.createElement("div");' +
'e.innerHTML = "' +
'<button ng-click="myfnc()"></button>' +
'";' +
'document.getElementsByTagName("body").appendChild(e);'
});
The button is added/appended as expected.
<body>
<div>
<button ng-click="myfnc()"></button>
</div>
</body>
The button has ng-click attribute that points to function on the web app. The function is just a simple alert call.
myfnc():
alert('Hello!');
However, when I click on the button nothing happens. Do you have any idea why? Can injected html coming from Google Chrome Extension interact directly with the web page's code?
Creating an element with the attribute ng-click does not inform Angular that the element exists within the page, as parsing of the document occurs once during bootstrap. You therefore have an element which exists 'outside' of any Angular scope, meaning the attribute ng-click just exists and has not caused the corresponding directive (ngClick) to be invoked.
Providing of course that the page has Angular, you will want to use the $compile service along with the desired $scope to compile the element after it has been inserted into the page.
A comprehensive solution is outside of the scope of your question. (Why does nothing happen when the button is clicked?) If you want to read more about using injected code with Angular, read up on:
the angular.element#scope() method, which lets you pick up the $scope object of an element,
appending an angular.element using the append() method available on angular elements
using the derived $scope object in compiling elements such that Angular is aware of it
The steps you want to take are something like...
Get the $scope you want to insert the element within:
var angular = document.querySelector('body');
var scope = angular.element(angular).scope();
Insert the new element into the page:
var newElem = angular.element('div');
angular.append(newElem);
$compile the element with this $scope:
$compile(newElem)(scope);
More information on dynamically creating Angular elements can be found in the answer to this question.

Compile angular controller inserted by javascript dynamically?

Im working in an app that creates html dynamically. We started using angular so now we are trying to create html using angular.element() and defining a controller in it.
angular.element("<div ng-controller='myController'/>");
The problem is, that as it is created after the page renders (when an user clicks somewhere, for example), the html inserted is not working with angular, is like plain html. How can I solve it?
I use this way:
var template = angular.element(YOU_HTML_IN_STRING);
var linkFn = $compile(template);
var element = linkFn($scope);
angular.element(CSS_SELECTOR).html('').append(element);
If you don't have access to $compile. You can have a look here:
how can we use $compile outside a directive in Angularjs

Writing directives in the link function of a directive in angular-js

I have defined a directive in angular.js. That directive has a link function and a controller function, and no template, so all the view is generated in the link function. In the link function I am doing the following:
var button=angular.element("<a>");
button.addClass("ng-click: previousLink();");
//previousLink() is a function defined in the scope.
//I am doing it like that, because before that one I attempted to do:
//button.prop("ng-click", "previousLink()");
//button.text("Previous");
//but for some reason it was showing on html as <a>Next</a>, without adding the property.
It does not work. If I click the button it does nothing. If, instead of doing this in the link function in code I were doing it using a template, it would work. For some reason I need to make some manipulations using jquery in the link function. What should I do? Is there anyway to make this work, or would I have to use both template and link function and combine things there?
To use $compile you need to follow your existing code with something like:
$compile(button.contents())(scope);
If you want it to be dynamic, you can put this inside a $watch like so:
link: function (scope, ele, attrs) {
scope.$watch(attrs.yourval, function(html) {
var button=angular.element("<a>");
button.addClass("ng-click: previousLink();");
$compile(button.contents())(scope);
});
}
$compile attaches the scope (supplied as a parameter) to the html you have defined. This will make your button clicks work properly.

Javascript - Execute HTML/Angular ng-include

I'm using AngularJS to design a small app for searching. I have a div that's currently empty, and after running a function, for it to replace it with a div that has ng-include. The div replaces just fine, but ng-include doesn't load up.
I'm currently running the following in console for testing to see get it running. How would I go about getting this to work? Any help is appreciated!
document.getElementById("resultsDiv").innerHTML = '<div ng-include="" src=" \'sr.html\' "></div>';
read about angularjs $compile function
I don't know why you need to make this JavaScript-call, but its definitely no the 'angular-way'. If you need to conditionally include html, i would recommend using ng-if, ng-hide, ng-show or even ng-switch.
You could do something like this:
// somewhere in your controller
$scope.triggerSomeInclude = true;
// in your template
<div ng-if="triggerSomeInclude">
<div ng-include ="'someFile.html'"></div>
</div>
Another approach would be using a directive. They are the only place, where selecting an element directly could make sense (although even there it usually doesn't to select an element via id). But as I said, it's hard to stay what the best method would be, as I'm not sure what you're trying to achieve.
Although you're not using jQuery, what you're trying to do looks very jQueryesque (awful word) as you're selecting an element directly seemingly totally detached from the $digest and $compile-cycles of angular, so I also would recommend to read this answer:
"Thinking in AngularJS" if I have a jQuery background?
In the end, the method I used was templating example used for ngInclude.
http://docs.angularjs.org/api/ng.directive:ngInclude
Inside my controller, for example, by default it would set the following:
$scope.mainDivTemplate = {url: 'partials/test1.html'}
If I wanted to switch it to something else, I'd call a function that would look a little something like this.
$scope.loadHome = ->
$scope.mainDivTemplate = {url: 'partials/home.html'}
$scope.$apply()

Hide input-help on form using AngularJS

I'm currently learning AngularJS and i would like to accomplish a simple task.
On a form input, i would like to hide corresponding 'input-help' even data entered in input is invalid.
The way i'm currently doing this invoke some jquery. But i'm searching the way to do it using AngularJS logic. I think i should use directive but as i'm new to angular, i don't know exactly how to do it.
Here is the jsFiddle sample code working using jquery: JSFIDDLE
And here is the jsFiddle sample code not working (no jquery): JSFIDDLE
{For test, enter just few text in password input and blur it}
This is the code i have: {jquery}
$(document).on('blur', '.immediate-help', function () {
$(this).next('.input-help').fadeOut();
}).on('focus', '.immediate-help', function () {
$(this).next('.input-help').fadeIn();
});
This works as expected but i would like to use angular directive to do it. Of course, i'm not against using jquery in angular directive.
So, to resume, i would like when blur input is triggered to hide 'input-help' even the text is not valid and using angular directive.
Could someone show me the right way to do it?
Several approaches:
Using script in directive:
elm argument within directive link callback is a jQuery object if jQuery.js loads before anugular.js in page... or it is a jQlite if jQuery.js not included.
jQlite has many of the most common jQuery methods so you can use :
elm.bind('blur....
See angular.element docs for list of jQlite methods.
Using ng-class
Give form and controls a name. This creates an object formName with properties represented by field names. You can then use angular expressions for classes, or properties like disabled within markup
<form name="myForm">
<input name="passord"/>
<div ng-class="{ShowMeClassName: myForm.password.$invalid}"> Error content</div>
</form>
ng-class will toggle the class ShowMeClassName depending on validity of field named password within form named myForm
You can use Angular-ui.
Angular-UI provides a bunch of directives, which can help you. You have the ui-event directive.
For example you can use
<input ui-event="{ blur : 'blurCallback()' }">
...
<script>
$scope.blurCallback = function() {
alert('Goodbye');
};
</script>

Categories