Angularjs on page load call function - javascript

I am learning AngularJS. I have some article tag and on clicking on a button each article page is showed without any page refresh. This is one page website. What I want is that when article id "showSelector" is loaded I want to call myFunction() and in this function I want to show an alert. But the alert is not showing.
How can I do that?
<article id="showSelector" class="panel" ng-controller="CinemaCtrl" onload="myFunction()">
<header>
<a ng-click="back()" class="icon fa-arrow-circle-left"></a><h2>Shows in {{getSelectedCinema()}}</h2>
</header>
<p>
These shows are played in our single room theatre. Select one to reserce a ticket for it.
</p>
<section>
<div class="row">
<div class="4u" ng-repeat="show in shows">
<div class="movieCard">
<a ng-click="selectShow(show)"></a>
<h3>{{show.nameOfShow}}</h3>
<h4>{{show.timeOfShow | date:'MMM d'}}</h4>
<h4>{{show.timeOfShow | date:'HH:mm'}}</h4>
<p>Free seats: {{show.reservations | freeSeatFilter}}</p>
</div>
</div>
</div>
</section>
<script>
function myFunction() {
alert("Page is loaded");
};
</script>
</article>

You should call this function from the controller.
angular.module('App', [])
.controller('CinemaCtrl', ['$scope', function($scope) {
myFunction();
}]);
Even with normal javascript/html your function won't run on page load as all your are doing is defining the function, you never call it. This is really nothing to do with angular, but since you're using angular the above would be the "angular way" to invoke the function.
Obviously better still declare the function in the controller too.
Edit: Actually I see your "onload" - that won't get called as angular injects the HTML into the DOM. The html is never "loaded" (or the page is only loaded once).

Instead of using onload, use Angular's ng-init.
<article id="showSelector" ng-controller="CinemaCtrl" ng-init="myFunction()">
Note: This requires that myFunction is a property of the CinemaCtrl scope.

<section ng-controller="testController as ctrl" class="test_cls" data-ng-init="fn_load()">
$scope.fn_load = function () {
console.log("page load")
};

It's not the angular way, remove the function from html body and use it in controller, or use
angular.element(document).ready
More details are available here: https://stackoverflow.com/a/18646795/4301583

you can also use the below code.
function activateController(){
console.log('HELLO WORLD');
}
$scope.$on('$viewContentLoaded', function ($evt, data) {
activateController();
});

you can use it directly with $scope instance
$scope.init=function()
{
console.log("entered");
data={};
/*do whatever you want such as initialising scope variable,
using $http instance etcc..*/
}
//simple call init function on controller
$scope.init();

var someVr= element[0].querySelector('#showSelector');
myfunction(){
alert("hi");
}
angular.element(someVr).ready(function () {
myfunction();
});
This will do the job.

Related

ng-if not working with simple javascript

ng-if is not working when I change the values through simple javascript function.My function is getting called but the changes in values cannot be seen in view. Please refer below code.
HTML
<div id="span" ng-app='MyModule' ng-cloak ng-controller="MyController">
<div ng-if="!bool">
This is for true
</div>
<div ng-if="bool">
This is False
</div>
{{bool}}
<br>
<input type="submit" ng-click = "myfunction('test')" value="ng-if button">
</div>
<input type="submit" onClick = "check1()" value="simple JS button">
JS
angular.module('MyModule', [])
.controller('MyController', function ($scope) {
$scope.bool = true;
$scope.myfunction = function (data) {
$scope.bool = !$scope.bool;
};
});
function check1() {
angular.element(document.getElementById('span')).scope().myfunction('test');
}
When I use ng-click button it changes value of bool changes, but same doesn't happens with simple JS button . Actually I am implementing Angular in a page that already uses jQuery, so I need to use simple JS button.
JS Fiddle : JS Fiddle
At first, ng-click is able to parse an angular expression.
Second, it handles the reference to the current scope and performs a call to $scope.$apply to notify any watchers to update. If you would add a call to angular.element(document.getElementById('span')).scope().$apply() in your function, it should work as expected.
Use $scope.apply . This is because angulars digest cycle will not know if your value changes outside of its scope like in a simple JS function.

compile ng-bind-html inside ng-repeat

