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

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>

Related

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.

AngularJS - using Angular UI router - how to fetch the next content via AJAX without removing the current content

I'm using Angular UI router in my app. This is what I'm doing.
A main view contains a child view and a div container for "pagination"
By default, initially, a first set of contents is loaded
When a user clicks on "next page", next set of contents is loaded (with the URL also being changed to /content/2 (where 2 indicates the next page number)
All is working well, but each time the contents are loaded, it goes "blank" before it loads. So it seems like it's reloading the view (which is obvious).
What I would like to do is reload the content without having that "blank" page. How can I achieve this?
At first thought, I think you could you the same approach as infinite-scroll, which is what I'm using. So you make a GET request to the server to get new content and push it to the list on clicking 'next'. However, since the URL changes also. This will cause the controller to be reloaded. You can actually bypass this by setting reloadOnSearch to false.

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: 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

undelegating events handlers on 'lose-focus'

I am trying to phrase this as clearly as I can.
I have a view that shows a form. I am tying an event handler to the submit button like this:
events: {
'click #bsubmit': 'save'
}
In the save function, on success, I take care to undelegateEvents() before I navigate away:
...
that.undelegateEvents();
window.router.navigate('#/home');
...
So if someone comes to this page, submits the page and goes to (actually: is sent back) the home page, is all good.
However, there is also a 'home' link shown there, which part of the top level template. It is specified like this:
Home
So if someone comes to this page, clicks on the home link, and (from there) returns to this page, the event is mapped a second time. Now when someone submits the form, it gets submitted two times.
Given that I have many views, and the navigation away can happen in many ways, what is the common pattern to undelegateEvents when navigation happens at a higher (uncontrollable) manner? Or am I doing something fundamentally wrong?
In your case you don't need to undelegate events. Simply remove your form from the DOM with $('el').remove(), javascript events will automatically be removed
The best solution would be to have a HomepageView and FormView each in the same container (let say .container).
Example of a complete scenario:
User go to #homepage, we instanciate a HomepageView and render it in .container
User go to #form, we instanciate a FormView and render it in .container
User go to #homepage, we instanciate a HomepageView and render it in .container
...etc, etc
So, each time the user navigate to a new route the previous view is replaced by the new one.
As the previous view HTML no longer belongs to the DOM you don't need anymore to undelegate events.
Of course the .container element do not belongs to our views, each view has it's own element rendered inside the .container element.
Read this blog post for more informations.

Resources