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

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.

Related

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();
}
});

Backbone.js: Disallow backbone history

I came on this site to research a problem that I've been having regarding negating Backbone.js's history for certain elements. Thankfully, I came across this answer: here.
While it had provided a solution for me, the ultimate result was partial.
PROBLEM:
I am using Backbone.js for my navigation. I navigate to a route called "Portfolio" and then a number of images show up which can then be clicked again to view information. In order to render this information, I have it going through another route. The aforementioned resolution had me assigning the following code to negate these Portfolio links from being part of the History:
$(this).bind('click', function(e){
theSiteController.navigate('portfolio/portfolioSelection/' + i, {trigger:true, replace: true });
});
I had applied replace: false to the .navigate and it worked: whenever I hit the Back button, I would skip back to the origin page that I came from. HOWEVER, when I hit the Forward button in my browser, it points me back to the Portfolio link that I had clicked before, which looks like this:
#portfolio/portfolioSelection/4
I have it set to a different View, so I'm wondering if that has something to do with it.
QUESTION:
When I click the Forward button in my browser, how would I re-route it so that way it goes to
#portfolio
instead of
#portfolio/portfolioSelection/4
To view the site, please click here.
I apologize if this has been answered, but I can't seem to find a proper resolution.
Thank you, in advance, for your help!

Backbone.js: How to utilize router.navigate to manipulate browser history?

I am writing something like a registration process containing several steps, and I want to make it a single-page like system so after some studying Backbone.js is my choice.
Every time the user completes the current step they will click on a NEXT button I create and I use the router.navigate method to update the url, as well as loading the content of the next page and doing some fancy transition with javascript.
Result is, URL is updated which the page is not refreshed, giving a smooth user experience. However, when the user clicks on the back button of the browser, the URL gets updated to that of a previous step, but the content stays the same. My question is through what way I can capture such an event and currently load the content of the previous step and present that to the user? Or even better, can I rely on browser cache to load that previously loaded page?
EDIT: in particular, I'm trying something like mentioned in this article.
You should not use route.navigate but let the router decide which form to display based on the current route.
exemple :
a link in your current form of the registration process :
<a href="#form/2" ...
in the router definition :
routes:{
"form/:formNumber" : "gotoForm"
},
gotoForm:function(formNumber){
// the code to display the correct form for the current url based on formNumber
}
and then use Backbone.history.start() to bootstrap routing

AngularJS Save Browse History

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/

How can I simulate a button click from a page controller?

I'm creating a Google-like application in Visualforce where the user enters a search term, clicks Search, and the results are displayed underneath the search box. As part of this, when the user clicks Search, an actionStatus is set up to display "Loading..." while the search is in progress:
<apex:commandButton value="Search" action="{!runQuery}" status="loading"/>
Now I'm trying to set up the landing page, which is just a page with an input field and a Search button, for the initial search. In Google style, the first search will take the user to the page where results are displayed with the search box moved up to the top.
The problem is that I don't know how to invoke the actionStatus at page load. It's easy enough when the user clicks a button, but when searching from the landing page, a new page is loaded and then the search is carried out. At the moment I just have the controller's constructor checking for parameters and, if any are found, calling runQuery() manually, but this simply delays the page load time and doesn't invoke the actionStatus.
Any ideas?
Use
<apex:actionFunction name="runQueryJS" action="{!runQuery}" status="loading" />
to create a client-side invocation point, then attach a handler on body's loaded event (or wherever else you want to run query from) which will call the runQueryJS() javascript function which will do an Ajax call to search.
Adding an onLoad event call didn't work, but putting this at the very end of the page, just before the closing apex:page tag, appears to. I'm not entirely sure why, but it's clean and gets the job done.
<script>
runQuery();
</script>

Resources