I am using the Angular Material CDK Drag and Drop Functionality in my application. The drag and drop functionality is working fine, unless I am using it within a dialog (for most components I am using Nebular, in this case the Nebular dialog). The problem I am encountering is, as soon as I drag a draggable element within the dialog, the element disappears behind the dialog. After dropping it, it reappears on the correct position. In the screenshot, I am dragging the "AAAA" element away from the list - it disappears behind the dialog.
Stackblitz: https://stackblitz.com/edit/angular-znqckb
I am using the following implementation:
<div cdkDropList cdkDropListOrientation="horizontal" class="example-list" [cdkDropListData]="techs"
(cdkDropListDropped)="drop($event)">
<button *ngFor="let tech of techs" nbButton cdkDrag>{{tech}}</button>
</div>
Component.ts:
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.techs, event.previousIndex, event.currentIndex);
}
I did not modify the style sheet. I assume this issue can be solved somehow by modifying the z-index but I don't know how to apply it to the "dragging" element.
You can change the DragRefConfig injecting the right config (with the desired z-index) in your component. For example:
const DragConfig = {
dragStartThreshold: 0,
pointerDirectionChangeThreshold: 5,
zIndex: 10000
};
providers: [{ provide: CDK_DRAG_CONFIG, useValue: DragConfig }]
The z-index of the preview element will be 10000 ;-)
For more infos: https://material.angular.io/cdk/drag-drop/api#DragRefConfig
I'm struggling with this problem myself and I'm using a crude workaround for now. Forcing the z-index of .cdk-overlay-container to 1000 in your global styles (styles.scss) should get you the result you want. It's not best practice though.
Add this in styles.scss:
.cdk-overlay-container {
z-index: 1000 !important;
}
Stackblitz here
To my knowledge, it's not possible to force a z-index on the drag preview ("dragging" element) because the cdk sets its z-index dynamically as inline style. The Nebular library you are using seems to be setting the z-index of the overlay container to 1040. The Angular Material library sets the drag preview's z-index as 1000, that's why it goes behind the overlay. Vanilla Angular Material sets the z-index of cdk overlay to 1000, so drag & drop will work in that scenario.
For previous angular material versions than 9.
In the html dragable element:
<div ... cdkDrag (cdkDragStarted)="onDragStarted($event)"</div>
In the compoonent ts:
export class ...{
zIndexSerial: number = 1000;
onDragStarted(event: CdkDragEnd): void {
event.source.element.nativeElement.style.zIndex=this.zIndexSerial+"";
this.zIndexSerial = this.zIndexSerial+1;
}
for anyone struggling with the same issue.I found the solution to be z-index only work on positioned elements Refer to this link description here
For Angular version 8, I added the following to styles.scss and got it to work in the modal:
.cdk-drag-preview {
z-index: 9000 !important;
}
See .cdk-drag-preview in https://material.angular.io/cdk/drag-drop/overview#styling
Related
I know there are lots of questions regarding modal not showing and I have it working in places already, but this one is different!
I have a Wordpress project where I am showing an Angular app in the admin. The app has Bootstrap 4 used. So I did not want to effect the Wordpress admin with the Bootstrap 4 css when the Angular app loads.
To make it work, I used a method where the app is wrapped by a div with a class="bootstrap" and I used less to convert the bootstrap css such that it all is surrounded by the .bootstrap class. Therefore a class .text-danger is written like .bootstrap .text-danger and it works perfect! My admin is not effected by the bootstrap css and yet the angular app inside the admin is isolated.
Now the problem is when I try to add ngb-modal to the game! It apparently adds the modal and its backdrop elements right before the body tag which is outside the bootstrap wrapper div and therefore the isolated css does not apply on these elements.
Is there a way that when I call the modal like below, it is added with a wrapping div element like this <div class="bootstrap">...ngb-modal code here...</div>?
const modalRef = this.modalService.open(MyModalComponent);
I hope I explained the issue well!
I found the solution!
It is to call the modal like this:
// Create modal options
const modalOptions: NgbModalOptions = {
container: '#id_my_bootstrap_container'
};
// Show the modal
const modalRef = this.modalService.open(MyModalComponent, modalOptions);
The div should have the id applied:
<div class="bootstrap" id="id_my_bootstrap_container">...ngb-modal code here...</div>
This will create the modal inside that div instead of creating it under body tag and thus the modal css applies to it even if it is prefixed by bootstrap class.
This seems to be some css issue and some guru would know how to fix right away.
I am using https://github.com/kekeh/mydatepicker which works as i require except i need to make some layout changes to the input box.
i am able to see desired changes if i do that in the chrome browser via developer tools but not able to get them working by applying the css.
so if you take a look at the screenshot:
https://www.dropbox.com/s/2dhri8ylss3pfgd/Screenshot%202017-09-30%2018.27.41.png?dl=0
i need to set the height to 25px rather 34px.
try to override class like .selectiongroup etc. doesnt help
you should use the height attribute to override input height.
private myOptions: IMyDpOptions = {
firstDayOfWeek: 'su',
editableDateField: false,
openSelectorOnInputClick: true,
height: '25px'
};
<my-date-picker [options]="myOptions" [(ngModel)]="XYZ" (dateChanged)="XYZ($event)"></my-date-picker>
I am using bootstrap datepicker on a website, It is also styled to be sticky by giving its parent a fixed position, Its working fine normally but on testing it on Ipad and Iphone (not tested on andriod devices yet), when I scroll down and try to touch the datepicker to open it , it scrolls back to the top of the page, how can I fix this issue?
Similar problem arises when I am using a custom dropdown Selectric
I have created a simple striped down version of the problem here. Note that the problem wont replicate on emulator but on an actual mobile device or ipad.
I also faced same issue and resolved it as below solution , you can try it.
datepicker has beforeShow property where you have to set calendar position.
$("#EffectiveDateAccept").datepicker({
changeMonth: true,
changeYear: true,
// minDate: 0,
dateFormat: 'mm/dd/yy',
beforeShow: function (input, inst) {
var calendar = inst.dpDiv;
setTimeout(function () {
calendar.position({
my: 'center bottom',
at: 'top',
collision: 'none',
of: input
});
}, 1);
}
});
Try this
.dropdown-menu{
position: fixed!important
}
This issue is found unrelated to specific environment (not iOS only) and has a solution as follows:
You should find out which datepicker div class sets datepicker actually from hidden to visible (which of them change upon successful show and hide event).
Add to your css for that class (here modal-open) the missing show command:
body.modal-open {
overflow: visible;
}
Now the scroll should stay in place.
Example refers to html like:
<body>
<div class="modal-open">
Datepicker
</div>
</body>
Source:
Bootstrap modal: background jumps to top on toggle
PS. My source has also 18 other options, if this seems too hacky.
I have made this current one once, worked like charm and was not so tricky to do.
just add This CSS code to your site it will fix that issue.
.element{
position: sticky!important;
}
If you view it in Inspect Element, it's creating a separate DIV in HTML which has position absolute. Just change that position to sticky. That's why that happens. See in the image.
You can do this by adding this line of CSS code:
.dropdown-menu {
position: sticky;
}
Hope that will help you
As a start, have you looked thru the GH repo's issues for something matching your description?
This link specifically sounds promising:
https://github.com/uxsolutions/bootstrap-datepicker/issues/1866
I think what might be occurring is that your datepicker is set to absolute of the body, not the parent you are setting as "fixed".
So when you click to open the datepicker, your mobile device is scrolling you to the active element (in this case, the datepicker at the top, set to absolute on the parent).
Also there seems to be some default mobile behavior related to scrolling:
https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling
Perhaps setting the following will help:
-webkit-overflow-scrolling: auto; /* Stops scrolling immediately */
The following link provides more context on this scrolling behavior:
https://weblog.west-wind.com/posts/2015/Jun/05/IPad-Scroll-Issues-with-Fixed-Content
I have a web app using angular 2 and angular materials. I am using a simple modal:
<h1 md-dialog-title *ngIf="data">{{data.title}}</h1>
<div md-dialog-content>What would you like to do?</div>
<div md-dialog-actions></div>
But when I run the app the modal's height is 100%. When I inspect with Chrome dev tools, it looks like Angular Materials/Angular 2 is injecting some classes that wrap around the md-dialog-content. Here is a snapshot:
Anyways, does anyone have any suggestion how to override the behavior so I can manually affect the size? Thanks.
Have you tried opening your dialog with specific height that you need? like:
let dialogRef = dialog.open(UserProfileComponent, {
height: '400px',
width: '600px',
});
Another way to force custom styles is to customize the theme itself. you can have a look at the guide here.
You can override material styling from your scss/css.
But due to view encapsulation, you need to use /deep/ selector that will allow you to get hold of the Material class added when the component is rendered. For example:
/deep/ .mat-tab-group.mat-primary .mat-ink-bar{
background-color: red;
}
I'm new to Dojo and CSS, so maybe I'm missing something obvious here.
I have a page with several Dijit buttons that are created programmatically, and I want to make one of them bigger- leave the text alone and increase the space between the text and the edge of the button. I don't want to override the CSS for .dijiButtonNode to do so because there are other Dijit buttons the page that shouldn't be altered.
I tried adding this to the widget declaration:
style: { padding: "1em" }
and this:
class: "PaddedButton"
.PaddedButton
{
padding: 1em;
}
but since Dijit buttons are rendered as nested spans it padded the area around the button instead.
The best way to work with CSS is using one of the browser debugging tools (that you should already be using) like Firebug or the Chrome developer tools. You can find an element's DOM node easily with inspect_element and then directly edit its CSS styles until they do what you want. You can also see what CSS rules are active and what are being ignored or overwritten.
I have come up with a working example here:
http://jsfiddle.net/missingno/FrYdx/2/
The important part is the following CSS selector:
.paddedButton.dijitButton .dijitButtonNode {
padding: 1em;
}
This selects any node with class dijitButtonNode that descends from a node that has both of the paddedButton and dijitButton classes. I couldn't do just a .paddedButton .dijitButtonNode because then the rule would end up being cascaded by a more specific selector.