Uikit Modal not destroying when route is changed (Angular) - javascript

What do I want?
I want to destroy Modals containing my Angular components to be closed and destroyed so it does produce side-effects when I am changing routes (For example using the browser back button).
Actual Results
When changing routes using my app's Navbar, either the Modal stays in the DOM and I am not able to scroll anything on the screen or The Modal simply does not close.
Artifacts such as which should be removed when we close the modal are still present.
I have tried using
UIkit.modal(myModalId).$destroy(true) to remove the modal from dom.
Jquery $(modalId).remove(); Modal removed from DOM but when we go back to the modal page, the Buttons are not triggering the modals.
My Code
Button that Opens Modal
<button uk-toggle="target: #myModalId">Open Modal</button>
Modal template
<div id="myModalId" class="uk-flex-top acc-modal" uk-modal="esc-close: false; bg-close: false; stacked: true; cls-page: 'acc-modal-page';">
<div class="uk-modal-dialog uk-modal-body uk-margin-auto-vertical" style="width: 431.6px !important; ">
<button class="uk-modal-close-default uk-close-large" type="button" id="close-event" uk-close></button>
<h2 class="uk-modal-title">
Modal Title</h2>
<My-Child-Component (newItemEvent)="updateDataAfterChild($event)" #MyChildComponent></My-Child-Component>
</div>
</div>
Hide and Destroy modal when route component destroys.
destroyModal(modalId: string){
const modal = uikit.modal(modalId);
modal.hide();
modal.$destroy(true);
}
ngOnDestroy(){
try{
this.destroyModal('#'+myModalId);
}catch(err){
console.log(err);
}
}

Use routerLink and <router-outlet></router-outlet>.
You can do something like this.
<button mat-flat-button color="primary" routerLink="/login">Login</button>
<button mat-flat-button color="primary" routerLink="/signup">Signup</button>
<router-outlet></router-outlet>
Your Components will show in place of <router-outlet></router-outlet> and they will destroy previous component. [Source]
Thoughts:
I believe this way of routing is done because of the 'nature' of the Single Page Applications.

Related

Vue/JavaScript - Stop 'preventDefault' from affecting child components

I am trying to create a modal dialog in Vue. When the dialog is open, I want the page scrolling to be disabled but the user should still be able to scroll the dialog, and I was trying to achieve this with preventDefault. My component looks like this:
<!--Modal.vue-->
<template>
<div v-show="open" class="modal" #scroll.stop.prevent #wheel.stop.prevent>
<div class="mask"></div>
<div class="overlay">
<div class="dialog">
<button #click="$emit('close')">CLOSE</button>
<Paragraphs />
</div>
</div>
</div>
</template>
<script>
import Paragraphs from "./Paragraphs";
export default {
components: {
Paragraphs,
},
props: {
open: Boolean,
},
};
</script>
<!--some scoped CSS here-->
Full working example on the sandbox https://codesandbox.io/s/optimistic-pond-3zrxsf
The problem is that while this arrangement is preventing page scrolling, it is also freezing scrolling on the dialog itself, which I don't want. And apparently stopPropagation only prevents bubbling up, but not down the DOM tree, so that isn't helping either. What can I do to achieve this?
Note: I do not want to set the overflow-y property of the body tag as that takes away the scrollbars completely and has a jittery effect of everything shifting to the side by a few pixels when the dialog is opened or closed.

Preventing automatic modal in second level container

I am using bootstrap modals in project. In one page i have 2 containers that, one of them is inside the other one. The outer one has a modal trigger on click event and the inner one has a routing to another page. I can get modal popup if i click on outer container. That's okay but the problem is if i click the smaller container, modal triggered also before routing.
<div class="outer" data-toggle="modal" data-target="#exampleModal">
<a href="somewhere">
<div class="inner></div>
</a>
</div>
How can i prevent the pop up if i click the inner container.
I know i can cancel modal if i catch the hover event for inner container but i am looking more bootstrap way.
Changed your html a bit. I have put the link inside the inner div. Then using jquery you can stop propagation.
<div class="outer" data-toggle="modal" data-target="#exampleModal">
sadsdaddsads<br/>
asdsddsa<br/>
<div class="inner">asadds </div>
</div>
<script>
$(document).ready(function() {
$('.outer > .inner').click(function(e) {
//alert("inner div clicked");
e.stopPropagation();
});
});
</script>

Open and close modal dialog in same function

