I am developing an angular mobile APP, where i wanted to go tho the specific url for eg: www.google.com on clicking of a particular div. but i am not able to do that as i am new to this angular world.
<div ng-click="goToGoogle('www.google.com');" class="" id="">
<p class=""><span class="">Go to Google Full Web Site</span></p>
</div>
In controller Function
$scope.goToGoogle = function (url) {
$scope.$apply( $location.path(url) );
}
Please help me to do that.Thanks in advance for any help.
In your controller, have you passed in the $location service along with the scope?
UPDATE
Try passing the $window service.
$window.location.href = url;
You don't even have to use $scope.apply for it.
Related
Say I have a button that's within the ng-app scope, but outside the ng-controller/ng-view scope.
<html ng-app="myApp">
<!-- ... -->
<body>
<button id="myButton">Click me!</button>
<div ng-view> <!-- angular-view --> </div>
</body>
</html>
And I want to change the URL/Route when I click the button.
var button = document.getElementById('myButton');
button.addEventListener('click', function() {
//code that changes path.
});
How do I do that? If I try window.location.href = '/'; the whole page gets reloaded, not just the view. $location isn't visible from html javascript, so that's not an option neitehr.
If anyone knows a way I can change the path/route/url from javascript, I'd be more than happy to accept any valid answer, or a redirect to some helpful documentary post, or a rederect to another SO question, because I'm trying to find an answer to this for a while and I've got nothing...
I'll note that I tried making a global scope function, but that didn't work, neither.
angular.module('myApp', [])
.config( ... )
.run(function($rootScope, $location) {
$rootScope.setUrl = function(url) {
$location.path(url);
};
})
.controller(
.....
and called with setUrl('/');, $root.setUrl('/'); and $rootScope.setUrl('/');, but still nothing ('undefined').
note: the button script is just an example, the real purpose why I'm asking this is a little bit larger, so I'm trying to simplify.
If your purpose is to change route from outside of the Angular app, then you need to change location hash part:
window.location.hash = 'new-route';
Inside Angular controller use $location.path method.
I'm trying to make a maps call from my ionic framework app. In my html file I use:
<a ng-href="maps://?q={{dest.Latitude}},{{dest.Longitude}}">Maps</a>
<div>{{dest.Latitude}},{{dest.Longitude}}</div>
In my controller the data for dest looks like this:
{"Latitude":12.34567, "Longitude":1.23456}
The latitude and longitude are shown in the div correctly.
But I get an error if I click on the link:
Failed to load webpage with error: The URL can't be shown
I also tried to cast the lat and long to string but it had no effect on it.
If I use static geocordinates like this everything works fine:
<a ng-href="maps://?q=12.34567,1.23456">Maps</a>
What am I missing?
You have to add map in to href Sanitization white list.
example code:
angular.module('app',[])
.config(
function( $compileProvider ){
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension|map|geo|skype):/);
}
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<a ng-href="map:lat=51.527141,lon=-0.087853">Map</a>
<a ng-href="skype:username">Skype</a>
</div>
CompileProvider Docs
Well the compileProvider solution didn't worked for me so I made a workaround.
In my controller I use:
$scope.navigate = function(){
var geoString = 'maps://?q='+dest.Latitude+','+dest.Longitude+'';
window.open(geoString, '_system');
};
And I'm calling the function like here:
<button ng-click="navigate()" class="button button-icon ion-earth"></button>
This works. I think there is a problem with data binding in the href.
Just to be sure, are testing it on a iOS device?
If I'm not mistaken the maps:// protocol only works on iOS with Apple Maps.
I'm all but sure this is the best practice to achieve my objective (manage OAuth in AngularJS) but here it is what I've done and what doesn't work:
By using Hello.js (injected in Angular through angular-global-injector) I managed to open the OAuth popup window (in my case Google+) by using the following code in my controllers.js file.
hello.init({
google: MY_APPLICATION_ID
},{redirect_uri:'app/_partials/'});
$scope.doLogin = function(network) {
console.log('Calling hello ' + network);
hello.login(network,function(r){ // callback
console.log("login successful..");
});
};
The pop-up with login request opens (note that I had to use a "fake" index.html view since $routerProvider doesn't seem to work properly on URI-redict on the child window (page not found, but the URI /auth would world normally on the parent window..since all the others routers work flawlessly on it. So I can't only guess the problem is with the child window.).
This way instead the index.html is loaded since the redirect is done as AngularJS wasn't there.
Here is my route configuration.
$routeProvider.
when("/userLogin", {templateUrl: "_partials/userLogin.html", controller: "webClientController"})
.when("/dialInterface", {templateUrl: "_partials/dialInterface.html", controller: "webClientController"})
.when("/error404", {templateUrl: "_partials/error404.html", controller: "webClientController"})
.otherwise({redirectTo: '/error404'});
Here is the content of my popup window (the fake "index.html").
<!-- temp workaround to manage oAuth since routeProvider doesn't match the REDIRECT URI correctly -->
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
$("#go-to-dial-interface",opener.document).trigger('click');
window.close();
</script>
And here is the code of the view (loaded correctly by AngularJS) /userLogin
<md-content class="md-padding md-primary" style="height: 600px;padding: 24px;" layout-fill>
<a ng-click="doLogin('google')" class="zocial googleplus">Sign in with Google+</a>
</md-content>
<a id="go-to-dial-interface" href="#dialInterface" style="visibility:hidden;"></a>
Basicly the logic (and the problem) is:
The user clicks on the a tag which leads to execution of doLogin('google') (this calls the function in the controller which contains the call to Hello.js)
A Google account is chosen, afterwards there is the redirect (in this case to the "fake" index.html since I don't manage it with Angular routes
this index.html is loaded properly in the OAuth popup and the javascript code is executed correctly: trigger go-to-dial-interface's click() event and close the OAuth popup
The triggered click() event is supposed to cause a redirect in the main window to a new view (#dialInterface) but it doesn't: the current view (userLogin) is reloaded (or perhaps not..) and the new one doesn't (of course the URL in the browser address bar doesn't change)
Any better solution / improvement is also well accepted.
Thank you in advance
Do you also have the webClientController ready for the /dialInterface view?
Any console errors?
I am designing a site which has a fixed data set (17 records - each representing a 'book' for sale) and allows navigation between several pages that display details about each of the books. The problem I am having is that when the hyperlink goes to a different view, everything works fine, but if it is hyperlink is to a different book of the same view, it fails to run the controller script. How do I force this to be done.
I have made a minimal executable example:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.min.js"></script>
<script>
var fooApp = angular.module('fooApp', []);
fooApp.controller('fooCtrl', function ($scope) {
$scope.books = ["Book1", "Book2", "Book3", "Book4", "Book5"]
$scope.selectedBook = "Book1";
var curPath = window.location.toString();
var hashPos = curPath.indexOf("#/");
if (hashPos>0) {
$scope.selectedBook = curPath.substring(hashPos+2);
}
});
</script>
</head>
<body ng-app="fooApp" ng-controller="fooCtrl">
Selected Book: {{selectedBook}}
<ul>
<li ng-repeat="book in books">Visit A {{book}}
</li>
</ul>
<ul>
<li ng-repeat="book in books">Visit B {{book}}
</li>
</ul>
</body></html>
Save the above to two different files: PageA.htm and also as PageB.htm. The selected book is passed as a parameter after the hash mark. You will see the behavior as this: When on PageA you can click on a link to PageB and the book is selected appropriately. But if you click on a link to PageA the URL changes in the address bar, but the controller function does not apparently run. Similarly, on PageB, links to PageA will select a book, but links that stay on PageB do not.
I like the fact that the page is NOT re-read from the server ... it comes out of cache, but I would like to somehow trigger the the controller function again so that the new passed parameter can be read and the correct data displayed. What am I doing wrong?
Update One
Some have suggested to add target="_self" to the hyperlink tag. This works in the simplified minimal example above. Unfortunately, it does not work on fully elaborated site. I don't know why. You can check the full site and the problem is that the "Featured-Book" does not display if you are showing the details of any other book.
Ok. It seems you need to use the $location service and $locationChangeSuccess event in order to keep track url changes. These are part of the Angular core API.
fooApp.controller('fooCtrl', function ($scope, $rootScope, $location) {
$scope.books = ["Book1", "Book2", "Book3", "Book4", "Book5"]
$scope.selectedBook = "Book1";
$rootScope.$on('$locationChangeSuccess', function (event, location) {
$scope.selectedBook = $location.path().substring(1);
});
});
It seems that you are trying to implement a route system.
Have you looked into Angular's ngRoute? check out this example.
ngRoute is great because you can access route data via its $route service or simply via $routeParams.
I have a angularjs app with a controller and a partial wired up..
In my controller I have a array of links..
$scope.links = ['http://www.example.com/1','http://www.example.com/2'];
In my partial, I have the following code..
<div ng-repeat="link in links">
Link
</div>
This does not seem to work.. I am running this via a NodeJS app locally..and so my URLs always end up as
http://dev-server.local:3000/"http://www.example.com"
Can anyone please help me figure out how I can add a hyperlink from my controller directly into my partial template and make Angular not append the page URL..
You have to explicitly trust extern URL:s. Look at the documentation for $sce.
In you controller, make sure you have a dependency to $sce, then in create a method that trust the external url.
$scope.trustUrl = function(url) {
return $sce.trustAsResourceUrl(url);
}
In your view you can reference this method and pass in the url with
<a ng-href="{{ trustUrl(item) }}">Click me!</a>
instead of
href={{link}}
use
ng-href={{link}}