I have a draggable modal window and users move it around. They want it to open at the original position, every time they close the window and reopen again. How can I do that? Thanks.
You can use bootstrap modal events
show.bs.modal This event fires immediately when the show instance method is called. If caused by a click, the clicked element is available as the relatedTarget property of the event.
by default the bootstrap modal slide-down from top and if position of modal changes while dragging, it can be rest to original position with show.bs.modal when close and re-open next time.
$('selector').on('show.bs.modal', function () {
// do something...
});
Demo Fiddle modal slide and open in middle
In above fiddle, added a custom position to modal so modal slide and open in middle of the page
.modalnewposition {
-webkit-transform: translateX(-0%) translateY(25%);
-moz-transform: translateX(-0%) translateY(25%);
-ms-transform: translateX(-0%) translateY(25%);
transform: translateX(-0%) translateY(25%);
}
HTML
<div id="myModal" class="modal fade modalnewposition" role="dialog">
Then created another class
.original {
transform: translate(0px, 0px);
transition: transform 0.3s ease-out 0s;
transition: opacity 0.15s linear 0s;
}
Using show.bs.modal I added the original selector to modal so it adjust it's position before showing and override the modalnewposition selector so modal slide and open at top instead in middle of page.
$(document).ready(function() {
$('#myModal').on('show.bs.modal', function () {
$('.modal').addClass("original");
});
});
Demo Fiddle modal slide and open at top
Above example is just to demonstrate that what you asked is achievable with show.bs.modal function.
Add this code to js and execute it every time modal window closes:
var scrollableContentOfModal = document.getElementById(...);// change it accordingly
document.querySelector(scrollableContentOfModal).scrollTop = 0;
Related
I'm trying to make a dual infinite scroll case when new items are added as the user scrolls either all the way up or all the way down.
<ion-infinite-scroll (ionInfinite)="scrolledUp($event)" position="top">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
<ion-list>
<ion-item *ngFor="let item of items">
<!-- item content -->
<ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="scrolledDown($event)" position="bottom">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
The problem is that the list opens initially at the bottom. Of course I can scrollIntoView the first item on ionViewDidEnter but it wouldn't look nice and would confuse the users.
I noticed it's the one with position=top that is responsible for the initial position at the bottom.
Is there a way to set the initial scroll position for the ion-infinite-scroll without having to explicitly scroll the list to top?
As I initially suspected the infinite scroll component does force a scroll to bottom if position is set to top. It occurs in the componentDidLoad method as shown below:
async componentDidLoad() {
const contentEl = this.el.closest('ion-content');
if (contentEl) {
await contentEl.componentOnReady();
this.scrollEl = await contentEl.getScrollElement();
}
this.thresholdChanged();
this.disabledChanged();
if (this.position === 'top') {
writeTask(() => {
if (this.scrollEl) {
this.scrollEl.scrollTop = this.scrollEl.scrollHeight - this.scrollEl.clientHeight;
}
});
}
}
As the component provides no means to intervene in this behavior and without an option to extend or otherwise customize the default stencil components, I turned to a somewhat hacky way to achieve the desired behavior.
Therefore, you first need to remove the position=top part from the ion-infinite-scroll declaration in your view so that the scroll part of the above code won't trigger. You would also provide a name for the ion-infinite-scroll so that it can be referenced from your page class.
<ion-infinite-scroll #top (ionInfinite)="scrolledUp($event)">
Then you make a reference to #top above in your page.
#ViewChild('top') topScroller;
Then in the ionViewDidEnter life cycle hook, you can set the position for the scroller as top.
setTimeout(() => {
this.topScroller.position = 'top';
}, 200);
It has to be in a time out because the topScroller variable is still not assigned when ionViewDidEnter is called and the next life cycle hook is ionViewWillLeave which won't be that useful for our purpose.
I'm having trouble finding documentation on this.
In Ionic, the menu has functionality where if you click on the backdrop, the menu dismisses. So basically click anywhere except the menu and the menu goes away. I want to disable this functionality so users can interact with items below the backdrop.
I've tried disabling pointer events on the backdrop and the menu, but the dismiss still seems to occur. Any thoughts?
Interesting discovery; the menu dismiss functionality actually looks like it might be on the ion-content. Which leads to an issue:
I want users to be able to interact with the content with ion-content without dismissing the menu.
For me, this helped:
ion-menu {
pointer-events: none;
}
ion-menu > * {
pointer-events: all;
}
Here is the sample code how you can do this in your ionic application.
import { Platform, MenuController } from 'ionic-angular';
// ... Other code
constructor(menuCtrl: MenuController /* ... other code ...*/)
// ... Other code
let menu = menuCtrl.get();
menu.swipeEnable(false); // Disable drag to open/close
// Override default behaviour of closing the menu on
// content or backdrop click
menu['onBackdropClick'] = () => {
// No-op
};
menu.ionOpen.subscribe(() => {
// When the menu is open ...
// Remove Ionic's CSS rules for menu-content-open class that restricts
// mouse events on ion-nav
menu.getContentElement().classList.remove("menu-content-open");
// Reduce the size of the content pane so that it does not
// overflow off the screen
menu.getContentElement().style.width =
`calc(100% - ${menu.getMenuElement().clientWidth}px)`;
});
menu.ionClose.subscribe(() => {
// When the menu is closed ...
// Restore the size of the content pane
menu.getContentElement().style.width = '';
});
I made a stackblitz project you can check it out. You can check it out from here.
this is Ionic version 1 question:
i have 4 tabs, each of the tab have it's content, one of them have a list inside it...
so if we have a list inside 3rd tab, then we choose the list and go to single page with back button...
after i tab the back button, it back to 1st tab, not to 3rd tab...
it seems that it cannot remember the position by default, i have tried some workaround like this...
i set the tab just before it enter the previous page:
$scope.$on("$ionicView.beforeEnter", function (event, data) {
$ionicTabsDelegate.select($scope.maintabindex);
});
with this on-select on each tab:
<ion-tab title="Forum" icon-on="ion-tab-fa-headphones" icon-off="ion-tab-fa-headphones" on-select="tabSelected()" href="#/app/home">
and then i have this function:
$scope.tabSelected = function () {
$scope.maintabindex = $ionicTabsDelegate.selectedIndex();
};
the problem is, the on-select method executed after i back to the parent page (*with tab page), so it cannot working well, because $ionicTabsDelegate.selectedIndex() on-select always give 0 index after i back from the single page to the tabbed page
any idea?
The ionic go back button should work in those scenarios, be sure that the child's view route is using the same ui-view as the parent tab. If that is the case and it is still not working, it's better for you to override the backbutton on the childs view to go to the parent.
Like this:
<ion-nav-bar ng-controller="MyCtrl">
<ion-nav-back-button class="button-clear"
ng-click="myGoBack()">
<i class="ion-arrow-left-c"></i> Back
</ion-nav-back-button>
</ion-nav-bar>
function MyCtrl($scope, $ionicHistory) {
$scope.myGoBack = function() {
$ionicHistory.goBack();
};
}
You can even replace the myGoBack() function with $state.go('parent-tab-view')
Can the navigation between tabs be customized to as in the navcontainer i.e. while selecting tabs the view should scroll and change from left to right like swipe navigation with new page as in navcontainer.
You could achieve the slide in effect rather easily by adding the following CSS to your application
#keyframes slidein {
from {
right: -100%;
}
to {
right: -6px;
}
}
.sapUiTabPanel {
overflow:hidden;
}
.sapUiTabPanel > * {
animation: slidein 500ms;
position: absolute;
}
Note that you may need to add CSS with vendor prefixes depending on which browsers you are supporting.
To achieve the slide out of the current displayed tab is a bit tricky, one possible way this could be achieved is with the following code added to somewhere like the onInit method of your controller
oTabStrip1.attachBrowserEvent("mousedown",function(oEvent){
var oTarget = oEvent.target;
if(oTarget.className==="sapUiTabClose"){
return;
}
var iIdx = oTabStrip1.getItemIndex(oTarget);
if (iIdx > -1) {
if ((iIdx !== oTabStrip1.getSelectedIndex()) && (oTabStrip1.getTabs()[iIdx].getEnabled())) {
oEvent.stopPropagation();
oEvent.preventDefault();
jQuery.each(
oTabStrip1.getTabs()[oTabStrip1.getSelectedIndex()].getContent(),function(i,o){
var sAnimateLeft = (o.$().innerWidth() * -1) + "px";
o.$().animate({left:sAnimateLeft},500);
});
setTimeout(function(){
oTabStrip1.selectTabByDomRef(oTarget);
},250);
}
}
});
The above is assuming oTabStrip1 is the instance of your tabstrip control. Although it's often not good practice to modify the DOM directly within UI5 applications, in this case it's probably safe as the content of the displayed tab is removed and replaced with the clicked tab content, so all we are doing is delaying this until the slide out animation is complete.
You can see a working example at http://jsbin.com/vukibi - the code has been taken directly from the tabstrip example with the above CSS and JS added
I need to hide dockbar for non logged in guests. I did that by creating custom theme that uses welcome-theme as a parent, and the following snippet:
#if($is_signed_in)
#dockbar()
#end
in theme's templates\portal_normal.vm.
This presents another problem - when page reorders to fit a mobile screen, menu collapses to a button in the dockbar which is hidden. I would love to have it collapse somewhere else, just that it isn't hidden - for example next to the small logo / site title, or as a first breadcrumbs item.
How to do it, or where to begin. I appreciate any help.
Menu collapses by default for phone and tablet viewports. You can create your own button to open/close collapsed menu in phone/tablet viewport. Check following simplified example:
Theme velocity template:
#if(!$is_signed_in)
<div id="mainNavigationToggle" class="btn btn-secondary">
<i class="icon-reorder"></i>
</div>
#end
Theme main.js:
AUI().ready(function (A) {
var navigationToggleBtn = A.one('#mainNavigationToggle'); // get our toggle button
var navigationUl = A.one(Liferay.Data.NAV_SELECTOR); // get default navigation ul element
if (navigationToggleBtn && navigationUl) { // do nothing when toggle button not present (user not signed in) or if navigation is not present
navigationToggleBtn.on( // otherwise assign simple function that'll toggle 'open' menu class on default navigation which will cause it to open, same for menu toggle button
'click',
function (event) {
navigationToggleBtn.toggleClass('open');
navigationUl.toggleClass('open');
}
);
}
}
);
Theme custom.css:
#mainNavigationToggle {
display: none; /* hide by default */
#include respond-to(phone, tablet) {
display: block; /* show only for phone and tablet viewports */
}
}