I have a site that populates data into a table when it loads. Each column header is clickable resulting in the table sorting based on that column's data. This works fine, but it is slow so i was hoping to have a modal window popup advising the end user to wait while it sorts. I have the code for the modal window already made as well as the javascript line to call it and close it, but I cannot get it to appear and then disappear when the sort is done.
Modal Code:
<div id="SortingBox" class="modal3">
<!-- Modal content -->
<div class="modal-content3">
<div class="modal-header2">
<h2>Loading</h2>
</div>
<div class="modal-body2">
<pre><strong style="color: black;">Please Wait...</strong></pre>
</div>
</div>
</div>
I call the modal with this line:
document.getElementById('SortingBox').style.display='block';
And close it with this:
document.getElementById('SortingBox').style.display='none';
Now I already have this working on page load and the line to close it is at the end of the sorting script in a separate js file. So all I want it to be able to have it appear when a column header is clicked and close again after the sort is complete.
Thanks.
Why not just use classList's toggle method?
Create a class that called is-modal-hidden, with display: none.
// style.css
.is-modal-hidden {
display: none;
}
Create a js function to toggle modal, by toggling the class.
Something like that:
function toggleModal() {
document.getElementById('SortingBox').classList.toggle('is-modal-hidden');
}

Angular2 - MaterializeCSS: Modal dialogs don't open

I'm using Angular2 with materializecss.
At the moment I'm trying to create modal dialogs which open on button click. There is also an example in the docs https://www.npmjs.com/package/angular2-materialize.
I also use a materilize-select which works perfectly fine, so I guess the installation, imports etc. are correct.
The problem is, when I click the modal-trigger the router resolves the new Route "localhost:4200/#modal1" and I'm redirected to my startpage.
I also tried to replace href with data-target="modal1" but that didn't work either.
Can I somehow disable the Hash-Links for the Router? My other routes are without hashes.
Heres the example from npm docs. I copied this part 1:1.
<!-- Modal Trigger -->
<a materialize="leanModal" [materializeParams]="[{dismissible: false}]" class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
<!-- Modal Structure -->
<div id="modal1" class="modal">
<div class="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div class="modal-footer">
Agree
</div>
</div>
Any help/hints are appreciated!
Edit: I changed the anchor to call a function on click
<a materialize="leanModal" [materializeParams]="[{dismissible: false}]" class="waves-effect waves-light btn modal-trigger" (click)="openModal()>Modal</a>
which triggers
$('#modal1').openModal()
But now I get an error:
j.velocity is not a function
Edit 2:
Got it to open the modals by using jQuery instead of $. I still get the error and the Application is stuck after opening the modal.
I found a solution. Was quite frustrating to get there but here it is:
I reinstalled everything that was related to materialize + angular-cli, being angular2-materialize, materialize-css, jquery and hammerjs (which does not need to be installed manually).
Then I followed the instruction from npmjs and removed the part which imports material-css in app.module.ts.
import "materialize-css";
And after that everything works just fine. No need to alter the webpack settings in angular2-materialize package or anything like that. My versions are:
angular-cli 1.0.0-beta.16
angular2-materialize 5.2.1
materialize-css 0.97.7
jquery 2.2.4
I hope that I can save other people some frustrating hours I had with that.
I might be late for this, but you put those two attributes in modal trigger <a> rather than the modal <div> itself.
I also did exactly same mistake as OP, but after reading the angular2-materialize page carefully, I corrected my code as mentioned below.
Instead of this
<!-- Modal Trigger -->
<a materialize="leanModal" [materializeParams]="[{dismissible: false}]" class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
You have to put like:
<!-- Modal Trigger -->
<a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
<!-- Modal Structure -->
<div id="modal1" class="modal" materialize="leanModal" [materializeParams]="[{dismissible: false}]">
...
</div>
Three points to note here:
there are no special attributes in <a> i.e. the trigger
in place of materialize="leanModal", it is materialize="modal" in modal
didn't need to remove import "materialize-css"; in my case
You can try to use open\close programmatically by:
handle (click)="openModal()" on the href
$('#modal1').openModal(); inside the openModal() function
remove the href="#modal1"
having a closeModal() function with $('#modal1').closeModal();
see http://materializecss.com/modals.html when the doc says:
You can also open modals programatically, the below code will make your modal open on document ready:
Face same problem and above solutions not help me on this, so write a new answer
Just add $('.modal').modal(); in your components constructor.
import ... './stuff'
declare var $: any
#Component{...}
export class EditBlogComponent ...{
constructor(){
//Initialize modal here solve my
$('.modal').modal();
}
}

Add a Back button after removing nav-bar in Meteor-Ionic app

In a Meteor-Angular-ionic app, after hiding the nav-bar in a template to achieve a full-screen view using
<ion-view hide-nav-bar="true">
how do we add a Back button on the top left of the screen that will bring the user back to the previous page?
The idea is to have no visible navbar in one particular template/controller, but still have a back button.
One solution could be to add your custom back button, which will be navigating to the previous screen.
In your template, add the following button
<button class="button icon-left ion-android-arrow-back button-clear button-dark"
ng-click="myGoBack()">
</button>
Now, define the custom myGoBack function in your controller
// Your controller
function MyCtrl($scope, $ionicHistory) {
// myGoBack method
$scope.myGoBack = function() {
$ionicHistory.goBack();
};
}
Remember to inject the dependency of ionicHistory in your controller.
Please refer the link ionNavBackButton
for more detailed information.
Hope this will help.
Thanks!
Use the following div
<div class="col-md-12">
<button class="pull-left btn btn-primary"> Back </button>
<div>

Categories