AngularJS Save Browse History - angularjs

I'm trying to solve a problem. I want that when a perform an action or function in the controller to be saved in the brose history. For example, I want to do this:
Type something in a textbox.
Click a link to call a function that will set the string I typed to a variable in $scope and save it at the browser history.
Do the same as the previous step with a different value.
If I click the "back" button from the browser, I want to display the first value I entered.
I have a very simple example of what I want but I don't know what do I have to add to be able to use the "back" and "forward" button from the browser.
http://jsfiddle.net/XMFua/
Thank you very much in advance!

You should use the $location service to set the URL. I don't know how to make it work on jsFiddle, however the following should work:
http://jsfiddle.net/marcenuc/BSDxG/

Related

Calling a view controller from index.html

I have an index.html that has a top bar with links and a side bar with links. I want the center to be replaced with content (ng-view). Let's say the top bar is Pictures, Stats, Chat. The side bar is Tigers, Lions, Bears.
These never change. This is why index.html holds them. The top bar of Pictures, Stats, Chat I want to actually route to different views/controllers (replaces ng-view on index.html). Easy.
However, when inside a given view controller (let's say Pictures) I now want to know what side bar was clicked (I would like to default to a given side bar animal when Pictures is first clicked in the app since that would be required) and I'd also like to be able to copy the link directly to there (ie Pictures/Bears (but this always just goes to the Pictures controller but inside there I know Bears was clicked so I can act accordingly)).
So if I click Tigers, the controller will know this and I can code it to get pictures of Tigers.
I don't want to put that side bar into each page itself since it's always the same. I just want it on index.html to avoid repeating myself even though this would be more direct in terms of coding each top bar view. This would be something I'd fall back to in the case of what I'm asking to do isn't possible.
I'm also wondering if it's possible to maintain the current side bar value when they click on a different top link animal. So if I was in Pictures/Lions and they click Bears, it would know to route Pictures/Bears. Since it's staying in Pictures would it really even need to route? Can it route and then call a method on the Pictures controller passing in the animal so it can do what it needs to with that information?
Try making a service like animalService that keeps track of the selected animal. This will act like your own route handler for just that side menu.
The controller for the side menu would then be able to call animalService.selectAnimal(selectedAnimal) to update the selection.
Each main page controller could then watch the value of the selected animal from animalService. There are a few ways to do this, but it would probably be easiest to use a subscription based approach:
Each controller would call animalService.subscribeToChange('controllerName', callback) on initialization and then on destroy it would call animalService.unsubscribeFromChange('controllerName'). The animalService would keep a list/map of all of the subscribed controllers, so it can execute the callback every time the selectAnimal function is called and detects a change.
If you provide a code sample I could try to give a more detailed solution.
Alternatively
You could take advantage of $rootScope. I find this a bit more hacky, but it would be probably quicker to implement. The side menu can access a root scope variable via something like $root.currentAnimal, and it can both get and set that value. Then each controller can use $rootScope.$watch('currentAnimal', function() {}) to trigger something on change ($rootScope is a service).

Cordova - Angular - <select> tag open a new view

I have an Angular/Cordova app and I'm trying to figure out how should I handle the HTML SELECT tag. What I would like to do is to open a new window with all the options in a list, the user picks one and returns with that value.
The problem is when I do that I lose all the data I had in the first screen as I am closing it when I move to the second one.
I am using Angular's UI.ROUTER. One thing, which I am not too convinced to do, is to save all data entered into StateParams, and when I return, place it back.
What would be the best approach?
It really depends on the use case. If you need to be able to "deep link" to the view where a link loads the view with the pop-up active then using ui-router and stateparams makes the most sense. If deep linking isn't a concern and the user must always select something then you can just use a service/factory/value/provider in order to share the data between the controllers during the lifetime of the app.

Ionic Back Button Doesn't Hide after exhausting $window.history.back()

I have an ionic app that has a search template that has a form where you can query posts by keyword. I also have a service that returns the post(s) as a list on another view. All that is working well.
My search controller upon submitting the search form uses:
$state.go('app.search.results', {'searchId': hash});
so that I can have a unique url for that search. I needed this unique url to implement 'back' functionality so that if a user clicks on one of the posts in the list, after viewing the post if they decide to click back, they would get to see the results of the search still (by default they would be returned to the search form without any results anymore).
To allow for a back to search results I implemented a custom back button function and put it on the ionic back button element like this:
<ion-nav-back-button ng-click="goBack()">
and then setup a the custom function:
$scope.goBack = function() {
$window.history.back();
}
All of this works well, I can go back to search results and see them, essentially very much like normal browser back functionality.
Problem for me is that when I have gone all the way 'back' via the back button, my initial state contains the 'Back' button and clicking it does not go anywhere and the 'Back' button still shows. Ionic does pretty good about hiding the back button when it shouldn't be there but in this case not so. Any ideas for how to check when history is exhausted and hiding the back button conditionally would be appreciated.
EDIT:
Here is a jsFiddle ; Note: open fiddle in a new, separate tab to see back button issue. FYI Search is in the menu.
One of the few qualms I have with Ionic is their "smart" navigation. I have run into a lot of problems with this myself. My solution was to create a back button of my own, this back button stores previous states and their params so you can go back and not lose search results for example with your scenario.
This component gives you both a back button and breadcrumbs to use (or you can just use back button)
It is open source and feel free to use it!
jscBreadcrumbs
Strange Milk - Breadcrumbs Post
Here is your jsFiddle with the jscBreadcrumbs implemented and working:
jsFiddle
jscbreadcrumbs
You use $window.history.back(), I think you should use $ionicHistory.goBack(); instead. It can control the history and view and state in the ionic way.

Intercepting all clicks with AngularJS to warn user of unsaved data

I have a lengthy form customers will need to fill out. If they click a link on a page, it will navigate away from that Controller and they will lose any data they may have already input.
If I can determine the form has not yet been saved, how can I intercept any click to the links on the page so I can ask the user if they want to save their form first?
No code yet- sorry. Many thanks.
I've written an angularjs directive that you can apply to any form that will automatically watch for changes and message the user if they reload the page or navigate away. #see https://github.com/facultymatt/angular-unsavedChanges
Hopefully you find this directive useful!
sorry for the late answer but mabye someone stumbles upon this and finds it useful. I have encountered the same problem and at the beginning i tryed to use the ng-dirty class applyed to the form element but because i had some custom controls the ng-bind won't be applyed when i changed some fields.
The best way i found so far is to detect when the model is changed with the use of $locationChangeStart event.
$scope.$on('$locationChangeStart', function (event, next, current) {
//we are about to leave the page so it's time to see if the form was modified by the user
if (!$scope.isFormClean())
{
event.preventDefault();
}
});

Add to passbook not working

I am having a lot of trouble with this and I have finally decided to come here. I feel as if I am making a noob mistake. I created a Passbook pass and I am using PKAddPassesViewController to add the pass. When I present the pass controller, the pass shows up correctly. However, when I decide to press "add" nothing happens, nothing gets logged or anything. After investigating, I added a delegate and the delegate method is as follows:
-(void)addPassesViewControllerDidFinish:(PKAddPassesViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
However, instead for the normal animated dismiss, The controller dismisses as of the app crashes but instead goes to the previous view controller. This is absolutely driving me nuts and any help at all would be greatly appreciated :)
Thanks.
The addPassesViewControllerDidFinish is an optional delegate method, and it is called after the PKAddPassesViewController view controller has been dismissed. In your case, your code could be crashing because you are attempting to dismiss the parent view controller (self).
When 'nothing happens' when adding a pass, it is usually because the pass is not valid. The pass signature does not get checked until after the 'Add' button has been pressed, so this may explain why you see a pass displayed, but then it disappears after you press add. If everything works as expected if you press cancel, then this is probably your issue.
To get more info on what is happening to the Pass, turn on 'Additional Logging' in the Developer Settings on your device, then check the console log of the device (from the Organizer) as you try to add the pass to see if it gives any clues as to why the add is failing.

Resources