My angular app's content creation flow is being broken by androids and browsers physical buttons which take the user to where they came from instead of previous step in the process. I tried fixing it with locationChangeStart as well as few other similar events, but they all get triggered both by my "Continue" buttons as well as physical "back" buttons.
Is there a way to trigger an event only when user presses browsers/android's back button, or alternatively to know if locationChangeStart was triggered by the back button vs app's button? If possible, I would like avoid adding jQuery as we are not currently using it.
I gave up on trying to detect the user pressing back button and act on it. Instead, make it the default action and change the way our buttons behave. I detect when user is pressing one of our buttons and set a variable based on it.
var navigating = false;
$scope.$on('$locationChangeStart', function(event) {
if($scope.global.application="new-ad" && !navigating){
event.preventDefault();
$scope.areYouSure = true;
}
});
$scope.nextStep = function() {
navigating = true;
$location.url('/step-two');
}
Basically, we first set our variable to false, and if the user presses physical back, it will display the prompt alerting user they will lose their work. However, if the user instead uses our "continue" button, also triggering the locationChange, it will set variable to true, letting the app know what the locationChange is triggered from within the app and allowing it to continue.
Related
I am creating a simple app for mobile using angular6. There are two buttons in my app and I need to call a function when click/tap the two buttons at the same time. After a lot of search, I found touch event handling functions in js.Here is my code
app.component.ts
testfunc(event) {
this.testval = 1;
}
testfunc1() {
this.testval = 2;
}
testfunc2(event) {
event.preventDefault();
if (this.testval == 1) {
alert(this.testval);
}
}
app.component.html
<div class="clutchBtn" #clBtn (touchstart)="testfunc($event)" (touchend)="testfunc1()"></div>
<div class="gearBtn" #gearBtn (touchstart)="testfunc2($event)"></div>
in the above code I used 'touchstart' and 'touchend' event handlers to detect the entering and leaving of touch events in the dom elements.If the user touches the first button then testfunc() will be called and the value of 'testVal' will be set to 1. If the user finger removed from the first button then value of 'testVal' is set to 2.Then I add a testfun2() in the second button to detect whether the user is still touches the first button.The issue is the touch event doesn't work properly ie, when I press two buttons at the same time then the alert box will be displayed after that it still be displayed when i press only the second button. Because the value of testVal is still '1'.how can I solve this issue?is there any other good way to detect the clicking of two buttons at the same time?
you should be able to query the element
#ViewChild('buttonVar') button;
touchStart1$:Observable<any>;
Then apply register the touch event
ngOnInit() {
this.touchStart1$ = Observable.fromEvent(this.button.nativeElement, 'touchstart');
}
do that for both the button and use RxJS forkJoin operator to combine the two observables to wait for both actions to be clicked.
Edit:
In fact, do not use forkJoin. There are more to it to achieve that is described.
For working example, check out this stackblitz:
https://stackblitz.com/edit/angular-5cjt1b
I want to redirect client to custom controller when he click back browser button.
Do you know any clear ways to catch back button event and force to call server?
Bests,
Thank you
Back button question is quite well answered on SO. A quick search will turn up lots of extra information. Here is a bit of a summary.
You have a few strategies to choose from.
1 - If you are developing an SPA (or not) you may find making use of the history api useful.
https://developer.mozilla.org/en-US/docs/Web/API/History
https://developer.mozilla.org/en-US/docs/Web/API/History_API
You will find plenty on SO about history api.
Try starting here Preserve dynamically changed HTML on back button
Basically, by adding a listener for popstate event which fires everytime the active history entry changes :
(in jQuery)
$(document).ready(function () {
$(window).on('popstate' , function (event) {
console.log('popstate');
console.log(event);
console.log(event.originalEvent);
});
};
http://caniuse.com/#search=history
2 - add a listner for the pageshow event, will fire when a page load is completed and when session history entry is used for navigation, so basically forward & back buttons.
https://developer.mozilla.org/en-US/docs/Web/Events/pageshow
$(window).on('pageshow' , function (event) {
console.log('pageshow');
console.log(event);
console.log(event.originalEvent);
});
http://caniuse.com/#search=pageshow
3 - Append a hashvalues to your urls with window.location.hash = 'pageHashValue'.
Listen for hashchange event and you can then act based on the #value if needed.
https://developer.mozilla.org/en-US/docs/Web/Events/hashchange
This is a common approach in single page applications.
$(window).on('hashchange' , function (event) {
console.log('hashchange');
console.log(event);
console.log(event.originalEvent);
console.log(window.location.hash);
});
http://caniuse.com/#search=hashchange
Finally take note that while you, as a developer, no doubt hate the browser back button (like me) our users tend to love it. If you change the expected behavior of the back button you can also expect your user experience to be negatively affected. The best strategy is to use these events to maintain the expected behavior of the back button rather than to try and change it.
I'm building a custom confirmation popup which comes when ever user want to navigate from page without saving any detail. & I'm not able to find a right way to do this ?
Basically I have decided to put a function on window.beforeunload = func(e) event and use
e.preventDefault(); this syntax to prevent the redirect , actually the occurrence of event e. Now is there any way to re-fire the same event(It could be page redirect/ submit), If use clicks on the 'Ok' button.
You cannot use event.preventDefault() in window.onbeforeunload. You can only return dialogue for the onbeforeunload() function to give to the user.
https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload
I am creating a mozilla extension that converts the content of a webpage on click of the "convert button"(Label: Convert) in other language
and its label gets converted to English so that on click of that button(Label: English) the content gets converted into original form
I tried to set attribute "changedcontent" with each tab so that on event focus ,focussed tab reads its "changedcontent" attribute and set the label on button ("Convert" or "English")
problem arises where i need to switch between multiple tabs, plugin in the different tab should maintain different state depending on whether it is displaying changed content(should display button label: English)
or it is in its original form(should display button label: "Convert")
so when i click refresh button or click other link in the webpage. The label of the button which is "English" with converted content on the page should gets changed to "Convert"
so for this i have handled page unload event to track page refresh or link click, but since webpage may contain multiple frames/iframes this event is getting called multiple times.
If in the meantime i switch the tab, label of other tab gets converted from "English" to "Convert"
code of the unload event is:
window.addEventListener('unload', unloadingDocument, true);
function unloadingDocument()
{
var currentTab = gBrowser.selectedTab;
currentTab.setAttribute("changedcontent" , "false");//set the transliterated attribute back to false
var convertButton = document.getElementById("convert_button");
convertButton.setAttribute("label","Convert");
}
Please suggest how can i solve this problem and maintain different states of mozilla plugin between multiple tabs.
Thanks
You could use the Session Store API to have independent state between tabs.
-- EDIT:
So if you already have a way to know if a specific tab is "Translated or not", if you want the button to change to have the correct state when another tab is selected, you might want to check for the tabSelect event: Detecting tab selection
In this event you check your tab attribute to check if you have to change or not the label/behaviour of your button.
-- Edit 2 :
If when you click the "Convert" button you do your processing, and you set the attribute changedcontent of that tab to true. Then you have a load/unload listener to check for the refresh, to change the state back to false. Then if you change tabs, you would have the tabSelect event to change the button whenever you change tabs.
If you add this listener when you change changedcontent to true. Then when the event beforeunload is first called, you check if changedcontent is true, you change it to false and remove the listener.
I am creating a datagrid with hundreds of rows which contain a checkbox on each row so that the user can select an item from the grid.
Now the user may spend a great deal of time going filtering/searching through the grid and ticking the required checkboxes, only to accidentally press the backspace key on their keyboard or click on a hyperlink on the page. And they would lose all their checkbox selections.
So I want to introduce some functionality whereby if at least one checkbox has been ticked, then if the user unintentionally does an action that would navigate them away from the page, then a JavaScript confirm message is displayed to notify the user of this.
The checkboxes would all belong to the same group, for instance it would be called "products".
Is this possible to do at all?
There is a beforeunload event which occurs when the user navigates away: http://jsfiddle.net/FprNV/1/.
Returning a string there results in a message appearing with two buttons (stay/navigate); the exact implementation of this dialog differs across browsers.
$(window).bind('beforeunload', function() {
var checkboxcount = $("input:checkbox:checked").length;
if(checkboxcount > 0) {
return 'Are you sure?';
}
});