I have a special template problem... I have a array of products, every products have a property "button_code", this property is a result in plain text of HTML laravel template with some angular code inside.
Actually im using a ng-bind-html="product.button_code" inside a and use this template inside a ng-repeat, the html code is correctly inserted in every repeat iteration, but the code is plain text, and I need to "wake up" the ng-controllers ng-clicks etc inside this html
I try with this:
var targets = $('.buy-button-container').toArray();
for (var target in targets) {
console.log($(targets[target]));
$compile($(targets[target]))($scope);
}
$scope.$apply();
But this make the code inside the container (all html code inserted in the ng-bind-html) dissapear of the DOM.
How i can do this?
PD: and yes, im forced to use these template in these product.button_code because special things...)
Thanks
EDIT: This is a piece of code i want to bind:
<button class="buy-link btn btn-default" data-toggle="modal" role="button" ng-controller="BuyController" ng-click="doProduct({'id':'8888','title':'testestest','price':13.99,'currency':'EUR''preorder_enabled':false,'crossedPrice':100,'stock':true,'short_desc':'bla bla bla.','lbonus':false,'bonus_txt':false})">
<span class="left">
<i class="fa fa-cart"></i>
<span itemprop="price">€13.99</span>
</span>
<span class="right">
{{GETIT}}</span>
</button>
Use the transclude function furnished as the second argument of the function created by the $compile service:
app.directive("compileBindExpn", function($compile) {
return function linkFn(scope, elem, attrs) {
scope.$watch("::"+attrs.compileBindExpn, function (html) {
var expnLinker = $compile(html);
expnLinker(scope, function transclude(clone) {
elem.empty();
elem.append(clone);
})
});
};
});
The above directive evaluates the compile-bind-expn attribute as an AngularJS expression. It then uses the $compile service to bind the evaluated HTML to the element. Any existing content will be removed.
Usage:
<div class="buy-button-container" compile-bind-expn="buttonCode">
<p>This Node disappears when expression binds</p>
</div>
Note that the directive uses a one-time binding in the $watch to avoid memory leaks.
The DEMO on JSFiddle
In order to make HTML render you have to use the following function:
$sce.trustAsHtml('<b>Your html</b>');
You will have to inject $sce into your Controller.
If you are doing this in a ng-repeat you will need a function in your controller that does this. Ex:
$scope.transformHTML = function(html) {
return $sce.trustAsHtml(html);
}
in your template...
<div ng-repat="foo in bar">
<div ng-bind-html="transformHTML(foo.html)"></div>
</div>
Anyway, I don't think that the "Angular" magic within your HTML will work.

How to print to console.log from inside Angular.js inline-template's script tag?

