Custom Modal Dialog Box in Browser back in Angular 4+ - javascript

Suppose my current route is /transact/orders and is in Order summary view, What I want to do is to open a custom dialog which gives the option to add to cart or cancel button when he/she presses browser back button of the browser.If user press add to cart button it goes to the cart or else the browser back button functionality will happen. Currently, I am using Angular 5.2.I would like to know if it is possible with LocationStrategy.I searched but could not get a proper example of it.Can anybody explain with proper example?

You can subscribe to Location events anywhere you want to do actions on back button pressed:
import { Subscription } from 'rxjs/Subscription';
ngOnInit() {
this.subscription = <Subscription> this.location.subscribe( () => {
// your code here
} );
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
Don't forget to unsubscribe in OnDestroy.
EDIT: location should be type Location, not LocationStrategy

Related

Close a modal when user clicks back button in browser React Js

I am showing user a modal that takes over the entire screen if user is accessing the website on phone. A user tends to instinctively click the back button on their phone to go back to the previous screen instead of using the close button provided on the modal.
Is there a way to intercept the function that is triggered when a user clicks the back button? I want to close the modal when user clicks the back button on their phone, instead of having them redirect to the previous page.
Use the History API. An example on how to acomplish this is:
//listen for state changes
window.onpopstate = (event) =>
{
if (!event.state.modalOpened)
{
closeModal()
}
}
//change the actual page state so it contains the modalOpened property
window.history.replaceState({modalOpened: false})
function openModal(content)
{
//push new state, put the modal information in the state object, this will push a new state, when the user presses the back button, the browser will just trigger the onpopstate event, instead of going to the previous page
window.history.replaceState({modalOpened: true})
//this is any code you use to open your modal, for example
ReactDOM.render(<Modal>{content}</Modal>, document.getElementById("modal-container")
}
class based component
There are many ways to aproach this, this is one of them, everything you need to make something that fits with your app is in the History API DOCS.
//listen for state changes
window.onpopstate = (event) =>
{
if (!event.state.modalOpened)
{
updateModal(false, null)
}
}
function openModal()
{
//push new state, put the modal information in the state object, this will push a new state, when the user presses the back button, the browser will just trigger the onpopstate event, instead of going to the previous page
window.history.replaceState({modalOpened: true})
updateModal(false, <div>Modal content!</div>)
}
function updateModal(open, content)
{
ReactDOM.render(<Modal open={open} content={content} />, document.getElementById("modal-container")
}
//change the actual page state so it contains the modalOpened property
window.history.replaceState({modalOpened: false})
class Modal extends React.Component {
constructor(props) {
super(props);
}
render() {
//check the history to determine if we have to open or close the modal
return <div className={"modal " + (props.open)? "show" : ""}><div className="modal-content">{props.content}</div><button onClick={() => window.history.back()}>OK</button></div>;
}
}

ng-bootstrap(NgbModal): Is there any way to conditionally prevent a modal from closing?

I have a pretty basic modal that is being used to let a user enter notes
openNotes(conquest) {
const modalRef = this.modalService.open(EditNotesModalComponent);
modalRef.result.then((result) => {
console.log('closed', result);
},
(reason) => {
console.log('dismissed', reason);
});
return modalRef;
}
What I'd like to do is, in the event that the user closes the modal when there is an unfinished note, show another modal that will remind them that they have unsaved work that will be lost if they close the modal. I would like the user to then be able to choose to keep editing (in which case the second modal will close and the first modal will remain open) or discard their work (in which case both modals would close).
It's easy enough to connect something like this to custom modal closing actions, such as the user manually clicking a button that would normally close the modal. The problem I am having is that I do not seem to be able to know when the user has dismissed the modal via clicking outside the modal or hitting the ESC key.
In UibModal for AngularJS, you could catch such events with something like this:
$scope.$on('modal.closing', (event) => {
if (this.newNote.length > 0) {
event.preventDefault();
this.openConfirmModal();
}
});
and then, depending on how the confirmation modal resolves, one can decide to either close the modal or keep it open. Is something like this possible for NgbModal in Angular 4?
Thanks!
Edit: I know about the beforeDismiss function on in NgbModalOptions, but AFAIK you can't pass any parameters to this function. I would like the confirmation modal to pop up only when the user has unfinished notes in the modal.
You can use #Viewchild to get a reference to the input field in the modal, then use the beforeDimiss function to get the text typed by the user.
The following example has a modal with a <textarea> and when the modal is dismissed (either by clicking the backdrop or pressing ESC), the value in the textarea is logged to the console.
HTML
In the HTML, add a template reference variable to the input field:
<div class="modal-body">
<textarea #myTextarea></textarea>
</div>
Modal Component TypeScript
In the modal component TS file, get a reference to the input field using #ViewChild:
#ViewChild('myTextarea') textarea;
Parent Component Typescript
In the component where the modal is opened from, add the following beforeDimiss function. The line modalRef.componentInstance.textarea.nativeElement.value will get the value from the input field:
open() {
const modalRef = this.modalService.open(NgbdModalContent, {
beforeDismiss: () => {
console.log('The text typed by the user before the modal was dimissed was:')
console.log(modalRef.componentInstance.textarea.nativeElement.value)
return true;
}
});
}
Please see this StackBlitz for a demo.

Is there anyway to find whether the add to home screen - app icon has been added to home screen using Javascript?

Configured our app to support Add to home screen option, to ask for permission we added one button, onclick the prompt will ask to add the icon in home screen. If the user keep clicking close, then it wont ask further, so the button becomes non-functional.
If the user already added icon, i didn't get any method to find it.
There isn't any method best known to me to capture whether the app icon has been added to home screen or not. Simple reason for that could be absence of any valid existing use case. However, what you can capture is the action taken by the user. When the A2HS banner is shown, you can tap into the beforeinstallprompt event to determine the choice made by the user when presented with the banner.
The code below shows this in action:
window.addEventListener('beforeinstallprompt', function(event) {
event.userChoice.then(function(result) {
if(result.outcome == 'dismissed') {
// User dismissed
}
else {
// User accepted
}
});
});
UPDATE:
While going through the official doc for A2HS, found a way to determine if the app was successfully added to the users home screen after they accepted the prompt, you can listen for the appinstalled event. Code:
window.addEventListener('appinstalled', (evt) => {
app.logEvent('a2hs', 'installed');
});
appinstalled does not work
window.addEventListener('appinstalled', (evt) => {
app.logEvent('a2hs', 'installed');
});

Prevent component from unmounting - showing notification to users before opening other component

In my web app there is a form where users put in data. If they want to navigate to other component or back, I want to notify them that changes were made to form and show them confirmation dialog.
I know how to implement this if users click on back button on top of the form, but don't have any idea how to handle it when users click on sidebar menu options. (there is a sidebar with multiple links to other components - using react-router).
I have tried something using componentWillunmount() but no luck since component gets unmounted in any case.
If anyone has experience in this I would really need some help.
Try the routerWillLeave hook, here is a example from react-router's documentation:
const Home = withRouter(
React.createClass({
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave)
},
routerWillLeave(nextLocation) {
// return false to prevent a transition w/o prompting the user,
// or return a string to allow the user to decide:
if (!this.state.isSaved)
return 'Your work is not saved! Are you sure you want to leave?'
},
// ...
})
)
https://github.com/ReactTraining/react-router/blob/master/docs/guides/ConfirmingNavigation.md

React Redux Confirming Navigation

I'm trying to achieve a product page, which gives the Administrator an ability to modify the product details by clicking an edit button, but if the Admin tries to leave the page with changes that they have not yet saved, it would confirm that the user wants to leave the page without saving.
Here is what I currently have in my ProductForm.js, which is used by Product.js when Admin clicks edit.
import { browserHistory } from 'react-router';
componentWillReceiveProps() {
browserHistory.listenBefore(location => {
console.log(location);
return 'Are you sure you want to leave the page without saving?';
});
}
The issue with the following code is that when the user opens the edit form, this confirmation message shows on every page transition, even if you're not on the product page.
I am using the following skeleton. https://github.com/erikras/react-redux-universal-hot-example
You can cancel listener like this:
import { browserHistory } from 'react-router';
componentWillReceiveProps() {
const cancelListner = browserHistory.listenBefore(location => {
console.log(location);
cancelListner();
return 'Are you sure you want to leave the page without saving?';
});
}

Categories

Resources