I'm trying out the inline-template of Angular.js. I would like to have a way to debug Angular objects by printing to the console whenever an html page is rendered.
The inline-template puts html templates inside script tags. For example:
<script type="text/ng-template" id="/htmlpage.html">
<div class="page-header">
<h1>Title</h1>
</div>
<!-- everything else here is html too -->
</script>
It's tricky because the stuff inside the script tags is not really JavaScript anymore. So I don't know how to printing to the console inside the htmlpage.html with inline-template.
I have tried but failed with nesting a script tag:
<script type="text/ng-template" id="/htmlpage.html">
<!-- html page template Angular stuff before is okay -->
<script>console.log("this line DOESN'T SHOW UP anywhere");</script>
<!-- html page template Angular stuff AFTERWARDS ALL FAIL-->
</script>
I also tried just throwing in a bare console.log, since it's inside a script tag.
<script type="text/ng-template" id="/htmlpage.html">
<!-- rest of html page template is okay -->
console.log("this entire line gets output as text on the html page");
<!-- rest of html page template is okay -->
</script>
but the entire line, console.log("this entire line gets output as text on the html page");, gets printed out to the html page, not the console!
You can achieve this by calling some debugging function defined in the controller scope with ng-init in the template definition. See this example.
Let's say the template is defined by
<script type="text/ng-template" id="myTemplate.html">
<div ng-init="log('In template: '+$index)">{{greet}} Melissa<div>
</script>
and you have a controller defined as
var app = angular.module('myApp', [])
.controller('myController', ['$scope', '$log', function($scope, $log) {
$scope.greetings = ["Hello", "Bonjour", "Guten tag"];
$scope.log = function(message) {
$log.debug(message);
}
}]);
then
<ul ng-controller="myController">
<li ng-repeat="greet in greetings">
<div ng-include src="'myTemplate.html'"></div>
</li>
</ul>
should print in the console
In template: 0
In template: 1
In template: 2
The ng-init is called each time a template is instantiated. I just log some values available in the scope, like $index which is the index in the ng-repeat loop.
See this example.
Using the above answer, I found the following simpler.
The easiest solution for me was to temporarily set $scope.console = console in my controller, letting the template have access to the window.console global variable and its associated functions as normal, through the $scope binding
Because the templates are tightly scoped, they do not have access to global and window variables, as a result console.X() is not available from the template. And, like you probably experienced, attempting to reference undefined values from within the template did not result in an error, just... nothing. (Cue tearing hair out trying to figure out why events aren't firing)

Reading <script> value from html/view

Please see the code here http://plnkr.co/edit/FqfkcyZSqPkA7JjMMLrb?p=preview
I am embedding a javascript object/value in html, which needs to be read by angular. It reads value in index.html, but not in partial. (_global_link is read properly, but not _global_link_partial). Is it because _global_link_partial not available at $routeChangeSuccess, if so which event I need to listen to. I could provide the value as const in module definition, or directly in controller etc, but this value is very view specific and better to maintain there.
Thanks.
error:
_global_link Object {link: "abc"} controllers.js:3
ReferenceError: _global_link_partial is not defined
code:
function Test1Ctrl($scope) {
$scope.$on('$routeChangeSuccess', function ($event, current) {
console.log('_global_link', _global_link);
console.log('_global_link_partial', _global_link_partial);
});
}
function Test2Ctrl($scope) {
$scope.$on('$routeChangeSuccess', function ($event, current) {
console.log('_global_link', _global_link);
console.log('_global_link_partial', _global_link_partial); });
}
index.html
<div class="container">
<ul>
<li>test1
<li>test2
</ul>
<div ng-view></div>
</div>
<h2>in index.html</h2>
<script>
_global_link = {link: 'abc'}
</script>
partials (test1, test2)
<h2>In test1</h2>
<script>
_global_link_partial = {link: 'link1'}
</script>
<h2>In test2</h2>
<script>
_global_link_partial = {link: 'link2'}
</script>
I short, you need to include jQuery before angular.js
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js"></script>
Take a look at #igor's answer at https://groups.google.com/forum/?fromgroups=#!topic/angular/H4haaMePJU0 :
long story short: it's because the script tag is special and angular doesn't treat it as such. if you include jquery on this page, the code should work.
When angular detects jquery, it will use it for dom manipulation and jquery is smart enough to treat the script tag as special.
Here is a plunker: http://plnkr.co/edit/UhKx8QWGTExLgdQMJuyi?p=preview
I changed your example plunker to latest version of angular.js (1.2.13) and also changed the routes a little.

passing a local variable within the function

By clicking on the following DIV, nothing happens.
Where is the error ?
<div onclick="function dummy(that) { alert(that.toString())}" class="next">></div>
Please help.
You are defining dummy but not calling it. I don't think it works that way, not in the HTML onclick property anyway.
I suggest you move dummy() into a separate code block:
<script type='text/javascript'>
function dummy(that) { alert(that.toString())}
</script>
and then:
<div onclick="dummy(this);" class="next">></div>
or attach the function programmatically like so:
document.getElementById("myDummyDIV").onclick = function(event) { ..... }
This should do the trick:
<div onclick="dummy(this);" class="next"></div>
<script type="text/javascript">
function dummy(that) {
alert(that.toString());
}
</script>
This is silly actually. The function you've declared is unusable as a function unless you intend to do some more fantastic stuff and call the click event of this link from other methods elsewhere. However, if you're hell-bent-for-leather intent on putting the function declaration in the onclick event, it can be done this way:
<div onclick="(function dummy(that) { alert(that.toString())})();" class="next">></div>
You end up putting the function in it's own block and then the () at the end tells the parser to do it.
This is a function declaration, not invocation.
You could do something like this:
(function dummy(that) { alert(that.toString())}) (event);
and the complete HTML would be:
<div onclick="(function dummy(that) { alert(that.toString())})(event);" class="next">></div>
you dont create function here
you can just write the following
<div onclick="alert(that.toString())" class="next">></div>

Categories